github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/lib/operatorstatus/builder_test.go (about) 1 package operatorstatus 2 3 import ( 4 "testing" 5 "time" 6 7 configv1 "github.com/openshift/api/config/v1" 8 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 utilclock "k8s.io/utils/clock/testing" 10 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestBuilder(t *testing.T) { 15 fakeClock := utilclock.NewFakeClock(time.Now()) 16 minuteAgo := metav1.NewTime(time.Now().Add(-1 * time.Minute)) 17 18 tests := []struct { 19 name string 20 action func(b *Builder) 21 existing *configv1.ClusterOperatorStatus 22 expected *configv1.ClusterOperatorStatus 23 }{ 24 // Condition: (Progressing, True). 25 // existing status.Conditions is empty. 26 { 27 name: "WithProgressing/NoProgressingConditionPresentInExistingStatus", 28 action: func(b *Builder) { 29 b.WithProgressing(configv1.ConditionTrue, "message") 30 }, 31 expected: &configv1.ClusterOperatorStatus{ 32 Conditions: []configv1.ClusterOperatorStatusCondition{ 33 { 34 Type: configv1.OperatorProgressing, 35 Status: configv1.ConditionTrue, 36 Message: "message", 37 LastTransitionTime: metav1.NewTime(fakeClock.Now()), 38 }, 39 }, 40 Versions: []configv1.OperandVersion{}, 41 RelatedObjects: []configv1.ObjectReference{}, 42 }, 43 }, 44 45 // Condition: (Progressing, True). 46 // (Progressing, False) is already present in existing status.Conditions. 47 { 48 name: "WithProgressing/ProgressingConditionPresentInExistingStatus", 49 action: func(b *Builder) { 50 b.WithProgressing(configv1.ConditionTrue, "message") 51 }, 52 existing: &configv1.ClusterOperatorStatus{ 53 Conditions: []configv1.ClusterOperatorStatusCondition{ 54 { 55 Type: configv1.OperatorProgressing, 56 Status: configv1.ConditionFalse, 57 }, 58 }, 59 Versions: []configv1.OperandVersion{}, 60 RelatedObjects: []configv1.ObjectReference{}, 61 }, 62 expected: &configv1.ClusterOperatorStatus{ 63 Conditions: []configv1.ClusterOperatorStatusCondition{ 64 { 65 Type: configv1.OperatorProgressing, 66 Status: configv1.ConditionTrue, 67 Message: "message", 68 LastTransitionTime: metav1.NewTime(fakeClock.Now()), 69 }, 70 }, 71 Versions: []configv1.OperandVersion{}, 72 RelatedObjects: []configv1.ObjectReference{}, 73 }, 74 }, 75 76 // Condition: (Progressing, True). 77 // (Progressing, True) is already present in existing status.Conditions. 78 { 79 name: "WithProgressing/ProgressingConditionMatchesInExistingStatus", 80 action: func(b *Builder) { 81 b.WithProgressing(configv1.ConditionTrue, "message") 82 }, 83 existing: &configv1.ClusterOperatorStatus{ 84 Conditions: []configv1.ClusterOperatorStatusCondition{ 85 { 86 Type: configv1.OperatorProgressing, 87 Status: configv1.ConditionTrue, 88 LastTransitionTime: minuteAgo, 89 }, 90 }, 91 Versions: []configv1.OperandVersion{}, 92 RelatedObjects: []configv1.ObjectReference{}, 93 }, 94 expected: &configv1.ClusterOperatorStatus{ 95 Conditions: []configv1.ClusterOperatorStatusCondition{ 96 { 97 Type: configv1.OperatorProgressing, 98 Status: configv1.ConditionTrue, 99 Message: "message", 100 LastTransitionTime: minuteAgo, 101 }, 102 }, 103 Versions: []configv1.OperandVersion{}, 104 RelatedObjects: []configv1.ObjectReference{}, 105 }, 106 }, 107 108 // Condition: (Upgradeable, True). 109 // existing status.Conditions is empty. 110 { 111 name: "WithUpgradeable/NoUpgradeableConditionPresentInExistingStatus", 112 action: func(b *Builder) { 113 b.WithUpgradeable(configv1.ConditionTrue, "message") 114 }, 115 expected: &configv1.ClusterOperatorStatus{ 116 Conditions: []configv1.ClusterOperatorStatusCondition{ 117 { 118 Type: configv1.OperatorUpgradeable, 119 Status: configv1.ConditionTrue, 120 Message: "message", 121 LastTransitionTime: metav1.NewTime(fakeClock.Now()), 122 }, 123 }, 124 Versions: []configv1.OperandVersion{}, 125 RelatedObjects: []configv1.ObjectReference{}, 126 }, 127 }, 128 129 // Condition: (Upgradeable, True). 130 // (Upgradeable, False) is already present in existing status.Conditions. 131 { 132 name: "WithUpgradeable/UpgradeableConditionPresentInExistingStatus", 133 action: func(b *Builder) { 134 b.WithUpgradeable(configv1.ConditionTrue, "message") 135 }, 136 existing: &configv1.ClusterOperatorStatus{ 137 Conditions: []configv1.ClusterOperatorStatusCondition{ 138 { 139 Type: configv1.OperatorUpgradeable, 140 Status: configv1.ConditionFalse, 141 }, 142 }, 143 Versions: []configv1.OperandVersion{}, 144 RelatedObjects: []configv1.ObjectReference{}, 145 }, 146 expected: &configv1.ClusterOperatorStatus{ 147 Conditions: []configv1.ClusterOperatorStatusCondition{ 148 { 149 Type: configv1.OperatorUpgradeable, 150 Status: configv1.ConditionTrue, 151 Message: "message", 152 LastTransitionTime: metav1.NewTime(fakeClock.Now()), 153 }, 154 }, 155 Versions: []configv1.OperandVersion{}, 156 RelatedObjects: []configv1.ObjectReference{}, 157 }, 158 }, 159 160 // Condition: (Upgradeable, True). 161 // (Upgradeable, True) is already present in existing status.Conditions. 162 { 163 name: "WithUpgradeable/UpgradeableConditionMatchesInExistingStatus", 164 action: func(b *Builder) { 165 b.WithUpgradeable(configv1.ConditionTrue, "message") 166 }, 167 existing: &configv1.ClusterOperatorStatus{ 168 Conditions: []configv1.ClusterOperatorStatusCondition{ 169 { 170 Type: configv1.OperatorUpgradeable, 171 Status: configv1.ConditionTrue, 172 LastTransitionTime: minuteAgo, 173 }, 174 }, 175 Versions: []configv1.OperandVersion{}, 176 RelatedObjects: []configv1.ObjectReference{}, 177 }, 178 expected: &configv1.ClusterOperatorStatus{ 179 Conditions: []configv1.ClusterOperatorStatusCondition{ 180 { 181 Type: configv1.OperatorUpgradeable, 182 Status: configv1.ConditionTrue, 183 Message: "message", 184 LastTransitionTime: minuteAgo, 185 }, 186 }, 187 Versions: []configv1.OperandVersion{}, 188 RelatedObjects: []configv1.ObjectReference{}, 189 }, 190 }, 191 192 // A new version is being added to status. 193 // Existing status does not have any matching name. 194 { 195 name: "WithVersion/WithNoMatchingName", 196 action: func(b *Builder) { 197 b.WithVersion("foo", "1.00") 198 }, 199 expected: &configv1.ClusterOperatorStatus{ 200 Conditions: []configv1.ClusterOperatorStatusCondition{}, 201 Versions: []configv1.OperandVersion{ 202 { 203 Name: "foo", 204 Version: "1.00", 205 }, 206 }, 207 RelatedObjects: []configv1.ObjectReference{}, 208 }, 209 }, 210 211 // A new version is being added to status. 212 // Existing status already has a matching same name and version. 213 { 214 name: "WithVersion/WithMatchingNameAndVersion", 215 action: func(b *Builder) { 216 b.WithVersion("foo", "1.00") 217 }, 218 existing: &configv1.ClusterOperatorStatus{ 219 Conditions: []configv1.ClusterOperatorStatusCondition{}, 220 Versions: []configv1.OperandVersion{ 221 { 222 Name: "foo", 223 Version: "1.00", 224 }, 225 }, 226 RelatedObjects: []configv1.ObjectReference{}, 227 }, 228 expected: &configv1.ClusterOperatorStatus{ 229 Conditions: []configv1.ClusterOperatorStatusCondition{}, 230 Versions: []configv1.OperandVersion{ 231 { 232 Name: "foo", 233 Version: "1.00", 234 }, 235 }, 236 RelatedObjects: []configv1.ObjectReference{}, 237 }, 238 }, 239 240 // A new version is being added to status. 241 // Existing status already has a matching name but a different version. 242 { 243 name: "WithVersion/WithMatchingNameButDifferentVersion", 244 action: func(b *Builder) { 245 b.WithVersion("foo", "2.00") 246 }, 247 existing: &configv1.ClusterOperatorStatus{ 248 Conditions: []configv1.ClusterOperatorStatusCondition{}, 249 Versions: []configv1.OperandVersion{ 250 { 251 Name: "foo", 252 Version: "1.00", 253 }, 254 }, 255 RelatedObjects: []configv1.ObjectReference{}, 256 }, 257 expected: &configv1.ClusterOperatorStatus{ 258 Conditions: []configv1.ClusterOperatorStatusCondition{}, 259 Versions: []configv1.OperandVersion{ 260 { 261 Name: "foo", 262 Version: "2.00", 263 }, 264 }, 265 RelatedObjects: []configv1.ObjectReference{}, 266 }, 267 }, 268 269 // Multiple versions are added to status. 270 { 271 name: "WithVersion/WithMultipleVersions", 272 action: func(b *Builder) { 273 b.WithVersion("foo", "2.00").WithVersion("bar", "1.00") 274 }, 275 existing: &configv1.ClusterOperatorStatus{ 276 Conditions: []configv1.ClusterOperatorStatusCondition{}, 277 Versions: []configv1.OperandVersion{ 278 { 279 Name: "foo", 280 Version: "1.00", 281 }, 282 }, 283 RelatedObjects: []configv1.ObjectReference{}, 284 }, 285 expected: &configv1.ClusterOperatorStatus{ 286 Conditions: []configv1.ClusterOperatorStatusCondition{}, 287 Versions: []configv1.OperandVersion{ 288 { 289 Name: "foo", 290 Version: "2.00", 291 }, 292 { 293 Name: "bar", 294 Version: "1.00", 295 }, 296 }, 297 RelatedObjects: []configv1.ObjectReference{}, 298 }, 299 }, 300 301 // A version is being removed from status. 302 // Existing status already has a matching name. 303 { 304 name: "WithoutVersion/WithMatchingName", 305 action: func(b *Builder) { 306 b.WithoutVersion("foo", "1.00") 307 }, 308 existing: &configv1.ClusterOperatorStatus{ 309 Conditions: []configv1.ClusterOperatorStatusCondition{}, 310 Versions: []configv1.OperandVersion{ 311 { 312 Name: "foo", 313 Version: "1.00", 314 }, 315 { 316 Name: "bar", 317 Version: "1.00", 318 }, 319 }, 320 RelatedObjects: []configv1.ObjectReference{}, 321 }, 322 expected: &configv1.ClusterOperatorStatus{ 323 Conditions: []configv1.ClusterOperatorStatusCondition{}, 324 Versions: []configv1.OperandVersion{ 325 { 326 Name: "bar", 327 Version: "1.00", 328 }, 329 }, 330 RelatedObjects: []configv1.ObjectReference{}, 331 }, 332 }, 333 334 // A new related object is being added. 335 // Existing status is empty. 336 { 337 name: "WithRelatedObject/ReferenceNotPresentInStatus", 338 action: func(b *Builder) { 339 b.WithRelatedObject("group", "resources", "namespace", "name") 340 }, 341 expected: &configv1.ClusterOperatorStatus{ 342 Conditions: []configv1.ClusterOperatorStatusCondition{}, 343 Versions: []configv1.OperandVersion{}, 344 RelatedObjects: []configv1.ObjectReference{ 345 { 346 Group: "group", 347 Resource: "resources", 348 Namespace: "namespace", 349 Name: "name", 350 }, 351 }, 352 }, 353 }, 354 355 // A new related object reference is being added. 356 // Existing status already has the same related object reference. 357 { 358 name: "WithRelatedObject/ReferencePresentInStatus", 359 action: func(b *Builder) { 360 b.WithRelatedObject("group", "resources", "namespace", "name") 361 }, 362 existing: &configv1.ClusterOperatorStatus{ 363 Conditions: []configv1.ClusterOperatorStatusCondition{}, 364 Versions: []configv1.OperandVersion{}, 365 RelatedObjects: []configv1.ObjectReference{ 366 { 367 Group: "group", 368 Resource: "resources", 369 Namespace: "namespace", 370 Name: "name", 371 }, 372 }, 373 }, 374 expected: &configv1.ClusterOperatorStatus{ 375 Conditions: []configv1.ClusterOperatorStatusCondition{}, 376 Versions: []configv1.OperandVersion{}, 377 RelatedObjects: []configv1.ObjectReference{ 378 { 379 Group: "group", 380 Resource: "resources", 381 Namespace: "namespace", 382 Name: "name", 383 }, 384 }, 385 }, 386 }, 387 388 // A related object reference is being removed. 389 // Existing status already has the same related object reference. 390 { 391 name: "WithoutRelatedObject/ReferenceBeingRemoved", 392 action: func(b *Builder) { 393 b.WithoutRelatedObject("group", "resources", "namespace", "name") 394 }, 395 existing: &configv1.ClusterOperatorStatus{ 396 Conditions: []configv1.ClusterOperatorStatusCondition{}, 397 Versions: []configv1.OperandVersion{}, 398 RelatedObjects: []configv1.ObjectReference{ 399 { 400 Group: "group", 401 Resource: "resources", 402 Namespace: "namespace", 403 Name: "name", 404 }, 405 }, 406 }, 407 expected: &configv1.ClusterOperatorStatus{ 408 Conditions: []configv1.ClusterOperatorStatusCondition{}, 409 Versions: []configv1.OperandVersion{}, 410 RelatedObjects: []configv1.ObjectReference{}, 411 }, 412 }, 413 } 414 415 for _, tt := range tests { 416 t.Run(tt.name, func(t *testing.T) { 417 builder := &Builder{ 418 clock: fakeClock, 419 status: tt.existing, 420 } 421 422 // Go through the build steps specified. 423 tt.action(builder) 424 425 statusWant := tt.expected 426 statusGot := builder.GetStatus() 427 428 assert.Equal(t, statusWant, statusGot) 429 }) 430 } 431 }