@@ -1448,11 +1448,148 @@ func TestImageBuildDegradedOnFailureAndClearedOnBuildStart(t *testing.T) {
14481448 moscChangeMosb := buildrequest .NewMachineOSBuildFromAPIOrDie (ctx , cs .GetKubeclient (), updated , mcp )
14491449
14501450 // Wait for the second build to start
1451- waitForBuildToStart (t , cs , moscChangeMosb )
1451+ secondMosb := waitForBuildToStart (t , cs , moscChangeMosb )
1452+ t .Logf ("Second build started successfully: %s" , secondMosb .Name )
14521453
14531454 // Wait for and verify ImageBuildDegraded condition is False after the new build starts.
1455+ // The condition should be cleared when the build starts.
14541456 degradedCondition = waitForImageBuildDegradedCondition (ctx , t , cs , layeredMCPName , corev1 .ConditionFalse )
14551457 require .NotNil (t , degradedCondition , "ImageBuildDegraded condition should still be present" )
14561458 assert .Equal (t , string (mcfgv1 .MachineConfigPoolBuilding ), degradedCondition .Reason , "ImageBuildDegraded reason should be Building" )
1457- t .Logf ("ImageBuildDegraded condition correctly cleared to False with message: %s" , degradedCondition .Message )
1459+ t .Logf ("ImageBuildDegraded condition correctly cleared to False when build started with message: %s" , degradedCondition .Message )
1460+
1461+ // Wait for the second build to complete successfully
1462+ finishedBuild := waitForBuildToComplete (t , cs , secondMosb )
1463+ t .Logf ("Second build completed successfully: %s" , finishedBuild .Name )
1464+
1465+ // Wait for the MachineOSConfig to get the new pullspec, which indicates full reconciliation
1466+ waitForMOSCToGetNewPullspec (ctx , t , cs , mosc .Name , string (finishedBuild .Status .DigestedImagePushSpec ))
1467+
1468+ // Wait for and verify ImageBuildDegraded condition is False with reason BuildSucceeded
1469+ degradedCondition = waitForImageBuildDegradedCondition (ctx , t , cs , layeredMCPName , corev1 .ConditionFalse )
1470+ require .NotNil (t , degradedCondition , "ImageBuildDegraded condition should still be present" )
1471+ assert .Equal (t , string (mcfgv1 .MachineConfigPoolBuildSuccess ), degradedCondition .Reason , "ImageBuildDegraded reason should be BuildSuccess" )
1472+ t .Logf ("ImageBuildDegraded condition correctly set to False when build succeeded with message: %s" , degradedCondition .Message )
1473+
1474+ // Verify MCP status is correct after successful build and full reconciliation
1475+ successMcp , err := cs .MachineconfigurationV1Interface .MachineConfigPools ().Get (ctx , layeredMCPName , metav1.GetOptions {})
1476+ require .NoError (t , err )
1477+
1478+ // After successful build completion and full reconciliation, MCP should show:
1479+ // Updated=True, Updating=False, Degraded=False, ImageBuildDegraded=False
1480+ kubeassert .Eventually ().MachineConfigPoolReachesState (successMcp , func (mcp * mcfgv1.MachineConfigPool , err error ) (bool , error ) {
1481+ if err != nil {
1482+ return false , err
1483+ }
1484+ // Return false (keep polling) if conditions don't match expected state
1485+ if ! apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ) ||
1486+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ) ||
1487+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ) ||
1488+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ) {
1489+ return false , nil
1490+ }
1491+
1492+ // Return true when expected state is reached
1493+ t .Logf ("MCP status after successful build - Updated: %v, Updating: %v, Degraded: %v, ImageBuildDegraded: %v" ,
1494+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ),
1495+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ),
1496+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ),
1497+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ))
1498+
1499+ return true , nil
1500+ }, "MCP should reach correct state after successful build (Updated=True, Updating=False, Degraded=False, ImageBuildDegraded=False)" )
1501+
1502+ // Now trigger another build to test MCP status transitions when a new build starts
1503+ t .Logf ("Triggering a third build to test MCP status transitions" )
1504+
1505+ // Modify the containerfile slightly to trigger a new build
1506+ apiMosc , err = cs .MachineconfigurationV1Interface .MachineOSConfigs ().Get (ctx , mosc .Name , metav1.GetOptions {})
1507+ require .NoError (t , err )
1508+
1509+ // Add a comment to the containerfile to change it and trigger a new build
1510+ modifiedDockerfile := cowsayDockerfile + "\n # Comment to trigger new build"
1511+ apiMosc .Spec .Containerfile = []mcfgv1.MachineOSContainerfile {
1512+ {
1513+ ContainerfileArch : mcfgv1 .NoArch ,
1514+ Content : modifiedDockerfile ,
1515+ },
1516+ }
1517+
1518+ updated , err = cs .MachineconfigurationV1Interface .MachineOSConfigs ().Update (ctx , apiMosc , metav1.UpdateOptions {})
1519+ require .NoError (t , err )
1520+
1521+ t .Logf ("Modified containerfile, waiting for third build to start" )
1522+
1523+ // Get the updated MCP to compute the new build
1524+ mcp , err = cs .MachineconfigurationV1Interface .MachineConfigPools ().Get (ctx , layeredMCPName , metav1.GetOptions {})
1525+ require .NoError (t , err )
1526+
1527+ // Compute the new MachineOSBuild name for the third build
1528+ thirdMoscMosb := buildrequest .NewMachineOSBuildFromAPIOrDie (ctx , cs .GetKubeclient (), updated , mcp )
1529+
1530+ // Wait for the third build to start
1531+ thirdMosb := waitForBuildToStart (t , cs , thirdMoscMosb )
1532+ t .Logf ("Third build started: %s" , thirdMosb .Name )
1533+
1534+ // Verify MCP status during active build:
1535+ // Updated=False, Updating=True, Degraded=False, ImageBuildDegraded=False
1536+ buildingMcp , err := cs .MachineconfigurationV1Interface .MachineConfigPools ().Get (ctx , layeredMCPName , metav1.GetOptions {})
1537+ require .NoError (t , err )
1538+
1539+ kubeassert .Eventually ().MachineConfigPoolReachesState (buildingMcp , func (mcp * mcfgv1.MachineConfigPool , err error ) (bool , error ) {
1540+ if err != nil {
1541+ return false , err
1542+ }
1543+ // During build, MCP should show: Updated=False, Updating=True
1544+ if apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ) ||
1545+ ! apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ) ||
1546+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ) ||
1547+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ) {
1548+ return false , nil
1549+ }
1550+
1551+ t .Logf ("MCP status during active build - Updated: %v, Updating: %v, Degraded: %v, ImageBuildDegraded: %v" ,
1552+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ),
1553+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ),
1554+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ),
1555+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ))
1556+
1557+ return true , nil
1558+ }, "MCP should reach correct state during active build (Updated=False, Updating=True, Degraded=False, ImageBuildDegraded=False)" )
1559+
1560+ // Wait for the third build to complete successfully
1561+ finalBuild := waitForBuildToComplete (t , cs , thirdMosb )
1562+ t .Logf ("Third build completed successfully: %s" , finalBuild .Name )
1563+
1564+ // Wait for the MachineOSConfig to get the new pullspec, which indicates full reconciliation
1565+ waitForMOSCToGetNewPullspec (ctx , t , cs , mosc .Name , string (finalBuild .Status .DigestedImagePushSpec ))
1566+
1567+ // Final verification: MCP status should return to:
1568+ // Updated=True, Updating=False, Degraded=False, ImageBuildDegraded=False
1569+ finalMcp , err := cs .MachineconfigurationV1Interface .MachineConfigPools ().Get (ctx , layeredMCPName , metav1.GetOptions {})
1570+ require .NoError (t , err )
1571+
1572+ kubeassert .Eventually ().MachineConfigPoolReachesState (finalMcp , func (mcp * mcfgv1.MachineConfigPool , err error ) (bool , error ) {
1573+ if err != nil {
1574+ return false , err
1575+ }
1576+ // Return false (keep polling) if conditions don't match expected state
1577+ if ! apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ) ||
1578+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ) ||
1579+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ) ||
1580+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ) {
1581+ return false , nil
1582+ }
1583+
1584+ // Return true when expected state is reached
1585+ t .Logf ("Final MCP status after third build completion - Updated: %v, Updating: %v, Degraded: %v, ImageBuildDegraded: %v" ,
1586+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdated ),
1587+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolUpdating ),
1588+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolDegraded ),
1589+ apihelpers .IsMachineConfigPoolConditionTrue (mcp .Status .Conditions , mcfgv1 .MachineConfigPoolImageBuildDegraded ))
1590+
1591+ return true , nil
1592+ }, "MCP should return to correct state after final build completion (Updated=True, Updating=False, Degraded=False, ImageBuildDegraded=False)" )
1593+
1594+ t .Logf ("All MCP status transitions verified successfully across build failure, success, and subsequent new build" )
14581595}
0 commit comments