diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go b/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go index b10fe4858bf..f6f7c10de62 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go @@ -411,7 +411,8 @@ func (c *unstructuredConverter) ToUnstructured(obj interface{}) (map[string]inte var u map[string]interface{} var err error if unstr, ok := obj.(Unstructured); ok { - u = DeepCopyJSON(unstr.UnstructuredContent()) + // UnstructuredContent() mutates the object so we need to make a copy first + u = unstr.DeepCopyObject().(Unstructured).UnstructuredContent() } else { t := reflect.TypeOf(obj) value := reflect.ValueOf(obj) diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/converter_test.go b/staging/src/k8s.io/apimachinery/pkg/runtime/converter_test.go index 1e9515102cf..7820b8cefd8 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/converter_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/converter_test.go @@ -135,7 +135,7 @@ func doRoundTrip(t *testing.T, item interface{}) { return } unmarshalledObj := reflect.New(reflect.TypeOf(item).Elem()).Interface() - err = json.Unmarshal(data, &unmarshalledObj) + err = json.Unmarshal(data, unmarshalledObj) if err != nil { t.Errorf("Error when unmarshaling to object: %v", err) return @@ -169,6 +169,38 @@ func TestRoundTrip(t *testing.T) { testCases := []struct { obj interface{} }{ + { + obj: &unstructured.UnstructuredList{ + Object: map[string]interface{}{ + "kind": "List", + }, + // Not testing a list with nil Items because items is a non-optional field and hence + // is always marshaled into an empty array which is not equal to nil when unmarshalled and will fail. + // That is expected. + Items: []unstructured.Unstructured{}, + }, + }, + { + obj: &unstructured.UnstructuredList{ + Object: map[string]interface{}{ + "kind": "List", + }, + Items: []unstructured.Unstructured{ + { + Object: map[string]interface{}{ + "kind": "Pod", + }, + }, + }, + }, + }, + { + obj: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "Pod", + }, + }, + }, { obj: &unstructured.Unstructured{ Object: map[string]interface{}{ @@ -260,7 +292,7 @@ func TestRoundTrip(t *testing.T) { // produces the same object. func doUnrecognized(t *testing.T, jsonData string, item interface{}, expectedErr error) { unmarshalledObj := reflect.New(reflect.TypeOf(item).Elem()).Interface() - err := json.Unmarshal([]byte(jsonData), &unmarshalledObj) + err := json.Unmarshal([]byte(jsonData), unmarshalledObj) if (err != nil) != (expectedErr != nil) { t.Errorf("Unexpected error when unmarshaling to object: %v, expected: %v", err, expectedErr) return @@ -465,11 +497,10 @@ func TestUnrecognized(t *testing.T) { }, } - for i := range testCases { - doUnrecognized(t, testCases[i].data, testCases[i].obj, testCases[i].err) - if t.Failed() { - break - } + for _, tc := range testCases { + t.Run(tc.data, func(t *testing.T) { + doUnrecognized(t, tc.data, tc.obj, tc.err) + }) } } diff --git a/test/e2e/apimachinery/garbage_collector.go b/test/e2e/apimachinery/garbage_collector.go index 25960cdb3ad..e52ca37348b 100644 --- a/test/e2e/apimachinery/garbage_collector.go +++ b/test/e2e/apimachinery/garbage_collector.go @@ -919,8 +919,8 @@ var _ = SIGDescribe("Garbage collector", func() { "kind": definition.Spec.Names.Kind, "metadata": map[string]interface{}{ "name": dependentName, - "ownerReferences": []map[string]string{ - { + "ownerReferences": []interface{}{ + map[string]interface{}{ "uid": string(persistedOwner.GetUID()), "apiVersion": apiVersion, "kind": definition.Spec.Names.Kind,