func TestNewStatusPreservesPodStartTime(t *testing.T) { syncer := newTestStatusManager() pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ UID: "12345678", Name: "foo", Namespace: "new", }, Status: api.PodStatus{}, } now := util.Now() startTime := util.NewTime(now.Time.Add(-1 * time.Minute)) pod.Status.StartTime = &startTime syncer.SetPodStatus(pod, getRandomPodStatus()) status, _ := syncer.GetPodStatus(qingcontainer.GetPodFullName(pod)) if !status.StartTime.Time.Equal(startTime.Time) { t.Errorf("Unexpected start time, expected %v, actual %v", startTime, status.StartTime) } }
func TestPrintEventsResultSorted(t *testing.T) { // Arrange printer := NewHumanReadablePrinter(false /* noHeaders */, false, []string{}) obj := api.EventList{ Items: []api.Event{ { Source: api.EventSource{Component: "qinglet"}, Message: "Item 1", FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "scheduler"}, Message: "Item 2", FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "qinglet"}, Message: "Item 3", FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), Count: 1, }, }, } buffer := &bytes.Buffer{} // Act err := printer.PrintObj(&obj, buffer) // Assert if err != nil { t.Fatalf("An error occurred printing the EventList: %#v", err) } out := buffer.String() VerifyDatesInOrder(out, "\n" /* rowDelimiter */, " " /* columnDelimiter */, t) }
func TestPodDescribeResultsSorted(t *testing.T) { // Arrange fake := testclient.NewSimpleFake(&api.EventList{ Items: []api.Event{ { Source: api.EventSource{Component: "qinglet"}, Message: "Item 1", FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "scheduler"}, Message: "Item 2", FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "qinglet"}, Message: "Item 3", FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), Count: 1, }, }, }) c := &describeClient{T: t, Namespace: "foo", Interface: fake} d := PodDescriber{c} // Act out, err := d.Describe("foo", "bar") // Assert if err != nil { t.Errorf("unexpected error: %v", err) } VerifyDatesInOrder(out, "\n" /* rowDelimiter */, "\t" /* columnDelimiter */, t) }
func TestSortableEvents(t *testing.T) { // Arrange list := SortableEvents([]api.Event{ { Source: api.EventSource{Component: "qinglet"}, Message: "Item 1", FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "scheduler"}, Message: "Item 2", FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "qinglet"}, Message: "Item 3", FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), Count: 1, }, }) // Act sort.Sort(list) // Assert if list[0].Message != "Item 2" || list[1].Message != "Item 3" || list[2].Message != "Item 1" { t.Fatal("List is not sorted by time. List: ", list) } }
func TestDescribeContainers(t *testing.T) { testCases := []struct { container api.Container status api.ContainerStatus expectedElements []string }{ // Running state. { container: api.Container{Name: "test", Image: "image"}, status: api.ContainerStatus{ Name: "test", State: api.ContainerState{ Running: &api.ContainerStateRunning{ StartedAt: util.NewTime(time.Now()), }, }, Ready: true, RestartCount: 7, }, expectedElements: []string{"test", "State", "Running", "Ready", "True", "Restart Count", "7", "Image", "image", "Started"}, }, // Waiting state. { container: api.Container{Name: "test", Image: "image"}, status: api.ContainerStatus{ Name: "test", State: api.ContainerState{ Waiting: &api.ContainerStateWaiting{ Reason: "potato", }, }, Ready: true, RestartCount: 7, }, expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "Reason", "potato"}, }, // Terminated state. { container: api.Container{Name: "test", Image: "image"}, status: api.ContainerStatus{ Name: "test", State: api.ContainerState{ Terminated: &api.ContainerStateTerminated{ StartedAt: util.NewTime(time.Now()), FinishedAt: util.NewTime(time.Now()), Reason: "potato", ExitCode: 2, }, }, Ready: true, RestartCount: 7, }, expectedElements: []string{"test", "State", "Terminated", "Ready", "True", "Restart Count", "7", "Image", "image", "Reason", "potato", "Started", "Finished", "Exit Code", "2"}, }, // No state defaults to waiting. { container: api.Container{Name: "test", Image: "image"}, status: api.ContainerStatus{ Name: "test", Ready: true, RestartCount: 7, }, expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image"}, }, // Using limits. { container: api.Container{ Name: "test", Image: "image", Resources: api.ResourceRequirements{ Limits: api.ResourceList{ api.ResourceName(api.ResourceCPU): resource.MustParse("1000"), api.ResourceName(api.ResourceMemory): resource.MustParse("4G"), api.ResourceName(api.ResourceStorage): resource.MustParse("20G"), }, }, }, status: api.ContainerStatus{ Name: "test", Ready: true, RestartCount: 7, }, expectedElements: []string{"cpu", "1k", "memory", "4G", "storage", "20G"}, }, } for i, testCase := range testCases { out := new(bytes.Buffer) pod := api.Pod{ Spec: api.PodSpec{ Containers: []api.Container{testCase.container}, }, Status: api.PodStatus{ ContainerStatuses: []api.ContainerStatus{testCase.status}, }, } describeContainers(&pod, out) output := out.String() for _, expected := range testCase.expectedElements { if !strings.Contains(output, expected) { t.Errorf("Test case %d: expected to find %q in output: %q", i, expected, output) } } } }
func TestPrintHumanReadableWithNamespace(t *testing.T) { namespaceName := "testnamespace" name := "test" table := []struct { obj runtime.Object printNamespace bool }{ { obj: &api.Pod{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, }, printNamespace: true, }, { obj: &api.ReplicationController{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Spec: api.ReplicationControllerSpec{ Replicas: 2, 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, }, }, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSDefault, NodeSelector: map[string]string{ "baz": "blah", }, }, }, }, }, printNamespace: true, }, { obj: &api.Service{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Spec: api.ServiceSpec{ ClusterIP: "1.2.3.4", Ports: []api.ServicePort{ { Port: 80, Protocol: "TCP", }, }, }, Status: api.ServiceStatus{ LoadBalancer: api.LoadBalancerStatus{ Ingress: []api.LoadBalancerIngress{ { IP: "2.3.4.5", }, }, }, }, }, printNamespace: true, }, { obj: &api.Endpoints{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Subsets: []api.EndpointSubset{{ Addresses: []api.EndpointAddress{{IP: "127.0.0.1"}, {IP: "localhost"}}, Ports: []api.EndpointPort{{Port: 8080}}, }, }}, printNamespace: true, }, { obj: &api.Namespace{ ObjectMeta: api.ObjectMeta{Name: name}, }, printNamespace: false, }, { obj: &api.Secret{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, }, printNamespace: true, }, { obj: &api.ServiceAccount{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Secrets: []api.ObjectReference{}, }, printNamespace: true, }, { obj: &api.Node{ ObjectMeta: api.ObjectMeta{Name: name}, Status: api.NodeStatus{}, }, printNamespace: false, }, { obj: &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Spec: api.PersistentVolumeSpec{}, }, printNamespace: true, }, { obj: &api.PersistentVolumeClaim{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Spec: api.PersistentVolumeClaimSpec{}, }, printNamespace: true, }, { obj: &api.Event{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Source: api.EventSource{Component: "qinglet"}, Message: "Item 1", FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), Count: 1, }, printNamespace: false, }, { obj: &api.LimitRange{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, }, printNamespace: true, }, { obj: &api.ResourceQuota{ ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, }, printNamespace: true, }, { obj: &api.ComponentStatus{ Conditions: []api.ComponentCondition{ {Type: api.ComponentHealthy, Status: api.ConditionTrue, Message: "ok", Error: ""}, }, }, printNamespace: false, }, } printer := NewHumanReadablePrinter(false, false, []string{}) for _, test := range table { buffer := &bytes.Buffer{} err := printer.PrintObj(test.obj, buffer) if err != nil { t.Fatalf("An error occurred printing object: %#v", err) } matched := contains(strings.Fields(buffer.String()), fmt.Sprintf("%s/%s", namespaceName, name)) if matched { t.Errorf("Expect printing object not to contain namespace: %v", test.obj) } } printer = NewHumanReadablePrinter(false, true, []string{}) for _, test := range table { buffer := &bytes.Buffer{} err := printer.PrintObj(test.obj, buffer) if err != nil { t.Fatalf("An error occurred printing object: %#v", err) } matched := contains(strings.Fields(buffer.String()), fmt.Sprintf("%s/%s", namespaceName, name)) if test.printNamespace && !matched { t.Errorf("Expect printing object to contain namespace: %v", test.obj) } else if !test.printNamespace && matched { t.Errorf("Expect printing object not to contain namespace: %v", test.obj) } } }
defer GinkgoRecover() if p.Status.Phase == api.PodRunning { if _, found := watchTimes[p.Name]; !found { watchTimes[p.Name] = util.Now() createTimes[p.Name] = p.CreationTimestamp nodes[p.Name] = p.Spec.NodeName var startTime util.Time for _, cs := range p.Status.ContainerStatuses { if cs.State.Running != nil { if startTime.Before(cs.State.Running.StartedAt) { startTime = cs.State.Running.StartedAt } } } if startTime != util.NewTime(time.Time{}) { runTimes[p.Name] = startTime } else { Failf("Pod %v is reported to be running, but none of its containers is", p.Name) } } } } additionalPodsPrefix = "density-latency-pod-" + string(util.NewUUID()) _, controller := framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return c.Pods(ns).List(labels.SelectorFromSet(labels.Set{"name": additionalPodsPrefix}), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) {