Enable extract test for status subresource

This commit is contained in:
Joe Betz 2021-03-19 15:29:07 -07:00
parent a24e8acc32
commit d01788cd56
2 changed files with 80 additions and 49 deletions

View File

@ -43,13 +43,14 @@ func TestExtractInto(t *testing.T) {
managedFields []metav1.ManagedFieldsEntry // written to object before test is run managedFields []metav1.ManagedFieldsEntry // written to object before test is run
fieldManager string fieldManager string
expectedOut interface{} expectedOut interface{}
subresource string
}{ }{
{ {
name: "unstructured, no matching manager", name: "unstructured, no matching manager",
obj: &unstructured.Unstructured{Object: map[string]interface{}{"spec": map[string]interface{}{"replicas": 1}}}, obj: &unstructured.Unstructured{Object: map[string]interface{}{"spec": map[string]interface{}{"replicas": 1}}},
objType: parser.Type("io.k8s.api.apps.v1.Deployment"), objType: parser.Type("io.k8s.api.apps.v1.Deployment"),
managedFields: []metav1.ManagedFieldsEntry{ managedFields: []metav1.ManagedFieldsEntry{
applyFieldsEntry("mgr999", `{ "f:spec": { "f:replicas": {}}}`), applyFieldsEntry("mgr999", `{ "f:spec": { "f:replicas": {}}}`, ""),
}, },
fieldManager: "mgr1", fieldManager: "mgr1",
expectedOut: map[string]interface{}{}, 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}}}, obj: &unstructured.Unstructured{Object: map[string]interface{}{"spec": map[string]interface{}{"replicas": 1}}},
objType: parser.Type("io.k8s.api.apps.v1.Deployment"), objType: parser.Type("io.k8s.api.apps.v1.Deployment"),
managedFields: []metav1.ManagedFieldsEntry{ managedFields: []metav1.ManagedFieldsEntry{
applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`), applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`, ""),
}, },
fieldManager: "mgr1", fieldManager: "mgr1",
expectedOut: map[string]interface{}{"spec": map[string]interface{}{"replicas": 1}}, 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}}}, obj: &unstructured.Unstructured{Object: map[string]interface{}{"spec": map[string]interface{}{"paused": true}}},
objType: parser.Type("io.k8s.api.apps.v1.Deployment"), objType: parser.Type("io.k8s.api.apps.v1.Deployment"),
managedFields: []metav1.ManagedFieldsEntry{ managedFields: []metav1.ManagedFieldsEntry{
applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`), applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`, ""),
applyFieldsEntry("mgr2", `{ "f:spec": { "f:paused": {}}}`), applyFieldsEntry("mgr2", `{ "f:spec": { "f:paused": {}}}`, ""),
}, },
fieldManager: "mgr2", fieldManager: "mgr2",
expectedOut: map[string]interface{}{"spec": map[string]interface{}{"paused": true}}, 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}}, obj: &fakeDeployment{Spec: fakeDeploymentSpec{Replicas: &one}},
objType: parser.Type("io.k8s.api.apps.v1.Deployment"), objType: parser.Type("io.k8s.api.apps.v1.Deployment"),
managedFields: []metav1.ManagedFieldsEntry{ managedFields: []metav1.ManagedFieldsEntry{
applyFieldsEntry("mgr999", `{ "f:spec": { "f:replicas": {}}}`), applyFieldsEntry("mgr999", `{ "f:spec": { "f:replicas": {}}}`, ""),
}, },
fieldManager: "mgr1", fieldManager: "mgr1",
expectedOut: map[string]interface{}{}, expectedOut: map[string]interface{}{},
@ -90,7 +91,7 @@ func TestExtractInto(t *testing.T) {
obj: &fakeDeployment{Spec: fakeDeploymentSpec{Replicas: &one}}, obj: &fakeDeployment{Spec: fakeDeploymentSpec{Replicas: &one}},
objType: parser.Type("io.k8s.api.apps.v1.Deployment"), objType: parser.Type("io.k8s.api.apps.v1.Deployment"),
managedFields: []metav1.ManagedFieldsEntry{ managedFields: []metav1.ManagedFieldsEntry{
applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`), applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`, ""),
}, },
fieldManager: "mgr1", fieldManager: "mgr1",
expectedOut: map[string]interface{}{"spec": map[string]interface{}{"replicas": int64(1)}}, 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}}, obj: &fakeDeployment{Spec: fakeDeploymentSpec{Replicas: &one, Paused: true}},
objType: parser.Type("io.k8s.api.apps.v1.Deployment"), objType: parser.Type("io.k8s.api.apps.v1.Deployment"),
managedFields: []metav1.ManagedFieldsEntry{ managedFields: []metav1.ManagedFieldsEntry{
applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`), applyFieldsEntry("mgr1", `{ "f:spec": { "f:replicas": {}}}`, ""),
applyFieldsEntry("mgr2", `{ "f:spec": { "f:paused": {}}}`), applyFieldsEntry("mgr2", `{ "f:spec": { "f:paused": {}}}`, ""),
}, },
fieldManager: "mgr2", fieldManager: "mgr2",
expectedOut: map[string]interface{}{"spec": map[string]interface{}{"paused": true}}, 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 { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
@ -115,7 +127,7 @@ func TestExtractInto(t *testing.T) {
t.Fatalf("Error accessing object: %v", err) t.Fatalf("Error accessing object: %v", err)
} }
accessor.SetManagedFields(tc.managedFields) 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 { if err != nil {
t.Fatalf("Unexpected extract error: %v", err) 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{ return metav1.ManagedFieldsEntry{
Manager: fieldManager, Manager: fieldManager,
Operation: metav1.ManagedFieldsOperationApply, Operation: metav1.ManagedFieldsOperationApply,
APIVersion: "v1", APIVersion: "v1",
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
FieldsV1: &metav1.FieldsV1{Raw: []byte(fieldsJSON)}, FieldsV1: &metav1.FieldsV1{Raw: []byte(fieldsJSON)},
Subresource: subresource,
} }
} }
type fakeDeployment struct { type fakeDeployment struct {
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
Spec fakeDeploymentSpec `json:"spec"` Spec fakeDeploymentSpec `json:"spec"`
Status fakeDeploymentStatus `json:"status"`
} }
type fakeDeploymentSpec struct { type fakeDeploymentSpec struct {
@ -146,6 +160,10 @@ type fakeDeploymentSpec struct {
Paused bool `json:"paused,omitempty"` Paused bool `json:"paused,omitempty"`
} }
type fakeDeploymentStatus struct {
Replicas *int32 `json:"replicas"`
}
func (o *fakeDeployment) GetObjectMeta() metav1.ObjectMeta { func (o *fakeDeployment) GetObjectMeta() metav1.ObjectMeta {
return o.ObjectMeta return o.ObjectMeta
} }
@ -173,6 +191,9 @@ const schemaYAML = typed.YAMLObject(`types:
- name: spec - name: spec
type: type:
namedType: io.k8s.api.apps.v1.DeploymentSpec namedType: io.k8s.api.apps.v1.DeploymentSpec
- name: status
type:
namedType: io.k8s.api.apps.v1.DeploymentStatus
- name: io.k8s.api.apps.v1.DeploymentSpec - name: io.k8s.api.apps.v1.DeploymentSpec
map: map:
fields: fields:
@ -182,6 +203,12 @@ const schemaYAML = typed.YAMLObject(`types:
- name: replicas - name: replicas
type: type:
scalar: numeric 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 - name: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta
map: map:
fields: fields:
@ -215,6 +242,9 @@ const schemaYAML = typed.YAMLObject(`types:
- name: time - name: time
type: type:
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time
- name: subresource
type:
scalar: string
- name: io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1 - name: io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1
map: map:
elementType: elementType:

View File

@ -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
// // Append a condition to the status if the object name: "modify-status-conditions",
// name: "modify-status-conditions", modifyStatusFunc: func(apply *appsv1ac.DeploymentApplyConfiguration) {
// modifyStatusFunc: func(apply *appsv1ac.DeploymentApplyConfiguration) { apply.WithStatus(appsv1ac.DeploymentStatus().
// apply.WithStatus(appsv1ac.DeploymentStatus(). WithConditions(appsv1ac.DeploymentCondition().
// WithConditions(appsv1ac.DeploymentCondition(). WithType(appsv1.DeploymentProgressing).
// WithType(appsv1.DeploymentProgressing). WithStatus(v1.ConditionUnknown).
// WithStatus(v1.ConditionUnknown). WithLastTransitionTime(metav1.Now()).
// WithLastTransitionTime(metav1.Now()). WithLastUpdateTime(metav1.Now()).
// WithLastUpdateTime(metav1.Now()). WithMessage("progressing").
// WithMessage("progressing"). WithReason("TestExtractModifyApply_Status"),
// WithReason("TestExtractModifyApply_Status"), ),
// ), )
// ) },
// }, verifyStatusAppliedFunc: func(applied *appsv1ac.DeploymentApplyConfiguration) {
// verifyStatusAppliedFunc: func(applied *appsv1ac.DeploymentApplyConfiguration) { conditions := applied.Status.Conditions
// conditions := applied.Status.Conditions if len(conditions) != 1 {
// if len(conditions) != 1 { t.Errorf("Expected 1 conditions but got %d", len(conditions))
// t.Errorf("Expected 1 conditions but got %d", len(conditions)) }
// } if *conditions[0].Type != appsv1.DeploymentProgressing {
// if *conditions[0].Type != appsv1.DeploymentProgressing { t.Errorf("Expected condition name DeploymentProgressing but got: %s", *conditions[0].Type)
// t.Errorf("Expected condition name DeploymentProgressing but got: %s", *conditions[0].Type) }
// } },
// }, },
// },
} }
testServer := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins", "ServiceAccount"}, framework.SharedEtcd()) testServer := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins", "ServiceAccount"}, framework.SharedEtcd())
@ -1027,13 +1026,11 @@ func TestExtractModifyApply(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Failed to apply: %v", err) t.Fatalf("Failed to apply: %v", err)
} }
if tc.modifyFunc != nil {
extractedDeployment, err := appsv1ac.ExtractDeployment(actual, fieldMgr) extractedDeployment, err := appsv1ac.ExtractDeployment(actual, fieldMgr)
if err != nil { if err != nil {
t.Fatalf("Failed to extract: %v", err) t.Fatalf("Failed to extract: %v", err)
} }
if tc.modifyFunc != nil {
tc.modifyFunc(extractedDeployment) tc.modifyFunc(extractedDeployment)
result, err := deploymentClient.Apply(context.TODO(), extractedDeployment, metav1.ApplyOptions{FieldManager: fieldMgr}) result, err := deploymentClient.Apply(context.TODO(), extractedDeployment, metav1.ApplyOptions{FieldManager: fieldMgr})
if err != nil { if err != nil {
@ -1049,12 +1046,16 @@ func TestExtractModifyApply(t *testing.T) {
} }
if tc.modifyStatusFunc != nil { if tc.modifyStatusFunc != nil {
extractedDeployment, err := appsv1ac.ExtractDeploymentStatus(actual, fieldMgr)
if err != nil {
t.Fatalf("Failed to extract: %v", err)
}
tc.modifyStatusFunc(extractedDeployment) tc.modifyStatusFunc(extractedDeployment)
result, err := deploymentClient.ApplyStatus(context.TODO(), extractedDeployment, metav1.ApplyOptions{FieldManager: fieldMgr}) result, err := deploymentClient.ApplyStatus(context.TODO(), extractedDeployment, metav1.ApplyOptions{FieldManager: fieldMgr})
if err != nil { if err != nil {
t.Fatalf("Failed to apply extracted apply configuration to status: %v", err) 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 { if err != nil {
t.Fatalf("Failed to extract: %v", err) t.Fatalf("Failed to extract: %v", err)
} }