123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- /*
- Copyright 2015 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package runtime_test
- import (
- "fmt"
- "reflect"
- "strings"
- "testing"
- "time"
- "k8s.io/kubernetes/pkg/api"
- "k8s.io/kubernetes/pkg/api/meta/metatypes"
- "k8s.io/kubernetes/pkg/api/testapi"
- "k8s.io/kubernetes/pkg/api/unversioned"
- "k8s.io/kubernetes/pkg/api/validation"
- "k8s.io/kubernetes/pkg/runtime"
- "k8s.io/kubernetes/pkg/types"
- )
- 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},
- Raw: []byte(rawJson),
- ContentType: runtime.ContentTypeJSON,
- },
- &runtime.Unknown{
- TypeMeta: runtime.TypeMeta{Kind: "", APIVersion: groupVersionString},
- Raw: []byte(rawJson),
- ContentType: runtime.ContentTypeJSON,
- },
- &runtime.Unstructured{
- Object: map[string]interface{}{
- "kind": "Foo",
- "apiVersion": "Bar",
- "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 TestDecode(t *testing.T) {
- tcs := []struct {
- json []byte
- want runtime.Object
- }{
- {
- json: []byte(`{"apiVersion": "test", "kind": "test_kind"}`),
- want: &runtime.Unstructured{
- Object: map[string]interface{}{"apiVersion": "test", "kind": "test_kind"},
- },
- },
- {
- json: []byte(`{"apiVersion": "test", "kind": "test_list", "items": []}`),
- want: &runtime.UnstructuredList{
- Object: map[string]interface{}{"apiVersion": "test", "kind": "test_list"},
- },
- },
- {
- json: []byte(`{"items": [{"metadata": {"name": "object1"}, "apiVersion": "test", "kind": "test_kind"}, {"metadata": {"name": "object2"}, "apiVersion": "test", "kind": "test_kind"}], "apiVersion": "test", "kind": "test_list"}`),
- want: &runtime.UnstructuredList{
- Object: map[string]interface{}{"apiVersion": "test", "kind": "test_list"},
- Items: []*runtime.Unstructured{
- {
- Object: map[string]interface{}{
- "metadata": map[string]interface{}{"name": "object1"},
- "apiVersion": "test",
- "kind": "test_kind",
- },
- },
- {
- Object: map[string]interface{}{
- "metadata": map[string]interface{}{"name": "object2"},
- "apiVersion": "test",
- "kind": "test_kind",
- },
- },
- },
- },
- },
- }
- for _, tc := range tcs {
- got, _, err := runtime.UnstructuredJSONScheme.Decode(tc.json, nil, nil)
- if err != nil {
- t.Errorf("Unexpected error for %q: %v", string(tc.json), err)
- continue
- }
- if !reflect.DeepEqual(got, tc.want) {
- t.Errorf("Decode(%q) want: %v\ngot: %v", string(tc.json), tc.want, got)
- }
- }
- }
- func TestUnstructuredGetters(t *testing.T) {
- unstruct := runtime.Unstructured{
- Object: map[string]interface{}{
- "kind": "test_kind",
- "apiVersion": "test_version",
- "metadata": map[string]interface{}{
- "name": "test_name",
- "namespace": "test_namespace",
- "generateName": "test_generateName",
- "uid": "test_uid",
- "resourceVersion": "test_resourceVersion",
- "selfLink": "test_selfLink",
- "creationTimestamp": "2009-11-10T23:00:00Z",
- "deletionTimestamp": "2010-11-10T23:00:00Z",
- "labels": map[string]interface{}{
- "test_label": "test_value",
- },
- "annotations": map[string]interface{}{
- "test_annotation": "test_value",
- },
- "ownerReferences": []map[string]interface{}{
- {
- "kind": "Pod",
- "name": "poda",
- "apiVersion": "v1",
- "uid": "1",
- },
- {
- "kind": "Pod",
- "name": "podb",
- "apiVersion": "v1",
- "uid": "2",
- },
- },
- "finalizers": []interface{}{
- "finalizer.1",
- "finalizer.2",
- },
- "clusterName": "cluster123",
- },
- },
- }
- if got, want := unstruct.GetAPIVersion(), "test_version"; got != want {
- t.Errorf("GetAPIVersions() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetKind(), "test_kind"; got != want {
- t.Errorf("GetKind() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetNamespace(), "test_namespace"; got != want {
- t.Errorf("GetNamespace() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetName(), "test_name"; got != want {
- t.Errorf("GetName() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetGenerateName(), "test_generateName"; got != want {
- t.Errorf("GetGenerateName() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetUID(), types.UID("test_uid"); got != want {
- t.Errorf("GetUID() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetResourceVersion(), "test_resourceVersion"; got != want {
- t.Errorf("GetResourceVersion() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetSelfLink(), "test_selfLink"; got != want {
- t.Errorf("GetSelfLink() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetCreationTimestamp(), unversioned.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC); !got.Equal(want) {
- t.Errorf("GetCreationTimestamp() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetDeletionTimestamp(), unversioned.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC); got == nil || !got.Equal(want) {
- t.Errorf("GetDeletionTimestamp() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetLabels(), map[string]string{"test_label": "test_value"}; !reflect.DeepEqual(got, want) {
- t.Errorf("GetLabels() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetAnnotations(), map[string]string{"test_annotation": "test_value"}; !reflect.DeepEqual(got, want) {
- t.Errorf("GetAnnotations() = %s, want %s", got, want)
- }
- refs := unstruct.GetOwnerReferences()
- expectedOwnerReferences := []metatypes.OwnerReference{
- {
- Kind: "Pod",
- Name: "poda",
- APIVersion: "v1",
- UID: "1",
- },
- {
- Kind: "Pod",
- Name: "podb",
- APIVersion: "v1",
- UID: "2",
- },
- }
- if got, want := refs, expectedOwnerReferences; !reflect.DeepEqual(got, want) {
- t.Errorf("GetOwnerReferences()=%v, want %v", got, want)
- }
- if got, want := unstruct.GetFinalizers(), []string{"finalizer.1", "finalizer.2"}; !reflect.DeepEqual(got, want) {
- t.Errorf("GetFinalizers()=%v, want %v", got, want)
- }
- if got, want := unstruct.GetClusterName(), "cluster123"; got != want {
- t.Errorf("GetClusterName()=%v, want %v", got, want)
- }
- }
- func TestUnstructuredSetters(t *testing.T) {
- unstruct := runtime.Unstructured{}
- trueVar := true
- want := runtime.Unstructured{
- Object: map[string]interface{}{
- "kind": "test_kind",
- "apiVersion": "test_version",
- "metadata": map[string]interface{}{
- "name": "test_name",
- "namespace": "test_namespace",
- "generateName": "test_generateName",
- "uid": "test_uid",
- "resourceVersion": "test_resourceVersion",
- "selfLink": "test_selfLink",
- "creationTimestamp": "2009-11-10T23:00:00Z",
- "deletionTimestamp": "2010-11-10T23:00:00Z",
- "labels": map[string]interface{}{
- "test_label": "test_value",
- },
- "annotations": map[string]interface{}{
- "test_annotation": "test_value",
- },
- "ownerReferences": []map[string]interface{}{
- {
- "kind": "Pod",
- "name": "poda",
- "apiVersion": "v1",
- "uid": "1",
- "controller": (*bool)(nil),
- },
- {
- "kind": "Pod",
- "name": "podb",
- "apiVersion": "v1",
- "uid": "2",
- "controller": &trueVar,
- },
- },
- "finalizers": []interface{}{
- "finalizer.1",
- "finalizer.2",
- },
- "clusterName": "cluster123",
- },
- },
- }
- unstruct.SetAPIVersion("test_version")
- unstruct.SetKind("test_kind")
- unstruct.SetNamespace("test_namespace")
- unstruct.SetName("test_name")
- unstruct.SetGenerateName("test_generateName")
- unstruct.SetUID(types.UID("test_uid"))
- unstruct.SetResourceVersion("test_resourceVersion")
- unstruct.SetSelfLink("test_selfLink")
- unstruct.SetCreationTimestamp(unversioned.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC))
- date := unversioned.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC)
- unstruct.SetDeletionTimestamp(&date)
- unstruct.SetLabels(map[string]string{"test_label": "test_value"})
- unstruct.SetAnnotations(map[string]string{"test_annotation": "test_value"})
- newOwnerReferences := []metatypes.OwnerReference{
- {
- Kind: "Pod",
- Name: "poda",
- APIVersion: "v1",
- UID: "1",
- },
- {
- Kind: "Pod",
- Name: "podb",
- APIVersion: "v1",
- UID: "2",
- Controller: &trueVar,
- },
- }
- unstruct.SetOwnerReferences(newOwnerReferences)
- unstruct.SetFinalizers([]string{"finalizer.1", "finalizer.2"})
- unstruct.SetClusterName("cluster123")
- if !reflect.DeepEqual(unstruct, want) {
- t.Errorf("Wanted: \n%s\n Got:\n%s", want, unstruct)
- }
- }
- func TestUnstructuredListGetters(t *testing.T) {
- unstruct := runtime.UnstructuredList{
- Object: map[string]interface{}{
- "kind": "test_kind",
- "apiVersion": "test_version",
- "metadata": map[string]interface{}{
- "resourceVersion": "test_resourceVersion",
- "selfLink": "test_selfLink",
- },
- },
- }
- if got, want := unstruct.GetAPIVersion(), "test_version"; got != want {
- t.Errorf("GetAPIVersions() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetKind(), "test_kind"; got != want {
- t.Errorf("GetKind() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetResourceVersion(), "test_resourceVersion"; got != want {
- t.Errorf("GetResourceVersion() = %s, want %s", got, want)
- }
- if got, want := unstruct.GetSelfLink(), "test_selfLink"; got != want {
- t.Errorf("GetSelfLink() = %s, want %s", got, want)
- }
- }
- func TestUnstructuredListSetters(t *testing.T) {
- unstruct := runtime.UnstructuredList{}
- want := runtime.UnstructuredList{
- Object: map[string]interface{}{
- "kind": "test_kind",
- "apiVersion": "test_version",
- "metadata": map[string]interface{}{
- "resourceVersion": "test_resourceVersion",
- "selfLink": "test_selfLink",
- },
- },
- }
- unstruct.SetAPIVersion("test_version")
- unstruct.SetKind("test_kind")
- unstruct.SetResourceVersion("test_resourceVersion")
- unstruct.SetSelfLink("test_selfLink")
- if !reflect.DeepEqual(unstruct, want) {
- t.Errorf("Wanted: \n%s\n Got:\n%s", unstruct, want)
- }
- }
- func TestDecodeNumbers(t *testing.T) {
- // Start with a valid pod
- originalJSON := []byte(`{
- "kind":"Pod",
- "apiVersion":"v1",
- "metadata":{"name":"pod","namespace":"foo"},
- "spec":{
- "containers":[{"name":"container","image":"container"}],
- "activeDeadlineSeconds":1000030003
- }
- }`)
- pod := &api.Pod{}
- // Decode with structured codec
- codec, err := testapi.GetCodecForObject(pod)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- err = runtime.DecodeInto(codec, originalJSON, pod)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- // ensure pod is valid
- if errs := validation.ValidatePod(pod); len(errs) > 0 {
- t.Fatalf("pod should be valid: %v", errs)
- }
- // Round-trip with unstructured codec
- unstructuredObj, err := runtime.Decode(runtime.UnstructuredJSONScheme, originalJSON)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- roundtripJSON, err := runtime.Encode(runtime.UnstructuredJSONScheme, unstructuredObj)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- // Make sure we serialize back out in int form
- if !strings.Contains(string(roundtripJSON), `"activeDeadlineSeconds":1000030003`) {
- t.Errorf("Expected %s, got %s", `"activeDeadlineSeconds":1000030003`, string(roundtripJSON))
- }
- // Decode with structured codec again
- obj2, err := runtime.Decode(codec, roundtripJSON)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- // ensure pod is still valid
- pod2, ok := obj2.(*api.Pod)
- if !ok {
- t.Fatalf("expected an *api.Pod, got %#v", obj2)
- }
- if errs := validation.ValidatePod(pod2); len(errs) > 0 {
- t.Fatalf("pod should be valid: %v", errs)
- }
- // ensure round-trip preserved large integers
- if !reflect.DeepEqual(pod, pod2) {
- t.Fatalf("Expected\n\t%#v, got \n\t%#v", pod, pod2)
- }
- }
|