func (o objects) Add(obj runtime.Object) error { gvk, err := o.scheme.ObjectKind(obj) if err != nil { return err } kind := gvk.Kind switch { case meta.IsListType(obj): if kind != "List" { o.types[kind] = append(o.types[kind], obj) } list, err := meta.ExtractList(obj) if err != nil { return err } if errs := runtime.DecodeList(list, o.decoder); len(errs) > 0 { return errs[0] } for _, obj := range list { if err := o.Add(obj); err != nil { return err } } default: if status, ok := obj.(*unversioned.Status); ok && status.Details != nil { kind = status.Details.Kind } o.types[kind] = append(o.types[kind], obj) } return nil }
func TestDecodeList(t *testing.T) { pl := &api.List{ Items: []runtime.Object{ &api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}}, &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: testapi.Default.GroupVersion().String()}, RawJSON: []byte(`{"kind":"Pod","apiVersion":"` + testapi.Default.GroupVersion().String() + `","metadata":{"name":"test"}}`)}, &runtime.Unstructured{TypeMeta: runtime.TypeMeta{Kind: "Foo", APIVersion: "Bar"}, Object: map[string]interface{}{"test": "value"}}, }, } if errs := runtime.DecodeList(pl.Items, testapi.Default.Codec()); len(errs) != 0 { t.Fatalf("unexpected error %v", errs) } if pod, ok := pl.Items[1].(*api.Pod); !ok || pod.Name != "test" { t.Errorf("object not converted: %#v", pl.Items[1]) } }
func TestDecodeUnstructured(t *testing.T) { groupVersionString := testapi.Default.GroupVersion().String() rawJson := fmt.Sprintf(`{"kind":"Pod","apiVersion":"%s","metadata":{"name":"test"}}`, groupVersionString) pl := &api.List{ Items: []runtime.Object{ &api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}}, &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: groupVersionString}, RawJSON: []byte(rawJson)}, &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "", APIVersion: groupVersionString}, RawJSON: []byte(rawJson)}, &runtime.Unstructured{TypeMeta: runtime.TypeMeta{Kind: "Foo", APIVersion: "Bar"}, Object: map[string]interface{}{"test": "value"}}, }, } if errs := runtime.DecodeList(pl.Items, runtime.UnstructuredJSONScheme); len(errs) == 1 { t.Fatalf("unexpected error %v", errs) } if pod, ok := pl.Items[1].(*runtime.Unstructured); !ok || pod.Object["kind"] != "Pod" || pod.Object["metadata"].(map[string]interface{})["name"] != "test" { t.Errorf("object not converted: %#v", pl.Items[1]) } if pod, ok := pl.Items[2].(*runtime.Unstructured); !ok || pod.Object["kind"] != "Pod" || pod.Object["metadata"].(map[string]interface{})["name"] != "test" { t.Errorf("object not converted: %#v", pl.Items[2]) } }
func TestArrayOfRuntimeObject(t *testing.T) { internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} externalGV := unversioned.GroupVersion{Group: "test.group", Version: "v1test"} s := runtime.NewScheme() s.AddKnownTypes(internalGV, &EmbeddedTest{}) s.AddKnownTypeWithName(externalGV.WithKind("EmbeddedTest"), &EmbeddedTestExternal{}) s.AddKnownTypes(internalGV, &ObjectTest{}) s.AddKnownTypeWithName(externalGV.WithKind("ObjectTest"), &ObjectTestExternal{}) codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV) innerItems := []runtime.Object{ &EmbeddedTest{ID: "baz"}, } items := []runtime.Object{ &EmbeddedTest{ID: "foo"}, &EmbeddedTest{ID: "bar"}, // TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization &runtime.Unknown{RawJSON: []byte(`{"apiVersion":"unknown.group/unknown","foo":"bar","kind":"OtherTest"}`)}, &ObjectTest{ Items: runtime.NewEncodableList(codec, innerItems), }, } internal := &ObjectTest{ Items: runtime.NewEncodableList(codec, items), } wire, err := runtime.Encode(codec, internal) if err != nil { t.Fatalf("unexpected error: %v", err) } t.Logf("Wire format is:\n%s\n", string(wire)) obj := &ObjectTestExternal{} if err := json.Unmarshal(wire, obj); err != nil { t.Fatalf("unexpected error: %v", err) } t.Logf("exact wire is: %s", string(obj.Items[0].RawJSON)) items[3] = &ObjectTest{Items: innerItems} internal.Items = items decoded, err := runtime.Decode(codec, wire) if err != nil { t.Fatalf("unexpected error: %v", err) } list, err := meta.ExtractList(decoded) if err != nil { t.Fatalf("unexpected error: %v", err) } if errs := runtime.DecodeList(list, codec); len(errs) > 0 { t.Fatalf("unexpected error: %v", errs) } list2, err := meta.ExtractList(list[3]) if err != nil { t.Fatalf("unexpected error: %v", err) } if errs := runtime.DecodeList(list2, codec); len(errs) > 0 { t.Fatalf("unexpected error: %v", errs) } if err := meta.SetList(list[3], list2); err != nil { t.Fatalf("unexpected error: %v", err) } // we want DecodeList to set type meta if possible, even on runtime.Unknown objects internal.Items[2].(*runtime.Unknown).TypeMeta = runtime.TypeMeta{Kind: "OtherTest", APIVersion: "unknown.group/unknown"} if e, a := internal.Items, list; !reflect.DeepEqual(e, a) { t.Errorf("mismatched decoded: %s", util.ObjectGoPrintSideBySide(e, a)) } }