From 89a68be3a93fbbfdf1ba37d364fae080fb543c6d Mon Sep 17 00:00:00 2001 From: Joe Betz Date: Tue, 4 Jun 2024 11:41:46 -0400 Subject: [PATCH] Add integration test for a nop apply with an empty map --- .../integration/apiserver/apply/apply_test.go | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/test/integration/apiserver/apply/apply_test.go b/test/integration/apiserver/apply/apply_test.go index 735498b2fcf..a61c11db8ab 100644 --- a/test/integration/apiserver/apply/apply_test.go +++ b/test/integration/apiserver/apply/apply_test.go @@ -244,6 +244,117 @@ func TestNoOpUpdateSameResourceVersion(t *testing.T) { } } +// TestNoOpApplyWithEmptyMap +func TestNoOpApplyWithEmptyMap(t *testing.T) { + client, closeFn := setup(t) + defer closeFn() + + deploymentName := "no-op" + deploymentsResource := "deployments" + deploymentBytes := []byte(`{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "` + deploymentName + `", + "labels": { + "app": "nginx" + } + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "nginx" + } + }, + "template": { + "metadata": { + "annotations": {}, + "labels": { + "app": "nginx" + } + }, + "spec": { + "containers": [{ + "name": "nginx", + "image": "nginx:1.14.2", + "ports": [{ + "containerPort": 80 + }] + }] + } + } + } + }`) + + _, err := client.AppsV1().RESTClient().Patch(types.ApplyPatchType). + Namespace("default"). + Param("fieldManager", "apply_test"). + Resource(deploymentsResource). + Name(deploymentName). + Body(deploymentBytes). + Do(context.TODO()). + Get() + if err != nil { + t.Fatalf("Failed to create object: %v", err) + } + + // Sleep for one second to make sure that the times of each update operation is different. + time.Sleep(1 * time.Second) + + createdObject, err := client.AppsV1().RESTClient().Get().Namespace("default").Resource(deploymentsResource).Name(deploymentName).Do(context.TODO()).Get() + if err != nil { + t.Fatalf("Failed to retrieve created object: %v", err) + } + + createdAccessor, err := meta.Accessor(createdObject) + if err != nil { + t.Fatalf("Failed to get meta accessor for created object: %v", err) + } + + createdBytes, err := json.MarshalIndent(createdObject, "\t", "\t") + if err != nil { + t.Fatalf("Failed to marshal created object: %v", err) + } + + // Test that we can apply the same object and don't change the RV + _, err = client.AppsV1().RESTClient().Patch(types.ApplyPatchType). + Namespace("default"). + Param("fieldManager", "apply_test"). + Resource(deploymentsResource). + Name(deploymentName). + Body(deploymentBytes). + Do(context.TODO()). + Get() + if err != nil { + t.Fatalf("Failed to create object: %v", err) + } + + updatedObject, err := client.AppsV1().RESTClient().Get().Namespace("default").Resource(deploymentsResource).Name(deploymentName).Do(context.TODO()).Get() + if err != nil { + t.Fatalf("Failed to retrieve updated object: %v", err) + } + + updatedAccessor, err := meta.Accessor(updatedObject) + if err != nil { + t.Fatalf("Failed to get meta accessor for updated object: %v", err) + } + + updatedBytes, err := json.MarshalIndent(updatedObject, "\t", "\t") + if err != nil { + t.Fatalf("Failed to marshal updated object: %v", err) + } + + if createdAccessor.GetResourceVersion() != updatedAccessor.GetResourceVersion() { + t.Fatalf("Expected same resource version to be %v but got: %v\nold object:\n%v\nnew object:\n%v", + createdAccessor.GetResourceVersion(), + updatedAccessor.GetResourceVersion(), + string(createdBytes), + string(updatedBytes), + ) + } +} + func getRV(obj runtime.Object) (string, error) { acc, err := meta.Accessor(obj) if err != nil {