Skip to content

Commit fbdf984

Browse files
authored
Unit tests for reconciler Update with no delta (#78)
Description of changes: * Unit tests for reconciler update with no delta, checking for resource synced conditions By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 026e764 commit fbdf984

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

pkg/runtime/reconciler_test.go

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,154 @@ func TestReconcilerUpdate_ResourceNotSynced(t *testing.T) {
372372
rm.AssertCalled(t, "IsSynced", ctx, latest)
373373
}
374374

375+
func TestReconcilerUpdate_NoDelta_ResourceNotSynced(t *testing.T) {
376+
require := require.New(t)
377+
378+
ctx := context.TODO()
379+
arn := ackv1alpha1.AWSResourceName("mybook-arn")
380+
381+
delta := ackcompare.NewDelta()
382+
383+
desired, _, _ := resourceMocks()
384+
desired.On("ReplaceConditions", []*ackv1alpha1.Condition{}).Return()
385+
386+
ids := &ackmocks.AWSResourceIdentifiers{}
387+
ids.On("ARN").Return(&arn)
388+
389+
latest, latestRTObj, _ := resourceMocks()
390+
latest.On("Identifiers").Return(ids)
391+
392+
latest.On("Conditions").Return([]*ackv1alpha1.Condition{})
393+
latest.On(
394+
"ReplaceConditions",
395+
mock.AnythingOfType("[]*v1alpha1.Condition"),
396+
).Return().Run(func(args mock.Arguments) {
397+
conditions := args.Get(0).([]*ackv1alpha1.Condition)
398+
assert.Equal(t, 1, len(conditions))
399+
cond := conditions[0]
400+
assert.Equal(t, ackv1alpha1.ConditionTypeResourceSynced, cond.Type)
401+
// Synced condition is false because rm.IsSynced() method returns
402+
// False
403+
assert.Equal(t, corev1.ConditionFalse, cond.Status)
404+
assert.Equal(t, ackcondition.NotSyncedMessage, *cond.Message)
405+
})
406+
407+
rm := &ackmocks.AWSResourceManager{}
408+
rm.On("ResolveReferences", ctx, nil, desired).Return(
409+
desired, nil,
410+
)
411+
rm.On("ReadOne", ctx, desired).Return(
412+
latest, nil,
413+
)
414+
rm.On("IsSynced", ctx, latest).Return(false, nil)
415+
416+
rmf, rd := managedResourceManagerFactoryMocks(desired, latest)
417+
rd.On("Delta", desired, latest).Return(delta)
418+
419+
rm.On("LateInitialize", ctx, latest).Return(latest, nil)
420+
rd.On("Delta", latest, latest).Return(delta)
421+
422+
r, kc := reconcilerMocks(rmf)
423+
424+
// pointers returned from "client.MergeFrom" fails the equality check during
425+
// assertion even when parameters inside two objects are same.
426+
// hence we use mock.AnythingOfType parameter to assert patch call
427+
kc.On("Patch", ctx, latestRTObj, mock.AnythingOfType("*client.mergeFromPatch")).Return(nil)
428+
429+
// With the above mocks and below assertions, we check that if we got a
430+
// non-error return from `AWSResourceManager.ReadOne()` and the
431+
// `AWSResourceDescriptor.Delta()` returned a non-empty Delta, that we end
432+
// up calling the AWSResourceManager.Update() call in the Reconciler.Sync()
433+
// method,
434+
_, err := r.Sync(ctx, rm, desired)
435+
require.Nil(err)
436+
rm.AssertCalled(t, "ResolveReferences", ctx, nil, desired)
437+
rm.AssertCalled(t, "ReadOne", ctx, desired)
438+
rd.AssertCalled(t, "Delta", desired, latest)
439+
// Update is not called because there is no delta
440+
rm.AssertNotCalled(t, "Update", ctx, desired, latest, delta)
441+
// No changes to metadata or spec so Patch on the object shouldn't be done
442+
kc.AssertNotCalled(t, "Patch", ctx, latestRTObj, mock.AnythingOfType("*client.mergeFromPatch"))
443+
// Only the HandleReconcilerError wrapper function ever calls patchResourceStatus
444+
kc.AssertNotCalled(t, "Status")
445+
rm.AssertCalled(t, "LateInitialize", ctx, latest)
446+
rm.AssertCalled(t, "IsSynced", ctx, latest)
447+
}
448+
449+
func TestReconcilerUpdate_NoDelta_ResourceSynced(t *testing.T) {
450+
require := require.New(t)
451+
452+
ctx := context.TODO()
453+
arn := ackv1alpha1.AWSResourceName("mybook-arn")
454+
455+
delta := ackcompare.NewDelta()
456+
457+
desired, _, _ := resourceMocks()
458+
desired.On("ReplaceConditions", []*ackv1alpha1.Condition{}).Return()
459+
460+
ids := &ackmocks.AWSResourceIdentifiers{}
461+
ids.On("ARN").Return(&arn)
462+
463+
latest, latestRTObj, _ := resourceMocks()
464+
latest.On("Identifiers").Return(ids)
465+
466+
latest.On("Conditions").Return([]*ackv1alpha1.Condition{})
467+
latest.On(
468+
"ReplaceConditions",
469+
mock.AnythingOfType("[]*v1alpha1.Condition"),
470+
).Return().Run(func(args mock.Arguments) {
471+
conditions := args.Get(0).([]*ackv1alpha1.Condition)
472+
assert.Equal(t, 1, len(conditions))
473+
cond := conditions[0]
474+
assert.Equal(t, ackv1alpha1.ConditionTypeResourceSynced, cond.Type)
475+
// Synced condition is true because rm.IsSynced() method returns
476+
// True
477+
assert.Equal(t, corev1.ConditionTrue, cond.Status)
478+
assert.Equal(t, ackcondition.SyncedMessage, *cond.Message)
479+
})
480+
481+
rm := &ackmocks.AWSResourceManager{}
482+
rm.On("ResolveReferences", ctx, nil, desired).Return(
483+
desired, nil,
484+
)
485+
rm.On("ReadOne", ctx, desired).Return(
486+
latest, nil,
487+
)
488+
rm.On("IsSynced", ctx, latest).Return(true, nil)
489+
490+
rmf, rd := managedResourceManagerFactoryMocks(desired, latest)
491+
rd.On("Delta", desired, latest).Return(delta)
492+
493+
rm.On("LateInitialize", ctx, latest).Return(latest, nil)
494+
rd.On("Delta", latest, latest).Return(delta)
495+
496+
r, kc := reconcilerMocks(rmf)
497+
498+
// pointers returned from "client.MergeFrom" fails the equality check during
499+
// assertion even when parameters inside two objects are same.
500+
// hence we use mock.AnythingOfType parameter to assert patch call
501+
kc.On("Patch", ctx, latestRTObj, mock.AnythingOfType("*client.mergeFromPatch")).Return(nil)
502+
503+
// With the above mocks and below assertions, we check that if we got a
504+
// non-error return from `AWSResourceManager.ReadOne()` and the
505+
// `AWSResourceDescriptor.Delta()` returned a non-empty Delta, that we end
506+
// up calling the AWSResourceManager.Update() call in the Reconciler.Sync()
507+
// method,
508+
_, err := r.Sync(ctx, rm, desired)
509+
require.Nil(err)
510+
rm.AssertCalled(t, "ResolveReferences", ctx, nil, desired)
511+
rm.AssertCalled(t, "ReadOne", ctx, desired)
512+
rd.AssertCalled(t, "Delta", desired, latest)
513+
// Update is not called because there is no delta
514+
rm.AssertNotCalled(t, "Update", ctx, desired, latest, delta)
515+
// No changes to metadata or spec so Patch on the object shouldn't be done
516+
kc.AssertNotCalled(t, "Patch", ctx, latestRTObj, mock.AnythingOfType("*client.mergeFromPatch"))
517+
// Only the HandleReconcilerError wrapper function ever calls patchResourceStatus
518+
kc.AssertNotCalled(t, "Status")
519+
rm.AssertCalled(t, "LateInitialize", ctx, latest)
520+
rm.AssertCalled(t, "IsSynced", ctx, latest)
521+
}
522+
375523
func TestReconcilerUpdate_IsSyncedError(t *testing.T) {
376524
require := require.New(t)
377525

0 commit comments

Comments
 (0)