Commit 1c028de0 authored by Filipe Brandenburger's avatar Filipe Brandenburger

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.
parent dd8ada84
...@@ -27,6 +27,9 @@ import ( ...@@ -27,6 +27,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog" "github.com/golang/glog"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
// A basic test to check the deployment of an image using // 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 { ...@@ -189,3 +192,11 @@ func TestBasicImage(c *client.Client, test string, image string) bool {
func TestBasic(c *client.Client) bool { func TestBasic(c *client.Client) bool {
return TestBasicImage(c, "basic", "kubernetes/serve_hostname:1.1") 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())
})
})
...@@ -24,6 +24,9 @@ import ( ...@@ -24,6 +24,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog" "github.com/golang/glog"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
// TestClusterDNS checks that cluster DNS works. // TestClusterDNS checks that cluster DNS works.
...@@ -150,3 +153,11 @@ func TestClusterDNS(c *client.Client) bool { ...@@ -150,3 +153,11 @@ func TestClusterDNS(c *client.Client) bool {
glog.Infof("DNS probes using %s succeeded", pod.Name) glog.Infof("DNS probes using %s succeeded", pod.Name)
return true 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())
})
})
...@@ -17,46 +17,18 @@ limitations under the License. ...@@ -17,46 +17,18 @@ limitations under the License.
package e2e package e2e
import ( import (
"math/rand"
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/config"
"github.com/onsi/gomega"
) )
type testSpec struct { type testResult bool
// The test to run
test func(c *client.Client) bool
// The human readable name of this test
name string
}
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 (t *testResult) Fail() { *t = false }
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]
}
}
// Run each Go end-to-end-test. This function assumes the // Run each Go end-to-end-test. This function assumes the
// creation of a test cluster. // creation of a test cluster.
...@@ -77,85 +49,16 @@ func RunE2ETests(authConfig, certDir, host, repoRoot, provider string, orderseed ...@@ -77,85 +49,16 @@ func RunE2ETests(authConfig, certDir, host, repoRoot, provider string, orderseed
glog.Fatalf("This test has timed out. Cleanup not guaranteed.") glog.Fatalf("This test has timed out. Cleanup not guaranteed.")
}() }()
tests := []testSpec{ // TODO: Make -t TestName work again.
{TestKubernetesROService, "TestKubernetesROService"}, // TODO: Make "times" work again.
{TestKubeletSendsEvent, "TestKubeletSendsEvent"}, // TODO: Make orderseed work again.
{TestImportantURLs, "TestImportantURLs"},
{TestPodUpdate, "TestPodUpdate"},
{TestNetwork, "TestNetwork"},
{TestClusterDNS, "TestClusterDNS"},
{TestPodHasServiceEnvVars, "TestPodHasServiceEnvVars"},
{TestBasic, "TestBasic"},
{TestPrivate, "TestPrivate"},
{TestLivenessHttp, "TestLivenessHttp"},
{TestLivenessExec, "TestLivenessExec"},
}
// 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)
}
}
// if testList was specified, filter down now before we expand and shuffle var passed testResult = true
if len(testList) > 0 { gomega.RegisterFailHandler(ginkgo.Fail)
newTests := make([]testSpec, 0) // Turn of colors for now to make it easier to collect console output in Jenkins
for i, test := range tests { config.DefaultReporterConfig.NoColor = true
// Check if this test is supposed to run, either if listed explicitly in ginkgo.RunSpecs(&passed, "Kubernetes e2e Suite")
// 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 { if !passed {
glog.Fatalf("At least one test failed") glog.Fatalf("At least one test failed")
} else { } else {
......
...@@ -19,6 +19,9 @@ package e2e ...@@ -19,6 +19,9 @@ package e2e
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/golang/glog" "github.com/golang/glog"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
// TestImportantURLs validates that URLs that people depend on haven't moved. // TestImportantURLs validates that URLs that people depend on haven't moved.
...@@ -46,3 +49,11 @@ func TestImportantURLs(c *client.Client) bool { ...@@ -46,3 +49,11 @@ func TestImportantURLs(c *client.Client) bool {
} }
return ok 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())
})
})
...@@ -24,6 +24,9 @@ import ( ...@@ -24,6 +24,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/golang/glog" "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. // TestKubeletSendsEvent checks that kubelets and scheduler send events about pods scheduling and running.
...@@ -101,3 +104,11 @@ func TestKubeletSendsEvent(c *client.Client) bool { ...@@ -101,3 +104,11 @@ func TestKubeletSendsEvent(c *client.Client) bool {
glog.Info("Saw kubelet event for our pod.") glog.Info("Saw kubelet event for our pod.")
return true 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())
})
})
...@@ -26,6 +26,9 @@ import ( ...@@ -26,6 +26,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog" "github.com/golang/glog"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
func runLivenessTest(c *client.Client, yamlFileName string) bool { func runLivenessTest(c *client.Client, yamlFileName string) bool {
...@@ -92,3 +95,19 @@ func TestLivenessHttp(c *client.Client) bool { ...@@ -92,3 +95,19 @@ func TestLivenessHttp(c *client.Client) bool {
func TestLivenessExec(c *client.Client) bool { func TestLivenessExec(c *client.Client) bool {
return runLivenessTest(c, "exec-liveness.yaml") 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())
})
})
...@@ -23,6 +23,9 @@ import ( ...@@ -23,6 +23,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog" "github.com/golang/glog"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
func TestNetwork(c *client.Client) bool { func TestNetwork(c *client.Client) bool {
...@@ -138,3 +141,11 @@ func TestNetwork(c *client.Client) bool { ...@@ -138,3 +141,11 @@ func TestNetwork(c *client.Client) bool {
return false 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())
})
})
...@@ -23,6 +23,9 @@ import ( ...@@ -23,6 +23,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/golang/glog" "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. // TestPodHasServiceEnvVars checks that kubelets and scheduler send events about pods scheduling and running.
...@@ -159,3 +162,11 @@ func TestPodHasServiceEnvVars(c *client.Client) bool { ...@@ -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. // We could try a wget the service from the client pod. But services.sh e2e test covers that pretty well.
return success 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())
})
})
...@@ -24,6 +24,9 @@ import ( ...@@ -24,6 +24,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/golang/glog" "github.com/golang/glog"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
func TestPodUpdate(c *client.Client) bool { func TestPodUpdate(c *client.Client) bool {
...@@ -69,3 +72,11 @@ func TestPodUpdate(c *client.Client) bool { ...@@ -69,3 +72,11 @@ func TestPodUpdate(c *client.Client) bool {
glog.Infof("pod update OK") glog.Infof("pod update OK")
return true 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())
})
})
...@@ -19,6 +19,9 @@ package e2e ...@@ -19,6 +19,9 @@ package e2e
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/golang/glog" "github.com/golang/glog"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
// A basic test to check the deployment of the // A basic test to check the deployment of the
...@@ -33,3 +36,11 @@ func TestPrivate(c *client.Client) bool { ...@@ -33,3 +36,11 @@ func TestPrivate(c *client.Client) bool {
glog.Info("Calling out to TestBasic") glog.Info("Calling out to TestBasic")
return TestBasicImage(c, "private", "gcr.io/_b_k8s_test/serve_hostname:1.0") 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())
})
})
...@@ -20,6 +20,9 @@ import ( ...@@ -20,6 +20,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/golang/glog" "github.com/golang/glog"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
func TestKubernetesROService(c *client.Client) bool { func TestKubernetesROService(c *client.Client) bool {
...@@ -53,3 +56,11 @@ func TestKubernetesROService(c *client.Client) bool { ...@@ -53,3 +56,11 @@ func TestKubernetesROService(c *client.Client) bool {
} }
return true 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())
})
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment