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