func validNewPod() *api.Pod { grace := int64(30) return &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, Containers: []api.Container{ { Name: "foo", Image: "test", ImagePullPolicy: api.PullAlways, TerminationMessagePath: api.TerminationMessagePathDefault, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, }, } }
func TestDecodeSinglePod(t *testing.T) { grace := int64(30) pod := &v1.Pod{ TypeMeta: metav1.TypeMeta{ APIVersion: "", }, ObjectMeta: metav1.ObjectMeta{ Name: "test", UID: "12345", Namespace: "mynamespace", }, Spec: v1.PodSpec{ RestartPolicy: v1.RestartPolicyAlways, DNSPolicy: v1.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, Containers: []v1.Container{{ Name: "image", Image: "test/image", ImagePullPolicy: "IfNotPresent", TerminationMessagePath: "/dev/termination-log", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, }, } json, err := runtime.Encode(testapi.Default.Codec(), pod) if err != nil { t.Errorf("unexpected error: %v", err) } parsed, podOut, err := tryDecodeSinglePod(json, noDefault) if !parsed { t.Errorf("expected to have parsed file: (%s)", string(json)) } if err != nil { t.Errorf("unexpected error: %v (%s)", err, string(json)) } if !reflect.DeepEqual(pod, podOut) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(json)) } for _, gv := range api.Registry.EnabledVersionsForGroup(v1.GroupName) { info, _ := runtime.SerializerInfoForMediaType(api.Codecs.SupportedMediaTypes(), "application/yaml") encoder := api.Codecs.EncoderForVersion(info.Serializer, gv) yaml, err := runtime.Encode(encoder, pod) if err != nil { t.Errorf("unexpected error: %v", err) } parsed, podOut, err = tryDecodeSinglePod(yaml, noDefault) if !parsed { t.Errorf("expected to have parsed file: (%s)", string(yaml)) } if err != nil { t.Errorf("unexpected error: %v (%s)", err, string(yaml)) } if !reflect.DeepEqual(pod, podOut) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(yaml)) } } }
func newDaemonSet(name string) *extensions.DaemonSet { return &extensions.DaemonSet{ TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Extensions.GroupVersion().String()}, ObjectMeta: api.ObjectMeta{ Name: name, Namespace: api.NamespaceDefault, }, Spec: extensions.DaemonSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: simpleDaemonSetLabel}, Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: simpleDaemonSetLabel, }, Spec: api.PodSpec{ Containers: []api.Container{ { Image: "foo/bar", TerminationMessagePath: api.TerminationMessagePathDefault, ImagePullPolicy: api.PullIfNotPresent, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, DNSPolicy: api.DNSDefault, }, }, }, } }
func TestDecodeSinglePod(t *testing.T) { pod := &api.Pod{ TypeMeta: api.TypeMeta{ APIVersion: "", }, ObjectMeta: api.ObjectMeta{ Name: "test", UID: "12345", Namespace: "mynamespace", }, Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, Containers: []api.Container{{ Name: "image", Image: "test/image", ImagePullPolicy: "IfNotPresent", TerminationMessagePath: "/dev/termination-log", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, }, } json, err := testapi.Codec().Encode(pod) if err != nil { t.Errorf("unexpected error: %v", err) } parsed, podOut, err := tryDecodeSinglePod(json, noDefault) if !parsed { t.Errorf("expected to have parsed file: (%s)", string(json)) } if err != nil { t.Errorf("unexpected error: %v (%s)", err, string(json)) } if !reflect.DeepEqual(pod, podOut) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(json)) } for _, version := range registered.RegisteredVersions { externalPod, err := testapi.Converter().ConvertToVersion(pod, version) if err != nil { t.Errorf("unexpected error: %v", err) } yaml, err := yaml.Marshal(externalPod) if err != nil { t.Errorf("unexpected error: %v", err) } parsed, podOut, err = tryDecodeSinglePod(yaml, noDefault) if !parsed { t.Errorf("expected to have parsed file: (%s)", string(yaml)) } if err != nil { t.Errorf("unexpected error: %v (%s)", err, string(yaml)) } if !reflect.DeepEqual(pod, podOut) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(yaml)) } } }
func getTestCases(hostname types.NodeName) []*testCase { grace := int64(30) return []*testCase{ { desc: "Simple pod", pod: &v1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", APIVersion: "", }, ObjectMeta: metav1.ObjectMeta{ Name: "test", UID: "12345", Namespace: "mynamespace", }, Spec: v1.PodSpec{ Containers: []v1.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, }, Status: v1.PodStatus{ Phase: v1.PodPending, }, }, expected: CreatePodUpdate(kubetypes.SET, kubetypes.FileSource, &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "test-" + string(hostname), UID: "12345", Namespace: "mynamespace", Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "12345"}, SelfLink: getSelfLink("test-"+string(hostname), "mynamespace"), }, Spec: v1.PodSpec{ NodeName: string(hostname), RestartPolicy: v1.RestartPolicyAlways, DNSPolicy: v1.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, Containers: []v1.Container{{ Name: "image", Image: "test/image", TerminationMessagePath: "/dev/termination-log", ImagePullPolicy: "Always", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, }, Status: v1.PodStatus{ Phase: v1.PodPending, }, }), }, } }
func CreateValidPod(name, namespace string) *api.Pod { return &api.Pod{ ObjectMeta: api.ObjectMeta{ UID: types.UID(name), // for the purpose of testing, this is unique enough Name: name, Namespace: namespace, }, Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, Containers: []api.Container{ { Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, }, } }
func newReplicationController(replicas int) *api.ReplicationController { rc := &api.ReplicationController{ TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, ObjectMeta: api.ObjectMeta{ UID: util.NewUUID(), Name: "foobar", Namespace: api.NamespaceDefault, Tenant: api.TenantDefault, ResourceVersion: "18", }, Spec: api.ReplicationControllerSpec{ Replicas: replicas, Selector: map[string]string{"foo": "bar"}, Template: &api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{ "name": "foo", "type": "production", }, }, Spec: api.PodSpec{ Containers: []api.Container{ { Image: "foo/bar", TerminationMessagePath: api.TerminationMessagePathDefault, ImagePullPolicy: api.PullIfNotPresent, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSDefault, NodeSelector: map[string]string{ "baz": "blah", }, }, }, }, } return rc }
func newReplicationController(replicas int) *v1.ReplicationController { rc := &v1.ReplicationController{ TypeMeta: metav1.TypeMeta{APIVersion: api.Registry.GroupOrDie(v1.GroupName).GroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ UID: uuid.NewUUID(), Name: "foobar", Namespace: v1.NamespaceDefault, ResourceVersion: "18", }, Spec: v1.ReplicationControllerSpec{ Replicas: func() *int32 { i := int32(replicas); return &i }(), Selector: map[string]string{"foo": "bar"}, Template: &v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ "name": "foo", "type": "production", }, }, Spec: v1.PodSpec{ Containers: []v1.Container{ { Image: "foo/bar", TerminationMessagePath: v1.TerminationMessagePathDefault, ImagePullPolicy: v1.PullIfNotPresent, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, RestartPolicy: v1.RestartPolicyAlways, DNSPolicy: v1.DNSDefault, NodeSelector: map[string]string{ "baz": "blah", }, }, }, }, } return rc }
func newReplicaSet(replicas int, selectorMap map[string]string) *extensions.ReplicaSet { rs := &extensions.ReplicaSet{ TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.GroupVersion().String()}, ObjectMeta: api.ObjectMeta{ UID: uuid.NewUUID(), Name: "foobar", Namespace: api.NamespaceDefault, ResourceVersion: "18", }, Spec: extensions.ReplicaSetSpec{ Replicas: int32(replicas), Selector: &unversioned.LabelSelector{MatchLabels: selectorMap}, Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{ "name": "foo", "type": "production", }, }, Spec: api.PodSpec{ Containers: []api.Container{ { Image: "foo/bar", TerminationMessagePath: api.TerminationMessagePathDefault, ImagePullPolicy: api.PullIfNotPresent, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSDefault, NodeSelector: map[string]string{ "baz": "blah", }, }, }, }, } return rs }
func newPod(podName string, nodeName string, label map[string]string) *api.Pod { pod := &api.Pod{ TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.GroupVersion().String()}, ObjectMeta: api.ObjectMeta{ GenerateName: podName, Labels: label, Namespace: api.NamespaceDefault, }, Spec: api.PodSpec{ NodeName: nodeName, Containers: []api.Container{ { Image: "foo/bar", TerminationMessagePath: api.TerminationMessagePathDefault, ImagePullPolicy: api.PullIfNotPresent, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, DNSPolicy: api.DNSDefault, }, } api.GenerateName(api.SimpleNameGenerator, &pod.ObjectMeta) return pod }
func newPod(podName string, nodeName string, label map[string]string) *v1.Pod { pod := &v1.Pod{ TypeMeta: metav1.TypeMeta{APIVersion: registered.GroupOrDie(v1.GroupName).GroupVersion.String()}, ObjectMeta: v1.ObjectMeta{ GenerateName: podName, Labels: label, Namespace: v1.NamespaceDefault, }, Spec: v1.PodSpec{ NodeName: nodeName, Containers: []v1.Container{ { Image: "foo/bar", TerminationMessagePath: v1.TerminationMessagePathDefault, ImagePullPolicy: v1.PullIfNotPresent, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, DNSPolicy: v1.DNSDefault, }, } v1.GenerateName(v1.SimpleNameGenerator, &pod.ObjectMeta) return pod }
func TestEtcdUpdateScheduled(t *testing.T) { storage, _, _, server := newStorage(t) defer server.Terminate(t) ctx := api.NewDefaultContext() key, _ := storage.KeyFunc(ctx, "foo") key = etcdtest.AddPrefix(key) err := storage.Storage.Create(ctx, key, &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{ { Name: "foobar", Image: "foo:v1", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, SecurityContext: &api.PodSecurityContext{}, }, }, nil, 1) if err != nil { t.Errorf("Unexpected error: %v", err) } grace := int64(30) podIn := api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ "foo": "bar", }, }, Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{{ Name: "foobar", Image: "foo:v2", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePath: api.TerminationMessagePathDefault, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, SecurityContext: &api.PodSecurityContext{}, }, } _, _, err = storage.Update(ctx, &podIn) if err != nil { t.Errorf("Unexpected error: %v", err) } obj, err := storage.Get(ctx, "foo") if err != nil { t.Errorf("Unexpected error: %v", err) } podOut := obj.(*api.Pod) // Check to verify the Spec and Label updates match from change above. Those are the fields changed. if !api.Semantic.DeepEqual(podOut.Spec, podIn.Spec) || !api.Semantic.DeepEqual(podOut.Labels, podIn.Labels) { t.Errorf("objects differ: %v", util.ObjectDiff(podOut, podIn)) } }
func TestDecodePodList(t *testing.T) { grace := int64(30) pod := &api.Pod{ TypeMeta: unversioned.TypeMeta{ APIVersion: "", }, ObjectMeta: api.ObjectMeta{ Name: "test", UID: "12345", Namespace: "mynamespace", }, Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, Containers: []api.Container{{ Name: "image", Image: "test/image", ImagePullPolicy: "IfNotPresent", TerminationMessagePath: "/dev/termination-log", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, SecurityContext: &api.PodSecurityContext{}, }, } podList := &api.PodList{ Items: []api.Pod{*pod}, } json, err := testapi.Default.Codec().Encode(podList) if err != nil { t.Errorf("unexpected error: %v", err) } parsed, podListOut, err := tryDecodePodList(json, noDefault) if !parsed { t.Errorf("expected to have parsed file: (%s)", string(json)) } if err != nil { t.Errorf("unexpected error: %v (%s)", err, string(json)) } if !reflect.DeepEqual(podList, &podListOut) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", podList, &podListOut, string(json)) } for _, gv := range registered.EnabledVersionsForGroup(api.GroupName) { externalPodList, err := testapi.Default.Converter().ConvertToVersion(podList, gv.String()) if err != nil { t.Errorf("unexpected error: %v", err) } yaml, err := yaml.Marshal(externalPodList) if err != nil { t.Errorf("unexpected error: %v", err) } parsed, podListOut, err = tryDecodePodList(yaml, noDefault) if !parsed { t.Errorf("expected to have parsed file: (%s)", string(yaml)) } if err != nil { t.Errorf("unexpected error: %v (%s)", err, string(yaml)) } if !reflect.DeepEqual(podList, &podListOut) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, &podListOut, string(yaml)) } } }
func TestEtcdUpdateStatus(t *testing.T) { storage, _, statusStorage, fakeClient := newStorage(t) ctx := api.NewDefaultContext() fakeClient.TestIndex = true key, _ := storage.KeyFunc(ctx, "foo") key = etcdtest.AddPrefix(key) podStart := api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{ { Image: "foo:v1", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, }, } fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &podStart), 0) podIn := api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", ResourceVersion: "1", Labels: map[string]string{ "foo": "bar", }, }, Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{ { Image: "foo:v2", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePath: api.TerminationMessagePathDefault, }, }, }, Status: api.PodStatus{ Phase: api.PodRunning, PodIP: "127.0.0.1", Message: "is now scheduled", }, } expected := podStart expected.ResourceVersion = "2" grace := int64(30) expected.Spec.TerminationGracePeriodSeconds = &grace expected.Spec.RestartPolicy = api.RestartPolicyAlways expected.Spec.DNSPolicy = api.DNSClusterFirst expected.Spec.Containers[0].ImagePullPolicy = api.PullIfNotPresent expected.Spec.Containers[0].TerminationMessagePath = api.TerminationMessagePathDefault expected.Labels = podIn.Labels expected.Status = podIn.Status _, _, err := statusStorage.Update(ctx, &podIn) if err != nil { t.Fatalf("Unexpected error: %v", err) } podOut, err := storage.Get(ctx, "foo") if err != nil { t.Errorf("unexpected error: %v", err) } if !api.Semantic.DeepEqual(&expected, podOut) { t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, podOut)) } }
func TestEtcdUpdateScheduled(t *testing.T) { storage, _, _, fakeClient := newStorage(t) ctx := api.NewDefaultContext() fakeClient.TestIndex = true key, _ := storage.KeyFunc(ctx, "foo") key = etcdtest.AddPrefix(key) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{ { Name: "foobar", Image: "foo:v1", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, }, }), 1) grace := int64(30) podIn := api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", ResourceVersion: "1", Labels: map[string]string{ "foo": "bar", }, }, Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{ { Name: "foobar", Image: "foo:v2", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePath: api.TerminationMessagePathDefault, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, }, } _, _, err := storage.Update(ctx, &podIn) if err != nil { t.Errorf("Unexpected error: %v", err) } response, err := fakeClient.Get(key, false, false) if err != nil { t.Fatalf("Unexpected error: %v", err) } var podOut api.Pod testapi.Codec().DecodeInto([]byte(response.Node.Value), &podOut) if !api.Semantic.DeepEqual(podOut, podIn) { t.Errorf("expected: %#v, got: %#v", podOut, podIn) } }
func TestReadPodsFromFile(t *testing.T) { nodeName := "random-test-hostname" grace := int64(30) var testCases = []struct { desc string pod runtime.Object expected kubetypes.PodUpdate }{ { desc: "Simple pod", pod: &api.Pod{ TypeMeta: unversioned.TypeMeta{ Kind: "Pod", APIVersion: "", }, ObjectMeta: api.ObjectMeta{ Name: "test", UID: "12345", Namespace: "mynamespace", }, Spec: api.PodSpec{ Containers: []api.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, SecurityContext: &api.PodSecurityContext{}, }, Status: api.PodStatus{ Phase: api.PodPending, }, }, expected: CreatePodUpdate(kubetypes.SET, kubetypes.FileSource, &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-" + nodeName, UID: "12345", Namespace: "mynamespace", Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "12345"}, SelfLink: getSelfLink("test-"+nodeName, "mynamespace"), }, Spec: api.PodSpec{ NodeName: nodeName, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, Containers: []api.Container{{ Name: "image", Image: "test/image", TerminationMessagePath: "/dev/termination-log", ImagePullPolicy: "Always", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, SecurityContext: &api.PodSecurityContext{}, }, Status: api.PodStatus{ Phase: api.PodPending, }, }), }, } for _, testCase := range testCases { func() { var versionedPod runtime.Object err := testapi.Default.Converter().Convert(&testCase.pod, &versionedPod, nil) if err != nil { t.Fatalf("%s: error in versioning the pod: %v", testCase.desc, err) } fileContents, err := runtime.Encode(testapi.Default.Codec(), versionedPod) if err != nil { t.Fatalf("%s: error in encoding the pod: %v", testCase.desc, err) } file := writeTestFile(t, os.TempDir(), "test_pod_config", string(fileContents)) defer os.Remove(file.Name()) ch := make(chan interface{}) NewSourceFile(file.Name(), types.NodeName(nodeName), time.Millisecond, ch) select { case got := <-ch: update := got.(kubetypes.PodUpdate) for _, pod := range update.Pods { if errs := validation.ValidatePod(pod); len(errs) > 0 { t.Errorf("%s: Invalid pod %#v, %#v", testCase.desc, pod, errs) } } if !api.Semantic.DeepEqual(testCase.expected, update) { t.Errorf("%s: Expected %#v, Got %#v", testCase.desc, testCase.expected, update) } case <-time.After(wait.ForeverTestTimeout): t.Errorf("%s: Expected update, timeout instead", testCase.desc) } }() } }
func TestEtcdUpdateStatus(t *testing.T) { storage, _, statusStorage, server := newStorage(t) defer server.Terminate(t) ctx := api.NewDefaultContext() key, _ := storage.KeyFunc(ctx, "foo") key = etcdtest.AddPrefix(key) podStart := api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{ { Image: "foo:v1", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, SecurityContext: &api.PodSecurityContext{}, }, } err := storage.Storage.Create(ctx, key, &podStart, nil, 0) if err != nil { t.Errorf("unexpected error: %v", err) } podIn := api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ "foo": "bar", }, }, Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{ { Image: "foo:v2", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePath: api.TerminationMessagePathDefault, }, }, SecurityContext: &api.PodSecurityContext{}, }, Status: api.PodStatus{ Phase: api.PodRunning, PodIP: "127.0.0.1", Message: "is now scheduled", }, } expected := podStart expected.ResourceVersion = "2" grace := int64(30) expected.Spec.TerminationGracePeriodSeconds = &grace expected.Spec.RestartPolicy = api.RestartPolicyAlways expected.Spec.DNSPolicy = api.DNSClusterFirst expected.Spec.Containers[0].ImagePullPolicy = api.PullIfNotPresent expected.Spec.Containers[0].TerminationMessagePath = api.TerminationMessagePathDefault expected.Labels = podIn.Labels expected.Status = podIn.Status _, _, err = statusStorage.Update(ctx, &podIn) if err != nil { t.Fatalf("Unexpected error: %v", err) } obj, err := storage.Get(ctx, "foo") if err != nil { t.Errorf("unexpected error: %v", err) } podOut := obj.(*api.Pod) // Check to verify the Spec, Label, and Status updates match from change above. Those are the fields changed. if !api.Semantic.DeepEqual(podOut.Spec, podIn.Spec) || !api.Semantic.DeepEqual(podOut.Labels, podIn.Labels) || !api.Semantic.DeepEqual(podOut.Status, podIn.Status) { t.Errorf("objects differ: %v", util.ObjectDiff(podOut, podIn)) } }