Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
Enable testing SubReconcilers with duck typed resources
Browse files Browse the repository at this point in the history
The Resource is now converted to an unstructured before being set as a
given on the fake client. Previously it would panic because the duck was
not registered on the scheme (which it should not be).

Signed-off-by: Scott Andrews <[email protected]>
  • Loading branch information
scothis committed Nov 6, 2023
1 parent e19c127 commit ddfd714
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
61 changes: 61 additions & 0 deletions reconcilers/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,64 @@ func TestSyncReconciler(t *testing.T) {
return rtc.Metadata["SubReconciler"].(func(*testing.T, reconcilers.Config) reconcilers.SubReconciler[*resources.TestResource])(t, c)
})
}

func TestSyncReconcilerDuck(t *testing.T) {
testNamespace := "test-namespace"
testName := "test-resource"

scheme := runtime.NewScheme()
// _ = resources.AddToScheme(scheme)

resource := dies.TestDuckBlank.
APIVersion(resources.GroupVersion.String()).
Kind("TestResource").
MetadataDie(func(d *diemetav1.ObjectMetaDie) {
d.Namespace(testNamespace)
d.Name(testName)
}).
SpecDie(func(d *dies.TestDuckSpecDie) {
d.AddField("mutation", "false")
}).
StatusDie(func(d *dies.TestResourceStatusDie) {
d.ConditionsDie(
diemetav1.ConditionBlank.Type(apis.ConditionReady).Status(metav1.ConditionUnknown).Reason("Initializing"),
)
})

rts := rtesting.SubReconcilerTests[*resources.TestDuck]{
"sync no mutation": {
Resource: resource.DieReleasePtr(),
Metadata: map[string]interface{}{
"SubReconciler": func(t *testing.T, c reconcilers.Config) reconcilers.SubReconciler[*resources.TestDuck] {
return &reconcilers.SyncReconciler[*resources.TestDuck]{
Sync: func(ctx context.Context, resource *resources.TestDuck) error {
return nil
},
}
},
},
},
"sync with mutation": {
Resource: resource.DieReleasePtr(),
ExpectResource: resource.
SpecDie(func(d *dies.TestDuckSpecDie) {
d.AddField("mutation", "true")
}).
DieReleasePtr(),
Metadata: map[string]interface{}{
"SubReconciler": func(t *testing.T, c reconcilers.Config) reconcilers.SubReconciler[*resources.TestDuck] {
return &reconcilers.SyncReconciler[*resources.TestDuck]{
Sync: func(ctx context.Context, resource *resources.TestDuck) error {
resource.Spec.Fields["mutation"] = "true"
return nil
},
}
},
},
},
}

rts.Run(t, scheme, func(t *testing.T, rtc *rtesting.SubReconcilerTestCase[*resources.TestDuck], c reconcilers.Config) reconcilers.SubReconciler[*resources.TestDuck] {
return rtc.Metadata["SubReconciler"].(func(*testing.T, reconcilers.Config) reconcilers.SubReconciler[*resources.TestDuck])(t, c)
})
}
16 changes: 14 additions & 2 deletions testing/subreconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import (
"github.com/go-logr/logr/testr"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/vmware-labs/reconciler-runtime/duck"
"github.com/vmware-labs/reconciler-runtime/internal"
"github.com/vmware-labs/reconciler-runtime/reconcilers"
rtime "github.com/vmware-labs/reconciler-runtime/time"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -182,12 +184,22 @@ func (tc *SubReconcilerTestCase[T]) Run(t *testing.T, scheme *runtime.Scheme, fa
}()
}

var givenResource client.Object = tc.Resource
if duck.IsDuck(givenResource, scheme) {
// convert the given resource duck to Unstructured so that it can be created on the fake client
uobj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(tc.Resource)
if err != nil {
t.Fatalf("unable to convert Resource to Unstructured: %s", err)
}
givenResource = &unstructured.Unstructured{Object: uobj}
}

expectConfig := &ExpectConfig{
Name: "default",
Scheme: scheme,
StatusSubResourceTypes: tc.StatusSubResourceTypes,
GivenObjects: append(tc.GivenObjects, tc.Resource),
APIGivenObjects: append(tc.APIGivenObjects, tc.Resource),
GivenObjects: append(tc.GivenObjects, givenResource),
APIGivenObjects: append(tc.APIGivenObjects, givenResource),
WithClientBuilder: tc.WithClientBuilder,
WithReactors: tc.WithReactors,
GivenTracks: tc.GivenTracks,
Expand Down

0 comments on commit ddfd714

Please sign in to comment.