From a539a79dea44c3b553ef278e13413b1199d3a7cc Mon Sep 17 00:00:00 2001 From: Alvaro Aleman Date: Sun, 2 Mar 2025 12:43:08 -0500 Subject: [PATCH] ManagedFieldsObjectTracker: Reload scheme In controller-runtime it is generally not expected to do any sort of scheme registration if unstructured.Unstructured is used. To make this work in the fakeclient, the fakeclient will register unstructured to scheme if the scheme doesn't recognize the GVK. This currently doesn't work with the `ManagedFieldsObjectTracker` as it never reloads the scheme. This change makes it reload the scheme in an inefficient but simple manner, which should be good enough for unit tests. Kubernetes-commit: 1cd71cbb14ecfd0ec6c5e8a57db6be00ecb8a4d1 --- testing/fixture.go | 17 ++++++++++------- testing/fixture_test.go | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/testing/fixture.go b/testing/fixture.go index 3e749782..2bec0ed6 100644 --- a/testing/fixture.go +++ b/testing/fixture.go @@ -631,7 +631,7 @@ type managedFieldObjectTracker struct { ObjectTracker scheme ObjectScheme objectConverter runtime.ObjectConvertor - mapper meta.RESTMapper + mapper func() meta.RESTMapper typeConverter managedfields.TypeConverter } @@ -644,8 +644,10 @@ func NewFieldManagedObjectTracker(scheme *runtime.Scheme, decoder runtime.Decode ObjectTracker: NewObjectTracker(scheme, decoder), scheme: scheme, objectConverter: scheme, - mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme), - typeConverter: typeConverter, + mapper: func() meta.RESTMapper { + return testrestmapper.TestOnlyStaticRESTMapper(scheme) + }, + typeConverter: typeConverter, } } @@ -654,7 +656,7 @@ func (t *managedFieldObjectTracker) Create(gvr schema.GroupVersionResource, obj if err != nil { return err } - gvk, err := t.mapper.KindFor(gvr) + gvk, err := t.mapper().KindFor(gvr) if err != nil { return err } @@ -698,8 +700,9 @@ func (t *managedFieldObjectTracker) Update(gvr schema.GroupVersionResource, obj if err != nil { return err } - gvk, err := t.mapper.KindFor(gvr) + gvk, err := t.mapper().KindFor(gvr) if err != nil { + println("kindfor") return err } mgr, err := t.fieldManagerFor(gvk) @@ -728,7 +731,7 @@ func (t *managedFieldObjectTracker) Patch(gvr schema.GroupVersionResource, patch if err != nil { return err } - gvk, err := t.mapper.KindFor(gvr) + gvk, err := t.mapper().KindFor(gvr) if err != nil { return err } @@ -757,7 +760,7 @@ func (t *managedFieldObjectTracker) Apply(gvr schema.GroupVersionResource, apply if err != nil { return err } - gvk, err := t.mapper.KindFor(gvr) + gvk, err := t.mapper().KindFor(gvr) if err != nil { return err } diff --git a/testing/fixture_test.go b/testing/fixture_test.go index 2fa67cd6..54c25024 100644 --- a/testing/fixture_test.go +++ b/testing/fixture_test.go @@ -661,3 +661,25 @@ var configMapTypedSchema = typed.YAMLObject(`types: namedType: __untyped_deduced_ elementRelationship: separable `) + +func TestManagedFieldsObjectTrackerReloadsScheme(t *testing.T) { + cmResource := schema.GroupVersionResource{Version: "v1", Resource: "configmaps"} + scheme := runtime.NewScheme() + codecs := serializer.NewCodecFactory(scheme) + + // Create tracker without registered ConfigMap type + tracker := NewFieldManagedObjectTracker(scheme, codecs.UniversalDecoder(), configMapTypeConverter(scheme)) + + cm := &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cm", + }, + Data: map[string]string{"key": "value"}, + } + + // Register the type in scheme + scheme.AddKnownTypes(cmResource.GroupVersion(), &v1.ConfigMap{}) + + err := tracker.Create(cmResource, cm, "default", metav1.CreateOptions{FieldManager: "test-manager"}) + assert.NoError(t, err, "Create should succeed after registering type") +}