@@ -30,7 +30,7 @@ func (m *mockRecordPoster) PostOne(_ context.Context, record *deploymentrecord.D
3030 return m .err
3131}
3232
33- // Helper to read captured records safely
33+ // Helper that allows tests to read captured records safely
3434func (m * mockRecordPoster ) getRecords () []* deploymentrecord.DeploymentRecord {
3535 m .mu .Lock ()
3636 defer m .mu .Unlock ()
@@ -207,11 +207,52 @@ func deletePod(t *testing.T, clientset *kubernetes.Clientset, namespace, name st
207207 }
208208}
209209
210+ // pollForRecords polls until the mock has at least minCount records, then returns them.
211+ func pollForRecords (t * testing.T , mock * mockRecordPoster , minCount int , timeout time.Duration ) []* deploymentrecord.DeploymentRecord {
212+ t .Helper ()
213+ deadline := time .After (timeout )
214+ for {
215+ records := mock .getRecords ()
216+ if len (records ) >= minCount {
217+ return records
218+ }
219+ select {
220+ case <- deadline :
221+ t .Fatalf ("timed out waiting for at least %d records, got %d" , minCount , len (records ))
222+ case <- time .After (100 * time .Millisecond ):
223+ }
224+ }
225+ }
226+
227+ // assertNoNewRecords polls for the given duration and fails if the record count deviates from expectedCount.
228+ func assertNoNewRecords (t * testing.T , mock * mockRecordPoster , expectedCount int , timeout time.Duration ) {
229+ t .Helper ()
230+ deadline := time .After (timeout )
231+ for {
232+ select {
233+ case <- deadline :
234+ if got := len (mock .getRecords ()); got != expectedCount {
235+ t .Fatalf ("expected %d records, got %d" , expectedCount , got )
236+ }
237+ return
238+ case <- time .After (100 * time .Millisecond ):
239+ if got := len (mock .getRecords ()); got != expectedCount {
240+ t .Fatalf ("expected %d records, got %d" , expectedCount , got )
241+ }
242+ }
243+ }
244+ }
245+
210246func TestControllerIntegration_KubernetesDeployment (t * testing.T ) {
247+ if testing .Short () {
248+ t .Skip ("skipping integration test in short mode" )
249+ }
211250 namespace := "test-namespace"
212251 testEnv , cancel , clientset , mock := setup (t , namespace )
213- defer testEnv .Stop ()
214- defer cancel ()
252+ defer func (testEnv * envtest.Environment , cancelFunc context.CancelFunc ) {
253+ _ = testEnv .Stop ()
254+ cancel ()
255+ }(testEnv , cancel )
215256
216257 // Create deployment, replicaset, and pod; expect 1 record
217258 deployment := makeDeployment (t , clientset , []metav1.OwnerReference {}, namespace , "test-deployment" )
@@ -228,69 +269,38 @@ func TestControllerIntegration_KubernetesDeployment(t *testing.T) {
228269 UID : replicaSet .UID ,
229270 }}, namespace , "test-deployment-123456-1" )
230271
231- pollTime := time .After (5 * time .Second )
232- for {
233- records := mock .getRecords ()
234- if len (records ) > 0 {
235- if len (records ) != 1 {
236- t .Fatalf ("expected 1 record, got %d" , len (records ))
237- }
238- if records [0 ].Status != deploymentrecord .StatusDeployed {
239- t .Errorf ("expected %s, got %s" , deploymentrecord .StatusDeployed , records [0 ].Status )
240- }
241- break
242- }
243- select {
244- case <- pollTime :
245- t .Fatal ("timed out waiting for deployment record" )
246- case <- time .After (100 * time .Millisecond ):
247- }
272+ records := pollForRecords (t , mock , 1 , 5 * time .Second )
273+ if len (records ) != 1 {
274+ t .Fatalf ("expected 1 record, got %d" , len (records ))
275+ }
276+ if records [0 ].Status != deploymentrecord .StatusDeployed {
277+ t .Errorf ("expected %s, got %s" , deploymentrecord .StatusDeployed , records [0 ].Status )
248278 }
249279
250- // Create another pod in replicaset; the dedup cache should prevent a new record
251- // but since processing is async, both pods may be processed before the cache is set.
280+ // Create another pod in replicaset; the dedup cache should prevent a new record as there is only one worker
281+ // and no risk of multiple works processing before cache is set.
252282 _ = makePod (t , clientset , []metav1.OwnerReference {{
253283 APIVersion : "apps/v1" ,
254284 Kind : "ReplicaSet" ,
255285 Name : replicaSet .Name ,
256286 UID : replicaSet .UID ,
257287 }}, namespace , "test-deployment-123456-2" )
258-
259- time .Sleep (5 * time .Second )
260- recordsAfterSecondPod := len (mock .getRecords ())
261- if recordsAfterSecondPod > 2 {
262- t .Fatalf ("expected at most 2 records after second pod, got %d" , recordsAfterSecondPod )
263- }
288+ assertNoNewRecords (t , mock , 1 , 5 * time .Second )
264289
265290 // Delete second pod; still expect 1 record
266291 deletePod (t , clientset , namespace , "test-deployment-123456-2" )
267-
268- time .Sleep (5 * time .Second ) // wait to see if any new records are created
269- if len (mock .getRecords ()) != 1 {
270- t .Fatalf ("still expected 1 record after deleting second pod, got %d" , len (mock .getRecords ()))
271- }
292+ assertNoNewRecords (t , mock , 1 , 5 * time .Second )
272293
273294 // Delete deployment, replicaset, and first pod; expect 2 records
274295 deleteDeployment (t , clientset , namespace , "test-deployment" )
275296 deleteReplicaSet (t , clientset , namespace , "test-deployment-123456" )
276297 deletePod (t , clientset , namespace , "test-deployment-123456-1" )
277298
278- pollTime = time .After (5 * time .Second )
279- for {
280- records := mock .getRecords ()
281- if len (records ) > 1 {
282- if len (records ) != 2 {
283- t .Fatalf ("expected 2 records after deletion, got %d" , len (records ))
284- }
285- if records [1 ].Status != deploymentrecord .StatusDecommissioned {
286- t .Errorf ("expected second record to be %s, got %s" , deploymentrecord .StatusDecommissioned , records [1 ].Status )
287- }
288- break
289- }
290- select {
291- case <- pollTime :
292- t .Fatalf ("timed out waiting for more than one record, got %d" , len (records ))
293- case <- time .After (100 * time .Millisecond ):
294- }
299+ records = pollForRecords (t , mock , 2 , 5 * time .Second )
300+ if len (records ) != 2 {
301+ t .Fatalf ("expected 2 records after deletion, got %d" , len (records ))
302+ }
303+ if records [1 ].Status != deploymentrecord .StatusDecommissioned {
304+ t .Errorf ("expected second record to be %s, got %s" , deploymentrecord .StatusDecommissioned , records [1 ].Status )
295305 }
296306}
0 commit comments