From d526d748cdbca7b3f16ac92b7199ddb27505cb68 Mon Sep 17 00:00:00 2001 From: Max Brauer Date: Mon, 7 Nov 2022 18:53:41 +0100 Subject: [PATCH] Allow custom assertions for stashed values (#311) --- README.md | 2 +- testing/reconciler.go | 5 ++++- testing/subreconciler.go | 15 ++++++++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a94f9ee..aa83991 100644 --- a/README.md +++ b/README.md @@ -738,7 +738,7 @@ To setup a Config for a test and make assertions that the expected behavior matc The stash allows passing arbitrary state between sub reconcilers within the scope of a single reconciler request. Values are stored on the context by [`StashValue`](https://pkg.go.dev/github.com/vmware-labs/reconciler-runtime/reconcilers#StashValue) and accessed via [`RetrieveValue`](https://pkg.go.dev/github.com/vmware-labs/reconciler-runtime/reconcilers#RetrieveValue). -For testing, given stashed values can be defined in a [SubReconcilerTests](#subreconcilertests) with [`GivenStashedValues`](https://pkg.go.dev/github.com/vmware-labs/reconciler-runtime/testing#SubReconcilerTestCase.GivenStashedValues). Newly stashed or mutated values expectations are defined with [`ExpectStashedValues`](https://pkg.go.dev/github.com/vmware-labs/reconciler-runtime/testing#SubReconcilerTestCase.ExpectStashedValues). +For testing, given stashed values can be defined in a [SubReconcilerTests](#subreconcilertests) with [`GivenStashedValues`](https://pkg.go.dev/github.com/vmware-labs/reconciler-runtime/testing#SubReconcilerTestCase.GivenStashedValues). Newly stashed or mutated values expectations are defined with [`ExpectStashedValues`](https://pkg.go.dev/github.com/vmware-labs/reconciler-runtime/testing#SubReconcilerTestCase.ExpectStashedValues). An optional, custom function for asserting stashed values can be provided via [`VerifyStashedValue`](https://pkg.go.dev/github.com/vmware-labs/reconciler-runtime/testing#SubReconcilerTestCase.VerifyStashedValue). **Example:** diff --git a/testing/reconciler.go b/testing/reconciler.go index 20ed01e..ce50ec1 100644 --- a/testing/reconciler.go +++ b/testing/reconciler.go @@ -95,9 +95,12 @@ type ReconcilerTestCase struct { CleanUp func(t *testing.T, ctx context.Context, tc *ReconcilerTestCase) error } -// VerifyFunc is a verification function +// VerifyFunc is a verification function for a reconciler's result type VerifyFunc func(t *testing.T, result controllerruntime.Result, err error) +// VerifyStashedValueFunc is a verification function for the entries in the stash +type VerifyStashedValueFunc func(t *testing.T, key reconcilers.StashKey, expected, actual interface{}) + // ReconcilerTests represents a map of reconciler test cases. The map key is the name of each test // case. Test cases are executed in random order. type ReconcilerTests map[string]ReconcilerTestCase diff --git a/testing/subreconciler.go b/testing/subreconciler.go index b9b8f93..3cc4d96 100644 --- a/testing/subreconciler.go +++ b/testing/subreconciler.go @@ -59,6 +59,8 @@ type SubReconcilerTestCase struct { ExpectResource client.Object // ExpectStashedValues ensures each value is stashed. Values in the stash that are not expected are ignored. Factories are resolved to their object. ExpectStashedValues map[reconcilers.StashKey]interface{} + // VerifyStashedValue is an optional, custom verification function for stashed values + VerifyStashedValue VerifyStashedValueFunc // ExpectTracks holds the ordered list of Track calls expected during reconciliation ExpectTracks []TrackRequest // ExpectEvents holds the ordered list of events recorded during the reconciliation @@ -141,6 +143,15 @@ func (tc *SubReconcilerTestCase) Run(t *testing.T, scheme *runtime.Scheme, facto tc.Metadata = map[string]interface{}{} } + // Set func for verifying stashed values + if tc.VerifyStashedValue == nil { + tc.VerifyStashedValue = func(t *testing.T, key reconcilers.StashKey, expected, actual interface{}) { + if diff := cmp.Diff(expected, actual, IgnoreLastTransitionTime, SafeDeployDiff, IgnoreTypeMeta, IgnoreCreationTimestamp, IgnoreResourceVersion, cmpopts.EquateEmpty()); diff != "" { + t.Errorf("Unexpected stash value %q (-expected, +actual): %s", key, diff) + } + } + } + if tc.Prepare != nil { var err error if ctx, err = tc.Prepare(t, ctx, tc); err != nil { @@ -258,9 +269,7 @@ func (tc *SubReconcilerTestCase) Run(t *testing.T, scheme *runtime.Scheme, facto expected = f.DeepCopyObject() } actual := reconcilers.RetrieveValue(ctx, key) - if diff := cmp.Diff(expected, actual, IgnoreLastTransitionTime, SafeDeployDiff, IgnoreTypeMeta, IgnoreCreationTimestamp, IgnoreResourceVersion, cmpopts.EquateEmpty()); diff != "" { - t.Errorf("Unexpected stash value %q (-expected, +actual): %s", key, diff) - } + tc.VerifyStashedValue(t, key, expected, actual) } expectConfig.AssertExpectations(t)