diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/embedded_test.go b/staging/src/k8s.io/apimachinery/pkg/runtime/embedded_test.go index 37a145253a..67995d8ce4 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/embedded_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/embedded_test.go @@ -197,8 +197,8 @@ func TestNestedObject(t *testing.T) { if externalViaJSON.Kind == "" || externalViaJSON.APIVersion == "" || externalViaJSON.ID != "outer" { t.Errorf("Expected objects to have type info set, got %#v", externalViaJSON) } - if !reflect.DeepEqual(externalViaJSON.EmptyObject.Raw, []byte("null")) || len(externalViaJSON.Object.Raw) == 0 { - t.Errorf("Expected deserialization of nested objects into bytes, got %#v", externalViaJSON) + if len(externalViaJSON.EmptyObject.Raw) > 0 { + t.Errorf("Expected deserialization of empty nested objects into empty bytes, got %#v", externalViaJSON) } // test JSON decoding, too, since Decode uses yaml unmarshalling. diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/extension.go b/staging/src/k8s.io/apimachinery/pkg/runtime/extension.go index 4d23ee9ee3..737e2e9ff5 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/extension.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/extension.go @@ -17,6 +17,7 @@ limitations under the License. package runtime import ( + "bytes" "encoding/json" "errors" ) @@ -25,7 +26,9 @@ func (re *RawExtension) UnmarshalJSON(in []byte) error { if re == nil { return errors.New("runtime.RawExtension: UnmarshalJSON on nil pointer") } - re.Raw = append(re.Raw[0:0], in...) + if !bytes.Equal(in, []byte("null")) { + re.Raw = append(re.Raw[0:0], in...) + } return nil } diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/extension_test.go b/staging/src/k8s.io/apimachinery/pkg/runtime/extension_test.go index 9523f3144f..5f9154ea6b 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/extension_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/extension_test.go @@ -17,7 +17,9 @@ limitations under the License. package runtime_test import ( + "bytes" "encoding/json" + "reflect" "testing" "k8s.io/apimachinery/pkg/runtime" @@ -37,3 +39,75 @@ func TestEmbeddedRawExtensionMarshal(t *testing.T) { t.Errorf("unexpected data: %s", string(data)) } } +func TestEmbeddedRawExtensionUnmarshal(t *testing.T) { + type test struct { + Ext runtime.RawExtension + } + + testCases := map[string]struct { + orig test + }{ + "non-empty object": { + orig: test{Ext: runtime.RawExtension{Raw: []byte(`{"foo":"bar"}`)}}, + }, + "empty object": { + orig: test{Ext: runtime.RawExtension{}}, + }, + } + + for k, tc := range testCases { + new := test{} + data, _ := json.Marshal(tc.orig) + if err := json.Unmarshal(data, &new); err != nil { + t.Errorf("%s: umarshal error: %v", k, err) + } + if !reflect.DeepEqual(tc.orig, new) { + t.Errorf("%s: unmarshaled struct differs from original: %v %v", k, tc.orig, new) + } + } +} + +func TestEmbeddedRawExtensionRoundTrip(t *testing.T) { + type test struct { + Ext runtime.RawExtension + } + + testCases := map[string]struct { + orig test + }{ + "non-empty object": { + orig: test{Ext: runtime.RawExtension{Raw: []byte(`{"foo":"bar"}`)}}, + }, + "empty object": { + orig: test{Ext: runtime.RawExtension{}}, + }, + } + + for k, tc := range testCases { + new1 := test{} + new2 := test{} + data, err := json.Marshal(tc.orig) + if err != nil { + t.Errorf("1st marshal error: %v", err) + } + if err = json.Unmarshal(data, &new1); err != nil { + t.Errorf("1st unmarshal error: %v", err) + } + newData, err := json.Marshal(new1) + if err != nil { + t.Errorf("2st marshal error: %v", err) + } + if err = json.Unmarshal(newData, &new2); err != nil { + t.Errorf("2nd unmarshal error: %v", err) + } + if !bytes.Equal(data, newData) { + t.Errorf("%s: re-marshaled data differs from original: %v %v", k, data, newData) + } + if !reflect.DeepEqual(tc.orig, new1) { + t.Errorf("%s: unmarshaled struct differs from original: %v %v", k, tc.orig, new1) + } + if !reflect.DeepEqual(new1, new2) { + t.Errorf("%s: re-unmarshaled struct differs from original: %v %v", k, new1, new2) + } + } +}