Skip to content

Commit

Permalink
Add a test that validates ingress routes
Browse files Browse the repository at this point in the history
Create a new test harness to simplify sending URL requests to running
routers.
  • Loading branch information
smarterclayton committed Feb 19, 2018
1 parent d36f1f3 commit dd0be4c
Show file tree
Hide file tree
Showing 7 changed files with 636 additions and 1 deletion.
101 changes: 101 additions & 0 deletions test/extended/router/router.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package images

import (
"net/http"
"time"

g "github.com/onsi/ginkgo"
o "github.com/onsi/gomega"

kapierrs "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"

routev1 "github.com/openshift/api/route/v1"
routeclientset "github.com/openshift/client-go/route/clientset/versioned"
exutil "github.com/openshift/origin/test/extended/util"
"github.com/openshift/origin/test/extended/util/url"
)

var _ = g.Describe("[Conformance][Area:Networking][Feature:Router]", func() {
defer g.GinkgoRecover()
var (
host, ns string

configPath = exutil.FixturePath("testdata", "ingress.yaml")
oc = exutil.NewCLI("router", exutil.KubeConfigPath())
)

g.BeforeEach(func() {
_, err := oc.AdminAppsClient().Apps().DeploymentConfigs("default").Get("router", metav1.GetOptions{})
if kapierrs.IsNotFound(err) {
g.Skip("no router installed on the cluster")
return
}
o.Expect(err).NotTo(o.HaveOccurred())

// wait for the router endpoints to show up
err = wait.PollImmediate(2*time.Second, 120*time.Second, func() (bool, error) {
epts, err := oc.AdminKubeClient().CoreV1().Endpoints("default").Get("router", metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred())
if len(epts.Subsets) == 0 || len(epts.Subsets[0].Addresses) == 0 {
return false, nil
}
host = epts.Subsets[0].Addresses[0].IP
return true, nil
})
o.Expect(err).NotTo(o.HaveOccurred())

ns = oc.KubeFramework().Namespace.Name
})

g.AfterEach(func() {
if g.CurrentGinkgoTestDescription().Failed {
exutil.DumpPodLogsStartingWithInNamespace("router", "default", oc.AsAdmin())
}
})

g.Describe("The HAProxy router", func() {
g.It("should respond with 503 to unrecognized hosts", func() {
t := url.NewTester(oc.AdminKubeClient(), ns)
defer t.Close()
t.Within(
time.Minute,
url.Expect("GET", "https://www.google.com").Through(host).SkipTLSVerification().HasStatusCode(503),
url.Expect("GET", "http://www.google.com").Through(host).HasStatusCode(503),
)
})

g.It("should serve routes that were created from an ingress", func() {
g.By("deploying an ingress rule")
err := oc.Run("create").Args("-f", configPath).Execute()
o.Expect(err).NotTo(o.HaveOccurred())

g.By("waiting for the ingress rule to be converted to routes")
client := routeclientset.NewForConfigOrDie(oc.AdminConfig())
var r []routev1.Route
err = wait.Poll(time.Second, time.Minute, func() (bool, error) {
routes, err := client.Route().Routes(ns).List(metav1.ListOptions{})
if err != nil {
return false, err
}
r = routes.Items
return len(routes.Items) == 4, nil
})
o.Expect(err).NotTo(o.HaveOccurred())

g.By("verifying the router reports the correct behavior")
t := url.NewTester(oc.AdminKubeClient(), ns)
defer t.Close()
t.Within(
3*time.Minute,
url.Expect("GET", "http://1.ingress-test.com/test").Through(host).HasStatusCode(200),
url.Expect("GET", "http://1.ingress-test.com/other/deep").Through(host).HasStatusCode(200),
url.Expect("GET", "http://1.ingress-test.com/").Through(host).HasStatusCode(503),
url.Expect("GET", "http://2.ingress-test.com/").Through(host).HasStatusCode(200),
url.Expect("GET", "https://3.ingress-test.com/").Through(host).SkipTLSVerification().HasStatusCode(200),
url.Expect("GET", "http://3.ingress-test.com/").Through(host).RedirectsTo("https://3.ingress-test.com/", http.StatusFound),
)
})
})
})
124 changes: 124 additions & 0 deletions test/extended/testdata/bindata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

104 changes: 104 additions & 0 deletions test/extended/testdata/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
kind: List
apiVersion: v1
items:
# an ingress that should be captured as three routes
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
tls:
- hosts:
- 3.ingress-test.com
secretName: ingress-endpoint-secret
rules:
- host: 1.ingress-test.com
http:
paths:
- path: /test
backend:
serviceName: ingress-endpoint-1
servicePort: 80
- path: /other
backend:
serviceName: ingress-endpoint-2
servicePort: 80
- host: 2.ingress-test.com
http:
paths:
- path: /
backend:
serviceName: ingress-endpoint-1
servicePort: 80
- host: 3.ingress-test.com
http:
paths:
- path: /
backend:
serviceName: ingress-endpoint-1
servicePort: 80
# an empty secret
- apiVersion: v1
kind: Secret
metadata:
name: ingress-endpoint-secret
type: kubernetes.io/tls
stringData:
tls.key: ""
tls.crt: ""
# a service to be routed to
- apiVersion: v1
kind: Service
metadata:
name: ingress-endpoint-1
spec:
selector:
app: ingress-endpoint-1
ports:
- port: 80
targetPort: 8080
# a service to be routed to
- apiVersion: v1
kind: Service
metadata:
name: ingress-endpoint-2
spec:
selector:
app: ingress-endpoint-2
ports:
- port: 80
targetPort: 8080
# a pod that serves a response
- apiVersion: v1
kind: Pod
metadata:
name: ingress-endpoint-1
labels:
app: ingress-endpoint-1
spec:
terminationGracePeriodSeconds: 1
containers:
- name: test
image: openshift/hello-openshift
ports:
- containerPort: 8080
name: http
- containerPort: 100
protocol: UDP
# a pod that serves a response
- apiVersion: v1
kind: Pod
metadata:
name: ingress-endpoint-2
labels:
app: ingress-endpoint-2
spec:
terminationGracePeriodSeconds: 1
containers:
- name: test
image: openshift/hello-openshift
ports:
- containerPort: 8080
name: http
- containerPort: 100
protocol: UDP
9 changes: 9 additions & 0 deletions test/extended/util/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/storage/names"
kclientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
clientcmd "k8s.io/client-go/tools/clientcmd"
kinternalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
e2e "k8s.io/kubernetes/test/e2e/framework"
Expand Down Expand Up @@ -386,6 +387,14 @@ func (c *CLI) InternalAdminKubeClient() kinternalclientset.Interface {
return kubeClient
}

func (c *CLI) AdminConfig() *restclient.Config {
_, clientConfig, err := configapi.GetExternalKubeClient(c.adminConfigPath, nil)
if err != nil {
FatalErr(err)
}
return clientConfig
}

// Namespace returns the name of the namespace used in the current test case.
// If the namespace is not set, an empty string is returned.
func (c *CLI) Namespace() string {
Expand Down
2 changes: 1 addition & 1 deletion test/extended/util/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func DumpPodLogs(pods []kapiv1.Pod, oc *CLI) {
}

dumpContainer := func(container *kapiv1.Container) {
depOutput, err := oc.AsAdmin().Run("logs").Args("pod/"+pod.Name, "-c", container.Name).Output()
depOutput, err := oc.AsAdmin().Run("logs").WithoutNamespace().Args("pod/"+pod.Name, "-c", container.Name, "-n", pod.Namespace).Output()
if err == nil {
e2e.Logf("Log for pod %q/%q\n---->\n%s\n<----end of log for %[1]q/%[2]q\n", pod.Name, container.Name, depOutput)
} else {
Expand Down
Loading

0 comments on commit dd0be4c

Please sign in to comment.