func TestSetDefaulServiceTargetPort(t *testing.T) { in := &versioned.Service{Spec: versioned.ServiceSpec{Ports: []versioned.ServicePort{{Port: 1234}}}} obj := roundTrip(t, runtime.Object(in)) out := obj.(*versioned.Service) if out.Spec.Ports[0].TargetPort != intstr.FromInt(1234) { t.Errorf("Expected TargetPort to be defaulted, got %v", out.Spec.Ports[0].TargetPort) } in = &versioned.Service{Spec: versioned.ServiceSpec{Ports: []versioned.ServicePort{{Port: 1234, TargetPort: intstr.FromInt(5678)}}}} obj = roundTrip(t, runtime.Object(in)) out = obj.(*versioned.Service) if out.Spec.Ports[0].TargetPort != intstr.FromInt(5678) { t.Errorf("Expected TargetPort to be unchanged, got %v", out.Spec.Ports[0].TargetPort) } }
func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { s := versioned.PodSpec{ Containers: []versioned.Container{ { Env: []versioned.EnvVar{ { ValueFrom: &versioned.EnvVarSource{ FieldRef: &versioned.ObjectFieldSelector{}, }, }, }, }, }, } pod := &versioned.Pod{ Spec: s, } obj2 := roundTrip(t, runtime.Object(pod)) pod2 := obj2.(*versioned.Pod) s2 := pod2.Spec apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion if apiVersion != "v1" { t.Errorf("Expected default APIVersion v1, got: %v", apiVersion) } }
func TestEncode(t *testing.T) { internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"} scheme := runtime.NewScheme() scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{}) scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{}) codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV) test := &InternalSimple{ TestString: "I'm the same", } obj := runtime.Object(test) data, err := runtime.Encode(codec, obj) obj2, gvk, err2 := codec.Decode(data, nil, nil) if err != nil || err2 != nil { t.Fatalf("Failure: '%v' '%v'", err, err2) } if _, ok := obj2.(*InternalSimple); !ok { t.Fatalf("Got wrong type") } if !reflect.DeepEqual(obj2, test) { t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2) } if !reflect.DeepEqual(gvk, &unversioned.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "Simple"}) { t.Errorf("unexpected gvk returned by decode: %#v", gvk) } }
func TestDefaultRequestIsNotSetForReplicationController(t *testing.T) { s := versioned.PodSpec{} s.Containers = []versioned.Container{ { Resources: versioned.ResourceRequirements{ Limits: versioned.ResourceList{ versioned.ResourceCPU: resource.MustParse("100m"), }, }, }, } rc := &versioned.ReplicationController{ Spec: versioned.ReplicationControllerSpec{ Replicas: newInt(3), Template: &versioned.PodTemplateSpec{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, Spec: s, }, }, } output := roundTrip(t, runtime.Object(rc)) rc2 := output.(*versioned.ReplicationController) defaultRequest := rc2.Spec.Template.Spec.Containers[0].Resources.Requests requestValue := defaultRequest[versioned.ResourceCPU] if requestValue.String() != "0" { t.Errorf("Expected 0 request value, got: %s", requestValue.String()) } }
func TestDefaultRequestIsNotSetForReplicaSet(t *testing.T) { s := v1.PodSpec{} s.Containers = []v1.Container{ { Resources: v1.ResourceRequirements{ Limits: v1.ResourceList{ v1.ResourceCPU: resource.MustParse("100m"), }, }, }, } rs := &ReplicaSet{ Spec: ReplicaSetSpec{ Replicas: newInt32(3), Template: &v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, Spec: s, }, }, } output := roundTrip(t, runtime.Object(rs)) rs2 := output.(*ReplicaSet) defaultRequest := rs2.Spec.Template.Spec.Containers[0].Resources.Requests requestValue := defaultRequest[v1.ResourceCPU] if requestValue.String() != "0" { t.Errorf("Expected 0 request value, got: %s", requestValue.String()) } }
func TestSetDefaultPodSpecHostNetwork(t *testing.T) { portNum := int32(8080) s := versioned.PodSpec{} s.HostNetwork = true s.Containers = []versioned.Container{ { Ports: []versioned.ContainerPort{ { ContainerPort: portNum, }, }, }, } pod := &versioned.Pod{ Spec: s, } obj2 := roundTrip(t, runtime.Object(pod)) pod2 := obj2.(*versioned.Pod) s2 := pod2.Spec hostPortNum := s2.Containers[0].Ports[0].HostPort if hostPortNum != portNum { t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum) } }
func TestEncode_Ptr(t *testing.T) { grace := int64(30) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{"name": "foo"}, }, Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, SecurityContext: &api.PodSecurityContext{}, }, } obj := runtime.Object(pod) data, err := runtime.Encode(testapi.Default.Codec(), obj) obj2, err2 := runtime.Decode(testapi.Default.Codec(), data) if err != nil || err2 != nil { t.Fatalf("Failure: '%v' '%v'", err, err2) } if _, ok := obj2.(*api.Pod); !ok { t.Fatalf("Got wrong type") } if !api.Semantic.DeepEqual(obj2, pod) { t.Errorf("\nExpected:\n\n %#v,\n\nGot:\n\n %#vDiff: %v\n\n", pod, obj2, util.ObjectDiff(obj2, pod)) } }
func TestUnversionedTypes(t *testing.T) { internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"} otherGV := unversioned.GroupVersion{Group: "group", Version: "other"} scheme := runtime.NewScheme() scheme.AddUnversionedTypes(externalGV, &InternalSimple{}) scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{}) scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{}) scheme.AddKnownTypeWithName(otherGV.WithKind("Simple"), &ExternalSimple{}) codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV) if unv, ok := scheme.IsUnversioned(&InternalSimple{}); !unv || !ok { t.Fatal("type not unversioned and in scheme: %t %t", unv, ok) } kind, err := scheme.ObjectKind(&InternalSimple{}) if err != nil { t.Fatal(err) } if kind != externalGV.WithKind("InternalSimple") { t.Fatalf("unexpected: %#v", kind) } test := &InternalSimple{ TestString: "I'm the same", } obj := runtime.Object(test) data, err := runtime.Encode(codec, obj) if err != nil { t.Fatal(err) } obj2, gvk, err := codec.Decode(data, nil, nil) if err != nil { t.Fatal(err) } if _, ok := obj2.(*InternalSimple); !ok { t.Fatalf("Got wrong type") } if !reflect.DeepEqual(obj2, test) { t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2) } // object is serialized as an unversioned object (in the group and version it was defined in) if !reflect.DeepEqual(gvk, &unversioned.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "InternalSimple"}) { t.Errorf("unexpected gvk returned by decode: %#v", gvk) } // when serialized to a different group, the object is kept in its preferred name codec = serializer.NewCodecFactory(scheme).LegacyCodec(otherGV) data, err = runtime.Encode(codec, obj) if err != nil { t.Fatal(err) } if string(data) != `{"apiVersion":"test.group/testExternal","kind":"InternalSimple","testString":"I'm the same"}`+"\n" { t.Errorf("unexpected data: %s", data) } }
func TestSetDefaultNamespace(t *testing.T) { s := &versioned.Namespace{} obj2 := roundTrip(t, runtime.Object(s)) s2 := obj2.(*versioned.Namespace) if s2.Status.Phase != versioned.NamespaceActive { t.Errorf("Expected phase %v, got %v", versioned.NamespaceActive, s2.Status.Phase) } }
func TestSetDefaultPersistentVolumeClaim(t *testing.T) { pvc := &versioned.PersistentVolumeClaim{} obj2 := roundTrip(t, runtime.Object(pvc)) pvc2 := obj2.(*versioned.PersistentVolumeClaim) if pvc2.Status.Phase != versioned.ClaimPending { t.Errorf("Expected claim phase %v, got %v", versioned.ClaimPending, pvc2.Status.Phase) } }
func TestSetDefaultSecret(t *testing.T) { s := &versioned.Secret{} obj2 := roundTrip(t, runtime.Object(s)) s2 := obj2.(*versioned.Secret) if s2.Type != versioned.SecretTypeOpaque { t.Errorf("Expected secret type %v, got %v", versioned.SecretTypeOpaque, s2.Type) } }
func TestSetDefaultServicePort(t *testing.T) { // Unchanged if set. in := &versioned.Service{Spec: versioned.ServiceSpec{ Ports: []versioned.ServicePort{ {Protocol: "UDP", Port: 9376, TargetPort: intstr.FromString("p")}, {Protocol: "UDP", Port: 8675, TargetPort: intstr.FromInt(309)}, }, }} out := roundTrip(t, runtime.Object(in)).(*versioned.Service) if out.Spec.Ports[0].Protocol != versioned.ProtocolUDP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolUDP, out.Spec.Ports[0].Protocol) } if out.Spec.Ports[0].TargetPort != intstr.FromString("p") { t.Errorf("Expected port %v, got %v", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort) } if out.Spec.Ports[1].Protocol != versioned.ProtocolUDP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolUDP, out.Spec.Ports[1].Protocol) } if out.Spec.Ports[1].TargetPort != intstr.FromInt(309) { t.Errorf("Expected port %v, got %v", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort) } // Defaulted. in = &versioned.Service{Spec: versioned.ServiceSpec{ Ports: []versioned.ServicePort{ {Protocol: "", Port: 9376, TargetPort: intstr.FromString("")}, {Protocol: "", Port: 8675, TargetPort: intstr.FromInt(0)}, }, }} out = roundTrip(t, runtime.Object(in)).(*versioned.Service) if out.Spec.Ports[0].Protocol != versioned.ProtocolTCP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Spec.Ports[0].Protocol) } if out.Spec.Ports[0].TargetPort != intstr.FromInt(int(in.Spec.Ports[0].Port)) { t.Errorf("Expected port %v, got %v", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort) } if out.Spec.Ports[1].Protocol != versioned.ProtocolTCP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Spec.Ports[1].Protocol) } if out.Spec.Ports[1].TargetPort != intstr.FromInt(int(in.Spec.Ports[1].Port)) { t.Errorf("Expected port %v, got %v", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort) } }
func TestSetDefaultService(t *testing.T) { svc := &versioned.Service{} obj2 := roundTrip(t, runtime.Object(svc)) svc2 := obj2.(*versioned.Service) if svc2.Spec.SessionAffinity != versioned.ServiceAffinityNone { t.Errorf("Expected default session affinity type:%s, got: %s", versioned.ServiceAffinityNone, svc2.Spec.SessionAffinity) } if svc2.Spec.Type != versioned.ServiceTypeClusterIP { t.Errorf("Expected default type:%s, got: %s", versioned.ServiceTypeClusterIP, svc2.Spec.Type) } }
func TestSetDefaultPersistentVolume(t *testing.T) { pv := &versioned.PersistentVolume{} obj2 := roundTrip(t, runtime.Object(pv)) pv2 := obj2.(*versioned.PersistentVolume) if pv2.Status.Phase != versioned.VolumePending { t.Errorf("Expected volume phase %v, got %v", versioned.VolumePending, pv2.Status.Phase) } if pv2.Spec.PersistentVolumeReclaimPolicy != versioned.PersistentVolumeReclaimRetain { t.Errorf("Expected pv reclaim policy %v, got %v", versioned.PersistentVolumeReclaimRetain, pv2.Spec.PersistentVolumeReclaimPolicy) } }
func TestSetDefaultNodeExternalID(t *testing.T) { name := "node0" n := &versioned.Node{} n.Name = name obj2 := roundTrip(t, runtime.Object(n)) n2 := obj2.(*versioned.Node) if n2.Spec.ExternalID != name { t.Errorf("Expected default External ID: %s, got: %s", name, n2.Spec.ExternalID) } if n2.Spec.ProviderID != "" { t.Errorf("Expected empty default Cloud Provider ID, got: %s", n2.Spec.ProviderID) } }
func TestSetDefaultRequestsPod(t *testing.T) { // verify we default if limits are specified s := versioned.PodSpec{} s.Containers = []versioned.Container{ { Resources: versioned.ResourceRequirements{ Limits: versioned.ResourceList{ versioned.ResourceCPU: resource.MustParse("100m"), }, }, }, } pod := &versioned.Pod{ Spec: s, } output := roundTrip(t, runtime.Object(pod)) pod2 := output.(*versioned.Pod) defaultRequest := pod2.Spec.Containers[0].Resources.Requests requestValue := defaultRequest[versioned.ResourceCPU] if requestValue.String() != "100m" { t.Errorf("Expected request cpu: %s, got: %s", "100m", requestValue.String()) } // verify we do nothing if no limits are specified s = versioned.PodSpec{} s.Containers = []versioned.Container{{}} pod = &versioned.Pod{ Spec: s, } output = roundTrip(t, runtime.Object(pod)) pod2 = output.(*versioned.Pod) defaultRequest = pod2.Spec.Containers[0].Resources.Requests requestValue = defaultRequest[versioned.ResourceCPU] if requestValue.String() != "0" { t.Errorf("Expected 0 request value, got: %s", requestValue.String()) } }
func TestSetDefaultJobSelector(t *testing.T) { expected := &Job{ Spec: JobSpec{ Selector: &LabelSelector{ MatchLabels: map[string]string{"job": "selector"}, }, Completions: newInt32(1), Parallelism: newInt32(1), }, } tests := []*Job{ // selector set explicitly, completions and parallelism - default { Spec: JobSpec{ Selector: &LabelSelector{ MatchLabels: map[string]string{"job": "selector"}, }, }, }, // selector from template labels, completions and parallelism - default { Spec: JobSpec{ Template: v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{"job": "selector"}, }, }, }, }, } for _, original := range tests { obj2 := roundTrip(t, runtime.Object(original)) got, ok := obj2.(*Job) if !ok { t.Errorf("unexpected object: %v", got) t.FailNow() } if !reflect.DeepEqual(got.Spec.Selector, expected.Spec.Selector) { t.Errorf("got different selectors %#v %#v", got.Spec.Selector, expected.Spec.Selector) } } }
func TestSetDefaultLimitRangeItem(t *testing.T) { limitRange := &versioned.LimitRange{ ObjectMeta: versioned.ObjectMeta{ Name: "test-defaults", }, Spec: versioned.LimitRangeSpec{ Limits: []versioned.LimitRangeItem{{ Type: versioned.LimitTypeContainer, Max: versioned.ResourceList{ versioned.ResourceCPU: resource.MustParse("100m"), }, Min: versioned.ResourceList{ versioned.ResourceMemory: resource.MustParse("100Mi"), }, Default: versioned.ResourceList{}, DefaultRequest: versioned.ResourceList{}, }}, }, } output := roundTrip(t, runtime.Object(limitRange)) limitRange2 := output.(*versioned.LimitRange) defaultLimit := limitRange2.Spec.Limits[0].Default defaultRequest := limitRange2.Spec.Limits[0].DefaultRequest // verify that default cpu was set to the max defaultValue := defaultLimit[versioned.ResourceCPU] if defaultValue.String() != "100m" { t.Errorf("Expected default cpu: %s, got: %s", "100m", defaultValue.String()) } // verify that default request was set to the limit requestValue := defaultRequest[versioned.ResourceCPU] if requestValue.String() != "100m" { t.Errorf("Expected request cpu: %s, got: %s", "100m", requestValue.String()) } // verify that if a min is provided, it will be the default if no limit is specified requestMinValue := defaultRequest[versioned.ResourceMemory] if requestMinValue.String() != "100Mi" { t.Errorf("Expected request memory: %s, got: %s", "100Mi", requestMinValue.String()) } }
func TestSetDefaulEndpointsProtocol(t *testing.T) { in := &versioned.Endpoints{Subsets: []versioned.EndpointSubset{ {Ports: []versioned.EndpointPort{{}, {Protocol: "UDP"}, {}}}, }} obj := roundTrip(t, runtime.Object(in)) out := obj.(*versioned.Endpoints) for i := range out.Subsets { for j := range out.Subsets[i].Ports { if in.Subsets[i].Ports[j].Protocol == "" { if out.Subsets[i].Ports[j].Protocol != versioned.ProtocolTCP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Subsets[i].Ports[j].Protocol) } } else { if out.Subsets[i].Ports[j].Protocol != in.Subsets[i].Ports[j].Protocol { t.Errorf("Expected protocol %s, got %s", in.Subsets[i].Ports[j].Protocol, out.Subsets[i].Ports[j].Protocol) } } } } }
func TestSetDefaultProbe(t *testing.T) { originalProbe := versioned.Probe{} expectedProbe := versioned.Probe{ InitialDelaySeconds: 0, TimeoutSeconds: 1, PeriodSeconds: 10, SuccessThreshold: 1, FailureThreshold: 3, } pod := &versioned.Pod{ Spec: versioned.PodSpec{ Containers: []versioned.Container{{LivenessProbe: &originalProbe}}, }, } output := roundTrip(t, runtime.Object(pod)).(*versioned.Pod) actualProbe := *output.Spec.Containers[0].LivenessProbe if actualProbe != expectedProbe { t.Errorf("Expected probe: %+v\ngot: %+v\n", expectedProbe, actualProbe) } }
func TestSetDefaultReplicaSetReplicas(t *testing.T) { tests := []struct { rs ReplicaSet expectReplicas int32 }{ { rs: ReplicaSet{ Spec: ReplicaSetSpec{ Template: &v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectReplicas: 1, }, { rs: ReplicaSet{ Spec: ReplicaSetSpec{ Replicas: newInt32(0), Template: &v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectReplicas: 0, }, { rs: ReplicaSet{ Spec: ReplicaSetSpec{ Replicas: newInt32(3), Template: &v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectReplicas: 3, }, } for _, test := range tests { rs := &test.rs obj2 := roundTrip(t, runtime.Object(rs)) rs2, ok := obj2.(*ReplicaSet) if !ok { t.Errorf("unexpected object: %v", rs2) t.FailNow() } if rs2.Spec.Replicas == nil { t.Errorf("unexpected nil Replicas") } else if test.expectReplicas != *rs2.Spec.Replicas { t.Errorf("expected: %d replicas, got: %d", test.expectReplicas, *rs2.Spec.Replicas) } } }
func TestSetDefaultReplicaSet(t *testing.T) { tests := []struct { rs *ReplicaSet expectLabels bool expectSelector bool }{ { rs: &ReplicaSet{ Spec: ReplicaSetSpec{ Template: &v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectLabels: true, expectSelector: true, }, { rs: &ReplicaSet{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "bar": "foo", }, }, Spec: ReplicaSetSpec{ Template: &v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectLabels: false, expectSelector: true, }, { rs: &ReplicaSet{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "bar": "foo", }, }, Spec: ReplicaSetSpec{ Selector: &LabelSelector{ MatchLabels: map[string]string{ "some": "other", }, }, Template: &v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectLabels: false, expectSelector: false, }, { rs: &ReplicaSet{ Spec: ReplicaSetSpec{ Selector: &LabelSelector{ MatchLabels: map[string]string{ "some": "other", }, }, Template: &v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectLabels: true, expectSelector: false, }, } for _, test := range tests { rs := test.rs obj2 := roundTrip(t, runtime.Object(rs)) rs2, ok := obj2.(*ReplicaSet) if !ok { t.Errorf("unexpected object: %v", rs2) t.FailNow() } if test.expectSelector != reflect.DeepEqual(rs2.Spec.Selector.MatchLabels, rs2.Spec.Template.Labels) { if test.expectSelector { t.Errorf("expected: %v, got: %v", rs2.Spec.Template.Labels, rs2.Spec.Selector) } else { t.Errorf("unexpected equality: %v", rs.Spec.Selector) } } if test.expectLabels != reflect.DeepEqual(rs2.Labels, rs2.Spec.Template.Labels) { if test.expectLabels { t.Errorf("expected: %v, got: %v", rs2.Spec.Template.Labels, rs2.Labels) } else { t.Errorf("unexpected equality: %v", rs.Labels) } } } }
func TestSetDefaultJobParallelismAndCompletions(t *testing.T) { tests := []struct { original *Job expected *Job }{ // both unspecified -> sets both to 1 { original: &Job{ Spec: JobSpec{}, }, expected: &Job{ Spec: JobSpec{ Completions: newInt32(1), Parallelism: newInt32(1), }, }, }, // WQ: Parallelism explicitly 0 and completions unset -> no change { original: &Job{ Spec: JobSpec{ Parallelism: newInt32(0), }, }, expected: &Job{ Spec: JobSpec{ Parallelism: newInt32(0), }, }, }, // WQ: Parallelism explicitly 2 and completions unset -> no change { original: &Job{ Spec: JobSpec{ Parallelism: newInt32(2), }, }, expected: &Job{ Spec: JobSpec{ Parallelism: newInt32(2), }, }, }, // Completions explicitly 2 and parallelism unset -> parallelism is defaulted { original: &Job{ Spec: JobSpec{ Completions: newInt32(2), }, }, expected: &Job{ Spec: JobSpec{ Completions: newInt32(2), Parallelism: newInt32(1), }, }, }, // Both set -> no change { original: &Job{ Spec: JobSpec{ Completions: newInt32(10), Parallelism: newInt32(11), }, }, expected: &Job{ Spec: JobSpec{ Completions: newInt32(10), Parallelism: newInt32(11), }, }, }, // Both set, flipped -> no change { original: &Job{ Spec: JobSpec{ Completions: newInt32(11), Parallelism: newInt32(10), }, }, expected: &Job{ Spec: JobSpec{ Completions: newInt32(11), Parallelism: newInt32(10), }, }, }, } for _, tc := range tests { original := tc.original expected := tc.expected obj2 := roundTrip(t, runtime.Object(original)) got, ok := obj2.(*Job) if !ok { t.Errorf("unexpected object: %v", got) t.FailNow() } if (got.Spec.Completions == nil) != (expected.Spec.Completions == nil) { t.Errorf("got different *completions than expected: %v %v", got.Spec.Completions, expected.Spec.Completions) } if got.Spec.Completions != nil && expected.Spec.Completions != nil { if *got.Spec.Completions != *expected.Spec.Completions { t.Errorf("got different completions than expected: %d %d", *got.Spec.Completions, *expected.Spec.Completions) } } if (got.Spec.Parallelism == nil) != (expected.Spec.Parallelism == nil) { t.Errorf("got different *Parallelism than expected: %v %v", got.Spec.Parallelism, expected.Spec.Parallelism) } if got.Spec.Parallelism != nil && expected.Spec.Parallelism != nil { if *got.Spec.Parallelism != *expected.Spec.Parallelism { t.Errorf("got different parallelism than expected: %d %d", *got.Spec.Parallelism, *expected.Spec.Parallelism) } } } }
func TestSetDefaultDaemonSet(t *testing.T) { defaultIntOrString := intstr.FromInt(1) defaultLabels := map[string]string{"foo": "bar"} period := int64(v1.DefaultTerminationGracePeriodSeconds) defaultTemplate := v1.PodTemplateSpec{ Spec: v1.PodSpec{ DNSPolicy: v1.DNSClusterFirst, RestartPolicy: v1.RestartPolicyAlways, SecurityContext: &v1.PodSecurityContext{}, TerminationGracePeriodSeconds: &period, }, ObjectMeta: v1.ObjectMeta{ Labels: defaultLabels, }, } templateNoLabel := v1.PodTemplateSpec{ Spec: v1.PodSpec{ DNSPolicy: v1.DNSClusterFirst, RestartPolicy: v1.RestartPolicyAlways, SecurityContext: &v1.PodSecurityContext{}, TerminationGracePeriodSeconds: &period, }, } tests := []struct { original *DaemonSet expected *DaemonSet }{ { // Labels change/defaulting test. original: &DaemonSet{ Spec: DaemonSetSpec{ Template: defaultTemplate, }, }, expected: &DaemonSet{ ObjectMeta: v1.ObjectMeta{ Labels: defaultLabels, }, Spec: DaemonSetSpec{ Selector: &LabelSelector{ MatchLabels: defaultLabels, }, Template: defaultTemplate, UpdateStrategy: DaemonSetUpdateStrategy{ Type: RollingUpdateDaemonSetStrategyType, RollingUpdate: &RollingUpdateDaemonSet{ MaxUnavailable: &defaultIntOrString, }, }, UniqueLabelKey: newString(DefaultDaemonSetUniqueLabelKey), }, }, }, { // Labels change/defaulting test. original: &DaemonSet{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "bar": "foo", }, }, Spec: DaemonSetSpec{ Template: defaultTemplate, UpdateStrategy: DaemonSetUpdateStrategy{ Type: RollingUpdateDaemonSetStrategyType, RollingUpdate: &RollingUpdateDaemonSet{ MaxUnavailable: &defaultIntOrString, }, }, }, }, expected: &DaemonSet{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{ "bar": "foo", }, }, Spec: DaemonSetSpec{ Selector: &LabelSelector{ MatchLabels: defaultLabels, }, Template: defaultTemplate, UpdateStrategy: DaemonSetUpdateStrategy{ Type: RollingUpdateDaemonSetStrategyType, RollingUpdate: &RollingUpdateDaemonSet{ MaxUnavailable: &defaultIntOrString, }, }, UniqueLabelKey: newString(DefaultDaemonSetUniqueLabelKey), }, }, }, { // Update strategy. original: &DaemonSet{}, expected: &DaemonSet{ Spec: DaemonSetSpec{ Template: templateNoLabel, UpdateStrategy: DaemonSetUpdateStrategy{ Type: RollingUpdateDaemonSetStrategyType, RollingUpdate: &RollingUpdateDaemonSet{ MaxUnavailable: &defaultIntOrString, }, }, UniqueLabelKey: newString(DefaultDaemonSetUniqueLabelKey), }, }, }, { // Update strategy. original: &DaemonSet{ Spec: DaemonSetSpec{ UpdateStrategy: DaemonSetUpdateStrategy{ RollingUpdate: &RollingUpdateDaemonSet{}, }, }, }, expected: &DaemonSet{ Spec: DaemonSetSpec{ Template: templateNoLabel, UpdateStrategy: DaemonSetUpdateStrategy{ Type: RollingUpdateDaemonSetStrategyType, RollingUpdate: &RollingUpdateDaemonSet{ MaxUnavailable: &defaultIntOrString, }, }, UniqueLabelKey: newString(DefaultDaemonSetUniqueLabelKey), }, }, }, { // Custom unique label key. original: &DaemonSet{ Spec: DaemonSetSpec{ UpdateStrategy: DaemonSetUpdateStrategy{ RollingUpdate: &RollingUpdateDaemonSet{}, }, UniqueLabelKey: newString("customDaemonSetKey"), }, }, expected: &DaemonSet{ Spec: DaemonSetSpec{ Template: templateNoLabel, UpdateStrategy: DaemonSetUpdateStrategy{ Type: RollingUpdateDaemonSetStrategyType, RollingUpdate: &RollingUpdateDaemonSet{ MaxUnavailable: &defaultIntOrString, }, }, UniqueLabelKey: newString("customDaemonSetKey"), }, }, }, } for i, test := range tests { original := test.original expected := test.expected obj2 := roundTrip(t, runtime.Object(original)) got, ok := obj2.(*DaemonSet) if !ok { t.Errorf("(%d) unexpected object: %v", i, got) t.FailNow() } if !reflect.DeepEqual(got.Spec, expected.Spec) { t.Errorf("(%d) got different than expected\ngot:\n\t%+v\nexpected:\n\t%+v", i, got.Spec, expected.Spec) } } }
func TestSetDefaultDeployment(t *testing.T) { defaultIntOrString := intstr.FromInt(1) differentIntOrString := intstr.FromInt(5) deploymentLabelKey := DefaultDeploymentUniqueLabelKey period := int64(v1.DefaultTerminationGracePeriodSeconds) defaultTemplate := v1.PodTemplateSpec{ Spec: v1.PodSpec{ DNSPolicy: v1.DNSClusterFirst, RestartPolicy: v1.RestartPolicyAlways, SecurityContext: &v1.PodSecurityContext{}, TerminationGracePeriodSeconds: &period, }, } tests := []struct { original *Deployment expected *Deployment }{ { original: &Deployment{}, expected: &Deployment{ Spec: DeploymentSpec{ Replicas: newInt32(1), Strategy: DeploymentStrategy{ Type: RollingUpdateDeploymentStrategyType, RollingUpdate: &RollingUpdateDeployment{ MaxSurge: &defaultIntOrString, MaxUnavailable: &defaultIntOrString, }, }, Template: defaultTemplate, UniqueLabelKey: newString(deploymentLabelKey), }, }, }, { original: &Deployment{ Spec: DeploymentSpec{ Replicas: newInt32(5), Strategy: DeploymentStrategy{ RollingUpdate: &RollingUpdateDeployment{ MaxSurge: &differentIntOrString, }, }, }, }, expected: &Deployment{ Spec: DeploymentSpec{ Replicas: newInt32(5), Strategy: DeploymentStrategy{ Type: RollingUpdateDeploymentStrategyType, RollingUpdate: &RollingUpdateDeployment{ MaxSurge: &differentIntOrString, MaxUnavailable: &defaultIntOrString, }, }, Template: defaultTemplate, UniqueLabelKey: newString(deploymentLabelKey), }, }, }, { original: &Deployment{ Spec: DeploymentSpec{ Replicas: newInt32(5), Strategy: DeploymentStrategy{ Type: RecreateDeploymentStrategyType, }, }, }, expected: &Deployment{ Spec: DeploymentSpec{ Replicas: newInt32(5), Strategy: DeploymentStrategy{ Type: RecreateDeploymentStrategyType, }, Template: defaultTemplate, UniqueLabelKey: newString(deploymentLabelKey), }, }, }, { original: &Deployment{ Spec: DeploymentSpec{ Replicas: newInt32(5), Strategy: DeploymentStrategy{ Type: RecreateDeploymentStrategyType, }, UniqueLabelKey: newString("customDeploymentKey"), }, }, expected: &Deployment{ Spec: DeploymentSpec{ Replicas: newInt32(5), Strategy: DeploymentStrategy{ Type: RecreateDeploymentStrategyType, }, Template: defaultTemplate, UniqueLabelKey: newString("customDeploymentKey"), }, }, }, } for _, test := range tests { original := test.original expected := test.expected obj2 := roundTrip(t, runtime.Object(original)) got, ok := obj2.(*Deployment) if !ok { t.Errorf("unexpected object: %v", got) t.FailNow() } if !reflect.DeepEqual(got.Spec, expected.Spec) { t.Errorf("got different than expected:\n\t%+v\ngot:\n\t%+v", got.Spec, expected.Spec) } } }
func TestSetDefaultReplicationControllerReplicas(t *testing.T) { tests := []struct { rc versioned.ReplicationController expectReplicas int32 }{ { rc: versioned.ReplicationController{ Spec: versioned.ReplicationControllerSpec{ Template: &versioned.PodTemplateSpec{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectReplicas: 1, }, { rc: versioned.ReplicationController{ Spec: versioned.ReplicationControllerSpec{ Replicas: newInt(0), Template: &versioned.PodTemplateSpec{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectReplicas: 0, }, { rc: versioned.ReplicationController{ Spec: versioned.ReplicationControllerSpec{ Replicas: newInt(3), Template: &versioned.PodTemplateSpec{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectReplicas: 3, }, } for _, test := range tests { rc := &test.rc obj2 := roundTrip(t, runtime.Object(rc)) rc2, ok := obj2.(*versioned.ReplicationController) if !ok { t.Errorf("unexpected object: %v", rc2) t.FailNow() } if rc2.Spec.Replicas == nil { t.Errorf("unexpected nil Replicas") } else if test.expectReplicas != *rc2.Spec.Replicas { t.Errorf("expected: %d replicas, got: %d", test.expectReplicas, *rc2.Spec.Replicas) } } }
func TestSetDefaultNodeStatusAllocatable(t *testing.T) { capacity := versioned.ResourceList{ versioned.ResourceCPU: resource.MustParse("1000m"), versioned.ResourceMemory: resource.MustParse("10G"), } allocatable := versioned.ResourceList{ versioned.ResourceCPU: resource.MustParse("500m"), versioned.ResourceMemory: resource.MustParse("5G"), } tests := []struct { capacity versioned.ResourceList allocatable versioned.ResourceList expectedAllocatable versioned.ResourceList }{{ // Everything set, no defaulting. capacity: capacity, allocatable: allocatable, expectedAllocatable: allocatable, }, { // Allocatable set, no defaulting. capacity: nil, allocatable: allocatable, expectedAllocatable: allocatable, }, { // Capacity set, allocatable defaults to capacity. capacity: capacity, allocatable: nil, expectedAllocatable: capacity, }, { // Nothing set, allocatable "defaults" to capacity. capacity: nil, allocatable: nil, expectedAllocatable: nil, }} copyResourceList := func(rl versioned.ResourceList) versioned.ResourceList { if rl == nil { return nil } copy := make(versioned.ResourceList, len(rl)) for k, v := range rl { copy[k] = *v.Copy() } return copy } resourceListsEqual := func(a versioned.ResourceList, b versioned.ResourceList) bool { if len(a) != len(b) { return false } for k, v := range a { vb, found := b[k] if !found { return false } if v.Cmp(vb) != 0 { return false } } return true } for i, testcase := range tests { node := versioned.Node{ Status: versioned.NodeStatus{ Capacity: copyResourceList(testcase.capacity), Allocatable: copyResourceList(testcase.allocatable), }, } node2 := roundTrip(t, runtime.Object(&node)).(*versioned.Node) actual := node2.Status.Allocatable expected := testcase.expectedAllocatable if !resourceListsEqual(expected, actual) { t.Errorf("[%d] Expected NodeStatus.Allocatable: %+v; Got: %+v", i, expected, actual) } } }
func TestScheme(t *testing.T) { internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"} scheme := runtime.NewScheme() scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{}) scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{}) // If set, would clear TypeMeta during conversion. //scheme.AddIgnoredConversionType(&TypeMeta{}, &TypeMeta{}) // test that scheme is an ObjectTyper var _ runtime.ObjectTyper = scheme internalToExternalCalls := 0 externalToInternalCalls := 0 // Register functions to verify that scope.Meta() gets set correctly. err := scheme.AddConversionFuncs( func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error { if e, a := internalGV.String(), scope.Meta().SrcVersion; e != a { t.Errorf("Expected '%v', got '%v'", e, a) } if e, a := externalGV.String(), scope.Meta().DestVersion; e != a { t.Errorf("Expected '%v', got '%v'", e, a) } scope.Convert(&in.TypeMeta, &out.TypeMeta, 0) scope.Convert(&in.TestString, &out.TestString, 0) internalToExternalCalls++ return nil }, func(in *ExternalSimple, out *InternalSimple, scope conversion.Scope) error { if e, a := externalGV.String(), scope.Meta().SrcVersion; e != a { t.Errorf("Expected '%v', got '%v'", e, a) } if e, a := internalGV.String(), scope.Meta().DestVersion; e != a { t.Errorf("Expected '%v', got '%v'", e, a) } scope.Convert(&in.TypeMeta, &out.TypeMeta, 0) scope.Convert(&in.TestString, &out.TestString, 0) externalToInternalCalls++ return nil }, ) if err != nil { t.Fatalf("unexpected error: %v", err) } codecs := serializer.NewCodecFactory(scheme) codec := codecs.LegacyCodec(externalGV) jsonserializer, _ := codecs.SerializerForFileExtension("json") simple := &InternalSimple{ TestString: "foo", } // Test Encode, Decode, DecodeInto, and DecodeToVersion obj := runtime.Object(simple) data, err := runtime.Encode(codec, obj) if err != nil { t.Fatal(err) } obj2, err := runtime.Decode(codec, data) if err != nil { t.Fatal(err) } if _, ok := obj2.(*InternalSimple); !ok { t.Fatalf("Got wrong type") } if e, a := simple, obj2; !reflect.DeepEqual(e, a) { t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a) } obj3 := &InternalSimple{} if err := runtime.DecodeInto(codec, data, obj3); err != nil { t.Fatal(err) } // clearing TypeMeta is a function of the scheme, which we do not test here (ConvertToVersion // does not automatically clear TypeMeta anymore). simple.TypeMeta = runtime.TypeMeta{Kind: "Simple", APIVersion: externalGV.String()} if e, a := simple, obj3; !reflect.DeepEqual(e, a) { t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a) } obj4, err := runtime.Decode(jsonserializer, data) if err != nil { t.Fatal(err) } if _, ok := obj4.(*ExternalSimple); !ok { t.Fatalf("Got wrong type") } // Test Convert external := &ExternalSimple{} err = scheme.Convert(simple, external) if err != nil { t.Fatalf("Unexpected error: %v", err) } if e, a := simple.TestString, external.TestString; e != a { t.Errorf("Expected %v, got %v", e, a) } // Encode and Convert should each have caused an increment. if e, a := 2, internalToExternalCalls; e != a { t.Errorf("Expected %v, got %v", e, a) } // DecodeInto and Decode should each have caused an increment because of a conversion if e, a := 2, externalToInternalCalls; e != a { t.Errorf("Expected %v, got %v", e, a) } }
func TestSetDefaultReplicationController(t *testing.T) { tests := []struct { rc *versioned.ReplicationController expectLabels bool expectSelector bool }{ { rc: &versioned.ReplicationController{ Spec: versioned.ReplicationControllerSpec{ Template: &versioned.PodTemplateSpec{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectLabels: true, expectSelector: true, }, { rc: &versioned.ReplicationController{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "bar": "foo", }, }, Spec: versioned.ReplicationControllerSpec{ Template: &versioned.PodTemplateSpec{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectLabels: false, expectSelector: true, }, { rc: &versioned.ReplicationController{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "bar": "foo", }, }, Spec: versioned.ReplicationControllerSpec{ Selector: map[string]string{ "some": "other", }, Template: &versioned.PodTemplateSpec{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectLabels: false, expectSelector: false, }, { rc: &versioned.ReplicationController{ Spec: versioned.ReplicationControllerSpec{ Selector: map[string]string{ "some": "other", }, Template: &versioned.PodTemplateSpec{ ObjectMeta: versioned.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, }, expectLabels: true, expectSelector: false, }, } for _, test := range tests { rc := test.rc obj2 := roundTrip(t, runtime.Object(rc)) rc2, ok := obj2.(*versioned.ReplicationController) if !ok { t.Errorf("unexpected object: %v", rc2) t.FailNow() } if test.expectSelector != reflect.DeepEqual(rc2.Spec.Selector, rc2.Spec.Template.Labels) { if test.expectSelector { t.Errorf("expected: %v, got: %v", rc2.Spec.Template.Labels, rc2.Spec.Selector) } else { t.Errorf("unexpected equality: %v", rc.Spec.Selector) } } if test.expectLabels != reflect.DeepEqual(rc2.Labels, rc2.Spec.Template.Labels) { if test.expectLabels { t.Errorf("expected: %v, got: %v", rc2.Spec.Template.Labels, rc2.Labels) } else { t.Errorf("unexpected equality: %v", rc.Labels) } } } }