Skip to content

Commit 7b578ab

Browse files
committed
operator: add upgrade block unit tests
This commit adds unit tests for the new Upgradeable guards added in the previous commit.
1 parent f3bcf32 commit 7b578ab

File tree

2 files changed

+378
-0
lines changed

2 files changed

+378
-0
lines changed

pkg/controller/common/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ const (
142142
StubIgnitionTimestampAnnotation = "machineconfiguration.openshift.io/stub-ignition-upgraded-at"
143143

144144
// Current Boot Image Skew Limits
145+
// Note: Update units in status_test.go when the following are bumped
145146
RHCOSVersionBootImageSkewLimit = "9.2"
146147
OCPVersionBootImageSkewLimit = "4.13.0"
147148
)

pkg/operator/status_test.go

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ import (
2323
configv1 "github.com/openshift/api/config/v1"
2424
features "github.com/openshift/api/features"
2525
mcfgv1 "github.com/openshift/api/machineconfiguration/v1"
26+
opv1 "github.com/openshift/api/operator/v1"
2627
fakeconfigclientset "github.com/openshift/client-go/config/clientset/versioned/fake"
2728
configlistersv1 "github.com/openshift/client-go/config/listers/config/v1"
29+
mcoplistersv1 "github.com/openshift/client-go/operator/listers/operator/v1"
2830
cov1helpers "github.com/openshift/library-go/pkg/config/clusteroperator/v1helpers"
2931
ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common"
3032
"github.com/openshift/machine-config-operator/test/helpers"
@@ -795,3 +797,378 @@ func TestInClusterBringUpStayOnErr(t *testing.T) {
795797

796798
assert.False(t, optr.inClusterBringup)
797799
}
800+
801+
func TestCheckBootImageSkewUpgradeableGuard(t *testing.T) {
802+
tests := []struct {
803+
name string
804+
featureGateEnabled bool
805+
mcop *opv1.MachineConfiguration
806+
mcopNotFound bool
807+
mcopGetError error
808+
expectUpgradeBlock bool
809+
expectMessage string
810+
expectError bool
811+
}{
812+
{
813+
name: "feature gate disabled",
814+
featureGateEnabled: false,
815+
mcop: nil,
816+
expectUpgradeBlock: false,
817+
expectMessage: "",
818+
expectError: false,
819+
},
820+
{
821+
name: "MachineConfiguration not found",
822+
featureGateEnabled: true,
823+
mcopNotFound: true,
824+
expectUpgradeBlock: false,
825+
expectMessage: "",
826+
expectError: false,
827+
},
828+
{
829+
name: "mode is None",
830+
featureGateEnabled: true,
831+
mcop: &opv1.MachineConfiguration{
832+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
833+
Status: opv1.MachineConfigurationStatus{
834+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
835+
Mode: opv1.BootImageSkewEnforcementModeStatusNone,
836+
},
837+
},
838+
},
839+
expectUpgradeBlock: false,
840+
expectMessage: "",
841+
expectError: false,
842+
},
843+
{
844+
name: "mode is unset",
845+
featureGateEnabled: true,
846+
mcop: &opv1.MachineConfiguration{
847+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
848+
Status: opv1.MachineConfigurationStatus{
849+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
850+
Mode: "",
851+
},
852+
},
853+
},
854+
expectUpgradeBlock: false,
855+
expectMessage: "",
856+
expectError: false,
857+
},
858+
// OCP version tests in automatic mode
859+
{
860+
name: "mode is Automatic with OCP version within limit",
861+
featureGateEnabled: true,
862+
mcop: &opv1.MachineConfiguration{
863+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
864+
Status: opv1.MachineConfigurationStatus{
865+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
866+
Mode: opv1.BootImageSkewEnforcementModeStatusAutomatic,
867+
Automatic: opv1.ClusterBootImageAutomatic{
868+
OCPVersion: "4.17.0",
869+
},
870+
},
871+
},
872+
},
873+
expectUpgradeBlock: false,
874+
expectMessage: "",
875+
expectError: false,
876+
},
877+
{
878+
name: "mode is Automatic with OCP version below limit",
879+
featureGateEnabled: true,
880+
mcop: &opv1.MachineConfiguration{
881+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
882+
Status: opv1.MachineConfigurationStatus{
883+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
884+
Mode: opv1.BootImageSkewEnforcementModeStatusAutomatic,
885+
Automatic: opv1.ClusterBootImageAutomatic{
886+
OCPVersion: "4.12.0",
887+
},
888+
},
889+
},
890+
},
891+
expectUpgradeBlock: true,
892+
expectMessage: "Upgrades have been disabled because the cluster is using OCP boot image version 4.12.0, which is below the minimum required version " + ctrlcommon.OCPVersionBootImageSkewLimit + ". To enable upgrades, please update your boot images following the documentation at [TODO: insert link], or disable boot image skew enforcement at [TODO: insert link]",
893+
expectError: false,
894+
},
895+
// OCP version tests in manual mode
896+
{
897+
name: "mode is Manual with OCP version within limit",
898+
featureGateEnabled: true,
899+
mcop: &opv1.MachineConfiguration{
900+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
901+
Status: opv1.MachineConfigurationStatus{
902+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
903+
Mode: opv1.BootImageSkewEnforcementModeStatusManual,
904+
Manual: opv1.ClusterBootImageManual{
905+
Mode: opv1.ClusterBootImageSpecModeOCPVersion,
906+
OCPVersion: "4.16.0",
907+
},
908+
},
909+
},
910+
},
911+
expectUpgradeBlock: false,
912+
expectMessage: "",
913+
expectError: false,
914+
},
915+
{
916+
name: "mode is Manual with OCP version below limit",
917+
featureGateEnabled: true,
918+
mcop: &opv1.MachineConfiguration{
919+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
920+
Status: opv1.MachineConfigurationStatus{
921+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
922+
Mode: opv1.BootImageSkewEnforcementModeStatusManual,
923+
Manual: opv1.ClusterBootImageManual{
924+
Mode: opv1.ClusterBootImageSpecModeOCPVersion,
925+
OCPVersion: "4.10.0",
926+
},
927+
},
928+
},
929+
},
930+
expectUpgradeBlock: true,
931+
expectMessage: "Upgrades have been disabled because the cluster is using OCP boot image version 4.10.0, which is below the minimum required version " + ctrlcommon.OCPVersionBootImageSkewLimit + ". To enable upgrades, please update your boot images following the documentation at [TODO: insert link], or disable boot image skew enforcement at [TODO: insert link]",
932+
expectError: false,
933+
},
934+
{
935+
name: "mode is Automatic with exact minimum OCP version",
936+
featureGateEnabled: true,
937+
mcop: &opv1.MachineConfiguration{
938+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
939+
Status: opv1.MachineConfigurationStatus{
940+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
941+
Mode: opv1.BootImageSkewEnforcementModeStatusAutomatic,
942+
Automatic: opv1.ClusterBootImageAutomatic{
943+
OCPVersion: ctrlcommon.OCPVersionBootImageSkewLimit,
944+
},
945+
},
946+
},
947+
},
948+
expectUpgradeBlock: false,
949+
expectMessage: "",
950+
expectError: false,
951+
},
952+
// RHCOS version tests in Automatic mode
953+
{
954+
name: "mode is Automatic with modern RHCOS version within limit",
955+
featureGateEnabled: true,
956+
mcop: &opv1.MachineConfiguration{
957+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
958+
Status: opv1.MachineConfigurationStatus{
959+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
960+
Mode: opv1.BootImageSkewEnforcementModeStatusAutomatic,
961+
Automatic: opv1.ClusterBootImageAutomatic{
962+
RHCOSVersion: "9.4.20251023-0",
963+
},
964+
},
965+
},
966+
},
967+
expectUpgradeBlock: false,
968+
expectMessage: "",
969+
expectError: false,
970+
},
971+
{
972+
name: "mode is Automatic with modern RHCOS version below limit",
973+
featureGateEnabled: true,
974+
mcop: &opv1.MachineConfiguration{
975+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
976+
Status: opv1.MachineConfigurationStatus{
977+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
978+
Mode: opv1.BootImageSkewEnforcementModeStatusAutomatic,
979+
Automatic: opv1.ClusterBootImageAutomatic{
980+
RHCOSVersion: "9.0.20251023-0",
981+
},
982+
},
983+
},
984+
},
985+
expectUpgradeBlock: true,
986+
expectMessage: "Upgrades have been disabled because the cluster is using RHCOS boot image version 9.0.20251023-0(RHEL version: 9.0), which is below the minimum required RHEL version " + ctrlcommon.RHCOSVersionBootImageSkewLimit + ". To enable upgrades, please update your boot images following the documentation at [TODO: insert link], or disable boot image skew enforcement at [TODO: insert link]",
987+
expectError: false,
988+
},
989+
{
990+
name: "mode is Automatic with legacy RHCOS version within limit",
991+
featureGateEnabled: true,
992+
mcop: &opv1.MachineConfiguration{
993+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
994+
Status: opv1.MachineConfigurationStatus{
995+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
996+
Mode: opv1.BootImageSkewEnforcementModeStatusAutomatic,
997+
Automatic: opv1.ClusterBootImageAutomatic{
998+
RHCOSVersion: "416.94.202510081640-0",
999+
},
1000+
},
1001+
},
1002+
},
1003+
expectUpgradeBlock: false,
1004+
expectMessage: "",
1005+
expectError: false,
1006+
},
1007+
{
1008+
name: "mode is Automatic with legacy RHCOS version below limit",
1009+
featureGateEnabled: true,
1010+
mcop: &opv1.MachineConfiguration{
1011+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
1012+
Status: opv1.MachineConfigurationStatus{
1013+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
1014+
Mode: opv1.BootImageSkewEnforcementModeStatusAutomatic,
1015+
Automatic: opv1.ClusterBootImageAutomatic{
1016+
RHCOSVersion: "411.86.202308081056-0",
1017+
},
1018+
},
1019+
},
1020+
},
1021+
expectUpgradeBlock: true,
1022+
expectMessage: "Upgrades have been disabled because the cluster is using RHCOS boot image version 411.86.202308081056-0(RHEL version: 8.6), which is below the minimum required RHEL version " + ctrlcommon.RHCOSVersionBootImageSkewLimit + ". To enable upgrades, please update your boot images following the documentation at [TODO: insert link], or disable boot image skew enforcement at [TODO: insert link]",
1023+
expectError: false,
1024+
},
1025+
1026+
{
1027+
name: "mode is Automatic with exact minimum RHCOS version",
1028+
featureGateEnabled: true,
1029+
mcop: &opv1.MachineConfiguration{
1030+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
1031+
Status: opv1.MachineConfigurationStatus{
1032+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
1033+
Mode: opv1.BootImageSkewEnforcementModeStatusAutomatic,
1034+
Automatic: opv1.ClusterBootImageAutomatic{
1035+
RHCOSVersion: "413.92.202402131523-0",
1036+
},
1037+
},
1038+
},
1039+
},
1040+
expectUpgradeBlock: false,
1041+
expectMessage: "",
1042+
expectError: false,
1043+
},
1044+
// RHCOS version tests in manual mode
1045+
{
1046+
name: "mode is Manual with modern RHCOS version within limit",
1047+
featureGateEnabled: true,
1048+
mcop: &opv1.MachineConfiguration{
1049+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
1050+
Status: opv1.MachineConfigurationStatus{
1051+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
1052+
Mode: opv1.BootImageSkewEnforcementModeStatusManual,
1053+
Manual: opv1.ClusterBootImageManual{
1054+
Mode: opv1.ClusterBootImageSpecModeRHCOSVersion,
1055+
RHCOSVersion: "9.6.20251023-0",
1056+
},
1057+
},
1058+
},
1059+
},
1060+
expectUpgradeBlock: false,
1061+
expectMessage: "",
1062+
expectError: false,
1063+
},
1064+
{
1065+
name: "mode is Manual with modern RHCOS version below limit",
1066+
featureGateEnabled: true,
1067+
mcop: &opv1.MachineConfiguration{
1068+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
1069+
Status: opv1.MachineConfigurationStatus{
1070+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
1071+
Mode: opv1.BootImageSkewEnforcementModeStatusManual,
1072+
Manual: opv1.ClusterBootImageManual{
1073+
Mode: opv1.ClusterBootImageSpecModeRHCOSVersion,
1074+
RHCOSVersion: "9.1.20251023-0",
1075+
},
1076+
},
1077+
},
1078+
},
1079+
expectUpgradeBlock: true,
1080+
expectMessage: "Upgrades have been disabled because the cluster is using RHCOS boot image version 9.1.20251023-0(RHEL version: 9.1), which is below the minimum required RHEL version " + ctrlcommon.RHCOSVersionBootImageSkewLimit + ". To enable upgrades, please update your boot images following the documentation at [TODO: insert link], or disable boot image skew enforcement at [TODO: insert link]",
1081+
expectError: false,
1082+
},
1083+
{
1084+
name: "mode is Manual with legacy RHCOS version within limit",
1085+
featureGateEnabled: true,
1086+
mcop: &opv1.MachineConfiguration{
1087+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
1088+
Status: opv1.MachineConfigurationStatus{
1089+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
1090+
Mode: opv1.BootImageSkewEnforcementModeStatusManual,
1091+
Manual: opv1.ClusterBootImageManual{
1092+
Mode: opv1.ClusterBootImageSpecModeRHCOSVersion,
1093+
RHCOSVersion: "416.94.202510081640-0",
1094+
},
1095+
},
1096+
},
1097+
},
1098+
expectUpgradeBlock: false,
1099+
expectMessage: "",
1100+
expectError: false,
1101+
},
1102+
{
1103+
name: "mode is Manual with legacy RHCOS version below limit",
1104+
featureGateEnabled: true,
1105+
mcop: &opv1.MachineConfiguration{
1106+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
1107+
Status: opv1.MachineConfigurationStatus{
1108+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
1109+
Mode: opv1.BootImageSkewEnforcementModeStatusManual,
1110+
Manual: opv1.ClusterBootImageManual{
1111+
Mode: opv1.ClusterBootImageSpecModeRHCOSVersion,
1112+
RHCOSVersion: "411.86.202308081056-0",
1113+
},
1114+
},
1115+
},
1116+
},
1117+
expectUpgradeBlock: true,
1118+
expectMessage: "Upgrades have been disabled because the cluster is using RHCOS boot image version 411.86.202308081056-0(RHEL version: 8.6), which is below the minimum required RHEL version " + ctrlcommon.RHCOSVersionBootImageSkewLimit + ". To enable upgrades, please update your boot images following the documentation at [TODO: insert link], or disable boot image skew enforcement at [TODO: insert link]",
1119+
expectError: false,
1120+
},
1121+
{
1122+
name: "mode is manual with exact minimum RHCOS version",
1123+
featureGateEnabled: true,
1124+
mcop: &opv1.MachineConfiguration{
1125+
ObjectMeta: metav1.ObjectMeta{Name: ctrlcommon.MCOOperatorKnobsObjectName},
1126+
Status: opv1.MachineConfigurationStatus{
1127+
BootImageSkewEnforcementStatus: opv1.BootImageSkewEnforcementStatus{
1128+
Mode: opv1.BootImageSkewEnforcementModeStatusManual,
1129+
Manual: opv1.ClusterBootImageManual{
1130+
Mode: opv1.ClusterBootImageSpecModeRHCOSVersion,
1131+
RHCOSVersion: "413.92.202402131523-0",
1132+
},
1133+
},
1134+
},
1135+
},
1136+
expectUpgradeBlock: false,
1137+
expectMessage: "",
1138+
expectError: false,
1139+
},
1140+
}
1141+
1142+
for _, tc := range tests {
1143+
t.Run(tc.name, func(t *testing.T) {
1144+
// Set up feature gate handler
1145+
enabledFeatures := []configv1.FeatureGateName{}
1146+
if tc.featureGateEnabled {
1147+
enabledFeatures = append(enabledFeatures, features.FeatureGateBootImageSkewEnforcement)
1148+
}
1149+
fgHandler := ctrlcommon.NewFeatureGatesHardcodedHandler(enabledFeatures, []configv1.FeatureGateName{})
1150+
1151+
// Set up mcopLister
1152+
mcopIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
1153+
if tc.mcop != nil && !tc.mcopNotFound {
1154+
mcopIndexer.Add(tc.mcop)
1155+
}
1156+
mcopLister := mcoplistersv1.NewMachineConfigurationLister(mcopIndexer)
1157+
1158+
optr := &Operator{
1159+
fgHandler: fgHandler,
1160+
mcopLister: mcopLister,
1161+
}
1162+
1163+
upgradeBlock, message, err := optr.checkBootImageSkewUpgradeableGuard()
1164+
1165+
if tc.expectError {
1166+
assert.Error(t, err)
1167+
} else {
1168+
assert.NoError(t, err)
1169+
}
1170+
assert.Equal(t, tc.expectUpgradeBlock, upgradeBlock, "upgrade block mismatch")
1171+
assert.Equal(t, tc.expectMessage, message, "message mismatch")
1172+
})
1173+
}
1174+
}

0 commit comments

Comments
 (0)