...

Source file src/sigs.k8s.io/controller-runtime/pkg/client/fieldowner_test.go

Documentation: sigs.k8s.io/controller-runtime/pkg/client

     1  /*
     2  Copyright 2024 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 client_test
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	corev1 "k8s.io/api/core/v1"
    24  	"sigs.k8s.io/controller-runtime/pkg/client"
    25  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    26  	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
    27  )
    28  
    29  func TestWithFieldOwner(t *testing.T) {
    30  	calls := 0
    31  	fakeClient := testClient(t, "custom-field-mgr", func() { calls++ })
    32  	wrappedClient := client.WithFieldOwner(fakeClient, "custom-field-mgr")
    33  
    34  	ctx := context.Background()
    35  	dummyObj := &corev1.Namespace{}
    36  
    37  	_ = wrappedClient.Create(ctx, dummyObj)
    38  	_ = wrappedClient.Update(ctx, dummyObj)
    39  	_ = wrappedClient.Patch(ctx, dummyObj, nil)
    40  	_ = wrappedClient.Status().Create(ctx, dummyObj, dummyObj)
    41  	_ = wrappedClient.Status().Update(ctx, dummyObj)
    42  	_ = wrappedClient.Status().Patch(ctx, dummyObj, nil)
    43  	_ = wrappedClient.SubResource("some-subresource").Create(ctx, dummyObj, dummyObj)
    44  	_ = wrappedClient.SubResource("some-subresource").Update(ctx, dummyObj)
    45  	_ = wrappedClient.SubResource("some-subresource").Patch(ctx, dummyObj, nil)
    46  
    47  	if expectedCalls := 9; calls != expectedCalls {
    48  		t.Fatalf("wrong number of calls to assertions: expected=%d; got=%d", expectedCalls, calls)
    49  	}
    50  }
    51  
    52  func TestWithFieldOwnerOverridden(t *testing.T) {
    53  	calls := 0
    54  
    55  	fakeClient := testClient(t, "new-field-manager", func() { calls++ })
    56  	wrappedClient := client.WithFieldOwner(fakeClient, "old-field-manager")
    57  
    58  	ctx := context.Background()
    59  	dummyObj := &corev1.Namespace{}
    60  
    61  	_ = wrappedClient.Create(ctx, dummyObj, client.FieldOwner("new-field-manager"))
    62  	_ = wrappedClient.Update(ctx, dummyObj, client.FieldOwner("new-field-manager"))
    63  	_ = wrappedClient.Patch(ctx, dummyObj, nil, client.FieldOwner("new-field-manager"))
    64  	_ = wrappedClient.Status().Create(ctx, dummyObj, dummyObj, client.FieldOwner("new-field-manager"))
    65  	_ = wrappedClient.Status().Update(ctx, dummyObj, client.FieldOwner("new-field-manager"))
    66  	_ = wrappedClient.Status().Patch(ctx, dummyObj, nil, client.FieldOwner("new-field-manager"))
    67  	_ = wrappedClient.SubResource("some-subresource").Create(ctx, dummyObj, dummyObj, client.FieldOwner("new-field-manager"))
    68  	_ = wrappedClient.SubResource("some-subresource").Update(ctx, dummyObj, client.FieldOwner("new-field-manager"))
    69  	_ = wrappedClient.SubResource("some-subresource").Patch(ctx, dummyObj, nil, client.FieldOwner("new-field-manager"))
    70  
    71  	if expectedCalls := 9; calls != expectedCalls {
    72  		t.Fatalf("wrong number of calls to assertions: expected=%d; got=%d", expectedCalls, calls)
    73  	}
    74  }
    75  
    76  // testClient is a helper function that checks if calls have the expected field manager,
    77  // and calls the callback function on each intercepted call.
    78  func testClient(t *testing.T, expectedFieldManager string, callback func()) client.Client {
    79  	// TODO: we could use the dummyClient in interceptor pkg if we move it to an internal pkg
    80  	return fake.NewClientBuilder().WithInterceptorFuncs(interceptor.Funcs{
    81  		Create: func(ctx context.Context, c client.WithWatch, obj client.Object, opts ...client.CreateOption) error {
    82  			callback()
    83  			out := &client.CreateOptions{}
    84  			for _, f := range opts {
    85  				f.ApplyToCreate(out)
    86  			}
    87  			if got := out.FieldManager; expectedFieldManager != got {
    88  				t.Fatalf("wrong field manager: expected=%q; got=%q", expectedFieldManager, got)
    89  			}
    90  			return nil
    91  		},
    92  		Update: func(ctx context.Context, c client.WithWatch, obj client.Object, opts ...client.UpdateOption) error {
    93  			callback()
    94  			out := &client.UpdateOptions{}
    95  			for _, f := range opts {
    96  				f.ApplyToUpdate(out)
    97  			}
    98  			if got := out.FieldManager; expectedFieldManager != got {
    99  				t.Fatalf("wrong field manager: expected=%q; got=%q", expectedFieldManager, got)
   100  			}
   101  			return nil
   102  		},
   103  		Patch: func(ctx context.Context, c client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error {
   104  			callback()
   105  			out := &client.PatchOptions{}
   106  			for _, f := range opts {
   107  				f.ApplyToPatch(out)
   108  			}
   109  			if got := out.FieldManager; expectedFieldManager != got {
   110  				t.Fatalf("wrong field manager: expected=%q; got=%q", expectedFieldManager, got)
   111  			}
   112  			return nil
   113  		},
   114  		SubResourceCreate: func(ctx context.Context, c client.Client, subResourceName string, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error {
   115  			callback()
   116  			out := &client.SubResourceCreateOptions{}
   117  			for _, f := range opts {
   118  				f.ApplyToSubResourceCreate(out)
   119  			}
   120  			if got := out.FieldManager; expectedFieldManager != got {
   121  				t.Fatalf("wrong field manager: expected=%q; got=%q", expectedFieldManager, got)
   122  			}
   123  			return nil
   124  		},
   125  		SubResourceUpdate: func(ctx context.Context, c client.Client, subResourceName string, obj client.Object, opts ...client.SubResourceUpdateOption) error {
   126  			callback()
   127  			out := &client.SubResourceUpdateOptions{}
   128  			for _, f := range opts {
   129  				f.ApplyToSubResourceUpdate(out)
   130  			}
   131  			if got := out.FieldManager; expectedFieldManager != got {
   132  				t.Fatalf("wrong field manager: expected=%q; got=%q", expectedFieldManager, got)
   133  			}
   134  			return nil
   135  		},
   136  		SubResourcePatch: func(ctx context.Context, c client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
   137  			callback()
   138  			out := &client.SubResourcePatchOptions{}
   139  			for _, f := range opts {
   140  				f.ApplyToSubResourcePatch(out)
   141  			}
   142  			if got := out.FieldManager; expectedFieldManager != got {
   143  				t.Fatalf("wrong field manager: expected=%q; got=%q", expectedFieldManager, got)
   144  			}
   145  			return nil
   146  		},
   147  	}).Build()
   148  }
   149  

View as plain text