github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/runtime/embedded_test.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package runtime_test
    18  
    19  import (
    20  	"encoding/json"
    21  	"reflect"
    22  	"testing"
    23  
    24  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/api/meta"
    25  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime"
    26  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/schema"
    27  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/serializer"
    28  	runtimetesting "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/testing"
    29  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/diff"
    30  	utilruntime "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/runtime"
    31  )
    32  
    33  func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
    34  	internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
    35  	externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
    36  	externalGVK := externalGV.WithKind("ObjectTest")
    37  
    38  	s := runtime.NewScheme()
    39  	s.AddKnownTypes(internalGV, &runtimetesting.ObjectTest{})
    40  	s.AddKnownTypeWithName(externalGVK, &runtimetesting.ObjectTestExternal{})
    41  	utilruntime.Must(runtimetesting.RegisterConversions(s))
    42  
    43  	codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
    44  
    45  	obj, gvk, err := codec.Decode([]byte(`{"kind":"`+externalGVK.Kind+`","apiVersion":"`+externalGV.String()+`","items":[{}]}`), nil, nil)
    46  	if err != nil {
    47  		t.Fatalf("unexpected error: %v", err)
    48  	}
    49  	test := obj.(*runtimetesting.ObjectTest)
    50  	if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != "{}" || unk.ContentType != runtime.ContentTypeJSON {
    51  		t.Fatalf("unexpected object: %#v", test.Items[0])
    52  	}
    53  	if *gvk != externalGVK {
    54  		t.Fatalf("unexpected kind: %#v", gvk)
    55  	}
    56  
    57  	obj, gvk, err = codec.Decode([]byte(`{"kind":"`+externalGVK.Kind+`","apiVersion":"`+externalGV.String()+`","items":[{"kind":"Other","apiVersion":"v1"}]}`), nil, nil)
    58  	if err != nil {
    59  		t.Fatalf("unexpected error: %v", err)
    60  	}
    61  	test = obj.(*runtimetesting.ObjectTest)
    62  	if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != `{"kind":"Other","apiVersion":"v1"}` || unk.ContentType != runtime.ContentTypeJSON {
    63  		t.Fatalf("unexpected object: %#v", test.Items[0])
    64  	}
    65  	if *gvk != externalGVK {
    66  		t.Fatalf("unexpected kind: %#v", gvk)
    67  	}
    68  }
    69  
    70  func TestArrayOfRuntimeObject(t *testing.T) {
    71  	internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
    72  	externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
    73  
    74  	s := runtime.NewScheme()
    75  	s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
    76  	s.AddKnownTypeWithName(externalGV.WithKind("EmbeddedTest"), &runtimetesting.EmbeddedTestExternal{})
    77  	s.AddKnownTypes(internalGV, &runtimetesting.ObjectTest{})
    78  	s.AddKnownTypeWithName(externalGV.WithKind("ObjectTest"), &runtimetesting.ObjectTestExternal{})
    79  	utilruntime.Must(runtimetesting.RegisterConversions(s))
    80  
    81  	codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
    82  
    83  	innerItems := []runtime.Object{
    84  		&runtimetesting.EmbeddedTest{ID: "baz"},
    85  	}
    86  	items := []runtime.Object{
    87  		&runtimetesting.EmbeddedTest{ID: "foo"},
    88  		&runtimetesting.EmbeddedTest{ID: "bar"},
    89  		// TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization
    90  		&runtime.Unknown{
    91  			Raw:         []byte(`{"apiVersion":"unknown.group/unknown","foo":"bar","kind":"OtherTest"}`),
    92  			ContentType: runtime.ContentTypeJSON,
    93  		},
    94  		&runtimetesting.ObjectTest{
    95  			Items: runtime.NewEncodableList(codec, innerItems),
    96  		},
    97  	}
    98  	internal := &runtimetesting.ObjectTest{
    99  		Items: runtime.NewEncodableList(codec, items),
   100  	}
   101  	wire, err := runtime.Encode(codec, internal)
   102  	if err != nil {
   103  		t.Fatalf("unexpected error: %v", err)
   104  	}
   105  	t.Logf("Wire format is:\n%s\n", string(wire))
   106  
   107  	obj := &runtimetesting.ObjectTestExternal{}
   108  	if err := json.Unmarshal(wire, obj); err != nil {
   109  		t.Fatalf("unexpected error: %v", err)
   110  	}
   111  	t.Logf("exact wire is: %s", string(obj.Items[0].Raw))
   112  
   113  	items[3] = &runtimetesting.ObjectTest{Items: innerItems}
   114  	internal.Items = items
   115  
   116  	decoded, err := runtime.Decode(codec, wire)
   117  	if err != nil {
   118  		t.Fatalf("unexpected error: %v", err)
   119  	}
   120  	list, err := meta.ExtractList(decoded)
   121  	if err != nil {
   122  		t.Fatalf("unexpected error: %v", err)
   123  	}
   124  	if errs := runtime.DecodeList(list, codec); len(errs) > 0 {
   125  		t.Fatalf("unexpected error: %v", errs)
   126  	}
   127  
   128  	list2, err := meta.ExtractList(list[3])
   129  	if err != nil {
   130  		t.Fatalf("unexpected error: %v", err)
   131  	}
   132  	if errs := runtime.DecodeList(list2, codec); len(errs) > 0 {
   133  		t.Fatalf("unexpected error: %v", errs)
   134  	}
   135  	if err := meta.SetList(list[3], list2); err != nil {
   136  		t.Fatalf("unexpected error: %v", err)
   137  	}
   138  
   139  	// we want DecodeList to set type meta if possible, even on runtime.Unknown objects
   140  	internal.Items[2].(*runtime.Unknown).TypeMeta = runtime.TypeMeta{Kind: "OtherTest", APIVersion: "unknown.group/unknown"}
   141  	if e, a := internal.Items, list; !reflect.DeepEqual(e, a) {
   142  		t.Errorf("mismatched decoded: %s", diff.ObjectGoPrintSideBySide(e, a))
   143  	}
   144  }
   145  
   146  func TestNestedObject(t *testing.T) {
   147  	internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
   148  	externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
   149  	embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
   150  
   151  	s := runtime.NewScheme()
   152  	s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
   153  	s.AddKnownTypeWithName(embeddedTestExternalGVK, &runtimetesting.EmbeddedTestExternal{})
   154  	utilruntime.Must(runtimetesting.RegisterConversions(s))
   155  
   156  	codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
   157  
   158  	inner := &runtimetesting.EmbeddedTest{
   159  		ID: "inner",
   160  	}
   161  	outer := &runtimetesting.EmbeddedTest{
   162  		ID:     "outer",
   163  		Object: runtime.NewEncodable(codec, inner),
   164  	}
   165  
   166  	wire, err := runtime.Encode(codec, outer)
   167  	if err != nil {
   168  		t.Fatalf("Unexpected encode error '%v'", err)
   169  	}
   170  
   171  	t.Logf("Wire format is:\n%v\n", string(wire))
   172  
   173  	decoded, err := runtime.Decode(codec, wire)
   174  	if err != nil {
   175  		t.Fatalf("Unexpected decode error %v", err)
   176  	}
   177  
   178  	// for later tests
   179  	outer.Object = inner
   180  
   181  	if e, a := outer, decoded; reflect.DeepEqual(e, a) {
   182  		t.Errorf("Expected unequal %#v %#v", e, a)
   183  	}
   184  
   185  	obj, err := runtime.Decode(codec, decoded.(*runtimetesting.EmbeddedTest).Object.(*runtime.Unknown).Raw)
   186  	if err != nil {
   187  		t.Fatal(err)
   188  	}
   189  	decoded.(*runtimetesting.EmbeddedTest).Object = obj
   190  	if e, a := outer, decoded; !reflect.DeepEqual(e, a) {
   191  		t.Errorf("Expected equal %#v %#v", e, a)
   192  	}
   193  
   194  	// test JSON decoding of the external object, which should preserve
   195  	// raw bytes
   196  	var externalViaJSON runtimetesting.EmbeddedTestExternal
   197  	err = json.Unmarshal(wire, &externalViaJSON)
   198  	if err != nil {
   199  		t.Fatalf("Unexpected decode error %v", err)
   200  	}
   201  	if externalViaJSON.Kind == "" || externalViaJSON.APIVersion == "" || externalViaJSON.ID != "outer" {
   202  		t.Errorf("Expected objects to have type info set, got %#v", externalViaJSON)
   203  	}
   204  	if len(externalViaJSON.EmptyObject.Raw) > 0 {
   205  		t.Errorf("Expected deserialization of empty nested objects into empty bytes, got %#v", externalViaJSON)
   206  	}
   207  
   208  	// test JSON decoding, too, since Decode uses yaml unmarshalling.
   209  	// Generic Unmarshalling of JSON cannot load the nested objects because there is
   210  	// no default schema set.  Consumers wishing to get direct JSON decoding must use
   211  	// the external representation
   212  	var decodedViaJSON runtimetesting.EmbeddedTest
   213  	err = json.Unmarshal(wire, &decodedViaJSON)
   214  	if err == nil {
   215  		t.Fatal("Expeceted decode error")
   216  	}
   217  	if _, ok := err.(*json.UnmarshalTypeError); !ok {
   218  		t.Fatalf("Unexpected decode error: %v", err)
   219  	}
   220  	if a := decodedViaJSON; a.Object != nil || a.EmptyObject != nil {
   221  		t.Errorf("Expected embedded objects to be nil: %#v", a)
   222  	}
   223  }
   224  
   225  // TestDeepCopyOfRuntimeObject checks to make sure that runtime.Objects's can be passed through DeepCopy with fidelity
   226  func TestDeepCopyOfRuntimeObject(t *testing.T) {
   227  	internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
   228  	externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
   229  	embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
   230  
   231  	s := runtime.NewScheme()
   232  	s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
   233  	s.AddKnownTypeWithName(embeddedTestExternalGVK, &runtimetesting.EmbeddedTestExternal{})
   234  	utilruntime.Must(runtimetesting.RegisterConversions(s))
   235  
   236  	original := &runtimetesting.EmbeddedTest{
   237  		ID: "outer",
   238  		Object: &runtimetesting.EmbeddedTest{
   239  			ID: "inner",
   240  		},
   241  	}
   242  
   243  	codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
   244  
   245  	originalData, err := runtime.Encode(codec, original)
   246  	if err != nil {
   247  		t.Errorf("unexpected error: %v", err)
   248  	}
   249  	t.Logf("originalRole = %v\n", string(originalData))
   250  
   251  	copyOfOriginal := original.DeepCopy()
   252  	copiedData, err := runtime.Encode(codec, copyOfOriginal)
   253  	if err != nil {
   254  		t.Errorf("unexpected error: %v", err)
   255  	}
   256  	t.Logf("copyOfRole   = %v\n", string(copiedData))
   257  
   258  	if !reflect.DeepEqual(original, copyOfOriginal) {
   259  		t.Errorf("expected \n%v\n, got \n%v", string(originalData), string(copiedData))
   260  	}
   261  }