From 1c028de03ab593ceaaeffbafb58e330efe120b6c Mon Sep 17 00:00:00 2001 From: Filipe Brandenburger Date: Tue, 27 Jan 2015 16:38:48 -0800 Subject: [PATCH] Initial adoption of ginkgo in e2e tests In order to adopt ginkgo incrementally, let's start by replacing test/e2e/driver.go with a call to ginkgo runner and convert each of the other tests to a small Decscribe() snippet that simply calls the legacy TestXYZ function. From this basis we can take further incremental steps by converting individual tests to native ginkgo format, using Fail() for all failure cases, using By() for logs, enabling JUnit reports, etc. Tested: - cmd/e2e builds and `make check` passes. - Running _output/bin/.../e2e on an alive cluster works. - Running the full hack/e2e-test.sh works as expected. --- test/e2e/basic.go | 11 +++ test/e2e/cluster_dns.go | 11 +++ test/e2e/driver.go | 123 +++------------------------ test/e2e/important_urls.go | 11 +++ test/e2e/kubelet_sends_events.go | 11 +++ test/e2e/liveness.go | 19 +++++ test/e2e/network.go | 11 +++ test/e2e/pod_has_service_env_vars.go | 11 +++ test/e2e/pod_update.go | 11 +++ test/e2e/private.go | 11 +++ test/e2e/roservice.go | 11 +++ 11 files changed, 131 insertions(+), 110 deletions(-) diff --git a/test/e2e/basic.go b/test/e2e/basic.go index b8ca60ce9db..71fe3025c56 100644 --- a/test/e2e/basic.go +++ b/test/e2e/basic.go @@ -27,6 +27,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) // A basic test to check the deployment of an image using @@ -189,3 +192,11 @@ func TestBasicImage(c *client.Client, test string, image string) bool { func TestBasic(c *client.Client) bool { return TestBasicImage(c, "basic", "kubernetes/serve_hostname:1.1") } + +var _ = Describe("TestBasic", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestBasic(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/cluster_dns.go b/test/e2e/cluster_dns.go index 3a817868aa6..4ed5f6cca2c 100644 --- a/test/e2e/cluster_dns.go +++ b/test/e2e/cluster_dns.go @@ -24,6 +24,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) // TestClusterDNS checks that cluster DNS works. @@ -150,3 +153,11 @@ func TestClusterDNS(c *client.Client) bool { glog.Infof("DNS probes using %s succeeded", pod.Name) return true } + +var _ = Describe("TestClusterDNS", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestClusterDNS(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/driver.go b/test/e2e/driver.go index b20b5ca4383..58882516295 100644 --- a/test/e2e/driver.go +++ b/test/e2e/driver.go @@ -17,46 +17,18 @@ limitations under the License. package e2e import ( - "math/rand" "time" - "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" + "github.com/onsi/ginkgo" + "github.com/onsi/ginkgo/config" + "github.com/onsi/gomega" ) -type testSpec struct { - // The test to run - test func(c *client.Client) bool - // The human readable name of this test - name string -} +type testResult bool -type testInfo struct { - passed bool - spec testSpec -} - -// Output a summary in the TAP (test anything protocol) format for automated processing. -// See http://testanything.org/ for more info -func outputTAPSummary(infoList []testInfo) { - glog.Infof("1..%d", len(infoList)) - for i, info := range infoList { - if info.passed { - glog.Infof("ok %d - %s", i+1, info.spec.name) - } else { - glog.Infof("not ok %d - %s", i+1, info.spec.name) - } - } -} - -// Fisher-Yates shuffle using the given RNG r -func shuffleTests(tests []testSpec, r *rand.Rand) { - for i := len(tests) - 1; i > 0; i-- { - j := r.Intn(i + 1) - tests[i], tests[j] = tests[j], tests[i] - } -} +func (t *testResult) Fail() { *t = false } // Run each Go end-to-end-test. This function assumes the // creation of a test cluster. @@ -77,85 +49,16 @@ func RunE2ETests(authConfig, certDir, host, repoRoot, provider string, orderseed glog.Fatalf("This test has timed out. Cleanup not guaranteed.") }() - tests := []testSpec{ - {TestKubernetesROService, "TestKubernetesROService"}, - {TestKubeletSendsEvent, "TestKubeletSendsEvent"}, - {TestImportantURLs, "TestImportantURLs"}, - {TestPodUpdate, "TestPodUpdate"}, - {TestNetwork, "TestNetwork"}, - {TestClusterDNS, "TestClusterDNS"}, - {TestPodHasServiceEnvVars, "TestPodHasServiceEnvVars"}, - {TestBasic, "TestBasic"}, - {TestPrivate, "TestPrivate"}, - {TestLivenessHttp, "TestLivenessHttp"}, - {TestLivenessExec, "TestLivenessExec"}, - } + // TODO: Make -t TestName work again. + // TODO: Make "times" work again. + // TODO: Make orderseed work again. - // Check testList for non-existent tests and populate a StringSet with tests to run. - validTestNames := util.NewStringSet() - for _, test := range tests { - validTestNames.Insert(test.name) - } - runTestNames := util.NewStringSet() - for _, testName := range testList { - if validTestNames.Has(testName) { - runTestNames.Insert(testName) - } else { - glog.Warningf("Requested test %s does not exist", testName) - } - } + var passed testResult = true + gomega.RegisterFailHandler(ginkgo.Fail) + // Turn of colors for now to make it easier to collect console output in Jenkins + config.DefaultReporterConfig.NoColor = true + ginkgo.RunSpecs(&passed, "Kubernetes e2e Suite") - // if testList was specified, filter down now before we expand and shuffle - if len(testList) > 0 { - newTests := make([]testSpec, 0) - for i, test := range tests { - // Check if this test is supposed to run, either if listed explicitly in - // a --test flag or if no --test flags were supplied. - if !runTestNames.Has(test.name) { - glog.Infof("Skipping test %d %s", i+1, test.name) - continue - } - newTests = append(newTests, test) - } - tests = newTests - } - if times != 1 { - newTests := make([]testSpec, 0, times*len(tests)) - for i := 0; i < times; i++ { - newTests = append(newTests, tests...) - } - tests = newTests - } - if orderseed == 0 { - // Use low order bits of NanoTime as the default seed. (Using - // all the bits makes for a long, very similar looking seed - // between runs.) - orderseed = time.Now().UnixNano() & (1<<32 - 1) - } - // TODO(satnam6502): When the tests are run in parallel we will - // no longer need the shuffle. - shuffleTests(tests, rand.New(rand.NewSource(orderseed))) - glog.Infof("Tests shuffled with orderseed %#x\n", orderseed) - - info := []testInfo{} - passed := true - for i, test := range tests { - glog.Infof("Running test %d %s", i+1, test.name) - // A client is made for each test. This allows us to attribute - // issues with rate ACLs etc. to a specific test and supports - // parallel testing. - testPassed := test.test(loadClientOrDie()) - if !testPassed { - glog.Infof(" test %d failed", i+1) - passed = false - } else { - glog.Infof(" test %d passed", i+1) - } - // TODO: clean up objects created during a test after the test, so cases - // are independent. - info = append(info, testInfo{testPassed, test}) - } - outputTAPSummary(info) if !passed { glog.Fatalf("At least one test failed") } else { diff --git a/test/e2e/important_urls.go b/test/e2e/important_urls.go index c8399aaa6cc..4e16cce003e 100644 --- a/test/e2e/important_urls.go +++ b/test/e2e/important_urls.go @@ -19,6 +19,9 @@ package e2e import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) // TestImportantURLs validates that URLs that people depend on haven't moved. @@ -46,3 +49,11 @@ func TestImportantURLs(c *client.Client) bool { } return ok } + +var _ = Describe("TestImportantURLs", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestImportantURLs(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/kubelet_sends_events.go b/test/e2e/kubelet_sends_events.go index d1f1341edaa..b0e8b4b98ca 100644 --- a/test/e2e/kubelet_sends_events.go +++ b/test/e2e/kubelet_sends_events.go @@ -24,6 +24,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) // TestKubeletSendsEvent checks that kubelets and scheduler send events about pods scheduling and running. @@ -101,3 +104,11 @@ func TestKubeletSendsEvent(c *client.Client) bool { glog.Info("Saw kubelet event for our pod.") return true } + +var _ = Describe("TestKubeletSendsEvent", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestKubeletSendsEvent(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/liveness.go b/test/e2e/liveness.go index 0468426a3db..7c8217a2986 100644 --- a/test/e2e/liveness.go +++ b/test/e2e/liveness.go @@ -26,6 +26,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) func runLivenessTest(c *client.Client, yamlFileName string) bool { @@ -92,3 +95,19 @@ func TestLivenessHttp(c *client.Client) bool { func TestLivenessExec(c *client.Client) bool { return runLivenessTest(c, "exec-liveness.yaml") } + +var _ = Describe("TestLivenessHttp", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestLivenessHttp(loadClientOrDie())).To(BeTrue()) + }) +}) + +var _ = Describe("TestLivenessExec", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestLivenessExec(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/network.go b/test/e2e/network.go index dcc6a6a7512..d035b267fb7 100644 --- a/test/e2e/network.go +++ b/test/e2e/network.go @@ -23,6 +23,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) func TestNetwork(c *client.Client) bool { @@ -138,3 +141,11 @@ func TestNetwork(c *client.Client) bool { return false } + +var _ = Describe("TestNetwork", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestNetwork(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/pod_has_service_env_vars.go b/test/e2e/pod_has_service_env_vars.go index 3c8fb5108c8..e4584e4a546 100644 --- a/test/e2e/pod_has_service_env_vars.go +++ b/test/e2e/pod_has_service_env_vars.go @@ -23,6 +23,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) // TestPodHasServiceEnvVars checks that kubelets and scheduler send events about pods scheduling and running. @@ -159,3 +162,11 @@ func TestPodHasServiceEnvVars(c *client.Client) bool { // We could try a wget the service from the client pod. But services.sh e2e test covers that pretty well. return success } + +var _ = Describe("TestPodHasServiceEnvVars", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestPodHasServiceEnvVars(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/pod_update.go b/test/e2e/pod_update.go index dcaa10f943c..0f231a9d654 100644 --- a/test/e2e/pod_update.go +++ b/test/e2e/pod_update.go @@ -24,6 +24,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) func TestPodUpdate(c *client.Client) bool { @@ -69,3 +72,11 @@ func TestPodUpdate(c *client.Client) bool { glog.Infof("pod update OK") return true } + +var _ = Describe("TestPodUpdate", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestPodUpdate(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/private.go b/test/e2e/private.go index 2f1e19073f9..baa721e507d 100644 --- a/test/e2e/private.go +++ b/test/e2e/private.go @@ -19,6 +19,9 @@ package e2e import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) // A basic test to check the deployment of the @@ -33,3 +36,11 @@ func TestPrivate(c *client.Client) bool { glog.Info("Calling out to TestBasic") return TestBasicImage(c, "private", "gcr.io/_b_k8s_test/serve_hostname:1.0") } + +var _ = Describe("TestPrivate", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestPrivate(loadClientOrDie())).To(BeTrue()) + }) +}) diff --git a/test/e2e/roservice.go b/test/e2e/roservice.go index 845d01654a7..a631fbcdb9c 100644 --- a/test/e2e/roservice.go +++ b/test/e2e/roservice.go @@ -20,6 +20,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/golang/glog" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) func TestKubernetesROService(c *client.Client) bool { @@ -53,3 +56,11 @@ func TestKubernetesROService(c *client.Client) bool { } return true } + +var _ = Describe("TestKubernetesROService", func() { + It("should pass", func() { + // TODO: Instead of OrDie, client should Fail the test if there's a problem. + // In general tests should Fail() instead of glog.Fatalf(). + Expect(TestKubernetesROService(loadClientOrDie())).To(BeTrue()) + }) +})