@@ -1399,6 +1399,22 @@ func TestSyncWithNonDistributableBlob(t *testing.T) {
13991399 })
14001400}
14011401
1402+ // removeAllWithRetry retries os.RemoveAll until it succeeds or the timeout expires.
1403+ // This is primarily to tolerate brief ENOTEMPTY races when background sync/meta
1404+ // tasks momentarily re-create entries under repoDir while RemoveAll is deleting it,
1405+ // making rmdir observe a non-empty directory.
1406+ func removeAllWithRetry (repoDir string , timeout time.Duration ) error {
1407+ var err error
1408+
1409+ for deadline := time .Now ().Add (timeout ); ; {
1410+ if err = os .RemoveAll (repoDir ); err == nil || time .Now ().After (deadline ) {
1411+ return err
1412+ }
1413+
1414+ time .Sleep (50 * time .Millisecond )
1415+ }
1416+ }
1417+
14021418func TestDockerImagesAreSkipped (t * testing.T ) {
14031419 testCases := []struct {
14041420 name string
@@ -1550,7 +1566,7 @@ func TestDockerImagesAreSkipped(t *testing.T) {
15501566
15511567 // trigger config blob upstream error
15521568 // remove synced image
1553- err = os . RemoveAll (path .Join (destDir , testImage ))
1569+ err = removeAllWithRetry (path .Join (destDir , testImage ), 10 * time . Second )
15541570 So (err , ShouldBeNil )
15551571
15561572 configBlobPath := path .Join (srcDir , testImage , "blobs/sha256" , configBlobDigest .Encoded ())
@@ -1720,7 +1736,7 @@ func TestDockerImagesAreSkipped(t *testing.T) {
17201736
17211737 // trigger config blob upstream error
17221738 // remove synced image
1723- err = os . RemoveAll (path .Join (destDir , indexRepoName ))
1739+ err = removeAllWithRetry (path .Join (destDir , indexRepoName ), 10 * time . Second )
17241740 So (err , ShouldBeNil )
17251741
17261742 configBlobPath := path .Join (srcDir , indexRepoName , "blobs/sha256" , configBlobDigest .Encoded ())
0 commit comments