// newTestNetworkPlugin returns a mock plugin that implements network.NetworkPlugin func newTestNetworkPlugin(t *testing.T) *mock_network.MockNetworkPlugin { ctrl := gomock.NewController(t) return mock_network.NewMockNetworkPlugin(ctrl) }
func TestGetPodStatus(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() fr := newFakeRktInterface() fs := newFakeSystemd() fnp := mock_network.NewMockNetworkPlugin(ctrl) fos := &containertesting.FakeOS{} frh := &fakeRuntimeHelper{} r := &Runtime{ apisvc: fr, systemd: fs, runtimeHelper: frh, os: fos, networkPlugin: fnp, } ns := func(seconds int64) int64 { return seconds * 1e9 } tests := []struct { pods []*rktapi.Pod result *kubecontainer.PodStatus }{ // No pods. { nil, &kubecontainer.PodStatus{ID: "42", Name: "guestbook", Namespace: "default"}, }, // One pod. { []*rktapi.Pod{ makeRktPod(rktapi.PodState_POD_STATE_RUNNING, "uuid-4002", "42", "guestbook", "default", ns(10), ns(20), "7", []string{"app-1", "app-2"}, []string{"img-id-1", "img-id-2"}, []string{"img-name-1", "img-name-2"}, []string{"1001", "1002"}, []rktapi.AppState{rktapi.AppState_APP_STATE_RUNNING, rktapi.AppState_APP_STATE_EXITED}, []int32{0, 0}, ), }, &kubecontainer.PodStatus{ ID: "42", Name: "guestbook", Namespace: "default", IP: "10.10.10.42", ContainerStatuses: []*kubecontainer.ContainerStatus{ { ID: kubecontainer.BuildContainerID("rkt", "uuid-4002:app-1"), Name: "app-1", State: kubecontainer.ContainerStateRunning, CreatedAt: time.Unix(10, 0), StartedAt: time.Unix(20, 0), FinishedAt: time.Unix(0, 30), Image: "img-name-1:latest", ImageID: "rkt://img-id-1", Hash: 1001, RestartCount: 7, }, { ID: kubecontainer.BuildContainerID("rkt", "uuid-4002:app-2"), Name: "app-2", State: kubecontainer.ContainerStateExited, CreatedAt: time.Unix(10, 0), StartedAt: time.Unix(20, 0), FinishedAt: time.Unix(0, 30), Image: "img-name-2:latest", ImageID: "rkt://img-id-2", Hash: 1002, RestartCount: 7, Reason: "Completed", }, }, }, }, // Multiple pods. { []*rktapi.Pod{ makeRktPod(rktapi.PodState_POD_STATE_EXITED, "uuid-4002", "42", "guestbook", "default", ns(10), ns(20), "7", []string{"app-1", "app-2"}, []string{"img-id-1", "img-id-2"}, []string{"img-name-1", "img-name-2"}, []string{"1001", "1002"}, []rktapi.AppState{rktapi.AppState_APP_STATE_RUNNING, rktapi.AppState_APP_STATE_EXITED}, []int32{0, 0}, ), makeRktPod(rktapi.PodState_POD_STATE_RUNNING, // The latest pod is running. "uuid-4003", "42", "guestbook", "default", ns(10), ns(20), "10", []string{"app-1", "app-2"}, []string{"img-id-1", "img-id-2"}, []string{"img-name-1", "img-name-2"}, []string{"1001", "1002"}, []rktapi.AppState{rktapi.AppState_APP_STATE_RUNNING, rktapi.AppState_APP_STATE_EXITED}, []int32{0, 1}, ), }, &kubecontainer.PodStatus{ ID: "42", Name: "guestbook", Namespace: "default", IP: "10.10.10.42", // Result should contain all containers. ContainerStatuses: []*kubecontainer.ContainerStatus{ { ID: kubecontainer.BuildContainerID("rkt", "uuid-4002:app-1"), Name: "app-1", State: kubecontainer.ContainerStateRunning, CreatedAt: time.Unix(10, 0), StartedAt: time.Unix(20, 0), FinishedAt: time.Unix(0, 30), Image: "img-name-1:latest", ImageID: "rkt://img-id-1", Hash: 1001, RestartCount: 7, }, { ID: kubecontainer.BuildContainerID("rkt", "uuid-4002:app-2"), Name: "app-2", State: kubecontainer.ContainerStateExited, CreatedAt: time.Unix(10, 0), StartedAt: time.Unix(20, 0), FinishedAt: time.Unix(0, 30), Image: "img-name-2:latest", ImageID: "rkt://img-id-2", Hash: 1002, RestartCount: 7, Reason: "Completed", }, { ID: kubecontainer.BuildContainerID("rkt", "uuid-4003:app-1"), Name: "app-1", State: kubecontainer.ContainerStateRunning, CreatedAt: time.Unix(10, 0), StartedAt: time.Unix(20, 0), FinishedAt: time.Unix(0, 30), Image: "img-name-1:latest", ImageID: "rkt://img-id-1", Hash: 1001, RestartCount: 10, }, { ID: kubecontainer.BuildContainerID("rkt", "uuid-4003:app-2"), Name: "app-2", State: kubecontainer.ContainerStateExited, CreatedAt: time.Unix(10, 0), StartedAt: time.Unix(20, 0), FinishedAt: time.Unix(0, 30), Image: "img-name-2:latest", ImageID: "rkt://img-id-2", Hash: 1002, RestartCount: 10, ExitCode: 1, Reason: "Error", }, }, }, }, } for i, tt := range tests { testCaseHint := fmt.Sprintf("test case #%d", i) fr.pods = tt.pods podTimes := map[string]time.Time{} for _, pod := range tt.pods { podTimes[podFinishedMarkerPath(r.runtimeHelper.GetPodDir(tt.result.ID), pod.Id)] = tt.result.ContainerStatuses[0].FinishedAt } r.os.(*containertesting.FakeOS).StatFn = func(name string) (os.FileInfo, error) { podTime, ok := podTimes[name] if !ok { t.Errorf("osStat called with %v, but only knew about %#v", name, podTimes) } mockFI := mock_os.NewMockFileInfo(ctrl) mockFI.EXPECT().ModTime().Return(podTime) return mockFI, nil } if tt.result.IP != "" { fnp.EXPECT().GetPodNetworkStatus("default", "guestbook", kubecontainer.ContainerID{ID: "42"}). Return(&network.PodNetworkStatus{IP: net.ParseIP(tt.result.IP)}, nil) } else { fnp.EXPECT().GetPodNetworkStatus("default", "guestbook", kubecontainer.ContainerID{ID: "42"}). Return(nil, fmt.Errorf("no such network")) } status, err := r.GetPodStatus("42", "guestbook", "default") if err != nil { t.Errorf("test case #%d: unexpected error: %v", i, err) } assert.Equal(t, tt.result, status, testCaseHint) assert.Equal(t, []string{"ListPods"}, fr.called, testCaseHint) fr.CleanCalls() } }
func TestGetPodStatusFromNetworkPlugin(t *testing.T) { cases := []struct { pod *v1.Pod fakePodIP string containerID string infraContainerID string networkStatusError error expectRunning bool expectUnknown bool }{ { pod: &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ UID: "12345678", Name: "foo", Namespace: "new", }, Spec: v1.PodSpec{ Containers: []v1.Container{{Name: "container"}}, }, }, fakePodIP: "10.10.10.10", containerID: "123", infraContainerID: "9876", networkStatusError: nil, expectRunning: true, expectUnknown: false, }, { pod: &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ UID: "12345678", Name: "foo", Namespace: "new", }, Spec: v1.PodSpec{ Containers: []v1.Container{{Name: "container"}}, }, }, fakePodIP: "", containerID: "123", infraContainerID: "9876", networkStatusError: fmt.Errorf("CNI plugin error"), expectRunning: false, expectUnknown: true, }, } for _, test := range cases { dm, fakeDocker := newTestDockerManager() ctrl := gomock.NewController(t) fnp := mock_network.NewMockNetworkPlugin(ctrl) dm.networkPlugin = fnp fakeDocker.SetFakeRunningContainers([]*FakeContainer{ { ID: test.containerID, Name: fmt.Sprintf("/k8s_container_%s_%s_%s_42", test.pod.Name, test.pod.Namespace, test.pod.UID), Running: true, }, { ID: test.infraContainerID, Name: fmt.Sprintf("/k8s_POD.%s_%s_%s_%s_42", strconv.FormatUint(generatePodInfraContainerHash(test.pod), 16), test.pod.Name, test.pod.Namespace, test.pod.UID), Running: true, }, }) fnp.EXPECT().Name().Return("someNetworkPlugin").AnyTimes() var podNetworkStatus *network.PodNetworkStatus if test.fakePodIP != "" { podNetworkStatus = &network.PodNetworkStatus{IP: net.ParseIP(test.fakePodIP)} } fnp.EXPECT().GetPodNetworkStatus(test.pod.Namespace, test.pod.Name, kubecontainer.DockerID(test.infraContainerID).ContainerID()).Return(podNetworkStatus, test.networkStatusError) podStatus, err := dm.GetPodStatus(test.pod.UID, test.pod.Name, test.pod.Namespace) if err != nil { t.Fatal(err) } if podStatus.IP != test.fakePodIP { t.Errorf("Got wrong ip, expected %v, got %v", test.fakePodIP, podStatus.IP) } expectedStatesCount := 0 var expectedState kubecontainer.ContainerState if test.expectRunning { expectedState = kubecontainer.ContainerStateRunning } else if test.expectUnknown { expectedState = kubecontainer.ContainerStateUnknown } else { t.Errorf("Some state has to be expected") } for _, containerStatus := range podStatus.ContainerStatuses { if containerStatus.State == expectedState { expectedStatesCount++ } } if expectedStatesCount < 1 { t.Errorf("Invalid count of containers with expected state") } } }