@@ -1362,11 +1362,15 @@ func TestImageBuildDegradedOnFailureAndClearedOnBuildSuccess(t *testing.T) {
1362
1362
1363
1363
cs := framework .NewClientSet ("" )
1364
1364
1365
+ // Get a random worker node to add to the layered pool
1366
+ targetNode := helpers .GetRandomNode (t , cs , "worker" )
1367
+
1365
1368
mosc := prepareForOnClusterLayeringTest (t , cs , onClusterLayeringTestOpts {
1366
1369
poolName : layeredMCPName ,
1367
1370
customDockerfiles : map [string ]string {
1368
1371
layeredMCPName : cowsayDockerfile ,
1369
1372
},
1373
+ targetNode : & targetNode ,
1370
1374
})
1371
1375
1372
1376
// First, add a bad containerfile to cause a build failure
@@ -1419,10 +1423,135 @@ func TestImageBuildDegradedOnFailureAndClearedOnBuildSuccess(t *testing.T) {
1419
1423
1420
1424
t .Logf ("Second build completed successfully: %s" , finishedBuild .Name )
1421
1425
1426
+ // Wait for the MachineOSConfig to get the new pullspec, which indicates full reconciliation
1427
+ waitForMOSCToGetNewPullspec (ctx , t , cs , mosc .Name , string (finishedBuild .Status .DigestedImagePushSpec ))
1428
+
1422
1429
// Wait for and verify ImageBuildDegraded condition is now False
1423
1430
degradedCondition = waitForImageBuildDegradedCondition (ctx , t , cs , layeredMCPName , corev1 .ConditionFalse )
1424
1431
require .NotNil (t , degradedCondition , "ImageBuildDegraded condition should still be present" )
1425
1432
assert .Equal (t , "BuildSucceeded" , degradedCondition .Reason , "ImageBuildDegraded reason should be BuildSucceeded" )
1426
1433
1427
1434
t .Logf ("ImageBuildDegraded condition correctly cleared to False with message: %s" , degradedCondition .Message )
1435
+
1436
+ // Verify MCP status is correct after successful build and full reconciliation
1437
+ successMcp , err := cs .MachineconfigurationV1Interface .MachineConfigPools ().Get (ctx , layeredMCPName , metav1.GetOptions {})
1438
+ require .NoError (t , err )
1439
+
1440
+ // After successful build completion and full reconciliation, MCP should show:
1441
+ // Updated=True, Updating=False, Degraded=False, ImageBuildDegraded=False
1442
+ kubeassert .Eventually ().MachineConfigPoolReachesState (successMcp , func (mcp * mcfgv1.MachineConfigPool , err error ) (bool , error ) {
1443
+ if err != nil {
1444
+ return false , err
1445
+ }
1446
+ // Return false (keep polling) if conditions don't match expected state
1447
+ if ! apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ) ||
1448
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ) ||
1449
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ) ||
1450
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ) {
1451
+ return false , nil
1452
+ }
1453
+
1454
+ // Return true when expected state is reached
1455
+ t .Logf ("MCP status after successful build - Updated: %v, Updating: %v, Degraded: %v, ImageBuildDegraded: %v" ,
1456
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ),
1457
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ),
1458
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ),
1459
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ))
1460
+
1461
+ return true , nil
1462
+ }, "MCP should reach correct state after successful build (Updated=True, Updating=False, Degraded=False, ImageBuildDegraded=False)" )
1463
+
1464
+ // Now trigger another build to test MCP status transitions when a new build starts
1465
+ t .Logf ("Triggering a third build to test MCP status transitions" )
1466
+
1467
+ // Modify the containerfile slightly to trigger a new build
1468
+ apiMosc , err = cs .MachineconfigurationV1Interface .MachineOSConfigs ().Get (ctx , mosc .Name , metav1.GetOptions {})
1469
+ require .NoError (t , err )
1470
+
1471
+ // Add a comment to the containerfile to change it and trigger a new build
1472
+ modifiedDockerfile := cowsayDockerfile + "\n # Comment to trigger new build"
1473
+ apiMosc .Spec .Containerfile = []mcfgv1.MachineOSContainerfile {
1474
+ {
1475
+ ContainerfileArch : mcfgv1 .NoArch ,
1476
+ Content : modifiedDockerfile ,
1477
+ },
1478
+ }
1479
+
1480
+ updated , err = cs .MachineconfigurationV1Interface .MachineOSConfigs ().Update (ctx , apiMosc , metav1.UpdateOptions {})
1481
+ require .NoError (t , err )
1482
+
1483
+ t .Logf ("Modified containerfile, waiting for third build to start" )
1484
+
1485
+ // Get the updated MCP to compute the new build
1486
+ mcp , err = cs .MachineconfigurationV1Interface .MachineConfigPools ().Get (ctx , layeredMCPName , metav1.GetOptions {})
1487
+ require .NoError (t , err )
1488
+
1489
+ // Compute the new MachineOSBuild name for the third build
1490
+ thirdMoscMosb := buildrequest .NewMachineOSBuildFromAPIOrDie (ctx , cs .GetKubeclient (), updated , mcp )
1491
+
1492
+ // Wait for the third build to start
1493
+ thirdMosb := waitForBuildToStart (t , cs , thirdMoscMosb )
1494
+ t .Logf ("Third build started: %s" , thirdMosb .Name )
1495
+
1496
+ // Verify MCP status during active build:
1497
+ // Updated=False, Updating=True, Degraded=False, ImageBuildDegraded=False
1498
+ buildingMcp , err := cs .MachineconfigurationV1Interface .MachineConfigPools ().Get (ctx , layeredMCPName , metav1.GetOptions {})
1499
+ require .NoError (t , err )
1500
+
1501
+ kubeassert .Eventually ().MachineConfigPoolReachesState (buildingMcp , func (mcp * mcfgv1.MachineConfigPool , err error ) (bool , error ) {
1502
+ if err != nil {
1503
+ return false , err
1504
+ }
1505
+ // During build, MCP should show: Updated=False, Updating=True
1506
+ if apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ) ||
1507
+ ! apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ) ||
1508
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ) ||
1509
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ) {
1510
+ return false , nil
1511
+ }
1512
+
1513
+ t .Logf ("MCP status during active build - Updated: %v, Updating: %v, Degraded: %v, ImageBuildDegraded: %v" ,
1514
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ),
1515
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ),
1516
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ),
1517
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ))
1518
+
1519
+ return true , nil
1520
+ }, "MCP should reach correct state during active build (Updated=False, Updating=True, Degraded=False, ImageBuildDegraded=False)" )
1521
+
1522
+ // Wait for the third build to complete successfully
1523
+ finalBuild := waitForBuildToComplete (t , cs , thirdMosb )
1524
+ t .Logf ("Third build completed successfully: %s" , finalBuild .Name )
1525
+
1526
+ // Wait for the MachineOSConfig to get the new pullspec, which indicates full reconciliation
1527
+ waitForMOSCToGetNewPullspec (ctx , t , cs , mosc .Name , string (finalBuild .Status .DigestedImagePushSpec ))
1528
+
1529
+ // Final verification: MCP status should return to:
1530
+ // Updated=True, Updating=False, Degraded=False, ImageBuildDegraded=False
1531
+ finalMcp , err := cs .MachineconfigurationV1Interface .MachineConfigPools ().Get (ctx , layeredMCPName , metav1.GetOptions {})
1532
+ require .NoError (t , err )
1533
+
1534
+ kubeassert .Eventually ().MachineConfigPoolReachesState (finalMcp , func (mcp * mcfgv1.MachineConfigPool , err error ) (bool , error ) {
1535
+ if err != nil {
1536
+ return false , err
1537
+ }
1538
+ // Return false (keep polling) if conditions don't match expected state
1539
+ if ! apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ) ||
1540
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ) ||
1541
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ) ||
1542
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ) {
1543
+ return false , nil
1544
+ }
1545
+
1546
+ // Return true when expected state is reached
1547
+ t .Logf ("Final MCP status after third build completion - Updated: %v, Updating: %v, Degraded: %v, ImageBuildDegraded: %v" ,
1548
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ),
1549
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ),
1550
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ),
1551
+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ))
1552
+
1553
+ return true , nil
1554
+ }, "MCP should return to correct state after final build completion (Updated=True, Updating=False, Degraded=False, ImageBuildDegraded=False)" )
1555
+
1556
+ t .Logf ("All MCP status transitions verified successfully across build failure, success, and subsequent new build" )
1428
1557
}
0 commit comments