TestAtomicWriteFileStress applies extreme concurrent pressure to verify robustness
(t *testing.T)
| 13 | |
| 14 | // TestAtomicWriteFileStress applies extreme concurrent pressure to verify robustness |
| 15 | func TestAtomicWriteFileStress(t *testing.T) { |
| 16 | if testing.Short() { |
| 17 | t.Skip("Skipping stress test in short mode") |
| 18 | } |
| 19 | |
| 20 | tmpDir := t.TempDir() |
| 21 | targetFile := filepath.Join(tmpDir, "stress.json") |
| 22 | |
| 23 | // Large data to increase write time and chances of race conditions |
| 24 | largeData := make([]byte, 1024*10) // 10KB |
| 25 | for i := range largeData { |
| 26 | largeData[i] = byte('A' + (i % 26)) |
| 27 | } |
| 28 | testData := []byte(fmt.Sprintf(`{"large_data": "%s", "id": "test"}`, string(largeData))) |
| 29 | |
| 30 | // High concurrency stress test |
| 31 | var wg sync.WaitGroup |
| 32 | numGoroutines := 100 |
| 33 | writesPerGoroutine := 5 |
| 34 | |
| 35 | for i := range numGoroutines { |
| 36 | wg.Add(1) |
| 37 | go func(goroutineID int) { |
| 38 | defer wg.Done() |
| 39 | |
| 40 | for j := range writesPerGoroutine { |
| 41 | // Use different temp prefixes to test CreateTemp uniqueness |
| 42 | prefix := fmt.Sprintf("stress_%d_%d.json", goroutineID, j) |
| 43 | err := atomicWriteFile(testData, targetFile, prefix) |
| 44 | require.NoError(t, err) |
| 45 | |
| 46 | // No sleep - maximum pressure |
| 47 | } |
| 48 | }(i) |
| 49 | } |
| 50 | |
| 51 | wg.Wait() |
| 52 | |
| 53 | // Verify final file integrity |
| 54 | finalData, err := os.ReadFile(targetFile) |
| 55 | require.NoError(t, err) |
| 56 | require.NotEmpty(t, finalData, "Final file should not be empty") |
| 57 | |
| 58 | // Should be valid JSON |
| 59 | var result map[string]any |
| 60 | err = json.Unmarshal(finalData, &result) |
| 61 | require.NoError(t, err, "Final file should contain valid JSON after stress test") |
| 62 | |
| 63 | // Verify it's our expected data |
| 64 | require.Equal(t, "test", result["id"], "Final file should contain our test data") |
| 65 | |
| 66 | // Critical: No temp files should remain after stress test |
| 67 | files, err := filepath.Glob(filepath.Join(tmpDir, "*tmp*")) |
| 68 | require.NoError(t, err) |
| 69 | require.Empty(t, files, "No temporary files should remain after stress test - all should be cleaned up") |
| 70 | |
| 71 | t.Logf("Stress test completed: %d goroutines × %d writes = %d total operations", |
| 72 | numGoroutines, writesPerGoroutine, numGoroutines*writesPerGoroutine) |