Skip to content

Commit 3a21d11

Browse files
committed
add pod update events, add init containers test
1 parent a6c0ce9 commit 3a21d11

1 file changed

Lines changed: 114 additions & 8 deletions

File tree

internal/controller/controller_integration_test.go

Lines changed: 114 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,63 @@ func makePod(t *testing.T, clientset *kubernetes.Clientset, owners []metav1.Owne
179179
t.Fatalf("failed to create Pod: %v", err)
180180
}
181181

182-
created.Status.Phase = corev1.PodRunning
183-
created.Status.ContainerStatuses = []corev1.ContainerStatus{{
182+
// First set the pod to Pending phase
183+
created.Status.Phase = corev1.PodPending
184+
pending, err := clientset.CoreV1().Pods(namespace).UpdateStatus(ctx, created, metav1.UpdateOptions{})
185+
if err != nil {
186+
t.Fatalf("failed to update Pod status to Pending: %v", err)
187+
}
188+
189+
// Then transition to Running
190+
pending.Status.Phase = corev1.PodRunning
191+
pending.Status.ContainerStatuses = []corev1.ContainerStatus{{
192+
Name: "app",
193+
ImageID: "docker-pullable://nginx@sha256:abc123def456",
194+
}}
195+
updated, err := clientset.CoreV1().Pods(namespace).UpdateStatus(ctx, pending, metav1.UpdateOptions{})
196+
if err != nil {
197+
t.Fatalf("failed to update Pod status to Running: %v", err)
198+
}
199+
return updated
200+
}
201+
202+
func makePodWithInitContainer(t *testing.T, clientset *kubernetes.Clientset, owners []metav1.OwnerReference, namespace, name string) *corev1.Pod {
203+
t.Helper()
204+
ctx := context.Background()
205+
pod := &corev1.Pod{
206+
ObjectMeta: metav1.ObjectMeta{
207+
Name: name,
208+
Namespace: namespace,
209+
OwnerReferences: owners,
210+
},
211+
Spec: corev1.PodSpec{
212+
InitContainers: []corev1.Container{{Name: "init", Image: "busybox:latest"}},
213+
Containers: []corev1.Container{{Name: "app", Image: "nginx:latest"}},
214+
},
215+
}
216+
created, err := clientset.CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{})
217+
if err != nil {
218+
t.Fatalf("failed to create Pod: %v", err)
219+
}
220+
221+
created.Status.Phase = corev1.PodPending
222+
pending, err := clientset.CoreV1().Pods(namespace).UpdateStatus(ctx, created, metav1.UpdateOptions{})
223+
if err != nil {
224+
t.Fatalf("failed to update Pod status to Pending: %v", err)
225+
}
226+
227+
pending.Status.Phase = corev1.PodRunning
228+
pending.Status.InitContainerStatuses = []corev1.ContainerStatus{{
229+
Name: "init",
230+
ImageID: "docker-pullable://busybox@sha256:initdigest789",
231+
}}
232+
pending.Status.ContainerStatuses = []corev1.ContainerStatus{{
184233
Name: "app",
185234
ImageID: "docker-pullable://nginx@sha256:abc123def456",
186235
}}
187-
updated, err := clientset.CoreV1().Pods(namespace).UpdateStatus(ctx, created, metav1.UpdateOptions{})
236+
updated, err := clientset.CoreV1().Pods(namespace).UpdateStatus(ctx, pending, metav1.UpdateOptions{})
188237
if err != nil {
189-
t.Fatalf("failed to update Pod status: %v", err)
238+
t.Fatalf("failed to update Pod status to Running: %v", err)
190239
}
191240
return updated
192241
}
@@ -242,7 +291,7 @@ func TestControllerIntegration_KubernetesDeployment(t *testing.T) {
242291

243292
require.Eventually(t, func() bool {
244293
return len(mock.getRecords()) >= 1
245-
}, 5*time.Second, 100*time.Millisecond)
294+
}, 3*time.Second, 100*time.Millisecond)
246295
records := mock.getRecords()
247296
require.Len(t, records, 1)
248297
assert.Equal(t, deploymentrecord.StatusDeployed, records[0].Status)
@@ -257,13 +306,13 @@ func TestControllerIntegration_KubernetesDeployment(t *testing.T) {
257306
}}, namespace, "test-deployment-123456-2")
258307
require.Never(t, func() bool {
259308
return len(mock.getRecords()) != 1
260-
}, 5*time.Second, 100*time.Millisecond)
309+
}, 3*time.Second, 100*time.Millisecond)
261310

262311
// Delete second pod; still expect 1 record
263312
deletePod(t, clientset, namespace, "test-deployment-123456-2")
264313
require.Never(t, func() bool {
265314
return len(mock.getRecords()) != 1
266-
}, 5*time.Second, 100*time.Millisecond)
315+
}, 3*time.Second, 100*time.Millisecond)
267316

268317
// Delete deployment, replicaset, and first pod; expect 2 records
269318
deleteDeployment(t, clientset, namespace, "test-deployment")
@@ -272,8 +321,65 @@ func TestControllerIntegration_KubernetesDeployment(t *testing.T) {
272321

273322
require.Eventually(t, func() bool {
274323
return len(mock.getRecords()) >= 2
275-
}, 5*time.Second, 100*time.Millisecond)
324+
}, 3*time.Second, 100*time.Millisecond)
276325
records = mock.getRecords()
277326
require.Len(t, records, 2)
278327
assert.Equal(t, deploymentrecord.StatusDecommissioned, records[1].Status)
279328
}
329+
330+
func TestControllerIntegration_InitContainers(t *testing.T) {
331+
if testing.Short() {
332+
t.Skip("skipping integration test in short mode")
333+
}
334+
namespace := "test-init-containers"
335+
clientset, mock := setup(t, namespace)
336+
337+
// Create deployment, replicaset, and pod with an init container; expect 2 records (one per container)
338+
deployment := makeDeployment(t, clientset, []metav1.OwnerReference{}, namespace, "init-deployment")
339+
replicaSet := makeReplicaSet(t, clientset, []metav1.OwnerReference{{
340+
APIVersion: "apps/v1",
341+
Kind: "Deployment",
342+
Name: deployment.Name,
343+
UID: deployment.UID,
344+
}}, namespace, "init-deployment-abc123")
345+
_ = makePodWithInitContainer(t, clientset, []metav1.OwnerReference{{
346+
APIVersion: "apps/v1",
347+
Kind: "ReplicaSet",
348+
Name: replicaSet.Name,
349+
UID: replicaSet.UID,
350+
}}, namespace, "init-deployment-abc123-1")
351+
352+
require.Eventually(t, func() bool {
353+
return len(mock.getRecords()) >= 2
354+
}, 3*time.Second, 100*time.Millisecond)
355+
records := mock.getRecords()
356+
require.Len(t, records, 2)
357+
358+
// Both records should be deployed; collect deployment names to verify both containers are recorded
359+
deploymentNames := make([]string, len(records))
360+
for i, r := range records {
361+
assert.Equal(t, deploymentrecord.StatusDeployed, r.Status)
362+
deploymentNames[i] = r.DeploymentName
363+
}
364+
assert.Contains(t, deploymentNames, "test-init-containers/init-deployment/app")
365+
assert.Contains(t, deploymentNames, "test-init-containers/init-deployment/init")
366+
367+
// Delete deployment, replicaset, and pod; expect 2 more decommissioned records (one per container)
368+
deleteDeployment(t, clientset, namespace, "init-deployment")
369+
deleteReplicaSet(t, clientset, namespace, "init-deployment-abc123")
370+
deletePod(t, clientset, namespace, "init-deployment-abc123-1")
371+
372+
require.Eventually(t, func() bool {
373+
return len(mock.getRecords()) >= 4
374+
}, 3*time.Second, 100*time.Millisecond)
375+
records = mock.getRecords()
376+
require.Len(t, records, 4)
377+
378+
decommissionedNames := make([]string, 0, 2)
379+
for _, r := range records[2:] {
380+
assert.Equal(t, deploymentrecord.StatusDecommissioned, r.Status)
381+
decommissionedNames = append(decommissionedNames, r.DeploymentName)
382+
}
383+
assert.Contains(t, decommissionedNames, "test-init-containers/init-deployment/app")
384+
assert.Contains(t, decommissionedNames, "test-init-containers/init-deployment/init")
385+
}

0 commit comments

Comments
 (0)