From 3853b896f74a2cc9a24f7591a2106536c1fab9fc Mon Sep 17 00:00:00 2001 From: Joseph Callen Date: Fri, 14 Nov 2025 15:40:23 -0500 Subject: [PATCH] Fix VSphereMultiNetworks tests failing with 'cannot clone suite after tree has been built' After bumping to k8s 1.34 (commit dd24836d9), which updated ginkgo/v2 from v2.23.4 to v2.27.2, all VSphereMultiNetworks tests began failing immediately with the error "cannot clone suite after tree has been built". Root cause: The newer Ginkgo version enforces stricter checks preventing suite cloning after the tree has been built. When tests run in parallel, child processes are spawned with the "run-test" command, which re-enters main() and calls BuildExtensionTestSpecsFromOpenShiftGinkgoSuite() again, rebuilding the Ginkgo suite tree. When the child process attempts to run the test, Ginkgo's RunSpecs() calls PushClone() which fails because the tree was already built. Solution: Only build the Ginkgo test specs when NOT in "run-test" mode. This prevents child processes from rebuilding the suite tree, allowing the clone operation to succeed during parallel test execution. Co-Authored-By: Claude --- cmd/machine-api-tests-ext/main.go | 52 +++++++++++++++++-------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/cmd/machine-api-tests-ext/main.go b/cmd/machine-api-tests-ext/main.go index 7f5b625b6f..403c84ec03 100644 --- a/cmd/machine-api-tests-ext/main.go +++ b/cmd/machine-api-tests-ext/main.go @@ -45,37 +45,43 @@ func main() { Qualifiers: []string{`labels.exists(l, l == "Serial") && labels.exists(l, l == "Conformance")`}, }) - // Build our specs from ginkgo - specs, err := g.BuildExtensionTestSpecsFromOpenShiftGinkgoSuite() - if err != nil { - panic(err) - } - - // Initialization for kube ginkgo test framework needs to run before all tests execute - specs.AddBeforeAll(func() { - if err := initializeTestFramework(os.Getenv("TEST_PROVIDER")); err != nil { + // Build our specs from ginkgo only when not running a single test + // When running in parallel, child processes are spawned with "run-test" command + // and should not rebuild the Ginkgo suite tree to avoid "cannot clone suite after tree has been built" error + isRunningTest := len(os.Args) > 1 && os.Args[1] == "run-test" + if !isRunningTest { + // Build our specs from ginkgo + specs, err := g.BuildExtensionTestSpecsFromOpenShiftGinkgoSuite() + if err != nil { panic(err) } - }) - // Let's scan for tests with a platform label and create the rule for them such as [platform:vsphere] - foundPlatforms := make(map[string]string) - for _, test := range specs.Select(extensiontests.NameContains("[platform:")).Names() { - re := regexp.MustCompile(`\[platform:[a-z]*]`) - match := re.FindStringSubmatch(test) - for _, platformDef := range match { - if _, ok := foundPlatforms[platformDef]; !ok { - platform := platformDef[strings.Index(platformDef, ":")+1 : len(platformDef)-1] - foundPlatforms[platformDef] = platform - specs.Select(extensiontests.NameContains(platformDef)). - Include(extensiontests.PlatformEquals(platform)) + // Initialization for kube ginkgo test framework needs to run before all tests execute + specs.AddBeforeAll(func() { + if err := initializeTestFramework(os.Getenv("TEST_PROVIDER")); err != nil { + panic(err) } + }) + + // Let's scan for tests with a platform label and create the rule for them such as [platform:vsphere] + foundPlatforms := make(map[string]string) + for _, test := range specs.Select(extensiontests.NameContains("[platform:")).Names() { + re := regexp.MustCompile(`\[platform:[a-z]*]`) + match := re.FindStringSubmatch(test) + for _, platformDef := range match { + if _, ok := foundPlatforms[platformDef]; !ok { + platform := platformDef[strings.Index(platformDef, ":")+1 : len(platformDef)-1] + foundPlatforms[platformDef] = platform + specs.Select(extensiontests.NameContains(platformDef)). + Include(extensiontests.PlatformEquals(platform)) + } + } + } + kubeTestsExtension.AddSpecs(specs) } - kubeTestsExtension.AddSpecs(specs) - // Cobra stuff root := &cobra.Command{ Long: "Machine API Operator tests extension for OpenShift",