mirror of https://github.com/knative/func.git
214 lines
4.6 KiB
Go
214 lines
4.6 KiB
Go
//go:build integration
|
|
// +build integration
|
|
|
|
package k8s_test
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
appsV1 "k8s.io/api/apps/v1"
|
|
coreV1 "k8s.io/api/core/v1"
|
|
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/util/intstr"
|
|
"k8s.io/apimachinery/pkg/util/rand"
|
|
"k8s.io/client-go/kubernetes"
|
|
"knative.dev/func/pkg/k8s"
|
|
)
|
|
|
|
func TestDialInClusterService(t *testing.T) {
|
|
var err error
|
|
var ctx = context.Background()
|
|
|
|
clientConfig := k8s.GetClientConfig()
|
|
|
|
rc, err := clientConfig.ClientConfig()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
cliSet, err := kubernetes.NewForConfig(rc)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pp := metaV1.DeletePropagationForeground
|
|
creatOpts := metaV1.CreateOptions{}
|
|
deleteOpts := metaV1.DeleteOptions{
|
|
PropagationPolicy: &pp,
|
|
}
|
|
|
|
testingNS, _, err := clientConfig.Namespace()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
rnd := rand.String(5)
|
|
one := int32(1)
|
|
labels := map[string]string{"app.kubernetes.io/name": "helloworld"}
|
|
deployment := &appsV1.Deployment{
|
|
ObjectMeta: metaV1.ObjectMeta{
|
|
Name: "helloworld-" + rnd,
|
|
Labels: labels,
|
|
},
|
|
Spec: appsV1.DeploymentSpec{
|
|
Replicas: &one,
|
|
Selector: &metaV1.LabelSelector{
|
|
MatchLabels: labels,
|
|
},
|
|
Template: coreV1.PodTemplateSpec{
|
|
ObjectMeta: metaV1.ObjectMeta{
|
|
Labels: labels,
|
|
},
|
|
Spec: coreV1.PodSpec{
|
|
Containers: []coreV1.Container{
|
|
{
|
|
Name: "helloworld",
|
|
Image: "gcr.io/knative-samples/helloworld-go@sha256:2babda8ec819e24d5a6342095e8f8a25a67b44eb7231ae253ecc2c448632f07e",
|
|
Ports: []coreV1.ContainerPort{
|
|
{
|
|
Name: "http",
|
|
ContainerPort: 8080,
|
|
Protocol: coreV1.ProtocolTCP,
|
|
},
|
|
},
|
|
Env: []coreV1.EnvVar{
|
|
{
|
|
Name: "PORT",
|
|
Value: "8080",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
_, err = cliSet.AppsV1().Deployments(testingNS).Create(ctx, deployment, creatOpts)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_ = cliSet.AppsV1().Deployments(testingNS).Delete(ctx, deployment.Name, deleteOpts)
|
|
})
|
|
t.Log("created deployment:", deployment.Name)
|
|
|
|
svc := &coreV1.Service{
|
|
ObjectMeta: metaV1.ObjectMeta{
|
|
Name: "helloworld-" + rnd,
|
|
},
|
|
Spec: coreV1.ServiceSpec{
|
|
Ports: []coreV1.ServicePort{
|
|
{
|
|
Name: "http",
|
|
Protocol: coreV1.ProtocolTCP,
|
|
Port: 80,
|
|
TargetPort: intstr.FromInt(8080),
|
|
},
|
|
},
|
|
Selector: labels,
|
|
},
|
|
}
|
|
|
|
svc, err = cliSet.CoreV1().Services(testingNS).Create(ctx, svc, creatOpts)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_ = cliSet.CoreV1().Services(testingNS).Delete(ctx, svc.Name, deleteOpts)
|
|
})
|
|
t.Log("created svc:", svc.Name)
|
|
|
|
// wait for service to start
|
|
time.Sleep(time.Second * 5)
|
|
|
|
dialer := k8s.NewLazyInitInClusterDialer(clientConfig)
|
|
t.Cleanup(func() {
|
|
dialer.Close()
|
|
})
|
|
|
|
transport := &http.Transport{
|
|
DialContext: dialer.DialContext,
|
|
}
|
|
|
|
var client = http.Client{
|
|
Transport: transport,
|
|
}
|
|
|
|
svcInClusterURL := fmt.Sprintf("http://%s.%s.svc", svc.Name, svc.Namespace)
|
|
resp, err := client.Get(svcInClusterURL)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
runeReader := bufio.NewReader(resp.Body)
|
|
matched, err := regexp.MatchReader("Hello World!", runeReader)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !matched {
|
|
t.Error("body doesn't contain 'Welcome to nginx!' substring")
|
|
}
|
|
if resp.StatusCode != 200 {
|
|
t.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
}
|
|
|
|
var eg errgroup.Group
|
|
for i := 0; i < 10; i++ {
|
|
eg.Go(func() error {
|
|
resp, err := client.Get(svcInClusterURL)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
_, err = io.Copy(io.Discard, resp.Body)
|
|
return err
|
|
})
|
|
}
|
|
err = eg.Wait()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestDialUnreachable(t *testing.T) {
|
|
var ctx = context.Background()
|
|
|
|
dialer, err := k8s.NewInClusterDialer(ctx, k8s.GetClientConfig())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
dialer.Close()
|
|
})
|
|
|
|
_, err = dialer.DialContext(ctx, "tcp", "does-not.exists.svc:80")
|
|
if err == nil {
|
|
t.Error("error was expected but got nil")
|
|
return
|
|
}
|
|
if !strings.Contains(err.Error(), "no such host") && !strings.Contains(err.Error(), "does not resolve") {
|
|
t.Errorf("error %q doesn't contain expected substring: ", err.Error())
|
|
}
|
|
|
|
_, err = dialer.DialContext(ctx, "tcp", "localhost:80")
|
|
if err == nil {
|
|
t.Error("error was expected but got nil")
|
|
return
|
|
}
|
|
if !strings.Contains(err.Error(), "connection refused") {
|
|
t.Errorf("error %q doesn't contain expected substring: ", err.Error())
|
|
}
|
|
}
|