fieldmanagertest: Reduce API surface of the test package

This commit is contained in:
Antoine Pelisse 2022-12-15 20:50:38 -08:00
parent 7e97b4b322
commit 7899157345
8 changed files with 270 additions and 220 deletions

View File

@ -63,7 +63,7 @@ var fakeTypeConverter = func() fieldmanager.TypeConverter {
// TestUpdateApplyConflict tests that applying to an object, which // TestUpdateApplyConflict tests that applying to an object, which
// wasn't created by apply, will give conflicts // wasn't created by apply, will give conflicts
func TestUpdateApplyConflict(t *testing.T) { func TestUpdateApplyConflict(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
patch := []byte(`{ patch := []byte(`{
"apiVersion": "apps/v1", "apiVersion": "apps/v1",
@ -124,7 +124,7 @@ func TestUpdateApplyConflict(t *testing.T) {
} }
func TestApplyStripsFields(t *testing.T) { func TestApplyStripsFields(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
newObj := &unstructured.Unstructured{ newObj := &unstructured.Unstructured{
Object: map[string]interface{}{ Object: map[string]interface{}{
@ -156,7 +156,7 @@ func TestApplyStripsFields(t *testing.T) {
} }
func TestVersionCheck(t *testing.T) { func TestVersionCheck(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}} appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -196,7 +196,7 @@ func TestVersionCheck(t *testing.T) {
} }
} }
func TestVersionCheckDoesNotPanic(t *testing.T) { func TestVersionCheckDoesNotPanic(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}} appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -235,7 +235,7 @@ func TestVersionCheckDoesNotPanic(t *testing.T) {
} }
func TestApplyDoesNotStripLabels(t *testing.T) { func TestApplyDoesNotStripLabels(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"))
appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}} appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -289,7 +289,7 @@ func TestApplyNewObject(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.gvk.String(), func(t *testing.T) { t.Run(test.gvk.String(), func(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, test.gvk) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, test.gvk)
appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}} appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal(test.obj, &appliedObj.Object); err != nil { if err := yaml.Unmarshal(test.obj, &appliedObj.Object); err != nil {
@ -327,7 +327,7 @@ func BenchmarkNewObject(b *testing.B) {
} }
for _, test := range tests { for _, test := range tests {
b.Run(test.gvk.Kind, func(b *testing.B) { b.Run(test.gvk.Kind, func(b *testing.B) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, test.gvk) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, test.gvk)
decoder := serializer.NewCodecFactory(scheme).UniversalDecoder(test.gvk.GroupVersion()) decoder := serializer.NewCodecFactory(scheme).UniversalDecoder(test.gvk.GroupVersion())
newObj, err := runtime.Decode(decoder, test.obj) newObj, err := runtime.Decode(decoder, test.obj)
@ -540,7 +540,7 @@ func BenchmarkCompare(b *testing.B) {
} }
func BenchmarkRepeatedUpdate(b *testing.B) { func BenchmarkRepeatedUpdate(b *testing.B) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"))
podBytes := getObjectBytes("pod.yaml") podBytes := getObjectBytes("pod.yaml")
var obj *corev1.Pod var obj *corev1.Pod
@ -579,7 +579,7 @@ func BenchmarkRepeatedUpdate(b *testing.B) {
} }
func TestApplyFailsWithManagedFields(t *testing.T) { func TestApplyFailsWithManagedFields(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"))
appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}} appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -604,7 +604,7 @@ func TestApplyFailsWithManagedFields(t *testing.T) {
} }
func TestApplySuccessWithNoManagedFields(t *testing.T) { func TestApplySuccessWithNoManagedFields(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"))
appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}} appliedObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -627,7 +627,7 @@ func TestApplySuccessWithNoManagedFields(t *testing.T) {
// Run an update and apply, and make sure that nothing has changed. // Run an update and apply, and make sure that nothing has changed.
func TestNoOpChanges(t *testing.T) { func TestNoOpChanges(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"))
obj := &unstructured.Unstructured{Object: map[string]interface{}{}} obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -678,7 +678,7 @@ func TestNoOpChanges(t *testing.T) {
// Tests that one can reset the managedFields by sending either an empty // Tests that one can reset the managedFields by sending either an empty
// list // list
func TestResetManagedFieldsEmptyList(t *testing.T) { func TestResetManagedFieldsEmptyList(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"))
obj := &unstructured.Unstructured{Object: map[string]interface{}{}} obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -719,7 +719,7 @@ func TestResetManagedFieldsEmptyList(t *testing.T) {
// Tests that one can reset the managedFields by sending either a list with one empty item. // Tests that one can reset the managedFields by sending either a list with one empty item.
func TestResetManagedFieldsEmptyItem(t *testing.T) { func TestResetManagedFieldsEmptyItem(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"))
obj := &unstructured.Unstructured{Object: map[string]interface{}{}} obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -759,7 +759,7 @@ func TestResetManagedFieldsEmptyItem(t *testing.T) {
} }
func TestServerSideApplyWithInvalidLastApplied(t *testing.T) { func TestServerSideApplyWithInvalidLastApplied(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
// create object with client-side apply // create object with client-side apply
newObj := &unstructured.Unstructured{Object: map[string]interface{}{}} newObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
@ -838,7 +838,7 @@ spec:
} }
func TestInteropForClientSideApplyAndServerSideApply(t *testing.T) { func TestInteropForClientSideApplyAndServerSideApply(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
// create object with client-side apply // create object with client-side apply
newObj := &unstructured.Unstructured{Object: map[string]interface{}{}} newObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
@ -922,7 +922,7 @@ spec:
} }
func TestNoTrackManagedFieldsForClientSideApply(t *testing.T) { func TestNoTrackManagedFieldsForClientSideApply(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
// create object // create object
newObj := &unstructured.Unstructured{Object: map[string]interface{}{}} newObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
@ -1102,7 +1102,7 @@ func getLastApplied(obj runtime.Object) (string, error) {
} }
func TestUpdateViaSubresources(t *testing.T) { func TestUpdateViaSubresources(t *testing.T) {
f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"), "scale", nil) f := fieldmanagertest.NewTestFieldManagerSubresource(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"), "scale")
obj := &unstructured.Unstructured{Object: map[string]interface{}{}} obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(`{ if err := yaml.Unmarshal([]byte(`{
@ -1157,7 +1157,7 @@ func TestUpdateViaSubresources(t *testing.T) {
// Ensures that a no-op Apply does not mutate managed fields // Ensures that a no-op Apply does not mutate managed fields
func TestApplyDoesNotChangeManagedFields(t *testing.T) { func TestApplyDoesNotChangeManagedFields(t *testing.T) {
originalManagedFields := []metav1.ManagedFieldsEntry{} originalManagedFields := []metav1.ManagedFieldsEntry{}
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter,
schema.FromAPIVersionAndKind("apps/v1", "Deployment")) schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
newObj := &unstructured.Unstructured{ newObj := &unstructured.Unstructured{
Object: map[string]interface{}{}, Object: map[string]interface{}{},
@ -1251,7 +1251,7 @@ func TestApplyDoesNotChangeManagedFields(t *testing.T) {
// Ensures that a no-op Update does not mutate managed fields // Ensures that a no-op Update does not mutate managed fields
func TestUpdateDoesNotChangeManagedFields(t *testing.T) { func TestUpdateDoesNotChangeManagedFields(t *testing.T) {
originalManagedFields := []metav1.ManagedFieldsEntry{} originalManagedFields := []metav1.ManagedFieldsEntry{}
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter,
schema.FromAPIVersionAndKind("apps/v1", "Deployment")) schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
newObj := &unstructured.Unstructured{ newObj := &unstructured.Unstructured{
Object: map[string]interface{}{}, Object: map[string]interface{}{},
@ -1323,7 +1323,7 @@ func TestUpdateDoesNotChangeManagedFields(t *testing.T) {
// This test makes sure that the liveObject during a patch does not mutate // This test makes sure that the liveObject during a patch does not mutate
// its managed fields. // its managed fields.
func TestLiveObjectManagedFieldsNotRemoved(t *testing.T) { func TestLiveObjectManagedFieldsNotRemoved(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter,
schema.FromAPIVersionAndKind("apps/v1", "Deployment")) schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
newObj := &unstructured.Unstructured{ newObj := &unstructured.Unstructured{
Object: map[string]interface{}{}, Object: map[string]interface{}{},

View File

@ -17,73 +17,13 @@ limitations under the License.
package fieldmanagertest package fieldmanagertest
import ( import (
"errors"
"fmt"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testing"
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
"sigs.k8s.io/structured-merge-diff/v4/merge"
"sigs.k8s.io/structured-merge-diff/v4/typed"
) )
type fakeObjectConvertor struct {
converter merge.Converter
apiVersion fieldpath.APIVersion
}
//nolint:staticcheck,ineffassign // SA4009 backwards compatibility
func (c *fakeObjectConvertor) Convert(in, out, context interface{}) error {
if typedValue, ok := in.(*typed.TypedValue); ok {
var err error
out, err = c.converter.Convert(typedValue, c.apiVersion)
return err
}
return nil
}
func (c *fakeObjectConvertor) ConvertToVersion(in runtime.Object, _ runtime.GroupVersioner) (runtime.Object, error) {
return in, nil
}
func (c *fakeObjectConvertor) ConvertFieldLabel(_ schema.GroupVersionKind, _, _ string) (string, string, error) {
return "", "", errors.New("not implemented")
}
type fakeObjectDefaulter struct{}
func (d *fakeObjectDefaulter) Default(in runtime.Object) {}
type sameVersionConverter struct{}
func (sameVersionConverter) Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) {
return object, nil
}
func (sameVersionConverter) IsMissingVersionError(error) bool {
return false
}
// NewFakeObjectCreater implements ObjectCreater, it can create empty
// objects (unstructured) of the given GVK.
func NewFakeObjectCreater() runtime.ObjectCreater {
return &fakeObjectCreater{}
}
type fakeObjectCreater struct{}
func (f *fakeObjectCreater) New(gvk schema.GroupVersionKind) (runtime.Object, error) {
u := unstructured.Unstructured{Object: map[string]interface{}{}}
u.SetAPIVersion(gvk.GroupVersion().String())
u.SetKind(gvk.Kind)
return &u, nil
}
// TestFieldManager is a FieldManager that can be used in test to // TestFieldManager is a FieldManager that can be used in test to
// simulate the behavior of Server-Side Apply and field tracking. This // simulate the behavior of Server-Side Apply and field tracking. This
// also has a few methods to get a sense of the state of the object. // also has a few methods to get a sense of the state of the object.
@ -95,105 +35,32 @@ func (f *fakeObjectCreater) New(gvk schema.GroupVersionKind) (runtime.Object, er
// You can use this rather than NewDefaultTestFieldManager if you want // You can use this rather than NewDefaultTestFieldManager if you want
// to specify either a sub-resource, or a set of modified Manager to // to specify either a sub-resource, or a set of modified Manager to
// test them specifically. // test them specifically.
type TestFieldManager struct { type TestFieldManager interface {
fieldManager *internal.FieldManager // APIVersion of the object that we're tracking.
apiVersion string APIVersion() string
emptyObj runtime.Object // Reset resets the state of the liveObject by resetting it to an empty object.
liveObj runtime.Object Reset()
// Live returns a copy of the current liveObject.
Live() runtime.Object
// Apply applies the given object on top of the current liveObj, for the
// given manager and force flag.
Apply(obj runtime.Object, manager string, force bool) error
// Update will updates the managed fields in the liveObj based on the
// changes performed by the update.
Update(obj runtime.Object, manager string) error
// ManagedFields returns the list of existing managed fields for the
// liveObj.
ManagedFields() []metav1.ManagedFieldsEntry
} }
// NewDefaultTestFieldManager returns a new TestFieldManager built for // NewTestFieldManager returns a new TestFieldManager built for the
// the given gvk, on the main resource. // given gvk, on the main resource.
func NewDefaultTestFieldManager(typeConverter fieldmanager.TypeConverter, gvk schema.GroupVersionKind) TestFieldManager { func NewTestFieldManager(typeConverter fieldmanager.TypeConverter, gvk schema.GroupVersionKind) TestFieldManager {
return NewTestFieldManager(typeConverter, gvk, "", nil) return testing.NewTestFieldManagerImpl(typeConverter, gvk, "", nil)
} }
// NewTestFieldManager creates a new manager for the given GVK. // NewTestFieldManagerSubresource returns a new TestFieldManager built
func NewTestFieldManager(typeConverter fieldmanager.TypeConverter, gvk schema.GroupVersionKind, subresource string, chainFieldManager func(internal.Manager) internal.Manager) TestFieldManager { // for the given gvk, on the given sub-resource.
apiVersion := fieldpath.APIVersion(gvk.GroupVersion().String()) func NewTestFieldManagerSubresource(typeConverter fieldmanager.TypeConverter, gvk schema.GroupVersionKind, subresource string) TestFieldManager {
objectConverter := &fakeObjectConvertor{sameVersionConverter{}, apiVersion} return testing.NewTestFieldManagerImpl(typeConverter, gvk, subresource, nil)
f, err := internal.NewStructuredMergeManager(
typeConverter,
objectConverter,
&fakeObjectDefaulter{},
gvk.GroupVersion(),
gvk.GroupVersion(),
nil,
)
if err != nil {
panic(err)
}
live := &unstructured.Unstructured{}
live.SetKind(gvk.Kind)
live.SetAPIVersion(gvk.GroupVersion().String())
// This is different from `internal.NewDefaultFieldManager` because:
// 1. We don't want to create a `internal.FieldManager`
// 2. We don't want to use the CapManager that is tested separately with
// a smaller than the default cap.
f = internal.NewLastAppliedUpdater(
internal.NewLastAppliedManager(
internal.NewProbabilisticSkipNonAppliedManager(
internal.NewBuildManagerInfoManager(
internal.NewManagedFieldsUpdater(
internal.NewStripMetaManager(f),
), gvk.GroupVersion(), subresource,
), NewFakeObjectCreater(), gvk, internal.DefaultTrackOnCreateProbability,
), typeConverter, objectConverter, gvk.GroupVersion(),
),
)
if chainFieldManager != nil {
f = chainFieldManager(f)
}
return TestFieldManager{
fieldManager: internal.NewFieldManager(f, subresource),
apiVersion: gvk.GroupVersion().String(),
emptyObj: live,
liveObj: live.DeepCopyObject(),
}
}
// APIVersion of the object that we're tracking.
func (f *TestFieldManager) APIVersion() string {
return f.apiVersion
}
// Reset resets the state of the liveObject by resetting it to an empty object.
func (f *TestFieldManager) Reset() {
f.liveObj = f.emptyObj.DeepCopyObject()
}
// Live returns a copy of the current liveObject.
func (f *TestFieldManager) Live() runtime.Object {
return f.liveObj.DeepCopyObject()
}
// Apply applies the given object on top of the current liveObj, for the
// given manager and force flag.
func (f *TestFieldManager) Apply(obj runtime.Object, manager string, force bool) error {
out, err := f.fieldManager.Apply(f.liveObj, obj, manager, force)
if err == nil {
f.liveObj = out
}
return err
}
// Update will updates the managed fields in the liveObj based on the
// changes performed by the update.
func (f *TestFieldManager) Update(obj runtime.Object, manager string) error {
out, err := f.fieldManager.Update(f.liveObj, obj, manager)
if err == nil {
f.liveObj = out
}
return err
}
// ManagedFields returns the list of existing managed fields for the
// liveObj.
func (f *TestFieldManager) ManagedFields() []metav1.ManagedFieldsEntry {
accessor, err := meta.Accessor(f.liveObj)
if err != nil {
panic(fmt.Errorf("couldn't get accessor: %v", err))
}
return accessor.GetManagedFields()
} }

View File

@ -31,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanagertest" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanagertest"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal"
internaltesting "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testing"
"sigs.k8s.io/structured-merge-diff/v4/fieldpath" "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
) )
@ -48,7 +49,7 @@ func (*fakeManager) Apply(_, _ runtime.Object, _ internal.Managed, _ string, _ b
} }
func TestCapManagersManagerMergesEntries(t *testing.T) { func TestCapManagersManagerMergesEntries(t *testing.T) {
f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"), f := internaltesting.NewTestFieldManagerImpl(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"),
"", "",
func(m internal.Manager) internal.Manager { func(m internal.Manager) internal.Manager {
return internal.NewCapManagersManager(m, 3) return internal.NewCapManagersManager(m, 3)
@ -114,7 +115,7 @@ func TestCapManagersManagerMergesEntries(t *testing.T) {
} }
func TestCapUpdateManagers(t *testing.T) { func TestCapUpdateManagers(t *testing.T) {
f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"), f := internaltesting.NewTestFieldManagerImpl(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"),
"", "",
func(m internal.Manager) internal.Manager { func(m internal.Manager) internal.Manager {
return internal.NewCapManagersManager(m, 3) return internal.NewCapManagersManager(m, 3)

View File

@ -46,7 +46,7 @@ type testArgs struct {
// created with the client-side apply last-applied annotation // created with the client-side apply last-applied annotation
// will not give conflicts // will not give conflicts
func TestApplyUsingLastAppliedAnnotation(t *testing.T) { func TestApplyUsingLastAppliedAnnotation(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"))
tests := []testArgs{ tests := []testArgs{
{ {
@ -566,7 +566,7 @@ spec:
} }
func TestServiceApply(t *testing.T) { func TestServiceApply(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Service")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Service"))
tests := []testArgs{ tests := []testArgs{
{ {
@ -677,7 +677,7 @@ spec:
} }
func TestReplicationControllerApply(t *testing.T) { func TestReplicationControllerApply(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ReplicationController")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ReplicationController"))
tests := []testArgs{ tests := []testArgs{
{ {
@ -740,7 +740,7 @@ spec:
} }
func TestPodApply(t *testing.T) { func TestPodApply(t *testing.T) {
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"))
tests := []testArgs{ tests := []testArgs{
{ {

View File

@ -27,13 +27,13 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanagertest"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal"
internaltesting "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testing"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
func TestLastAppliedUpdater(t *testing.T) { func TestLastAppliedUpdater(t *testing.T) {
f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"), f := internaltesting.NewTestFieldManagerImpl(fakeTypeConverter, schema.FromAPIVersionAndKind("apps/v1", "Deployment"),
"", "",
func(m internal.Manager) internal.Manager { func(m internal.Manager) internal.Manager {
return internal.NewLastAppliedUpdater(m) return internal.NewLastAppliedUpdater(m)
@ -190,7 +190,7 @@ func TestLargeLastApplied(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"), f := internaltesting.NewTestFieldManagerImpl(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"),
"", "",
func(m internal.Manager) internal.Manager { func(m internal.Manager) internal.Manager {
return internal.NewLastAppliedUpdater(m) return internal.NewLastAppliedUpdater(m)

View File

@ -35,9 +35,9 @@ import (
func TestManagedFieldsUpdateDoesModifyTime(t *testing.T) { func TestManagedFieldsUpdateDoesModifyTime(t *testing.T) {
var err error var err error
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"))
err = updateObject(&f, "fieldmanager_test", []byte(`{ err = updateObject(f, "fieldmanager_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -54,7 +54,7 @@ func TestManagedFieldsUpdateDoesModifyTime(t *testing.T) {
time.Sleep(time.Second) time.Sleep(time.Second)
err = updateObject(&f, "fieldmanager_test", []byte(`{ err = updateObject(f, "fieldmanager_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -76,9 +76,9 @@ func TestManagedFieldsUpdateDoesModifyTime(t *testing.T) {
func TestManagedFieldsApplyDoesModifyTime(t *testing.T) { func TestManagedFieldsApplyDoesModifyTime(t *testing.T) {
var err error var err error
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"))
err = applyObject(&f, "fieldmanager_test", []byte(`{ err = applyObject(f, "fieldmanager_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -95,7 +95,7 @@ func TestManagedFieldsApplyDoesModifyTime(t *testing.T) {
time.Sleep(time.Second) time.Sleep(time.Second)
err = applyObject(&f, "fieldmanager_test", []byte(`{ err = applyObject(f, "fieldmanager_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -117,9 +117,9 @@ func TestManagedFieldsApplyDoesModifyTime(t *testing.T) {
func TestManagedFieldsUpdateWithoutChangesDoesNotModifyTime(t *testing.T) { func TestManagedFieldsUpdateWithoutChangesDoesNotModifyTime(t *testing.T) {
var err error var err error
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"))
err = updateObject(&f, "fieldmanager_test", []byte(`{ err = updateObject(f, "fieldmanager_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -136,7 +136,7 @@ func TestManagedFieldsUpdateWithoutChangesDoesNotModifyTime(t *testing.T) {
time.Sleep(time.Second) time.Sleep(time.Second)
err = updateObject(&f, "fieldmanager_test", []byte(`{ err = updateObject(f, "fieldmanager_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -158,9 +158,9 @@ func TestManagedFieldsUpdateWithoutChangesDoesNotModifyTime(t *testing.T) {
func TestManagedFieldsApplyWithoutChangesDoesNotModifyTime(t *testing.T) { func TestManagedFieldsApplyWithoutChangesDoesNotModifyTime(t *testing.T) {
var err error var err error
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"))
err = applyObject(&f, "fieldmanager_test", []byte(`{ err = applyObject(f, "fieldmanager_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -177,7 +177,7 @@ func TestManagedFieldsApplyWithoutChangesDoesNotModifyTime(t *testing.T) {
time.Sleep(time.Second) time.Sleep(time.Second)
err = applyObject(&f, "fieldmanager_test", []byte(`{ err = applyObject(f, "fieldmanager_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -199,9 +199,9 @@ func TestManagedFieldsApplyWithoutChangesDoesNotModifyTime(t *testing.T) {
func TestNonManagedFieldsUpdateDoesNotModifyTime(t *testing.T) { func TestNonManagedFieldsUpdateDoesNotModifyTime(t *testing.T) {
var err error var err error
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"))
err = updateObject(&f, "fieldmanager_a_test", []byte(`{ err = updateObject(f, "fieldmanager_a_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -214,7 +214,7 @@ func TestNonManagedFieldsUpdateDoesNotModifyTime(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = updateObject(&f, "fieldmanager_b_test", []byte(`{ err = updateObject(f, "fieldmanager_b_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -235,7 +235,7 @@ func TestNonManagedFieldsUpdateDoesNotModifyTime(t *testing.T) {
time.Sleep(time.Second) time.Sleep(time.Second)
err = updateObject(&f, "fieldmanager_a_test", []byte(`{ err = updateObject(f, "fieldmanager_a_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -262,9 +262,9 @@ func TestNonManagedFieldsUpdateDoesNotModifyTime(t *testing.T) {
func TestNonManagedFieldsApplyDoesNotModifyTime(t *testing.T) { func TestNonManagedFieldsApplyDoesNotModifyTime(t *testing.T) {
var err error var err error
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"))
err = applyObject(&f, "fieldmanager_a_test", []byte(`{ err = applyObject(f, "fieldmanager_a_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -277,7 +277,7 @@ func TestNonManagedFieldsApplyDoesNotModifyTime(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = applyObject(&f, "fieldmanager_b_test", []byte(`{ err = applyObject(f, "fieldmanager_b_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -298,7 +298,7 @@ func TestNonManagedFieldsApplyDoesNotModifyTime(t *testing.T) {
time.Sleep(time.Second) time.Sleep(time.Second)
err = applyObject(&f, "fieldmanager_a_test", []byte(`{ err = applyObject(f, "fieldmanager_a_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -325,9 +325,9 @@ func TestNonManagedFieldsApplyDoesNotModifyTime(t *testing.T) {
func TestTakingOverManagedFieldsDuringUpdateDoesNotModifyPreviousManagerTime(t *testing.T) { func TestTakingOverManagedFieldsDuringUpdateDoesNotModifyPreviousManagerTime(t *testing.T) {
var err error var err error
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"))
err = updateObject(&f, "fieldmanager_a_test", []byte(`{ err = updateObject(f, "fieldmanager_a_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -349,7 +349,7 @@ func TestTakingOverManagedFieldsDuringUpdateDoesNotModifyPreviousManagerTime(t *
time.Sleep(time.Second) time.Sleep(time.Second)
err = updateObject(&f, "fieldmanager_b_test", []byte(`{ err = updateObject(f, "fieldmanager_b_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -376,9 +376,9 @@ func TestTakingOverManagedFieldsDuringUpdateDoesNotModifyPreviousManagerTime(t *
func TestTakingOverManagedFieldsDuringApplyDoesNotModifyPreviousManagerTime(t *testing.T) { func TestTakingOverManagedFieldsDuringApplyDoesNotModifyPreviousManagerTime(t *testing.T) {
var err error var err error
f := fieldmanagertest.NewDefaultTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap")) f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "ConfigMap"))
err = applyObject(&f, "fieldmanager_a_test", []byte(`{ err = applyObject(f, "fieldmanager_a_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -400,7 +400,7 @@ func TestTakingOverManagedFieldsDuringApplyDoesNotModifyPreviousManagerTime(t *t
time.Sleep(time.Second) time.Sleep(time.Second)
err = applyObject(&f, "fieldmanager_b_test", []byte(`{ err = applyObject(f, "fieldmanager_b_test", []byte(`{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
@ -435,7 +435,7 @@ func (NoopManager) Update(liveObj, newObj runtime.Object, managed internal.Manag
return nil, nil, nil return nil, nil, nil
} }
func updateObject(f *fieldmanagertest.TestFieldManager, fieldManagerName string, object []byte) error { func updateObject(f fieldmanagertest.TestFieldManager, fieldManagerName string, object []byte) error {
obj := &unstructured.Unstructured{Object: map[string]interface{}{}} obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal(object, &obj.Object); err != nil { if err := yaml.Unmarshal(object, &obj.Object); err != nil {
return fmt.Errorf("error decoding YAML: %v", err) return fmt.Errorf("error decoding YAML: %v", err)
@ -446,7 +446,7 @@ func updateObject(f *fieldmanagertest.TestFieldManager, fieldManagerName string,
return nil return nil
} }
func applyObject(f *fieldmanagertest.TestFieldManager, fieldManagerName string, object []byte) error { func applyObject(f fieldmanagertest.TestFieldManager, fieldManagerName string, object []byte) error {
obj := &unstructured.Unstructured{Object: map[string]interface{}{}} obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal(object, &obj.Object); err != nil { if err := yaml.Unmarshal(object, &obj.Object); err != nil {
return fmt.Errorf("error decoding YAML: %v", err) return fmt.Errorf("error decoding YAML: %v", err)

View File

@ -24,16 +24,16 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanagertest"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal"
internaltesting "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testing"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
func TestNoUpdateBeforeFirstApply(t *testing.T) { func TestNoUpdateBeforeFirstApply(t *testing.T) {
f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"), "", func(m internal.Manager) internal.Manager { f := internaltesting.NewTestFieldManagerImpl(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"), "", func(m internal.Manager) internal.Manager {
return internal.NewSkipNonAppliedManager( return internal.NewSkipNonAppliedManager(
m, m,
fieldmanagertest.NewFakeObjectCreater(), internaltesting.NewFakeObjectCreater(),
schema.FromAPIVersionAndKind("v1", "Pod"), schema.FromAPIVersionAndKind("v1", "Pod"),
) )
}) })
@ -70,10 +70,10 @@ func TestNoUpdateBeforeFirstApply(t *testing.T) {
} }
func TestUpdateBeforeFirstApply(t *testing.T) { func TestUpdateBeforeFirstApply(t *testing.T) {
f := fieldmanagertest.NewTestFieldManager(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"), "", func(m internal.Manager) internal.Manager { f := internaltesting.NewTestFieldManagerImpl(fakeTypeConverter, schema.FromAPIVersionAndKind("v1", "Pod"), "", func(m internal.Manager) internal.Manager {
return internal.NewSkipNonAppliedManager( return internal.NewSkipNonAppliedManager(
m, m,
fieldmanagertest.NewFakeObjectCreater(), internaltesting.NewFakeObjectCreater(),
schema.FromAPIVersionAndKind("v1", "Pod"), schema.FromAPIVersionAndKind("v1", "Pod"),
) )
}) })

View File

@ -0,0 +1,182 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package testing
import (
"errors"
"fmt"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal"
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
"sigs.k8s.io/structured-merge-diff/v4/merge"
"sigs.k8s.io/structured-merge-diff/v4/typed"
)
// NewFakeObjectCreater implements ObjectCreater, it can create empty
// objects (unstructured) of the given GVK.
func NewFakeObjectCreater() runtime.ObjectCreater {
return &fakeObjectCreater{}
}
type fakeObjectCreater struct{}
func (f *fakeObjectCreater) New(gvk schema.GroupVersionKind) (runtime.Object, error) {
u := unstructured.Unstructured{Object: map[string]interface{}{}}
u.SetAPIVersion(gvk.GroupVersion().String())
u.SetKind(gvk.Kind)
return &u, nil
}
type fakeObjectConvertor struct {
converter merge.Converter
apiVersion fieldpath.APIVersion
}
//nolint:staticcheck,ineffassign // SA4009 backwards compatibility
func (c *fakeObjectConvertor) Convert(in, out, context interface{}) error {
if typedValue, ok := in.(*typed.TypedValue); ok {
var err error
out, err = c.converter.Convert(typedValue, c.apiVersion)
return err
}
return nil
}
func (c *fakeObjectConvertor) ConvertToVersion(in runtime.Object, _ runtime.GroupVersioner) (runtime.Object, error) {
return in, nil
}
func (c *fakeObjectConvertor) ConvertFieldLabel(_ schema.GroupVersionKind, _, _ string) (string, string, error) {
return "", "", errors.New("not implemented")
}
type fakeObjectDefaulter struct{}
func (d *fakeObjectDefaulter) Default(in runtime.Object) {}
type sameVersionConverter struct{}
func (sameVersionConverter) Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) {
return object, nil
}
func (sameVersionConverter) IsMissingVersionError(error) bool {
return false
}
type TestFieldManagerImpl struct {
fieldManager *internal.FieldManager
apiVersion string
emptyObj runtime.Object
liveObj runtime.Object
}
// APIVersion of the object that we're tracking.
func (f *TestFieldManagerImpl) APIVersion() string {
return f.apiVersion
}
// Reset resets the state of the liveObject by resetting it to an empty object.
func (f *TestFieldManagerImpl) Reset() {
f.liveObj = f.emptyObj.DeepCopyObject()
}
// Live returns a copy of the current liveObject.
func (f *TestFieldManagerImpl) Live() runtime.Object {
return f.liveObj.DeepCopyObject()
}
// Apply applies the given object on top of the current liveObj, for the
// given manager and force flag.
func (f *TestFieldManagerImpl) Apply(obj runtime.Object, manager string, force bool) error {
out, err := f.fieldManager.Apply(f.liveObj, obj, manager, force)
if err == nil {
f.liveObj = out
}
return err
}
// Update will updates the managed fields in the liveObj based on the
// changes performed by the update.
func (f *TestFieldManagerImpl) Update(obj runtime.Object, manager string) error {
out, err := f.fieldManager.Update(f.liveObj, obj, manager)
if err == nil {
f.liveObj = out
}
return err
}
// ManagedFields returns the list of existing managed fields for the
// liveObj.
func (f *TestFieldManagerImpl) ManagedFields() []metav1.ManagedFieldsEntry {
accessor, err := meta.Accessor(f.liveObj)
if err != nil {
panic(fmt.Errorf("couldn't get accessor: %v", err))
}
return accessor.GetManagedFields()
}
// NewTestFieldManager creates a new manager for the given GVK.
func NewTestFieldManagerImpl(typeConverter fieldmanager.TypeConverter, gvk schema.GroupVersionKind, subresource string, chainFieldManager func(internal.Manager) internal.Manager) *TestFieldManagerImpl {
apiVersion := fieldpath.APIVersion(gvk.GroupVersion().String())
objectConverter := &fakeObjectConvertor{sameVersionConverter{}, apiVersion}
f, err := internal.NewStructuredMergeManager(
typeConverter,
objectConverter,
&fakeObjectDefaulter{},
gvk.GroupVersion(),
gvk.GroupVersion(),
nil,
)
if err != nil {
panic(err)
}
live := &unstructured.Unstructured{}
live.SetKind(gvk.Kind)
live.SetAPIVersion(gvk.GroupVersion().String())
// This is different from `internal.NewDefaultFieldManager` because:
// 1. We don't want to create a `internal.FieldManager`
// 2. We don't want to use the CapManager that is tested separately with
// a smaller than the default cap.
f = internal.NewLastAppliedUpdater(
internal.NewLastAppliedManager(
internal.NewProbabilisticSkipNonAppliedManager(
internal.NewBuildManagerInfoManager(
internal.NewManagedFieldsUpdater(
internal.NewStripMetaManager(f),
), gvk.GroupVersion(), subresource,
), NewFakeObjectCreater(), gvk, internal.DefaultTrackOnCreateProbability,
), typeConverter, objectConverter, gvk.GroupVersion(),
),
)
if chainFieldManager != nil {
f = chainFieldManager(f)
}
return &TestFieldManagerImpl{
fieldManager: internal.NewFieldManager(f, subresource),
apiVersion: gvk.GroupVersion().String(),
emptyObj: live,
liveObj: live.DeepCopyObject(),
}
}