@@ -2,8 +2,10 @@ package e2e
22
33import (
44 "fmt"
5+ "time"
56
67 . "github.com/onsi/ginkgo/v2"
8+ . "github.com/onsi/gomega"
79 configv1 "github.com/openshift/api/config/v1"
810 mapiv1beta1 "github.com/openshift/api/machine/v1beta1"
911 mapiframework "github.com/openshift/cluster-api-actuator-pkg/pkg/framework"
@@ -12,6 +14,7 @@ import (
1214
1315 awsv1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
1416 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
17+ "sigs.k8s.io/controller-runtime/pkg/envtest/komega"
1518)
1619
1720var _ = Describe ("[sig-cluster-lifecycle][OCPFeatureGate:MachineAPIMigration] Machine Migration CAPI Authoritative Tests" , Ordered , func () {
@@ -298,4 +301,161 @@ var _ = Describe("[sig-cluster-lifecycle][OCPFeatureGate:MachineAPIMigration] Ma
298301 })
299302 })*/
300303 })
304+
305+ var _ = Describe ("Update CAPI Machine" , Ordered , func () {
306+ var capiUpdateTestName = "machine-update-capi-test"
307+ var newMapiMachine * mapiv1beta1.Machine
308+ var newCapiMachine * clusterv1.Machine
309+ var previousState * MachineState
310+ Context ("with spec.authoritativeAPI: ClusterAPI (both MAPI and CAPI machine exist)" , func () {
311+ BeforeAll (func () {
312+ newMapiMachine = createMAPIMachineWithAuthority (ctx , cl , capiUpdateTestName , mapiv1beta1 .MachineAuthorityClusterAPI )
313+ newCapiMachine = capiframework .GetMachine (cl , newMapiMachine .Name , capiframework .CAPINamespace )
314+ verifyMachineRunning (cl , newCapiMachine )
315+
316+ DeferCleanup (func () {
317+ By ("Cleaning up machine resources" )
318+ cleanupMachineResources (
319+ ctx ,
320+ cl ,
321+ []* clusterv1.Machine {newCapiMachine },
322+ []* mapiv1beta1.Machine {newMapiMachine },
323+ )
324+ })
325+ })
326+
327+ It ("should add labels/annotations on CAPI machine" , func () {
328+ // Capture state before the update
329+ previousState = captureMachineStateBeforeUpdate (cl , newMapiMachine .Name )
330+
331+ // Add a small delay to ensure timestamps are distinguishable
332+ time .Sleep (1 * time .Second )
333+
334+ Eventually (komega .Update (newCapiMachine , func () {
335+ if newCapiMachine .Labels == nil {
336+ newCapiMachine .Labels = make (map [string ]string )
337+ }
338+ if newCapiMachine .Annotations == nil {
339+ newCapiMachine .Annotations = make (map [string ]string )
340+ }
341+ newCapiMachine .Labels ["test-capi-label" ] = "test-capi-label-value"
342+ newCapiMachine .Annotations ["test-capi-annotation" ] = "test-capi-annotation-value"
343+ }), capiframework .WaitMedium , capiframework .RetryMedium ).Should (Succeed (), "Failed to add CAPI Machine labels/annotations" )
344+ })
345+
346+ It ("should synchronize added labels/annotations to both metadata and spec on MAPI" , func () {
347+ Eventually (komega .Object (newMapiMachine ), capiframework .WaitMedium , capiframework .RetryMedium ).Should (
348+ SatisfyAll (
349+ // Check metadata
350+ WithTransform (func (m * mapiv1beta1.Machine ) string {
351+ return m .Labels ["test-capi-label" ]
352+ }, Equal ("test-capi-label-value" )),
353+ WithTransform (func (m * mapiv1beta1.Machine ) string {
354+ return m .Annotations ["test-capi-annotation" ]
355+ }, Equal ("test-capi-annotation-value" )),
356+ // Check spec template metadata
357+ WithTransform (func (m * mapiv1beta1.Machine ) string {
358+ return m .Spec .ObjectMeta .Labels ["test-capi-label" ]
359+ }, Equal ("test-capi-label-value" )),
360+ WithTransform (func (m * mapiv1beta1.Machine ) string {
361+ return m .Spec .ObjectMeta .Annotations ["test-capi-annotation" ]
362+ }, Equal ("test-capi-annotation-value" )),
363+ ),
364+ "Added labels should be copied to both metadata and spec on MAPI Machine" ,
365+ )
366+ })
367+
368+ It ("should verify MAPI generation changed and synchronized time changed after syncing labels to spec" , func () {
369+ Eventually (komega .Get (newMapiMachine ), capiframework .WaitMedium , capiframework .RetryMedium ).Should (Succeed (), "Failed to get updated MAPI Machine" )
370+
371+ verifyMachineStateChanged (cl , newMapiMachine , previousState , mapiv1beta1 .MachineAuthorityClusterAPI , "adding labels/annotations" )
372+ })
373+
374+ It ("should modify existing labels/annotations on CAPI machine" , func () {
375+ // Capture state before the update
376+ previousState = captureMachineStateBeforeUpdate (cl , newMapiMachine .Name )
377+
378+ // Add a small delay to ensure timestamps are distinguishable
379+ time .Sleep (1 * time .Second )
380+
381+ Eventually (komega .Update (newCapiMachine , func () {
382+ newCapiMachine .Labels ["test-capi-label" ] = "modified-capi-label-value"
383+ newCapiMachine .Annotations ["test-capi-annotation" ] = "modified-capi-annotation-value"
384+ }), capiframework .WaitMedium , capiframework .RetryMedium ).Should (Succeed (), "Failed to modify CAPI Machine labels/annotations" )
385+ })
386+
387+ It ("should synchronize modified labels/annotations to both metadata and spec on MAPI" , func () {
388+ Eventually (komega .Object (newMapiMachine ), capiframework .WaitMedium , capiframework .RetryMedium ).Should (
389+ SatisfyAll (
390+ // Check metadata
391+ WithTransform (func (m * mapiv1beta1.Machine ) string {
392+ return m .Labels ["test-capi-label" ]
393+ }, Equal ("modified-capi-label-value" )),
394+ WithTransform (func (m * mapiv1beta1.Machine ) string {
395+ return m .Annotations ["test-capi-annotation" ]
396+ }, Equal ("modified-capi-annotation-value" )),
397+ // Check spec template metadata
398+ WithTransform (func (m * mapiv1beta1.Machine ) string {
399+ return m .Spec .ObjectMeta .Labels ["test-capi-label" ]
400+ }, Equal ("modified-capi-label-value" )),
401+ WithTransform (func (m * mapiv1beta1.Machine ) string {
402+ return m .Spec .ObjectMeta .Annotations ["test-capi-annotation" ]
403+ }, Equal ("modified-capi-annotation-value" )),
404+ ),
405+ "Modified labels/annotations should be synchronized to both metadata and spec on MAPI Machine" ,
406+ )
407+ })
408+
409+ It ("should verify MAPI generation changed and synchronized time changed after syncing modified labels to spec" , func () {
410+ Eventually (komega .Get (newMapiMachine ), capiframework .WaitMedium , capiframework .RetryMedium ).Should (Succeed (), "Failed to get updated MAPI Machine" )
411+
412+ verifyMachineStateChanged (cl , newMapiMachine , previousState , mapiv1beta1 .MachineAuthorityClusterAPI , "modifying labels/annotations" )
413+ })
414+
415+ It ("should delete labels/annotations on CAPI machine" , func () {
416+ // Capture state before the update
417+ previousState = captureMachineStateBeforeUpdate (cl , newMapiMachine .Name )
418+
419+ // Add a small delay to ensure timestamps are distinguishable
420+ time .Sleep (1 * time .Second )
421+
422+ Eventually (komega .Update (newCapiMachine , func () {
423+ delete (newCapiMachine .Labels , "test-capi-label" )
424+ delete (newCapiMachine .Annotations , "test-capi-annotation" )
425+ }), capiframework .WaitMedium , capiframework .RetryMedium ).Should (Succeed (), "Failed to delete CAPI Machine labels/annotations" )
426+ })
427+
428+ It ("should synchronize label/annotation deletion to both metadata and spec on MAPI" , func () {
429+ Eventually (komega .Object (newMapiMachine ), capiframework .WaitMedium , capiframework .RetryMedium ).Should (
430+ SatisfyAll (
431+ // Check metadata deletion
432+ WithTransform (func (m * mapiv1beta1.Machine ) bool {
433+ _ , exists := m .Labels ["test-capi-label" ]
434+ return exists
435+ }, BeFalse ()),
436+ WithTransform (func (m * mapiv1beta1.Machine ) bool {
437+ _ , exists := m .Annotations ["test-capi-annotation" ]
438+ return exists
439+ }, BeFalse ()),
440+ // Verify deleted labels are also removed from spec
441+ WithTransform (func (m * mapiv1beta1.Machine ) bool {
442+ _ , exists := m .Spec .ObjectMeta .Labels ["test-capi-label" ]
443+ return exists
444+ }, BeFalse ()),
445+ WithTransform (func (m * mapiv1beta1.Machine ) bool {
446+ _ , exists := m .Spec .ObjectMeta .Annotations ["test-capi-annotation" ]
447+ return exists
448+ }, BeFalse ()),
449+ ),
450+ "Deleted labels/annotations should be synchronized to both metadata and spec on MAPI Machine" ,
451+ )
452+ })
453+
454+ It ("should verify MAPI generation changed and synchronized time changed after syncing deleted labels to spec" , func () {
455+ Eventually (komega .Get (newMapiMachine ), capiframework .WaitMedium , capiframework .RetryMedium ).Should (Succeed (), "Failed to get updated MAPI Machine" )
456+
457+ verifyMachineStateChanged (cl , newMapiMachine , previousState , mapiv1beta1 .MachineAuthorityClusterAPI , "deleting labels/annotations" )
458+ })
459+ })
460+ })
301461})
0 commit comments