1
16
17 package util
18
19 import (
20 "testing"
21
22 "github.com/stretchr/testify/require"
23
24 v1 "k8s.io/api/core/v1"
25 runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
26 kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
27 kubecontainertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
28 )
29
30 func TestPodSandboxChanged(t *testing.T) {
31 for desc, test := range map[string]struct {
32 pod *v1.Pod
33 status *kubecontainer.PodStatus
34 expectedChanged bool
35 expectedAttempt uint32
36 expectedSandboxID string
37 }{
38 "Pod with no existing sandboxes": {
39 pod: &v1.Pod{},
40 status: &kubecontainer.PodStatus{},
41 expectedChanged: true,
42 expectedAttempt: 0,
43 expectedSandboxID: "",
44 },
45 "Pod with multiple ready sandbox statuses": {
46 pod: &v1.Pod{},
47 status: &kubecontainer.PodStatus{
48 SandboxStatuses: []*runtimeapi.PodSandboxStatus{
49 {
50 Id: "sandboxID2",
51 Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(1)},
52 State: runtimeapi.PodSandboxState_SANDBOX_READY,
53 },
54 {
55 Id: "sandboxID1",
56 Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(0)},
57 State: runtimeapi.PodSandboxState_SANDBOX_READY,
58 },
59 },
60 },
61 expectedChanged: true,
62 expectedAttempt: 2,
63 expectedSandboxID: "sandboxID2",
64 },
65 "Pod with no ready sandbox statuses": {
66 pod: &v1.Pod{},
67 status: &kubecontainer.PodStatus{
68 SandboxStatuses: []*runtimeapi.PodSandboxStatus{
69 {
70 Id: "sandboxID2",
71 Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(1)},
72 State: runtimeapi.PodSandboxState_SANDBOX_NOTREADY,
73 },
74 {
75 Id: "sandboxID1",
76 Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(0)},
77 State: runtimeapi.PodSandboxState_SANDBOX_NOTREADY,
78 },
79 },
80 },
81 expectedChanged: true,
82 expectedAttempt: 2,
83 expectedSandboxID: "sandboxID2",
84 },
85 "Pod with ready sandbox status but network namespace mismatch": {
86 pod: &v1.Pod{
87 Spec: v1.PodSpec{
88 HostNetwork: true,
89 },
90 },
91 status: &kubecontainer.PodStatus{
92 SandboxStatuses: []*runtimeapi.PodSandboxStatus{
93 {
94 Id: "sandboxID1",
95 Linux: &runtimeapi.LinuxPodSandboxStatus{
96 Namespaces: &runtimeapi.Namespace{
97 Options: &runtimeapi.NamespaceOption{
98 Network: runtimeapi.NamespaceMode_POD,
99 },
100 },
101 },
102 Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(0)},
103 State: runtimeapi.PodSandboxState_SANDBOX_READY,
104 },
105 },
106 },
107 expectedChanged: true,
108 expectedAttempt: 1,
109 expectedSandboxID: "",
110 },
111 "Pod with ready sandbox status but no IP": {
112 pod: &v1.Pod{
113 Spec: v1.PodSpec{
114 HostNetwork: false,
115 },
116 },
117 status: &kubecontainer.PodStatus{
118 SandboxStatuses: []*runtimeapi.PodSandboxStatus{
119 {
120 Id: "sandboxID1",
121 Network: &runtimeapi.PodSandboxNetworkStatus{
122 Ip: "",
123 },
124 Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(0)},
125 State: runtimeapi.PodSandboxState_SANDBOX_READY,
126 },
127 },
128 },
129 expectedChanged: true,
130 expectedAttempt: 1,
131 expectedSandboxID: "sandboxID1",
132 },
133 "Pod with ready sandbox status with IP": {
134 pod: &v1.Pod{
135 Spec: v1.PodSpec{
136 HostNetwork: false,
137 },
138 },
139 status: &kubecontainer.PodStatus{
140 SandboxStatuses: []*runtimeapi.PodSandboxStatus{
141 {
142 Id: "sandboxID1",
143 Network: &runtimeapi.PodSandboxNetworkStatus{
144 Ip: "10.0.0.10",
145 },
146 Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(0)},
147 State: runtimeapi.PodSandboxState_SANDBOX_READY,
148 },
149 },
150 },
151 expectedChanged: false,
152 expectedAttempt: 0,
153 expectedSandboxID: "sandboxID1",
154 },
155 } {
156 t.Run(desc, func(t *testing.T) {
157 changed, attempt, id := PodSandboxChanged(test.pod, test.status)
158 require.Equal(t, test.expectedChanged, changed)
159 require.Equal(t, test.expectedAttempt, attempt)
160 require.Equal(t, test.expectedSandboxID, id)
161 })
162 }
163 }
164
165 func TestNamespacesForPod(t *testing.T) {
166 for desc, test := range map[string]struct {
167 input *v1.Pod
168 expected *runtimeapi.NamespaceOption
169 }{
170 "nil pod -> default v1 namespaces": {
171 input: nil,
172 expected: &runtimeapi.NamespaceOption{
173 Ipc: runtimeapi.NamespaceMode_POD,
174 Network: runtimeapi.NamespaceMode_POD,
175 Pid: runtimeapi.NamespaceMode_CONTAINER,
176 },
177 },
178 "v1.Pod default namespaces": {
179 input: &v1.Pod{},
180 expected: &runtimeapi.NamespaceOption{
181 Ipc: runtimeapi.NamespaceMode_POD,
182 Network: runtimeapi.NamespaceMode_POD,
183 Pid: runtimeapi.NamespaceMode_CONTAINER,
184 },
185 },
186 "Host Namespaces": {
187 input: &v1.Pod{
188 Spec: v1.PodSpec{
189 HostIPC: true,
190 HostNetwork: true,
191 HostPID: true,
192 },
193 },
194 expected: &runtimeapi.NamespaceOption{
195 Ipc: runtimeapi.NamespaceMode_NODE,
196 Network: runtimeapi.NamespaceMode_NODE,
197 Pid: runtimeapi.NamespaceMode_NODE,
198 },
199 },
200 "Shared Process Namespace (feature enabled)": {
201 input: &v1.Pod{
202 Spec: v1.PodSpec{
203 ShareProcessNamespace: &[]bool{true}[0],
204 },
205 },
206 expected: &runtimeapi.NamespaceOption{
207 Ipc: runtimeapi.NamespaceMode_POD,
208 Network: runtimeapi.NamespaceMode_POD,
209 Pid: runtimeapi.NamespaceMode_POD,
210 },
211 },
212 "Shared Process Namespace, redundant flag (feature enabled)": {
213 input: &v1.Pod{
214 Spec: v1.PodSpec{
215 ShareProcessNamespace: &[]bool{false}[0],
216 },
217 },
218 expected: &runtimeapi.NamespaceOption{
219 Ipc: runtimeapi.NamespaceMode_POD,
220 Network: runtimeapi.NamespaceMode_POD,
221 Pid: runtimeapi.NamespaceMode_CONTAINER,
222 },
223 },
224 } {
225 t.Run(desc, func(t *testing.T) {
226 actual, err := NamespacesForPod(test.input, &kubecontainertest.FakeRuntimeHelper{}, nil)
227 require.NoError(t, err)
228 require.Equal(t, test.expected, actual)
229 })
230 }
231 }
232
View as plain text