...

Source file src/k8s.io/apimachinery/pkg/util/managedfields/internal/testing/testfieldmanager.go

Documentation: k8s.io/apimachinery/pkg/util/managedfields/internal/testing

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package testing
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  
    23  	"k8s.io/apimachinery/pkg/api/meta"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/apimachinery/pkg/runtime/schema"
    28  	"k8s.io/apimachinery/pkg/util/managedfields"
    29  	"k8s.io/apimachinery/pkg/util/managedfields/internal"
    30  )
    31  
    32  // FakeObjectCreater implements ObjectCreater, it can create empty
    33  // objects (unstructured) of the given GVK.
    34  type FakeObjectCreater struct{}
    35  
    36  func (f *FakeObjectCreater) New(gvk schema.GroupVersionKind) (runtime.Object, error) {
    37  	u := unstructured.Unstructured{Object: map[string]interface{}{}}
    38  	u.SetAPIVersion(gvk.GroupVersion().String())
    39  	u.SetKind(gvk.Kind)
    40  	return &u, nil
    41  }
    42  
    43  // FakeObjectConvertor implements runtime.ObjectConvertor but it
    44  // actually does nothing but return its input.
    45  type FakeObjectConvertor struct{}
    46  
    47  //nolint:staticcheck,ineffassign // SA4009 backwards compatibility
    48  func (c *FakeObjectConvertor) Convert(in, out, context interface{}) error {
    49  	out = in
    50  	return nil
    51  }
    52  
    53  func (c *FakeObjectConvertor) ConvertToVersion(in runtime.Object, _ runtime.GroupVersioner) (runtime.Object, error) {
    54  	return in, nil
    55  }
    56  
    57  func (c *FakeObjectConvertor) ConvertFieldLabel(_ schema.GroupVersionKind, _, _ string) (string, string, error) {
    58  	return "", "", errors.New("not implemented")
    59  }
    60  
    61  // FakeObjectDefaulter implements runtime.Defaulter, but it actually
    62  // does nothing.
    63  type FakeObjectDefaulter struct{}
    64  
    65  func (d *FakeObjectDefaulter) Default(in runtime.Object) {}
    66  
    67  type TestFieldManagerImpl struct {
    68  	fieldManager *internal.FieldManager
    69  	apiVersion   string
    70  	emptyObj     runtime.Object
    71  	liveObj      runtime.Object
    72  }
    73  
    74  // APIVersion of the object that we're tracking.
    75  func (f *TestFieldManagerImpl) APIVersion() string {
    76  	return f.apiVersion
    77  }
    78  
    79  // Reset resets the state of the liveObject by resetting it to an empty object.
    80  func (f *TestFieldManagerImpl) Reset() {
    81  	f.liveObj = f.emptyObj.DeepCopyObject()
    82  }
    83  
    84  // Live returns a copy of the current liveObject.
    85  func (f *TestFieldManagerImpl) Live() runtime.Object {
    86  	return f.liveObj.DeepCopyObject()
    87  }
    88  
    89  // Apply applies the given object on top of the current liveObj, for the
    90  // given manager and force flag.
    91  func (f *TestFieldManagerImpl) Apply(obj runtime.Object, manager string, force bool) error {
    92  	out, err := f.fieldManager.Apply(f.liveObj, obj, manager, force)
    93  	if err == nil {
    94  		f.liveObj = out
    95  	}
    96  	return err
    97  }
    98  
    99  // Update will updates the managed fields in the liveObj based on the
   100  // changes performed by the update.
   101  func (f *TestFieldManagerImpl) Update(obj runtime.Object, manager string) error {
   102  	out, err := f.fieldManager.Update(f.liveObj, obj, manager)
   103  	if err == nil {
   104  		f.liveObj = out
   105  	}
   106  	return err
   107  }
   108  
   109  // ManagedFields returns the list of existing managed fields for the
   110  // liveObj.
   111  func (f *TestFieldManagerImpl) ManagedFields() []metav1.ManagedFieldsEntry {
   112  	accessor, err := meta.Accessor(f.liveObj)
   113  	if err != nil {
   114  		panic(fmt.Errorf("couldn't get accessor: %v", err))
   115  	}
   116  
   117  	return accessor.GetManagedFields()
   118  }
   119  
   120  // NewTestFieldManager creates a new manager for the given GVK.
   121  func NewTestFieldManagerImpl(typeConverter managedfields.TypeConverter, gvk schema.GroupVersionKind, subresource string, chainFieldManager func(internal.Manager) internal.Manager) *TestFieldManagerImpl {
   122  	f, err := internal.NewStructuredMergeManager(
   123  		typeConverter,
   124  		&FakeObjectConvertor{},
   125  		&FakeObjectDefaulter{},
   126  		gvk.GroupVersion(),
   127  		gvk.GroupVersion(),
   128  		nil,
   129  	)
   130  	if err != nil {
   131  		panic(err)
   132  	}
   133  	live := &unstructured.Unstructured{}
   134  	live.SetKind(gvk.Kind)
   135  	live.SetAPIVersion(gvk.GroupVersion().String())
   136  	// This is different from `internal.NewDefaultFieldManager` because:
   137  	// 1. We don't want to create a `internal.FieldManager`
   138  	// 2. We don't want to use the CapManager that is tested separately with
   139  	// a smaller than the default cap.
   140  	f = internal.NewVersionCheckManager(
   141  		internal.NewLastAppliedUpdater(
   142  			internal.NewLastAppliedManager(
   143  				internal.NewProbabilisticSkipNonAppliedManager(
   144  					internal.NewBuildManagerInfoManager(
   145  						internal.NewManagedFieldsUpdater(
   146  							internal.NewStripMetaManager(f),
   147  						), gvk.GroupVersion(), subresource,
   148  					), &FakeObjectCreater{}, internal.DefaultTrackOnCreateProbability,
   149  				), typeConverter, &FakeObjectConvertor{}, gvk.GroupVersion(),
   150  			),
   151  		), gvk,
   152  	)
   153  	if chainFieldManager != nil {
   154  		f = chainFieldManager(f)
   155  	}
   156  	return &TestFieldManagerImpl{
   157  		fieldManager: internal.NewFieldManager(f, subresource),
   158  		apiVersion:   gvk.GroupVersion().String(),
   159  		emptyObj:     live,
   160  		liveObj:      live.DeepCopyObject(),
   161  	}
   162  }
   163  

View as plain text