1/*
2Copyright 2016 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package kubelet
18
19import (
20	"reflect"
21	"testing"
22	"time"
23
24	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
25)
26
27func TestGetContainersToDeleteInPodWithFilter(t *testing.T) {
28	pod := kubecontainer.PodStatus{
29		ContainerStatuses: []*kubecontainer.Status{
30			{
31				ID:        kubecontainer.ContainerID{Type: "test", ID: "1"},
32				Name:      "foo",
33				CreatedAt: time.Now(),
34				State:     kubecontainer.ContainerStateExited,
35			},
36			{
37				ID:        kubecontainer.ContainerID{Type: "test", ID: "2"},
38				Name:      "bar",
39				CreatedAt: time.Now().Add(time.Second),
40				State:     kubecontainer.ContainerStateExited,
41			},
42			{
43				ID:        kubecontainer.ContainerID{Type: "test", ID: "3"},
44				Name:      "bar",
45				CreatedAt: time.Now().Add(2 * time.Second),
46				State:     kubecontainer.ContainerStateExited,
47			},
48			{
49				ID:        kubecontainer.ContainerID{Type: "test", ID: "4"},
50				Name:      "bar",
51				CreatedAt: time.Now().Add(3 * time.Second),
52				State:     kubecontainer.ContainerStateExited,
53			},
54			{
55				ID:        kubecontainer.ContainerID{Type: "test", ID: "5"},
56				Name:      "bar",
57				CreatedAt: time.Now().Add(4 * time.Second),
58				State:     kubecontainer.ContainerStateRunning,
59			},
60		},
61	}
62
63	testCases := []struct {
64		containersToKeep           int
65		expectedContainersToDelete containerStatusbyCreatedList
66	}{
67		{
68			0,
69			[]*kubecontainer.Status{pod.ContainerStatuses[3], pod.ContainerStatuses[2], pod.ContainerStatuses[1]},
70		},
71		{
72			1,
73			[]*kubecontainer.Status{pod.ContainerStatuses[2], pod.ContainerStatuses[1]},
74		},
75		{
76			2,
77			[]*kubecontainer.Status{pod.ContainerStatuses[1]},
78		},
79	}
80
81	for _, test := range testCases {
82		candidates := getContainersToDeleteInPod("4", &pod, test.containersToKeep)
83		if !reflect.DeepEqual(candidates, test.expectedContainersToDelete) {
84			t.Errorf("expected %v got %v", test.expectedContainersToDelete, candidates)
85		}
86	}
87}
88
89func TestGetContainersToDeleteInPod(t *testing.T) {
90	pod := kubecontainer.PodStatus{
91		ContainerStatuses: []*kubecontainer.Status{
92			{
93				ID:        kubecontainer.ContainerID{Type: "test", ID: "1"},
94				Name:      "foo",
95				CreatedAt: time.Now(),
96				State:     kubecontainer.ContainerStateExited,
97			},
98			{
99				ID:        kubecontainer.ContainerID{Type: "test", ID: "2"},
100				Name:      "bar",
101				CreatedAt: time.Now().Add(time.Second),
102				State:     kubecontainer.ContainerStateExited,
103			},
104			{
105				ID:        kubecontainer.ContainerID{Type: "test", ID: "3"},
106				Name:      "bar",
107				CreatedAt: time.Now().Add(2 * time.Second),
108				State:     kubecontainer.ContainerStateExited,
109			},
110			{
111				ID:        kubecontainer.ContainerID{Type: "test", ID: "4"},
112				Name:      "bar",
113				CreatedAt: time.Now().Add(3 * time.Second),
114				State:     kubecontainer.ContainerStateExited,
115			},
116			{
117				ID:        kubecontainer.ContainerID{Type: "test", ID: "5"},
118				Name:      "bar",
119				CreatedAt: time.Now().Add(4 * time.Second),
120				State:     kubecontainer.ContainerStateRunning,
121			},
122		},
123	}
124
125	testCases := []struct {
126		containersToKeep           int
127		expectedContainersToDelete containerStatusbyCreatedList
128	}{
129		{
130			0,
131			[]*kubecontainer.Status{pod.ContainerStatuses[3], pod.ContainerStatuses[2], pod.ContainerStatuses[1], pod.ContainerStatuses[0]},
132		},
133		{
134			1,
135			[]*kubecontainer.Status{pod.ContainerStatuses[2], pod.ContainerStatuses[1], pod.ContainerStatuses[0]},
136		},
137		{
138			2,
139			[]*kubecontainer.Status{pod.ContainerStatuses[1], pod.ContainerStatuses[0]},
140		},
141	}
142
143	for _, test := range testCases {
144		candidates := getContainersToDeleteInPod("", &pod, test.containersToKeep)
145		if !reflect.DeepEqual(candidates, test.expectedContainersToDelete) {
146			t.Errorf("expected %v got %v", test.expectedContainersToDelete, candidates)
147		}
148	}
149}
150
151func TestGetContainersToDeleteInPodWithNoMatch(t *testing.T) {
152	pod := kubecontainer.PodStatus{
153		ContainerStatuses: []*kubecontainer.Status{
154			{
155				ID:        kubecontainer.ContainerID{Type: "test", ID: "1"},
156				Name:      "foo",
157				CreatedAt: time.Now(),
158				State:     kubecontainer.ContainerStateExited,
159			},
160			{
161				ID:        kubecontainer.ContainerID{Type: "test", ID: "2"},
162				Name:      "bar",
163				CreatedAt: time.Now().Add(time.Second),
164				State:     kubecontainer.ContainerStateExited,
165			},
166			{
167				ID:        kubecontainer.ContainerID{Type: "test", ID: "3"},
168				Name:      "bar",
169				CreatedAt: time.Now().Add(2 * time.Second),
170				State:     kubecontainer.ContainerStateExited,
171			},
172			{
173				ID:        kubecontainer.ContainerID{Type: "test", ID: "4"},
174				Name:      "bar",
175				CreatedAt: time.Now().Add(3 * time.Second),
176				State:     kubecontainer.ContainerStateExited,
177			},
178			{
179				ID:        kubecontainer.ContainerID{Type: "test", ID: "5"},
180				Name:      "bar",
181				CreatedAt: time.Now().Add(4 * time.Second),
182				State:     kubecontainer.ContainerStateRunning,
183			},
184		},
185	}
186
187	testCases := []struct {
188		filterID                   string
189		expectedContainersToDelete containerStatusbyCreatedList
190	}{
191		{
192			"abc",
193			[]*kubecontainer.Status{},
194		},
195	}
196
197	for _, test := range testCases {
198		candidates := getContainersToDeleteInPod(test.filterID, &pod, len(pod.ContainerStatuses))
199		if !reflect.DeepEqual(candidates, test.expectedContainersToDelete) {
200			t.Errorf("expected %v got %v", test.expectedContainersToDelete, candidates)
201		}
202	}
203}
204