mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 02:41:25 +00:00
fieldmanagertest: Reduce API surface of the test package
This commit is contained in:
parent
7e97b4b322
commit
7899157345
@ -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{}{},
|
||||||
|
@ -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()
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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{
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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"),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -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(),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user