From d01788cd56629664afde8c1ad4f6ef8e9dcab658 Mon Sep 17 00:00:00 2001 From: Joe Betz Date: Fri, 19 Mar 2021 15:29:07 -0700 Subject: [PATCH] Enable extract test for status subresource --- .../pkg/util/managedfields/extract_test.go | 62 ++++++++++++----- test/integration/client/client_test.go | 67 ++++++++++--------- 2 files changed, 80 insertions(+), 49 deletions(-) diff --git a/staging/src/k8s.io/apimachinery/pkg/util/managedfields/extract_test.go b/staging/src/k8s.io/apimachinery/pkg/util/managedfields/extract_test.go index 0a9c019c789..f4244880893 100644 --- a/staging/src/k8s.io/apimachinery/pkg/util/managedfields/extract_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/util/managedfields/extract_test.go @@ -43,13 +43,14 @@ func TestExtractInto(t *testing.T) { managedFields []metav1.ManagedFieldsEntry // written to object before test is run fieldManager string expectedOut interface{} + subresource string }{ { name: "unstructured, no matching manager", obj: &unstructured.Unstructured{Object: map[string]interface{}{"spec": map[string]interface{}{"replicas": 1}}}, objType: parser.Type("io.k8s.api.apps.v1.Deployment"), managedFields: []metav1.ManagedFieldsEntry{ - applyFieldsEntry("mgr999", `{ "f:spec": { "f:replicas": {}}}`), + applyFieldsEntry("mgr999", `{ "f:spec": { "f:replicas": {}}}`, ""), }, fieldManager: "mgr1", expectedOut: map[string]interface{}{}, @@ -59,7 +60,7 @@ func TestExtractInto(t *testing.T) { obj: &unstructured.Unstructured{Object: map[string]interface{}{"spec": map[string]interface{}{"replicas": 1}}}, objType: parser.Type("io.k8s.api.apps.v1.Deployment"), managedFields: []metav1.ManagedFieldsEntry{ - applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`), + applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`, ""), }, fieldManager: "mgr1", expectedOut: map[string]interface{}{"spec": map[string]interface{}{"replicas": 1}}, @@ -69,8 +70,8 @@ func TestExtractInto(t *testing.T) { obj: &unstructured.Unstructured{Object: map[string]interface{}{"spec": map[string]interface{}{"paused": true}}}, objType: parser.Type("io.k8s.api.apps.v1.Deployment"), managedFields: []metav1.ManagedFieldsEntry{ - applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`), - applyFieldsEntry("mgr2", `{ "f:spec": { "f:paused": {}}}`), + applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`, ""), + applyFieldsEntry("mgr2", `{ "f:spec": { "f:paused": {}}}`, ""), }, fieldManager: "mgr2", expectedOut: map[string]interface{}{"spec": map[string]interface{}{"paused": true}}, @@ -80,7 +81,7 @@ func TestExtractInto(t *testing.T) { obj: &fakeDeployment{Spec: fakeDeploymentSpec{Replicas: &one}}, objType: parser.Type("io.k8s.api.apps.v1.Deployment"), managedFields: []metav1.ManagedFieldsEntry{ - applyFieldsEntry("mgr999", `{ "f:spec": { "f:replicas": {}}}`), + applyFieldsEntry("mgr999", `{ "f:spec": { "f:replicas": {}}}`, ""), }, fieldManager: "mgr1", expectedOut: map[string]interface{}{}, @@ -90,7 +91,7 @@ func TestExtractInto(t *testing.T) { obj: &fakeDeployment{Spec: fakeDeploymentSpec{Replicas: &one}}, objType: parser.Type("io.k8s.api.apps.v1.Deployment"), managedFields: []metav1.ManagedFieldsEntry{ - applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`), + applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`, ""), }, fieldManager: "mgr1", expectedOut: map[string]interface{}{"spec": map[string]interface{}{"replicas": int64(1)}}, @@ -100,12 +101,23 @@ func TestExtractInto(t *testing.T) { obj: &fakeDeployment{Spec: fakeDeploymentSpec{Replicas: &one, Paused: true}}, objType: parser.Type("io.k8s.api.apps.v1.Deployment"), managedFields: []metav1.ManagedFieldsEntry{ - applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`), - applyFieldsEntry("mgr2", `{ "f:spec": { "f:paused": {}}}`), + applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`, ""), + applyFieldsEntry("mgr2", `{ "f:spec": { "f:paused": {}}}`, ""), }, fieldManager: "mgr2", expectedOut: map[string]interface{}{"spec": map[string]interface{}{"paused": true}}, }, + { + name: "subresource", + obj: &fakeDeployment{Status: fakeDeploymentStatus{Replicas: &one}}, + objType: parser.Type("io.k8s.api.apps.v1.Deployment"), + managedFields: []metav1.ManagedFieldsEntry{ + applyFieldsEntry("mgr1", `{ "f:status": { "f:replicas": {}}}`, "status"), + }, + fieldManager: "mgr1", + expectedOut: map[string]interface{}{"status": map[string]interface{}{"replicas": int64(1)}}, + subresource: "status", + }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { @@ -115,7 +127,7 @@ func TestExtractInto(t *testing.T) { t.Fatalf("Error accessing object: %v", err) } accessor.SetManagedFields(tc.managedFields) - err = ExtractInto(tc.obj, tc.objType, tc.fieldManager, &out) + err = ExtractInto(tc.obj, tc.objType, tc.fieldManager, &out, tc.subresource) if err != nil { t.Fatalf("Unexpected extract error: %v", err) } @@ -126,19 +138,21 @@ func TestExtractInto(t *testing.T) { } } -func applyFieldsEntry(fieldManager string, fieldsJSON string) metav1.ManagedFieldsEntry { +func applyFieldsEntry(fieldManager string, fieldsJSON string, subresource string) metav1.ManagedFieldsEntry { return metav1.ManagedFieldsEntry{ - Manager: fieldManager, - Operation: metav1.ManagedFieldsOperationApply, - APIVersion: "v1", - FieldsType: "FieldsV1", - FieldsV1: &metav1.FieldsV1{Raw: []byte(fieldsJSON)}, + Manager: fieldManager, + Operation: metav1.ManagedFieldsOperationApply, + APIVersion: "v1", + FieldsType: "FieldsV1", + FieldsV1: &metav1.FieldsV1{Raw: []byte(fieldsJSON)}, + Subresource: subresource, } } type fakeDeployment struct { metav1.ObjectMeta `json:"metadata,omitempty"` - Spec fakeDeploymentSpec `json:"spec"` + Spec fakeDeploymentSpec `json:"spec"` + Status fakeDeploymentStatus `json:"status"` } type fakeDeploymentSpec struct { @@ -146,6 +160,10 @@ type fakeDeploymentSpec struct { Paused bool `json:"paused,omitempty"` } +type fakeDeploymentStatus struct { + Replicas *int32 `json:"replicas"` +} + func (o *fakeDeployment) GetObjectMeta() metav1.ObjectMeta { return o.ObjectMeta } @@ -173,6 +191,9 @@ const schemaYAML = typed.YAMLObject(`types: - name: spec type: namedType: io.k8s.api.apps.v1.DeploymentSpec + - name: status + type: + namedType: io.k8s.api.apps.v1.DeploymentStatus - name: io.k8s.api.apps.v1.DeploymentSpec map: fields: @@ -182,6 +203,12 @@ const schemaYAML = typed.YAMLObject(`types: - name: replicas type: scalar: numeric +- name: io.k8s.api.apps.v1.DeploymentStatus + map: + fields: + - name: replicas + type: + scalar: numeric - name: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta map: fields: @@ -215,6 +242,9 @@ const schemaYAML = typed.YAMLObject(`types: - name: time type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + - name: subresource + type: + scalar: string - name: io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1 map: elementType: diff --git a/test/integration/client/client_test.go b/test/integration/client/client_test.go index 8efbce5b3bc..8b53a6a859c 100644 --- a/test/integration/client/client_test.go +++ b/test/integration/client/client_test.go @@ -969,32 +969,31 @@ func TestExtractModifyApply(t *testing.T) { } }, }, - // TODO: We probably need "ExtractStatus" (or a variadic argument to "Extract"). - // { - // // Append a condition to the status if the object - // name: "modify-status-conditions", - // modifyStatusFunc: func(apply *appsv1ac.DeploymentApplyConfiguration) { - // apply.WithStatus(appsv1ac.DeploymentStatus(). - // WithConditions(appsv1ac.DeploymentCondition(). - // WithType(appsv1.DeploymentProgressing). - // WithStatus(v1.ConditionUnknown). - // WithLastTransitionTime(metav1.Now()). - // WithLastUpdateTime(metav1.Now()). - // WithMessage("progressing"). - // WithReason("TestExtractModifyApply_Status"), - // ), - // ) - // }, - // verifyStatusAppliedFunc: func(applied *appsv1ac.DeploymentApplyConfiguration) { - // conditions := applied.Status.Conditions - // if len(conditions) != 1 { - // t.Errorf("Expected 1 conditions but got %d", len(conditions)) - // } - // if *conditions[0].Type != appsv1.DeploymentProgressing { - // t.Errorf("Expected condition name DeploymentProgressing but got: %s", *conditions[0].Type) - // } - // }, - // }, + { + // Append a condition to the status if the object + name: "modify-status-conditions", + modifyStatusFunc: func(apply *appsv1ac.DeploymentApplyConfiguration) { + apply.WithStatus(appsv1ac.DeploymentStatus(). + WithConditions(appsv1ac.DeploymentCondition(). + WithType(appsv1.DeploymentProgressing). + WithStatus(v1.ConditionUnknown). + WithLastTransitionTime(metav1.Now()). + WithLastUpdateTime(metav1.Now()). + WithMessage("progressing"). + WithReason("TestExtractModifyApply_Status"), + ), + ) + }, + verifyStatusAppliedFunc: func(applied *appsv1ac.DeploymentApplyConfiguration) { + conditions := applied.Status.Conditions + if len(conditions) != 1 { + t.Errorf("Expected 1 conditions but got %d", len(conditions)) + } + if *conditions[0].Type != appsv1.DeploymentProgressing { + t.Errorf("Expected condition name DeploymentProgressing but got: %s", *conditions[0].Type) + } + }, + }, } testServer := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins", "ServiceAccount"}, framework.SharedEtcd()) @@ -1027,13 +1026,11 @@ func TestExtractModifyApply(t *testing.T) { if err != nil { t.Fatalf("Failed to apply: %v", err) } - - extractedDeployment, err := appsv1ac.ExtractDeployment(actual, fieldMgr) - if err != nil { - t.Fatalf("Failed to extract: %v", err) - } - if tc.modifyFunc != nil { + extractedDeployment, err := appsv1ac.ExtractDeployment(actual, fieldMgr) + if err != nil { + t.Fatalf("Failed to extract: %v", err) + } tc.modifyFunc(extractedDeployment) result, err := deploymentClient.Apply(context.TODO(), extractedDeployment, metav1.ApplyOptions{FieldManager: fieldMgr}) if err != nil { @@ -1049,12 +1046,16 @@ func TestExtractModifyApply(t *testing.T) { } if tc.modifyStatusFunc != nil { + extractedDeployment, err := appsv1ac.ExtractDeploymentStatus(actual, fieldMgr) + if err != nil { + t.Fatalf("Failed to extract: %v", err) + } tc.modifyStatusFunc(extractedDeployment) result, err := deploymentClient.ApplyStatus(context.TODO(), extractedDeployment, metav1.ApplyOptions{FieldManager: fieldMgr}) if err != nil { t.Fatalf("Failed to apply extracted apply configuration to status: %v", err) } - extractedResult, err := appsv1ac.ExtractDeployment(result, fieldMgr) + extractedResult, err := appsv1ac.ExtractDeploymentStatus(result, fieldMgr) if err != nil { t.Fatalf("Failed to extract: %v", err) }