Skip to content

Commit b9423a5

Browse files
committed
debug Objects with Changed Resource Versions
1 parent 6d2fe04 commit b9423a5

File tree

2 files changed

+156
-142
lines changed

2 files changed

+156
-142
lines changed

test/e2e/quick_start.go

Lines changed: 146 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -111,156 +111,161 @@ func QuickStartSpec(ctx context.Context, inputGetter func() QuickStartSpecInput)
111111
clusterResources *clusterctl.ApplyClusterTemplateAndWaitResult
112112
)
113113

114-
BeforeEach(func() {
115-
Expect(ctx).NotTo(BeNil(), "ctx is required for %s spec", specName)
116-
input = inputGetter()
117-
Expect(input.E2EConfig).ToNot(BeNil(), "Invalid argument. input.E2EConfig can't be nil when calling %s spec", specName)
118-
Expect(input.ClusterctlConfigPath).To(BeAnExistingFile(), "Invalid argument. input.ClusterctlConfigPath must be an existing file when calling %s spec", specName)
119-
Expect(input.BootstrapClusterProxy).ToNot(BeNil(), "Invalid argument. input.BootstrapClusterProxy can't be nil when calling %s spec", specName)
120-
Expect(os.MkdirAll(input.ArtifactFolder, 0750)).To(Succeed(), "Invalid argument. input.ArtifactFolder can't be created for %s spec", specName)
121-
122-
Expect(input.E2EConfig.Variables).To(HaveKey(KubernetesVersion))
123-
124-
if input.ExtensionServiceNamespace != "" && input.ExtensionServiceName != "" {
125-
if input.ExtensionConfigName == "" {
126-
input.ExtensionConfigName = specName
114+
for i := 0; i < 10; i++ {
115+
116+
BeforeEach(func() {
117+
Expect(ctx).NotTo(BeNil(), "ctx is required for %s spec", specName)
118+
input = inputGetter()
119+
Expect(input.E2EConfig).ToNot(BeNil(), "Invalid argument. input.E2EConfig can't be nil when calling %s spec", specName)
120+
Expect(input.ClusterctlConfigPath).To(BeAnExistingFile(), "Invalid argument. input.ClusterctlConfigPath must be an existing file when calling %s spec", specName)
121+
Expect(input.BootstrapClusterProxy).ToNot(BeNil(), "Invalid argument. input.BootstrapClusterProxy can't be nil when calling %s spec", specName)
122+
Expect(os.MkdirAll(input.ArtifactFolder, 0750)).To(Succeed(), "Invalid argument. input.ArtifactFolder can't be created for %s spec", specName)
123+
124+
Expect(input.E2EConfig.Variables).To(HaveKey(KubernetesVersion))
125+
126+
if input.ExtensionServiceNamespace != "" && input.ExtensionServiceName != "" {
127+
if input.ExtensionConfigName == "" {
128+
input.ExtensionConfigName = specName
129+
}
127130
}
128-
}
129-
130-
// Setup a Namespace where to host objects for this spec and create a watcher for the namespace events.
131-
namespace, cancelWatches = framework.SetupSpecNamespace(ctx, specName, input.BootstrapClusterProxy, input.ArtifactFolder, input.PostNamespaceCreated)
132-
133-
if input.DeployClusterClassInSeparateNamespace {
134-
clusterClassNamespace = framework.CreateNamespace(ctx, framework.CreateNamespaceInput{Creator: input.BootstrapClusterProxy.GetClient(), Name: fmt.Sprintf("%s-clusterclass", namespace.Name)}, "40s", "10s")
135-
Expect(clusterClassNamespace).ToNot(BeNil(), "Failed to create namespace")
136-
}
137-
138-
clusterResources = new(clusterctl.ApplyClusterTemplateAndWaitResult)
139-
})
140-
141-
It("Should create a workload cluster", func() {
142-
By("Creating a workload cluster")
143-
144-
infrastructureProvider := clusterctl.DefaultInfrastructureProvider
145-
if input.InfrastructureProvider != nil {
146-
infrastructureProvider = *input.InfrastructureProvider
147-
}
148-
149-
flavor := clusterctl.DefaultFlavor
150-
if input.Flavor != nil {
151-
flavor = *input.Flavor
152-
}
153-
154-
controlPlaneMachineCount := ptr.To[int64](1)
155-
if input.ControlPlaneMachineCount != nil {
156-
controlPlaneMachineCount = input.ControlPlaneMachineCount
157-
}
158-
159-
workerMachineCount := ptr.To[int64](1)
160-
if input.WorkerMachineCount != nil {
161-
workerMachineCount = input.WorkerMachineCount
162-
}
163-
164-
clusterName := fmt.Sprintf("%s-%s", specName, util.RandomString(6))
165-
if input.ClusterName != nil {
166-
clusterName = *input.ClusterName
167-
}
168-
169-
if input.ExtensionServiceNamespace != "" && input.ExtensionServiceName != "" {
170-
// NOTE: test extension is already deployed in the management cluster. If for any reason in future we want
171-
// to make this test more self-contained this test should be modified in order to create an additional
172-
// management cluster; also the E2E test configuration should be modified introducing something like
173-
// optional:true allowing to define which providers should not be installed by default in
174-
// a management cluster.
175-
By("Deploy Test Extension ExtensionConfig")
176-
177-
// In this test we are defaulting all handlers to non-blocking because we don't expect the handlers to block the
178-
// cluster lifecycle by default. Setting defaultAllHandlersToBlocking to false enforces that the test-extension
179-
// automatically creates the ConfigMap with non-blocking preloaded responses.
180-
defaultAllHandlersToBlocking := false
181-
// select on the current namespace
182-
// This is necessary so in CI this test doesn't influence other tests by enabling lifecycle hooks
183-
// in other test namespaces.
184-
namespaces := []string{namespace.Name}
131+
132+
// Setup a Namespace where to host objects for this spec and create a watcher for the namespace events.
133+
namespace, cancelWatches = framework.SetupSpecNamespace(ctx, specName, input.BootstrapClusterProxy, input.ArtifactFolder, input.PostNamespaceCreated)
134+
185135
if input.DeployClusterClassInSeparateNamespace {
186-
// Add the ClusterClass namespace, if the ClusterClass is deployed in a separate namespace.
187-
namespaces = append(namespaces, clusterClassNamespace.Name)
136+
clusterClassNamespace = framework.CreateNamespace(ctx, framework.CreateNamespaceInput{Creator: input.BootstrapClusterProxy.GetClient(), Name: fmt.Sprintf("%s-clusterclass", namespace.Name)}, "40s", "10s")
137+
Expect(clusterClassNamespace).ToNot(BeNil(), "Failed to create namespace")
188138
}
189-
extensionConfig := extensionConfig(input.ExtensionConfigName, input.ExtensionServiceNamespace, input.ExtensionServiceName, defaultAllHandlersToBlocking, namespaces...)
190-
Expect(input.BootstrapClusterProxy.GetClient().Create(ctx,
191-
extensionConfig)).
192-
To(Succeed(), "Failed to create the ExtensionConfig")
193-
}
194-
195-
variables := map[string]string{
196-
// This is used to template the name of the ExtensionConfig into the ClusterClass.
197-
"EXTENSION_CONFIG_NAME": input.ExtensionConfigName,
198-
}
199-
maps.Copy(variables, input.ClusterctlVariables)
200-
201-
if input.DeployClusterClassInSeparateNamespace {
202-
variables["CLUSTER_CLASS_NAMESPACE"] = clusterClassNamespace.Name
203-
By("Creating a cluster referencing a ClusterClass from another namespace")
204-
}
205-
206-
clusterctl.ApplyClusterTemplateAndWait(ctx, clusterctl.ApplyClusterTemplateAndWaitInput{
207-
ClusterProxy: input.BootstrapClusterProxy,
208-
ConfigCluster: clusterctl.ConfigClusterInput{
209-
LogFolder: filepath.Join(input.ArtifactFolder, "clusters", input.BootstrapClusterProxy.GetName()),
210-
ClusterctlConfigPath: input.ClusterctlConfigPath,
211-
ClusterctlVariables: variables,
212-
KubeconfigPath: input.BootstrapClusterProxy.GetKubeconfigPath(),
213-
InfrastructureProvider: infrastructureProvider,
214-
Flavor: flavor,
215-
Namespace: namespace.Name,
216-
ClusterName: clusterName,
217-
KubernetesVersion: input.E2EConfig.MustGetVariable(KubernetesVersion),
218-
ControlPlaneMachineCount: controlPlaneMachineCount,
219-
WorkerMachineCount: workerMachineCount,
220-
},
221-
ControlPlaneWaiters: input.ControlPlaneWaiters,
222-
WaitForClusterIntervals: input.E2EConfig.GetIntervals(specName, "wait-cluster"),
223-
WaitForControlPlaneIntervals: input.E2EConfig.GetIntervals(specName, "wait-control-plane"),
224-
WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"),
225-
PostMachinesProvisioned: func() {
226-
if input.PostMachinesProvisioned != nil {
227-
input.PostMachinesProvisioned(input.BootstrapClusterProxy, namespace.Name, clusterName)
228-
}
229-
},
230-
}, clusterResources)
231-
232-
Byf("Verify Cluster Available condition is true")
233-
framework.VerifyClusterAvailable(ctx, framework.VerifyClusterAvailableInput{
234-
Getter: input.BootstrapClusterProxy.GetClient(),
235-
Name: clusterResources.Cluster.Name,
236-
Namespace: clusterResources.Cluster.Namespace,
237-
})
238139

239-
Byf("Verify Machines Ready condition is true")
240-
framework.VerifyMachinesReady(ctx, framework.VerifyMachinesReadyInput{
241-
Lister: input.BootstrapClusterProxy.GetClient(),
242-
Name: clusterResources.Cluster.Name,
243-
Namespace: clusterResources.Cluster.Namespace,
140+
clusterResources = new(clusterctl.ApplyClusterTemplateAndWaitResult)
244141
})
245142

246-
By("PASSED!")
247-
})
143+
It("Should create a workload cluster", func() {
144+
By("Creating a workload cluster")
145+
146+
infrastructureProvider := clusterctl.DefaultInfrastructureProvider
147+
if input.InfrastructureProvider != nil {
148+
infrastructureProvider = *input.InfrastructureProvider
149+
}
150+
151+
flavor := clusterctl.DefaultFlavor
152+
if input.Flavor != nil {
153+
flavor = *input.Flavor
154+
}
155+
156+
controlPlaneMachineCount := ptr.To[int64](1)
157+
if input.ControlPlaneMachineCount != nil {
158+
controlPlaneMachineCount = input.ControlPlaneMachineCount
159+
}
160+
161+
workerMachineCount := ptr.To[int64](1)
162+
if input.WorkerMachineCount != nil {
163+
workerMachineCount = input.WorkerMachineCount
164+
}
165+
166+
clusterName := fmt.Sprintf("%s-%s", specName, util.RandomString(6))
167+
if input.ClusterName != nil {
168+
clusterName = *input.ClusterName
169+
}
248170

249-
AfterEach(func() {
250-
// Dumps all the resources in the spec namespace, then cleanups the cluster object and the spec namespace itself.
251-
framework.DumpSpecResourcesAndCleanup(ctx, specName, input.BootstrapClusterProxy, input.ClusterctlConfigPath, input.ArtifactFolder, namespace, cancelWatches, clusterResources.Cluster, input.E2EConfig.GetIntervals, input.SkipCleanup)
252-
if !input.SkipCleanup {
253171
if input.ExtensionServiceNamespace != "" && input.ExtensionServiceName != "" {
254-
Eventually(func() error {
255-
return input.BootstrapClusterProxy.GetClient().Delete(ctx, extensionConfig(input.ExtensionConfigName, input.ExtensionServiceNamespace, input.ExtensionServiceName, true))
256-
}, 10*time.Second, 1*time.Second).Should(Succeed(), "Deleting ExtensionConfig failed")
172+
// NOTE: test extension is already deployed in the management cluster. If for any reason in future we want
173+
// to make this test more self-contained this test should be modified in order to create an additional
174+
// management cluster; also the E2E test configuration should be modified introducing something like
175+
// optional:true allowing to define which providers should not be installed by default in
176+
// a management cluster.
177+
By("Deploy Test Extension ExtensionConfig")
178+
179+
// In this test we are defaulting all handlers to non-blocking because we don't expect the handlers to block the
180+
// cluster lifecycle by default. Setting defaultAllHandlersToBlocking to false enforces that the test-extension
181+
// automatically creates the ConfigMap with non-blocking preloaded responses.
182+
defaultAllHandlersToBlocking := false
183+
// select on the current namespace
184+
// This is necessary so in CI this test doesn't influence other tests by enabling lifecycle hooks
185+
// in other test namespaces.
186+
namespaces := []string{namespace.Name}
187+
if input.DeployClusterClassInSeparateNamespace {
188+
// Add the ClusterClass namespace, if the ClusterClass is deployed in a separate namespace.
189+
namespaces = append(namespaces, clusterClassNamespace.Name)
190+
}
191+
extensionConfig := extensionConfig(input.ExtensionConfigName, input.ExtensionServiceNamespace, input.ExtensionServiceName, defaultAllHandlersToBlocking, namespaces...)
192+
Expect(input.BootstrapClusterProxy.GetClient().Create(ctx,
193+
extensionConfig)).
194+
To(Succeed(), "Failed to create the ExtensionConfig")
257195
}
196+
197+
variables := map[string]string{
198+
// This is used to template the name of the ExtensionConfig into the ClusterClass.
199+
"EXTENSION_CONFIG_NAME": input.ExtensionConfigName,
200+
}
201+
maps.Copy(variables, input.ClusterctlVariables)
202+
258203
if input.DeployClusterClassInSeparateNamespace {
259-
framework.DeleteNamespace(ctx, framework.DeleteNamespaceInput{
260-
Deleter: input.BootstrapClusterProxy.GetClient(),
261-
Name: clusterClassNamespace.Name,
262-
})
204+
variables["CLUSTER_CLASS_NAMESPACE"] = clusterClassNamespace.Name
205+
By("Creating a cluster referencing a ClusterClass from another namespace")
206+
}
207+
208+
clusterctl.ApplyClusterTemplateAndWait(ctx, clusterctl.ApplyClusterTemplateAndWaitInput{
209+
ClusterProxy: input.BootstrapClusterProxy,
210+
ConfigCluster: clusterctl.ConfigClusterInput{
211+
LogFolder: filepath.Join(input.ArtifactFolder, "clusters", input.BootstrapClusterProxy.GetName()),
212+
ClusterctlConfigPath: input.ClusterctlConfigPath,
213+
ClusterctlVariables: variables,
214+
KubeconfigPath: input.BootstrapClusterProxy.GetKubeconfigPath(),
215+
InfrastructureProvider: infrastructureProvider,
216+
Flavor: flavor,
217+
Namespace: namespace.Name,
218+
ClusterName: clusterName,
219+
KubernetesVersion: input.E2EConfig.MustGetVariable(KubernetesVersion),
220+
ControlPlaneMachineCount: controlPlaneMachineCount,
221+
WorkerMachineCount: workerMachineCount,
222+
},
223+
ControlPlaneWaiters: input.ControlPlaneWaiters,
224+
WaitForClusterIntervals: input.E2EConfig.GetIntervals(specName, "wait-cluster"),
225+
WaitForControlPlaneIntervals: input.E2EConfig.GetIntervals(specName, "wait-control-plane"),
226+
WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"),
227+
PostMachinesProvisioned: func() {
228+
if input.PostMachinesProvisioned != nil {
229+
input.PostMachinesProvisioned(input.BootstrapClusterProxy, namespace.Name, clusterName)
230+
}
231+
},
232+
}, clusterResources)
233+
234+
Byf("Verify Cluster Available condition is true")
235+
framework.VerifyClusterAvailable(ctx, framework.VerifyClusterAvailableInput{
236+
Getter: input.BootstrapClusterProxy.GetClient(),
237+
Name: clusterResources.Cluster.Name,
238+
Namespace: clusterResources.Cluster.Namespace,
239+
})
240+
241+
Byf("Verify Machines Ready condition is true")
242+
framework.VerifyMachinesReady(ctx, framework.VerifyMachinesReadyInput{
243+
Lister: input.BootstrapClusterProxy.GetClient(),
244+
Name: clusterResources.Cluster.Name,
245+
Namespace: clusterResources.Cluster.Namespace,
246+
})
247+
248+
By("PASSED!")
249+
250+
})
251+
252+
AfterEach(func() {
253+
// Dumps all the resources in the spec namespace, then cleanups the cluster object and the spec namespace itself.
254+
framework.DumpSpecResourcesAndCleanup(ctx, specName, input.BootstrapClusterProxy, input.ClusterctlConfigPath, input.ArtifactFolder, namespace, cancelWatches, clusterResources.Cluster, input.E2EConfig.GetIntervals, input.SkipCleanup)
255+
if !input.SkipCleanup {
256+
if input.ExtensionServiceNamespace != "" && input.ExtensionServiceName != "" {
257+
Eventually(func() error {
258+
return input.BootstrapClusterProxy.GetClient().Delete(ctx, extensionConfig(input.ExtensionConfigName, input.ExtensionServiceNamespace, input.ExtensionServiceName, true))
259+
}, 10*time.Second, 1*time.Second).Should(Succeed(), "Deleting ExtensionConfig failed")
260+
}
261+
if input.DeployClusterClassInSeparateNamespace {
262+
framework.DeleteNamespace(ctx, framework.DeleteNamespaceInput{
263+
Deleter: input.BootstrapClusterProxy.GetClient(),
264+
Name: clusterClassNamespace.Name,
265+
})
266+
}
263267
}
264-
}
265-
})
268+
})
269+
270+
}
266271
}

test/framework/resourceversion_helpers.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ func ValidateResourceVersionStable(ctx context.Context, proxy ClusterProxy, name
5656
Consistently(func(g Gomega) {
5757
objectsWithResourceVersion, objects, err := getObjectsWithResourceVersion(ctx, proxy, namespace, ownerGraphFilterFunction)
5858
g.Expect(err).ToNot(HaveOccurred())
59+
resource, er := yaml.Marshal(objectsWithResourceVersion)
60+
g.Expect(er).ToNot(HaveOccurred())
61+
fmt.Printf("objectsWithResourceVersion:: %s\n", string(resource))
62+
resource1, er := yaml.Marshal(previousResourceVersions)
63+
g.Expect(er).ToNot(HaveOccurred())
64+
fmt.Printf("previousResourceVersions:: %s\n", string(resource1))
65+
5966
g.Expect(previousResourceVersions).To(BeComparableTo(objectsWithResourceVersion), printObjectDiff(previousObjects, objects))
6067
}, 2*time.Minute, 15*time.Second).Should(Succeed(), "resourceVersions didn't stay stable")
6168
}
@@ -67,7 +74,9 @@ func printObjectDiff(previousObjects, newObjects map[string]client.Object) func(
6774
preservedObjects := objectIDs(previousObjects).Intersection(objectIDs(newObjects))
6875

6976
var output strings.Builder
70-
77+
previousResource, _ := yaml.Marshal(previousObjects)
78+
newResource, _ := yaml.Marshal(newObjects)
79+
output.WriteString(fmt.Sprintf("\n printing Objects %s:\n%s\n", string(previousResource), string(newResource)))
7180
if len(createdObjects) > 0 {
7281
output.WriteString("\nDetected new objects\n")
7382
for objID := range createdObjects {

0 commit comments

Comments
 (0)