github.com/verrazzano/verrazzano@v1.7.0/application-operator/controllers/reconcileresults/reconcile_results_test.go (about) 1 // Copyright (c) 2020, 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package reconcileresults 5 6 import ( 7 "fmt" 8 oamrt "github.com/crossplane/crossplane-runtime/apis/common/v1" 9 asserts "github.com/stretchr/testify/assert" 10 "github.com/verrazzano/verrazzano/application-operator/apis/oam/v1alpha1" 11 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" 13 "testing" 14 ) 15 16 // TestContainsErrors tests positive and negative use cases using ContainsErrors 17 func TestContainsErrors(t *testing.T) { 18 assert := asserts.New(t) 19 var status ReconcileResults 20 21 // GIVEN status with all default fields 22 // WHEN the status is checked for errors 23 // THEN verify that errors are not detected 24 status = ReconcileResults{} 25 assert.False(status.ContainsErrors()) 26 27 // GIVEN status that contains an error 28 // WHEN the status is checked for errors 29 // THEN verify that errors are detected 30 status = ReconcileResults{Errors: []error{fmt.Errorf("test-error")}} 31 assert.True(status.ContainsErrors()) 32 33 // GIVEN status that contains no errors 34 // WHEN the status is checked for errors 35 // THEN verify that errors are not detected 36 status = ReconcileResults{Errors: []error{nil}} 37 assert.False(status.ContainsErrors()) 38 39 // GIVEN status that contains both errors and nils 40 // WHEN the status is checked for errors 41 // THEN verify that errors are detected 42 status = ReconcileResults{Errors: []error{nil, fmt.Errorf("test-error"), nil}} 43 assert.True(status.ContainsErrors()) 44 } 45 46 // TestContainsUpdates tests the ContainsUpdates method 47 func TestContainsUpdates(t *testing.T) { 48 assert := asserts.New(t) 49 var status ReconcileResults 50 51 // GIVEN an empty reconcile result 52 // WHEN a check is made for updates 53 // THEN verify false is returned 54 assert.False(status.ContainsUpdates()) 55 56 // GIVEN an empty reconcile result with an update 57 // WHEN a check is made for updates 58 // THEN verify true is returned 59 status = ReconcileResults{} 60 status.RecordOutcome(v1alpha1.QualifiedResourceRelation{}, controllerutil.OperationResultUpdated, nil) 61 assert.True(status.ContainsUpdates()) 62 63 // GIVEN an empty reconcile result with no updates 64 // WHEN a check is made for updates 65 // THEN verify false is returned 66 status = ReconcileResults{} 67 status.RecordOutcome(v1alpha1.QualifiedResourceRelation{}, controllerutil.OperationResultNone, nil) 68 assert.False(status.ContainsUpdates()) 69 } 70 71 // func (s *ReconcileResults) ContainsRelation(relation v1alpha1.QualifiedResourceRelation) bool { 72 // TestContainsRelation tests the ContainsRelation method. 73 func TestContainsRelation(t *testing.T) { 74 assert := asserts.New(t) 75 var results ReconcileResults 76 var rel = v1alpha1.QualifiedResourceRelation{ 77 APIVersion: "test-apiver", 78 Kind: "test-kind", 79 Name: "test-name", 80 Role: "test-role"} 81 82 // GIVEN a reconcile result with no relations 83 // WHEN a search is made for a relation 84 // THEN verify no relation is found 85 results = ReconcileResults{} 86 assert.False(results.ContainsRelation(rel)) 87 88 // GIVEN a reconcile result with at least one relation 89 // WHEN a search is made for a relation that was recorded 90 // THEN verify the relation is found 91 results = ReconcileResults{} 92 results.RecordOutcome(rel, controllerutil.OperationResultNone, nil) 93 assert.True(results.ContainsRelation(rel)) 94 } 95 96 // TestCreateConditionedStatus tests the CreateConditionedStatus method. 97 func TestCreateConditionedStatus(t *testing.T) { 98 assert := asserts.New(t) 99 var recStatus ReconcileResults 100 var condStatus oamrt.ConditionedStatus 101 102 // GIVEN a default reconcile status 103 // WHEN the conditioned status is created from the reconcile status 104 // THEN verify that the conditioned status indicates success 105 recStatus = ReconcileResults{} 106 condStatus = recStatus.CreateConditionedStatus() 107 assert.Len(condStatus.Conditions, 1) 108 assert.Equal(oamrt.ReasonReconcileSuccess, condStatus.Conditions[0].Reason) 109 110 // GIVEN a reconcile status with one error 111 // WHEN the conditioned status is created from the reconcile status 112 // THEN verify that the error is included in the conditioned status 113 recStatus = ReconcileResults{Errors: []error{fmt.Errorf("test-error")}} 114 condStatus = recStatus.CreateConditionedStatus() 115 assert.Len(condStatus.Conditions, 1) 116 assert.Equal(oamrt.ReasonReconcileError, condStatus.Conditions[0].Reason) 117 assert.Equal("test-error", condStatus.Conditions[0].Message) 118 119 // GIVEN a reconcile status with one success 120 // WHEN the conditioned status is created from the reconcile status 121 // THEN verify that the conditioned status indicates success 122 recStatus = ReconcileResults{Errors: []error{nil}} 123 condStatus = recStatus.CreateConditionedStatus() 124 assert.Len(condStatus.Conditions, 1) 125 assert.Equal(oamrt.ReasonReconcileSuccess, condStatus.Conditions[0].Reason) 126 127 // GIVEN a reconcile status with both success and error 128 // WHEN the conditioned status is created from the reconcile status 129 // THEN verify that the conditioned status indicates failure 130 recStatus = ReconcileResults{Errors: []error{fmt.Errorf("test-error"), nil}} 131 condStatus = recStatus.CreateConditionedStatus() 132 assert.Len(condStatus.Conditions, 1) 133 assert.Equal(oamrt.ReasonReconcileError, condStatus.Conditions[0].Reason) 134 assert.Equal("test-error", condStatus.Conditions[0].Message) 135 } 136 137 // TestCreateResources tests the CreateResources method 138 func TestCreateResources(t *testing.T) { 139 assert := asserts.New(t) 140 var status ReconcileResults 141 var resources []oamrt.TypedReference 142 143 // GIVEN a default reconcile results 144 // WHEN a resources slice is retrieved 145 // THEN verify the slice is empty. 146 status = ReconcileResults{} 147 resources = status.CreateResources() 148 assert.Len(resources, 0) 149 150 // GIVEN a reconcile status with a related resource 151 // WHEN related resources are retrieved 152 // THEN verify the retrieved slice matches the recorded resources. 153 relation := v1alpha1.QualifiedResourceRelation{ 154 APIVersion: "test-apiver", 155 Kind: "test-kind", 156 Name: "test-name", 157 Role: "test-role"} 158 resource := oamrt.TypedReference{ 159 APIVersion: "test-apiver", 160 Kind: "test-kind", 161 Name: "test-name"} 162 status.RecordOutcome(relation, controllerutil.OperationResultUpdated, nil) 163 resources = status.CreateResources() 164 assert.Len(resources, 1) 165 assert.Equal(resource, resources[0]) 166 } 167 168 // TestCreateStatusRelations tests the CreateStatusRelations method. 169 func TestCreateRelations(t *testing.T) { 170 assert := asserts.New(t) 171 var status ReconcileResults 172 var rels []v1alpha1.QualifiedResourceRelation 173 174 // GIVEN a default reconcile results 175 // WHEN a relations slice is retrieved 176 // THEN verify the slice is empty. 177 status = ReconcileResults{} 178 rels = status.CreateRelations() 179 assert.Len(rels, 0) 180 181 // GIVEN a reconcile status with a related resource 182 // WHEN related resources are retrieved 183 // THEN verify the retrieved slice matches the recorded relations. 184 rel := v1alpha1.QualifiedResourceRelation{ 185 APIVersion: "test-apiver", 186 Kind: "test-kind", 187 Name: "test-name", 188 Role: "test-role"} 189 status.RecordOutcome(rel, controllerutil.OperationResultUpdated, nil) 190 rels = status.CreateRelations() 191 assert.Len(rels, 1) 192 assert.Equal(rel, rels[0]) 193 } 194 195 // TestRecordOutcomeIfError tests the RecordOutcomeIfError method. 196 func TestRecordOutcomeIfError(t *testing.T) { 197 assert := asserts.New(t) 198 var status ReconcileResults 199 var rels []v1alpha1.QualifiedResourceRelation 200 var rel v1alpha1.QualifiedResourceRelation 201 var res controllerutil.OperationResult 202 203 // GIVEN an empty reconcile results 204 // WHEN no error outcomes have been recorded 205 // THEN verify that no relations have been recorded 206 rel = v1alpha1.QualifiedResourceRelation{ 207 APIVersion: "test-api-ver", 208 Kind: "test-kind", 209 Namespace: "test-space", 210 Name: "test-name", 211 Role: "test-role"} 212 res = controllerutil.OperationResultNone 213 status = ReconcileResults{} 214 status.RecordOutcomeIfError(rel, res, nil) 215 rels = status.CreateRelations() 216 assert.Len(rels, 0) 217 218 // GIVEN reconcile results that has recorded some errors and some successes. 219 // WHEN the recorded relations are returned 220 // THEN verify that only error relations have been recorded 221 err := fmt.Errorf("test-error") 222 relError := v1alpha1.QualifiedResourceRelation{ 223 APIVersion: "test-api-ver", 224 Kind: "test-kind", 225 Namespace: "test-space", 226 Name: "test-error-name", 227 Role: "test-role"} 228 relSuccess := v1alpha1.QualifiedResourceRelation{ 229 APIVersion: "test-api-ver", 230 Kind: "test-kind", 231 Namespace: "test-space", 232 Name: "test-error-name", 233 Role: "test-role"} 234 res = controllerutil.OperationResultNone 235 status = ReconcileResults{} 236 status.RecordOutcomeIfError(relSuccess, res, nil) 237 status.RecordOutcomeIfError(relError, res, err) 238 status.RecordOutcomeIfError(relSuccess, res, nil) 239 rels = status.CreateRelations() 240 assert.Len(rels, 1) 241 assert.Equal(relError, rels[0]) 242 } 243 244 // TestConditionsEquivalent tests the ConditionsEquivalent method. 245 func TestConditionsEquivalent(t *testing.T) { 246 assert := asserts.New(t) 247 var one oamrt.Condition 248 var two oamrt.Condition 249 250 one = oamrt.Condition{ 251 Type: "test-type", 252 Status: "test-status-1", 253 LastTransitionTime: metav1.Unix(0, 0), 254 Reason: "test-reason", 255 Message: "test-message"} 256 two = oamrt.Condition{ 257 Type: "test-type", 258 Status: "test-status-2", 259 LastTransitionTime: metav1.Unix(1, 1), 260 Reason: "test-reason", 261 Message: "test-message"} 262 263 // GIVEN two nil conditions 264 // WHEN the conditions are compared for equivalence 265 // THEN verify they are considered equivalent 266 assert.True(ConditionsEquivalent(nil, nil)) 267 268 // GIVEN one nil and one non-nil condition 269 // WHEN the conditions are compared for equivalence 270 // THEN verify they are not considered equivalent 271 assert.False(ConditionsEquivalent(&one, nil)) 272 273 // GIVEN one nil and one non-nil condition 274 // WHEN the conditions are compared for equivalence 275 // THEN verify they are not considered equivalent 276 assert.False(ConditionsEquivalent(nil, &two)) 277 278 // GIVEN two identical conditions 279 // WHEN the conditions are compared for equivalence 280 // THEN verify they are considered equivalent 281 assert.True(ConditionsEquivalent(&one, &one)) 282 283 // GIVEN two non-equivalent conditions 284 // WHEN the conditions are compared for equivalence 285 // THEN verify they are not considered equivalent 286 assert.False(ConditionsEquivalent(&one, &two)) 287 } 288 289 // TestConditionedStatusEquivalent tests the ConditionedStatusEquivalent method. 290 func TestConditionedStatusEquivalent(t *testing.T) { 291 assert := asserts.New(t) 292 293 one := oamrt.ConditionedStatus{Conditions: []oamrt.Condition{{ 294 Type: "test-type", 295 Status: "test-status-1", 296 LastTransitionTime: metav1.Unix(1, 1), 297 Reason: "test-reason", 298 Message: "test-message"}}} 299 two := oamrt.ConditionedStatus{Conditions: []oamrt.Condition{{ 300 Type: "test-type", 301 Status: "test-status-2", 302 LastTransitionTime: metav1.Unix(2, 2), 303 Reason: "test-reason", 304 Message: "test-message"}}} 305 three := oamrt.ConditionedStatus{Conditions: []oamrt.Condition{one.Conditions[0], one.Conditions[0]}} 306 307 // GIVEN two nil conditioned statuses 308 // WHEN they are compared for equivalence 309 // THEN verify they are considered equivalent 310 assert.True(ConditionedStatusEquivalent(nil, nil)) 311 312 // GIVEN a nil and non-nil conditioned statuses 313 // WHEN they are compared for equivalence 314 // THEN verify they are considered not equivalent 315 assert.False(ConditionedStatusEquivalent(&one, nil)) 316 317 // GIVEN a nil and non-nil conditioned statuses 318 // WHEN they are compared for equivalence 319 // THEN verify they are considered not equivalent 320 assert.False(ConditionedStatusEquivalent(nil, &two)) 321 322 // GIVEN two identical conditioned statuses 323 // WHEN they are compared for equivalence 324 // THEN verify they are considered equivalent 325 assert.True(ConditionedStatusEquivalent(&one, &one)) 326 327 // GIVEN two non-identical conditioned statuses 328 // WHEN they are compared for equivalence 329 // THEN verify they are considered not equivalent 330 assert.False(ConditionedStatusEquivalent(&one, &two)) 331 332 // GIVEN two conditioned statuses of different lengths 333 // WHEN they are compared for equivalence 334 // THEN verify they are considered not equivalent 335 assert.False(ConditionedStatusEquivalent(&one, &three)) 336 }