Skip to content

Commit af7b1ba

Browse files
committed
Added partial case and complete delete case
1 parent 7c60385 commit af7b1ba

File tree

1 file changed

+134
-71
lines changed

1 file changed

+134
-71
lines changed

artifactory_test.go

Lines changed: 134 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2801,18 +2801,16 @@ func TestArtifactoryDeleteByProps(t *testing.T) {
28012801
cleanArtifactoryTest()
28022802
}
28032803

2804-
// TestArtifactoryDeleteCountsWithPartial404 tests that delete returns accurate
2805-
// success/fail counts when 404 errors occur due to files being deleted between
2806-
// GetPathsToDelete and DeleteFiles (race condition scenario).
2807-
func TestArtifactoryDeleteCountsWithPartial404(t *testing.T) {
2804+
// TestArtifactoryDeleteCountsWithFull404 tests that delete returns accurate
2805+
// counts when ALL files are already deleted (all 404 errors).
2806+
func TestArtifactoryDeleteCountsWithFull404(t *testing.T) {
28082807
initArtifactoryTest(t, "")
28092808

2810-
// Step 1: Upload more than 5 test files (using testdata/a/ which has 9 .in files)
2809+
// Step 1: Upload test files
28112810
runRt(t, "upload", "testdata/a/*.in", tests.RtRepo1+"/delete-404-test/", "--flat=true")
2812-
runRt(t, "upload", "testdata/a/b/*.in", tests.RtRepo1+"/delete-404-test/", "--flat=true")
2813-
runRt(t, "upload", "testdata/a/b/c/*.in", tests.RtRepo1+"/delete-404-test/", "--flat=true")
2811+
t.Log("Uploaded test files")
28142812

2815-
// Verify we have more than 5 files uploaded
2813+
// Step 2: Search to find all uploaded files
28162814
searchSpec := spec.NewBuilder().
28172815
Pattern(tests.RtRepo1 + "/delete-404-test/*.in").
28182816
BuildSpec()
@@ -2823,10 +2821,10 @@ func TestArtifactoryDeleteCountsWithPartial404(t *testing.T) {
28232821
totalFiles, err := reader.Length()
28242822
assert.NoError(t, err)
28252823
readerCloseAndAssert(t, reader)
2826-
assert.Greater(t, totalFiles, 5, "Should have uploaded more than 5 files for this test")
2827-
t.Logf("Uploaded %d files for delete-404 test", totalFiles)
2824+
assert.Greater(t, totalFiles, 0, "Should have uploaded files for this test")
2825+
t.Logf("Found %d files to delete", totalFiles)
28282826

2829-
// Step 2: Create delete command and get paths to delete
2827+
// Step 3: Create delete command and get paths to delete
28302828
deleteSpec := spec.NewBuilder().
28312829
Pattern(tests.RtRepo1 + "/delete-404-test/*.in").
28322830
BuildSpec()
@@ -2838,92 +2836,157 @@ func TestArtifactoryDeleteCountsWithPartial404(t *testing.T) {
28382836
SetDryRun(false).
28392837
SetQuiet(true)
28402838

2841-
// Get paths to delete (this queries Artifactory for matching files)
2839+
// Get paths to delete
28422840
pathsReader, err := deleteCommand.GetPathsToDelete()
28432841
assert.NoError(t, err)
28442842

2845-
// Verify reader has the expected number of items
2843+
// Verify reader has the expected files
28462844
readerLength, err := pathsReader.Length()
28472845
assert.NoError(t, err)
28482846
assert.Equal(t, totalFiles, readerLength, "Reader should contain all uploaded files")
2849-
t.Logf("PathsReader contains %d items (expected %d)", readerLength, totalFiles)
2850-
2851-
// Reset the reader after Length() consumed it - required before passing to DeleteFiles
2847+
t.Logf("PathsReader contains %d items", readerLength)
28522848
pathsReader.Reset()
28532849

2854-
// Step 3: Simulate race condition - delete some files directly BEFORE calling DeleteFiles
2855-
// This will cause 404 errors when DeleteFiles tries to delete them
2856-
filesToPreDelete := 3
2857-
preDeleteSpec1 := spec.NewBuilder().Pattern(tests.RtRepo1 + "/delete-404-test/a1.in").BuildSpec()
2858-
preDeleteSuccess1, preDeleteFail1, err := tests.DeleteFiles(preDeleteSpec1, serverDetails)
2859-
assert.NoError(t, err, "Failed to pre-delete a1.in")
2860-
t.Logf("Pre-delete a1.in: success=%d, fail=%d", preDeleteSuccess1, preDeleteFail1)
2861-
2862-
preDeleteSpec2 := spec.NewBuilder().Pattern(tests.RtRepo1 + "/delete-404-test/a2.in").BuildSpec()
2863-
preDeleteSuccess2, preDeleteFail2, err := tests.DeleteFiles(preDeleteSpec2, serverDetails)
2864-
assert.NoError(t, err, "Failed to pre-delete a2.in")
2865-
t.Logf("Pre-delete a2.in: success=%d, fail=%d", preDeleteSuccess2, preDeleteFail2)
2866-
2867-
preDeleteSpec3 := spec.NewBuilder().Pattern(tests.RtRepo1 + "/delete-404-test/a3.in").BuildSpec()
2868-
preDeleteSuccess3, preDeleteFail3, err := tests.DeleteFiles(preDeleteSpec3, serverDetails)
2869-
assert.NoError(t, err, "Failed to pre-delete a3.in")
2870-
t.Logf("Pre-delete a3.in: success=%d, fail=%d", preDeleteSuccess3, preDeleteFail3)
2871-
2872-
// Verify pre-deletion actually removed the files
2873-
totalPreDeleted := preDeleteSuccess1 + preDeleteSuccess2 + preDeleteSuccess3
2874-
assert.Equal(t, filesToPreDelete, totalPreDeleted,
2875-
"Pre-deletion should have deleted %d files, but deleted %d", filesToPreDelete, totalPreDeleted)
2876-
2877-
// Double-check by searching - should now have (totalFiles - filesToPreDelete) files
2850+
// Step 4: Delete all files (first delete - should all succeed)
2851+
successCount1, failCount1, deleteErr1 := deleteCommand.DeleteFiles(pathsReader)
2852+
t.Logf("First delete: success=%d, fail=%d, err=%v", successCount1, failCount1, deleteErr1)
2853+
2854+
assert.NoError(t, deleteErr1, "First delete should succeed without errors")
2855+
assert.Equal(t, totalFiles, successCount1, "First delete should succeed for all %d files", totalFiles)
2856+
assert.Equal(t, 0, failCount1, "First delete should have no failures")
2857+
2858+
// Step 5: Verify all files are now gone
28782859
reader, err = searchCmd.Search()
2879-
assert.NoError(t, err, "Failed to search after pre-deletion")
2880-
filesAfterPreDelete, err := reader.Length()
2860+
assert.NoError(t, err)
2861+
remainingFiles, err := reader.Length()
2862+
assert.NoError(t, err)
2863+
readerCloseAndAssert(t, reader)
2864+
assert.Equal(t, 0, remainingFiles, "All files should be deleted after first delete")
2865+
t.Log("Verified all files are deleted")
2866+
2867+
// Step 6: Reset the reader and try to delete AGAIN (all should get 404)
2868+
pathsReader.Reset()
2869+
successCount2, failCount2, deleteErr2 := deleteCommand.DeleteFiles(pathsReader)
2870+
gofrogio.Close(pathsReader, &err)
2871+
2872+
t.Logf("Second delete (all 404): success=%d, fail=%d, err=%v", successCount2, failCount2, deleteErr2)
2873+
2874+
// Step 7: Verify the results - all should fail with 404
2875+
totalProcessed := successCount2 + failCount2
2876+
assert.Equal(t, totalFiles, totalProcessed,
2877+
"Total processed (success=%d + fail=%d = %d) should equal totalFiles=%d",
2878+
successCount2, failCount2, totalProcessed, totalFiles)
2879+
2880+
assert.Equal(t, 0, successCount2,
2881+
"Second delete should have 0 successes (files already deleted), got %d", successCount2)
2882+
2883+
assert.Equal(t, totalFiles, failCount2,
2884+
"Second delete should have %d failures (all 404), got %d", totalFiles, failCount2)
2885+
2886+
// Cleanup
2887+
cleanArtifactoryTest()
2888+
}
2889+
2890+
// TestArtifactoryDeleteCountsWithPartial404 tests that delete returns accurate
2891+
// counts when SOME files are already deleted (partial 404 errors).
2892+
func TestArtifactoryDeleteCountsWithPartial404(t *testing.T) {
2893+
initArtifactoryTest(t, "")
2894+
2895+
// Step 1: Upload 5 specific test files
2896+
runRt(t, "upload", "testdata/a/a1.in", tests.RtRepo1+"/delete-partial-404/", "--flat=true")
2897+
runRt(t, "upload", "testdata/a/a2.in", tests.RtRepo1+"/delete-partial-404/", "--flat=true")
2898+
runRt(t, "upload", "testdata/a/a3.in", tests.RtRepo1+"/delete-partial-404/", "--flat=true")
2899+
runRt(t, "upload", "testdata/a/b/b1.in", tests.RtRepo1+"/delete-partial-404/", "--flat=true")
2900+
runRt(t, "upload", "testdata/a/b/b2.in", tests.RtRepo1+"/delete-partial-404/", "--flat=true")
2901+
t.Log("Uploaded 5 test files")
2902+
2903+
// Step 2: Verify we have 5 files
2904+
searchSpec := spec.NewBuilder().
2905+
Pattern(tests.RtRepo1 + "/delete-partial-404/*.in").
2906+
BuildSpec()
2907+
searchCmd := generic.NewSearchCommand()
2908+
searchCmd.SetServerDetails(serverDetails).SetSpec(searchSpec)
2909+
reader, err := searchCmd.Search()
2910+
assert.NoError(t, err)
2911+
totalFiles, err := reader.Length()
28812912
assert.NoError(t, err)
28822913
readerCloseAndAssert(t, reader)
2883-
expectedAfterPreDelete := totalFiles - filesToPreDelete
2884-
assert.Equal(t, expectedAfterPreDelete, filesAfterPreDelete,
2885-
"After pre-deleting %d files, should have %d remaining, but found %d",
2886-
filesToPreDelete, expectedAfterPreDelete, filesAfterPreDelete)
2914+
assert.Equal(t, 5, totalFiles, "Should have uploaded 5 files")
2915+
t.Logf("Verified %d files uploaded", totalFiles)
2916+
2917+
// Step 3: Create delete command and get paths for ALL 5 files
2918+
deleteSpec := spec.NewBuilder().
2919+
Pattern(tests.RtRepo1 + "/delete-partial-404/*.in").
2920+
BuildSpec()
28872921

2888-
t.Logf("Pre-deleted %d files, verified %d files remaining (expected %d)",
2889-
totalPreDeleted, filesAfterPreDelete, expectedAfterPreDelete)
2922+
deleteCommand := generic.NewDeleteCommand()
2923+
deleteCommand.SetThreads(1).
2924+
SetSpec(deleteSpec).
2925+
SetServerDetails(serverDetails).
2926+
SetDryRun(false).
2927+
SetQuiet(true)
2928+
2929+
// Get paths for all 5 files
2930+
pathsReader, err := deleteCommand.GetPathsToDelete()
2931+
assert.NoError(t, err)
2932+
readerLength, err := pathsReader.Length()
2933+
assert.NoError(t, err)
2934+
assert.Equal(t, 5, readerLength, "Reader should contain 5 files")
2935+
t.Logf("PathsReader contains %d items", readerLength)
2936+
pathsReader.Reset()
28902937

2891-
// Step 4: Now call DeleteFiles with the original reader
2892-
// The reader still contains paths to the pre-deleted files, so we'll get 404s
2938+
// Step 4: Delete only 2 files (a1.in and a2.in)
2939+
preDeleteSpec := spec.NewBuilder().
2940+
Pattern(tests.RtRepo1 + "/delete-partial-404/a1.in").
2941+
BuildSpec()
2942+
preDeleteSuccess1, _, err := tests.DeleteFiles(preDeleteSpec, serverDetails)
2943+
assert.NoError(t, err)
2944+
assert.Equal(t, 1, preDeleteSuccess1, "Should have deleted a1.in")
2945+
t.Log("Pre-deleted a1.in")
2946+
2947+
preDeleteSpec2 := spec.NewBuilder().
2948+
Pattern(tests.RtRepo1 + "/delete-partial-404/a2.in").
2949+
BuildSpec()
2950+
preDeleteSuccess2, _, err := tests.DeleteFiles(preDeleteSpec2, serverDetails)
2951+
assert.NoError(t, err)
2952+
assert.Equal(t, 1, preDeleteSuccess2, "Should have deleted a2.in")
2953+
t.Log("Pre-deleted a2.in")
2954+
2955+
// Step 5: Verify only 3 files remain
2956+
reader, err = searchCmd.Search()
2957+
assert.NoError(t, err)
2958+
remainingFiles, err := reader.Length()
2959+
assert.NoError(t, err)
2960+
readerCloseAndAssert(t, reader)
2961+
assert.Equal(t, 3, remainingFiles, "Should have 3 files remaining after pre-delete")
2962+
t.Logf("Verified %d files remaining after pre-deleting 2", remainingFiles)
2963+
2964+
// Step 6: Now try to delete ALL 5 files using original pathsReader
2965+
// Expected: 3 success (a3, b1, b2), 2 fail (a1, a2 already deleted = 404)
28932966
successCount, failCount, deleteErr := deleteCommand.DeleteFiles(pathsReader)
28942967
gofrogio.Close(pathsReader, &err)
28952968

2896-
// Step 5: Verify the fix - counts should be properly returned even with 404 errors
2897-
// Before the fix: successCount=0, failCount=0 (bug!)
2898-
// After the fix: successCount + failCount should equal totalFiles
28992969
t.Logf("Delete result: success=%d, fail=%d, err=%v", successCount, failCount, deleteErr)
29002970

2901-
// Calculate expected values for clearer error messages
2902-
expectedSuccessful := totalFiles - filesToPreDelete
2971+
// Step 7: Verify counts
29032972
totalProcessed := successCount + failCount
2973+
assert.Equal(t, 5, totalProcessed,
2974+
"Total processed (success=%d + fail=%d = %d) should equal 5",
2975+
successCount, failCount, totalProcessed)
29042976

2905-
// The total of success + fail should equal what we tried to delete
2906-
assert.Equal(t, totalFiles, totalProcessed,
2907-
"Total processed (success=%d + fail=%d = %d) should equal totalFiles=%d",
2908-
successCount, failCount, totalProcessed, totalFiles)
2977+
assert.Equal(t, 3, successCount,
2978+
"Should have 3 successes (a3, b1, b2 still existed), got %d", successCount)
29092979

2910-
// We should have some successful deletes (files that weren't pre-deleted)
2911-
assert.Equal(t, expectedSuccessful, successCount,
2912-
"Success count=%d should match expected=%d (totalFiles=%d - preDeleted=%d)",
2913-
successCount, expectedSuccessful, totalFiles, filesToPreDelete)
2980+
assert.Equal(t, 2, failCount,
2981+
"Should have 2 failures (a1, a2 already deleted = 404), got %d", failCount)
29142982

2915-
// We should have some failures (the pre-deleted files that returned 404)
2916-
assert.Equal(t, filesToPreDelete, failCount,
2917-
"Fail count=%d should match pre-deleted files=%d",
2918-
failCount, filesToPreDelete)
2919-
2920-
// Verify all files are now gone
2983+
// Step 8: Verify all files are now gone
29212984
reader, err = searchCmd.Search()
29222985
assert.NoError(t, err)
2923-
remainingFiles, err := reader.Length()
2986+
finalCount, err := reader.Length()
29242987
assert.NoError(t, err)
29252988
readerCloseAndAssert(t, reader)
2926-
assert.Equal(t, 0, remainingFiles, "All files should be deleted")
2989+
assert.Equal(t, 0, finalCount, "All files should be deleted")
29272990

29282991
// Cleanup
29292992
cleanArtifactoryTest()

0 commit comments

Comments
 (0)