From 4f3f4e741219c4f0969f2ff008e264dd8053562b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=A5=96=E5=BB=BA?= Date: Fri, 24 Feb 2023 13:02:54 +0800 Subject: [PATCH] e2e: run specs in parallel (#2375) --- .github/workflows/build-x86-image.yaml | 47 ++++++++++++++++++--- Makefile.e2e | 58 ++++++++++++++------------ test/e2e/framework/framework.go | 4 ++ test/e2e/k8s-network/e2e_test.go | 6 +-- test/e2e/kube-ovn/e2e_test.go | 6 +-- test/e2e/kube-ovn/underlay/underlay.go | 2 +- test/e2e/lb-svc/e2e_test.go | 19 ++++----- test/e2e/ovn-eip/e2e_test.go | 6 +-- test/e2e/ovn-ic/e2e_test.go | 10 ++--- test/e2e/security/e2e_test.go | 6 +-- 10 files changed, 98 insertions(+), 66 deletions(-) diff --git a/.github/workflows/build-x86-image.yaml b/.github/workflows/build-x86-image.yaml index 2588f4a15ae..6b6f2f5d9e6 100644 --- a/.github/workflows/build-x86-image.yaml +++ b/.github/workflows/build-x86-image.yaml @@ -2,11 +2,6 @@ name: Build x86 Image on: pull_request: - types: - - opened - - synchronize - - reopened - - labeled branches: - master - release-* @@ -226,7 +221,11 @@ jobs: key: ${{ runner.os }}-e2e-${{ env.GO_FULL_VER }}-x86-${{ hashFiles(format('{0}/**/go.sum', env.E2E_DIR)) }} restore-keys: ${{ runner.os }}-e2e-${{ env.GO_FULL_VER }}-x86- - - run: make e2e-compile + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + + - run: make e2e-build working-directory: ${{ env.E2E_DIR }} k8s-conformance-e2e: @@ -296,6 +295,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download image uses: actions/download-artifact@v3 with: @@ -388,6 +391,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download image uses: actions/download-artifact@v3 with: @@ -476,6 +483,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download image uses: actions/download-artifact@v3 with: @@ -540,6 +551,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download image uses: actions/download-artifact@v3 with: @@ -622,6 +637,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download image uses: actions/download-artifact@v3 with: @@ -703,6 +722,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download image uses: actions/download-artifact@v3 with: @@ -927,6 +950,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download kube-ovn image uses: actions/download-artifact@v3 with: @@ -1055,6 +1082,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download image uses: actions/download-artifact@v3 with: @@ -1146,6 +1177,10 @@ jobs: with: install_only: true + - name: Install ginkgo + working-directory: ${{ env.E2E_DIR }} + run: go install -v -mod=mod github.com/onsi/ginkgo/v2/ginkgo + - name: Download image uses: actions/download-artifact@v3 with: diff --git a/Makefile.e2e b/Makefile.e2e index 0d5f397eb39..c77b852165e 100644 --- a/Makefile.e2e +++ b/Makefile.e2e @@ -33,39 +33,43 @@ K8S_CONFORMANCE_E2E_FOCUS += "sig-network.*Feature:IPv6DualStack" endif define ginkgo_option ---ginkgo.$(1)=$(shell echo '$(2)' | sed -E 's/^[[:space:]]+//' | sed -E 's/"[[:space:]]+"/" --ginkgo.$(1)="/g') +--$(1)=$(shell echo '$(2)' | sed -E 's/^[[:space:]]+//' | sed -E 's/"[[:space:]]+"/" --$(1)="/g') endef .PHONY: e2e e2e: kube-ovn-conformance-e2e -.PHONY: e2e-compile -e2e-compile: - go test ./test/e2e/k8s-network -c -o test/e2e/k8s-network/e2e.test - go test ./test/e2e/kube-ovn -c -o test/e2e/kube-ovn/e2e.test - go test ./test/e2e/ovn-ic -c -o test/e2e/ovn-ic/e2e.test - go test ./test/e2e/lb-svc -c -o test/e2e/lb-svc/e2e.test - go test ./test/e2e/security -c -o test/e2e/security/e2e.test +.PHONY: e2e-build +e2e-build: + ginkgo build ./test/e2e/k8s-network + ginkgo build ./test/e2e/kube-ovn + ginkgo build ./test/e2e/ovn-ic + ginkgo build ./test/e2e/lb-svc + ginkgo build ./test/e2e/ovn-eip + ginkgo build ./test/e2e/security .PHONY: k8s-conformance-e2e k8s-conformance-e2e: - go test ./test/e2e/k8s-network -c -o test/e2e/k8s-network/e2e.test - ./test/e2e/k8s-network/e2e.test --ginkgo.timeout=1h \ + ginkgo build ./test/e2e/k8s-network + ginkgo -p --randomize-all --timeout=1h \ $(call ginkgo_option,focus,$(K8S_CONFORMANCE_E2E_FOCUS)) \ - $(call ginkgo_option,skip,$(K8S_CONFORMANCE_E2E_SKIP)) + $(call ginkgo_option,skip,$(K8S_CONFORMANCE_E2E_SKIP)) \ + ./test/e2e/k8s-network/k8s-network.test .PHONY: k8s-netpol-legacy-e2e k8s-netpol-legacy-e2e: - go test ./test/e2e/k8s-network -c -o test/e2e/k8s-network/e2e.test - ./test/e2e/k8s-network/e2e.test --ginkgo.timeout=2h \ - $(call ginkgo_option,focus,$(K8S_NETPOL_LEGACY_E2E_FOCUS)) + ginkgo build ./test/e2e/k8s-network + ginkgo -p --randomize-all --timeout=2h \ + $(call ginkgo_option,focus,$(K8S_NETPOL_LEGACY_E2E_FOCUS)) \ + ./test/e2e/k8s-network/k8s-network.test .PHONY: k8s-netpol-e2e k8s-netpol-e2e: - go test ./test/e2e/k8s-network -c -o test/e2e/k8s-network/e2e.test - ./test/e2e/k8s-network/e2e.test --ginkgo.timeout=2h \ + ginkgo build ./test/e2e/k8s-network + ginkgo -p --randomize-all --timeout=2h \ $(call ginkgo_option,focus,$(K8S_NETPOL_E2E_FOCUS)) \ - $(call ginkgo_option,skip,$(K8S_NETPOL_E2E_SKIP)) + $(call ginkgo_option,skip,$(K8S_NETPOL_E2E_SKIP)) \ + ./test/e2e/k8s-network/k8s-network.test .PHONY: cyclonus-netpol-e2e cyclonus-netpol-e2e: @@ -83,40 +87,40 @@ cyclonus-netpol-e2e: .PHONY: kube-ovn-conformance-e2e kube-ovn-conformance-e2e: - go test ./test/e2e/kube-ovn -c -o test/e2e/kube-ovn/e2e.test + ginkgo build ./test/e2e/kube-ovn E2E_BRANCH=$(E2E_BRANCH) \ E2E_IP_FAMILY=$(E2E_IP_FAMILY) \ E2E_NETWORK_MODE=$(E2E_NETWORK_MODE) \ - ./test/e2e/kube-ovn/e2e.test --ginkgo.focus=CNI:Kube-OVN + ginkgo -p --randomize-all --focus=CNI:Kube-OVN ./test/e2e/kube-ovn/kube-ovn.test .PHONY: kube-ovn-ic-conformance-e2e kube-ovn-ic-conformance-e2e: - go test ./test/e2e/ovn-ic -c -o test/e2e/ovn-ic/e2e.test + ginkgo build ./test/e2e/ovn-ic E2E_BRANCH=$(E2E_BRANCH) \ E2E_IP_FAMILY=$(E2E_IP_FAMILY) \ E2E_NETWORK_MODE=$(E2E_NETWORK_MODE) \ - ./test/e2e/ovn-ic/e2e.test --ginkgo.focus=CNI:Kube-OVN + ginkgo -p --randomize-all --focus=CNI:Kube-OVN ./test/e2e/ovn-ic/ovn-ic.test .PHONY: kube-ovn-lb-svc-conformance-e2e kube-ovn-lb-svc-conformance-e2e: - go test ./test/e2e/lb-svc -c -o test/e2e/lb-svc/e2e.test + ginkgo build ./test/e2e/lb-svc E2E_BRANCH=$(E2E_BRANCH) \ E2E_IP_FAMILY=$(E2E_IP_FAMILY) \ E2E_NETWORK_MODE=$(E2E_NETWORK_MODE) \ - ./test/e2e/lb-svc/e2e.test --ginkgo.focus=CNI:Kube-OVN + ginkgo -p --randomize-all --focus=CNI:Kube-OVN ./test/e2e/lb-svc/lb-svc.test .PHONY: kube-ovn-eip-conformance-e2e kube-ovn-eip-conformance-e2e: - go test ./test/e2e/ovn-eip -c -o test/e2e/ovn-eip/e2e.test + ginkgo build ./test/e2e/ovn-eip E2E_BRANCH=$(E2E_BRANCH) \ E2E_IP_FAMILY=$(E2E_IP_FAMILY) \ E2E_NETWORK_MODE=$(E2E_NETWORK_MODE) \ - ./test/e2e/ovn-eip/e2e.test --ginkgo.focus=CNI:Kube-OVN + ginkgo -p --randomize-all --focus=CNI:Kube-OVN ./test/e2e/ovn-eip/ovn-eip.test .PHONY: kube-ovn-security-e2e kube-ovn-security-e2e: - go test ./test/e2e/security -c -o test/e2e/security/e2e.test + ginkgo build ./test/e2e/security E2E_BRANCH=$(E2E_BRANCH) \ E2E_IP_FAMILY=$(E2E_IP_FAMILY) \ E2E_NETWORK_MODE=$(E2E_NETWORK_MODE) \ - ./test/e2e/security/e2e.test --ginkgo.focus=CNI:Kube-OVN + ginkgo -p --randomize-all --focus=CNI:Kube-OVN ./test/e2e/security/security.test diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index c2eb88b1142..17943a9fe9d 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -139,6 +139,10 @@ func Describe(text string, body func()) bool { return ginkgo.Describe("[CNI:Kube-OVN] "+text, body) } +func SerialDescribe(text string, body func()) bool { + return ginkgo.Describe("[CNI:Kube-OVN] "+text, ginkgo.Serial, body) +} + func OrderedDescribe(text string, body func()) bool { return ginkgo.Describe("[CNI:Kube-OVN] "+text, ginkgo.Ordered, body) } diff --git a/test/e2e/k8s-network/e2e_test.go b/test/e2e/k8s-network/e2e_test.go index 4ea81101dd0..6d9192e2298 100644 --- a/test/e2e/k8s-network/e2e_test.go +++ b/test/e2e/k8s-network/e2e_test.go @@ -24,15 +24,13 @@ func init() { config.CopyFlags(config.Flags, flag.CommandLine) framework.RegisterCommonFlags(flag.CommandLine) framework.RegisterClusterFlags(flag.CommandLine) +} - // Parse all the flags - flag.Parse() +func TestE2E(t *testing.T) { if framework.TestContext.KubeConfig == "" { framework.TestContext.KubeConfig = filepath.Join(os.Getenv("HOME"), ".kube", "config") } framework.AfterReadingAllFlags(&framework.TestContext) -} -func TestE2E(t *testing.T) { e2e.RunE2ETests(t) } diff --git a/test/e2e/kube-ovn/e2e_test.go b/test/e2e/kube-ovn/e2e_test.go index 481bbc7d13f..8651d81d775 100644 --- a/test/e2e/kube-ovn/e2e_test.go +++ b/test/e2e/kube-ovn/e2e_test.go @@ -31,15 +31,13 @@ func init() { config.CopyFlags(config.Flags, flag.CommandLine) framework.RegisterCommonFlags(flag.CommandLine) framework.RegisterClusterFlags(flag.CommandLine) +} - // Parse all the flags - flag.Parse() +func TestE2E(t *testing.T) { if framework.TestContext.KubeConfig == "" { framework.TestContext.KubeConfig = filepath.Join(os.Getenv("HOME"), ".kube", "config") } framework.AfterReadingAllFlags(&framework.TestContext) -} -func TestE2E(t *testing.T) { e2e.RunE2ETests(t) } diff --git a/test/e2e/kube-ovn/underlay/underlay.go b/test/e2e/kube-ovn/underlay/underlay.go index 95a14a0d660..ea2d61f7071 100644 --- a/test/e2e/kube-ovn/underlay/underlay.go +++ b/test/e2e/kube-ovn/underlay/underlay.go @@ -44,7 +44,7 @@ func makeProviderNetwork(providerNetworkName string, exchangeLinkName bool, link return framework.MakeProviderNetwork(providerNetworkName, exchangeLinkName, defaultInterface, customInterfaces, nil) } -var _ = framework.Describe("[group:underlay]", func() { +var _ = framework.SerialDescribe("[group:underlay]", func() { f := framework.NewDefaultFramework("underlay") var skip bool diff --git a/test/e2e/lb-svc/e2e_test.go b/test/e2e/lb-svc/e2e_test.go index 9ca8468fa08..40f043b619f 100644 --- a/test/e2e/lb-svc/e2e_test.go +++ b/test/e2e/lb-svc/e2e_test.go @@ -5,6 +5,7 @@ import ( "flag" "fmt" "math/big" + "math/rand" "os" "path/filepath" "strings" @@ -40,16 +41,14 @@ func init() { config.CopyFlags(config.Flags, flag.CommandLine) k8sframework.RegisterCommonFlags(flag.CommandLine) k8sframework.RegisterClusterFlags(flag.CommandLine) +} - // Parse all the flags - flag.Parse() +func TestE2E(t *testing.T) { if k8sframework.TestContext.KubeConfig == "" { k8sframework.TestContext.KubeConfig = filepath.Join(os.Getenv("HOME"), ".kube", "config") } k8sframework.AfterReadingAllFlags(&k8sframework.TestContext) -} -func TestE2E(t *testing.T) { e2e.RunE2ETests(t) } @@ -57,7 +56,7 @@ func lbSvcDeploymentName(serviceName string) string { return "lb-svc-" + serviceName } -var _ = framework.Describe("[group:lb-svc]", func() { +var _ = framework.SerialDescribe("[group:lb-svc]", func() { f := framework.NewDefaultFramework("lb-svc") var skip bool @@ -76,7 +75,7 @@ var _ = framework.Describe("[group:lb-svc]", func() { serviceName = "service-" + framework.RandomSuffix() if skip { - ginkgo.Skip("underlay spec only runs on kind clusters") + ginkgo.Skip("lb svc spec only runs on kind clusters") } if clusterName == "" { @@ -87,7 +86,7 @@ var _ = framework.Describe("[group:lb-svc]", func() { cluster, ok := kind.IsKindProvided(k8sNodes.Items[0].Spec.ProviderID) if !ok { skip = true - ginkgo.Skip("underlay spec only runs on kind clusters") + ginkgo.Skip("lb svc spec only runs on kind clusters") } clusterName = cluster } @@ -140,8 +139,8 @@ var _ = framework.Describe("[group:lb-svc]", func() { service := framework.MakeService(serviceName, corev1.ServiceTypeLoadBalancer, annotations, selector, ports, corev1.ServiceAffinityNone) _ = serviceClient.CreateSync(service) - ginkgo.By("Waiting for 5 seconds") - time.Sleep(5 * time.Second) + ginkgo.By("Waiting for 10 seconds") + time.Sleep(10 * time.Second) deploymentName := lbSvcDeploymentName(serviceName) ginkgo.By("Getting deployment " + deploymentName) @@ -178,7 +177,7 @@ var _ = framework.Describe("[group:lb-svc]", func() { framework.ConformanceIt("should allocate static external IP for service", func() { ginkgo.By("Creating service " + serviceName) base := util.Ip2BigInt(gateway) - lbIP := util.BigInt2Ip(base.Add(base, big.NewInt(100))) + lbIP := util.BigInt2Ip(base.Add(base, big.NewInt(50+rand.Int63n(50)))) ports := []corev1.ServicePort{{ Name: "tcp", Protocol: corev1.ProtocolTCP, diff --git a/test/e2e/ovn-eip/e2e_test.go b/test/e2e/ovn-eip/e2e_test.go index bccfcf5667d..d48557cf1ed 100644 --- a/test/e2e/ovn-eip/e2e_test.go +++ b/test/e2e/ovn-eip/e2e_test.go @@ -336,15 +336,13 @@ func init() { config.CopyFlags(config.Flags, flag.CommandLine) k8sframework.RegisterCommonFlags(flag.CommandLine) k8sframework.RegisterClusterFlags(flag.CommandLine) +} - // Parse all the flags - flag.Parse() +func TestE2E(t *testing.T) { if k8sframework.TestContext.KubeConfig == "" { k8sframework.TestContext.KubeConfig = filepath.Join(os.Getenv("HOME"), ".kube", "config") } k8sframework.AfterReadingAllFlags(&k8sframework.TestContext) -} -func TestE2E(t *testing.T) { e2e.RunE2ETests(t) } diff --git a/test/e2e/ovn-ic/e2e_test.go b/test/e2e/ovn-ic/e2e_test.go index 4a33460ee9d..76618f44c66 100644 --- a/test/e2e/ovn-ic/e2e_test.go +++ b/test/e2e/ovn-ic/e2e_test.go @@ -42,9 +42,9 @@ func init() { config.CopyFlags(config.Flags, flag.CommandLine) k8sframework.RegisterCommonFlags(flag.CommandLine) k8sframework.RegisterClusterFlags(flag.CommandLine) +} - // Parse all the flags - flag.Parse() +func TestE2E(t *testing.T) { if k8sframework.TestContext.KubeConfig == "" { k8sframework.TestContext.KubeConfig = filepath.Join(os.Getenv("HOME"), ".kube", "config") } @@ -52,14 +52,12 @@ func init() { var err error if clusters, err = kind.ListClusters(); err != nil { - panic(fmt.Sprintf("failed to list kind clusters: %v", err)) + t.Fatalf("failed to list kind clusters: %v", err) } if len(clusters) < 2 { - panic("no enough kind clusters to run ovn-ic e2e testing") + t.Fatal("no enough kind clusters to run ovn-ic e2e testing") } -} -func TestE2E(t *testing.T) { e2e.RunE2ETests(t) } diff --git a/test/e2e/security/e2e_test.go b/test/e2e/security/e2e_test.go index 2deb83bc830..9453255e04d 100644 --- a/test/e2e/security/e2e_test.go +++ b/test/e2e/security/e2e_test.go @@ -34,16 +34,14 @@ func init() { config.CopyFlags(config.Flags, flag.CommandLine) k8sframework.RegisterCommonFlags(flag.CommandLine) k8sframework.RegisterClusterFlags(flag.CommandLine) +} - // Parse all the flags - flag.Parse() +func TestE2E(t *testing.T) { if k8sframework.TestContext.KubeConfig == "" { k8sframework.TestContext.KubeConfig = filepath.Join(os.Getenv("HOME"), ".kube", "config") } k8sframework.AfterReadingAllFlags(&k8sframework.TestContext) -} -func TestE2E(t *testing.T) { e2e.RunE2ETests(t) }