@@ -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