Ensure we're cleaning up after our tests
This commit is contained in:
@@ -6,25 +6,92 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Test helper to create a temporary test directory WITHIN the project
|
||||
func createTestDir(t *testing.T) string {
|
||||
// Get the project directory (current working directory)
|
||||
// TestMain runs setup and teardown for all tests
|
||||
func TestMain(m *testing.M) {
|
||||
// Setup: create test_temp directory
|
||||
projectDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to get working directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
testDir := filepath.Join(projectDir, "test_temp")
|
||||
|
||||
// Clean up any existing test_temp directory first
|
||||
if _, err := os.Stat(testDir); err == nil {
|
||||
if wd, _ := os.Getwd(); strings.HasPrefix(wd, testDir) {
|
||||
_ = os.Chdir(projectDir)
|
||||
}
|
||||
_ = os.RemoveAll(testDir)
|
||||
}
|
||||
|
||||
// Create fresh test_temp directory
|
||||
err = os.MkdirAll(testDir, 0755)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to create test directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Run tests
|
||||
code := m.Run()
|
||||
|
||||
// Teardown: remove test_temp directory
|
||||
if wd, _ := os.Getwd(); strings.HasPrefix(wd, testDir) {
|
||||
_ = os.Chdir(projectDir)
|
||||
}
|
||||
err = os.RemoveAll(testDir)
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: failed to remove test directory: %v\n", err)
|
||||
}
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// Test helper to get the shared test_temp directory
|
||||
func getTestDir(t *testing.T) string {
|
||||
projectDir, err := os.Getwd()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create test directory WITHIN the project
|
||||
testDir := filepath.Join(projectDir, "test_temp")
|
||||
err = os.MkdirAll(testDir, 0755)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Ensure test_temp exists (it should be created by TestMain)
|
||||
if _, err := os.Stat(testDir); os.IsNotExist(err) {
|
||||
t.Fatalf("test_temp directory does not exist - TestMain should have created it")
|
||||
}
|
||||
|
||||
return testDir
|
||||
}
|
||||
|
||||
// Global counter for unique directory names
|
||||
var dirCounter int64
|
||||
|
||||
// Test helper to create a unique subdirectory for a specific test
|
||||
func getTestSubDir(t *testing.T) string {
|
||||
testDir := getTestDir(t)
|
||||
|
||||
// For complete isolation, create a unique directory using test name, timestamp, and counter
|
||||
// This ensures even subtests within the same parent test are isolated
|
||||
testName := t.Name()
|
||||
timestamp := time.Now().UnixNano()
|
||||
counter := atomic.AddInt64(&dirCounter, 1)
|
||||
|
||||
// Create a unique directory name
|
||||
uniqueDirName := fmt.Sprintf("%s_%d_%d", testName, timestamp, counter)
|
||||
subDirPath := filepath.Join(testDir, uniqueDirName)
|
||||
|
||||
err := os.MkdirAll(subDirPath, 0755)
|
||||
assert.NoError(t, err)
|
||||
|
||||
return subDirPath
|
||||
}
|
||||
|
||||
// Test helper to ensure we're working within the project directory
|
||||
func ensureInProjectDir(t *testing.T, testDir string) {
|
||||
// Get current working directory (should be project directory)
|
||||
@@ -43,21 +110,9 @@ func ensureInProjectDir(t *testing.T, testDir string) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test helper to clean up test directory
|
||||
func cleanupTestDir(t *testing.T, testDir string) {
|
||||
// If current working dir is inside the testDir, move out before removal (Windows locks directories in use)
|
||||
if wd, _ := os.Getwd(); strings.HasPrefix(wd, testDir) {
|
||||
_ = os.Chdir(filepath.Dir(testDir))
|
||||
}
|
||||
|
||||
// We MUST remove the directory - this is critical for test isolation
|
||||
err := os.RemoveAll(testDir)
|
||||
assert.NoError(t, err, "Failed to remove test directory %s", testDir)
|
||||
}
|
||||
|
||||
func TestParseInstruction(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
@@ -161,9 +216,8 @@ func TestParseInstruction(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLinkInstruction_RunAsync(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -295,9 +349,9 @@ func TestLinkInstruction_RunAsync(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLinkInstruction_Undo(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -354,9 +408,8 @@ func TestLinkInstruction_Undo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGlobPatterns(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -766,9 +819,8 @@ func createGlobTestStructure(t *testing.T, testDir string) {
|
||||
}
|
||||
|
||||
func TestParseYAMLFile(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -874,9 +926,8 @@ func TestParseYAMLFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExpandPattern(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -948,9 +999,8 @@ func TestExpandPattern(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetSyncFilesRecursively(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -1012,9 +1062,8 @@ func TestGetSyncFilesRecursively(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestReadFromFile(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -1101,9 +1150,8 @@ func TestReadFromFile(t *testing.T) {
|
||||
|
||||
// Test main.go functions that are completely missing coverage
|
||||
func TestMainFunctions(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -1201,9 +1249,8 @@ func TestMainFunctions(t *testing.T) {
|
||||
|
||||
// Test 1:1 destination mapping for glob patterns
|
||||
func TestDestinationPathMapping(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -1407,9 +1454,9 @@ func TestDestinationPathMapping(t *testing.T) {
|
||||
|
||||
// Test missing instruction.go paths
|
||||
func TestInstructionEdgeCases(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -1685,9 +1732,8 @@ func TestInstructionEdgeCases(t *testing.T) {
|
||||
|
||||
// Test missing util.go paths
|
||||
func TestUtilEdgeCases(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -1895,9 +1941,8 @@ func TestPathFormattingFunctions(t *testing.T) {
|
||||
|
||||
// Test missing instruction.go YAML parsing paths
|
||||
func TestYAMLEdgeCases(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -2031,9 +2076,8 @@ func TestYAMLEdgeCases(t *testing.T) {
|
||||
|
||||
// Test the untested error paths in ReadFromFile and ReadFromStdin
|
||||
func TestErrorPaths(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -2381,9 +2425,8 @@ func TestErrorPaths(t *testing.T) {
|
||||
|
||||
// Test main.go functions that are currently at 0% coverage
|
||||
func TestMainFunctionsCoverage(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -2666,9 +2709,10 @@ func TestMainFunctionsCoverage(t *testing.T) {
|
||||
|
||||
// Test Unicode filename support
|
||||
func TestUnicodeFilenames(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Clean up any files from previous tests to prevent interference
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -2858,9 +2902,10 @@ func TestUnicodeFilenames(t *testing.T) {
|
||||
|
||||
// Test very long path handling (within project limits)
|
||||
func TestLongPaths(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Clean up any files from previous tests to prevent interference
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -3065,8 +3110,7 @@ func TestLongPaths(t *testing.T) {
|
||||
|
||||
// Test special characters in filenames
|
||||
func TestSpecialCharacters(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
@@ -3077,6 +3121,7 @@ func TestSpecialCharacters(t *testing.T) {
|
||||
os.Chdir(testDir)
|
||||
|
||||
t.Run("Special characters in filenames", func(t *testing.T) {
|
||||
|
||||
// Test various special characters
|
||||
specialFiles := []string{
|
||||
"file-with-dashes.txt",
|
||||
@@ -3159,6 +3204,12 @@ func TestSpecialCharacters(t *testing.T) {
|
||||
assert.Contains(t, instruction.Target, "target with spaces.txt")
|
||||
})
|
||||
|
||||
// Clean up files from previous subtests to prevent interference
|
||||
files, _ := os.ReadDir(testDir)
|
||||
for _, file := range files {
|
||||
_ = os.Remove(filepath.Join(testDir, file.Name()))
|
||||
}
|
||||
|
||||
t.Run("Special characters in glob patterns", func(t *testing.T) {
|
||||
// Create files with special characters for glob testing
|
||||
globFiles := []string{
|
||||
@@ -3357,9 +3408,10 @@ func TestSpecialCharacters(t *testing.T) {
|
||||
|
||||
// Test mixed source type integration tests
|
||||
func TestMixedSourceTypes(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Clean up any files from previous tests to prevent interference
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -3650,9 +3702,10 @@ func TestMixedSourceTypes(t *testing.T) {
|
||||
|
||||
// Test rollback scenario tests
|
||||
func TestRollbackScenarios(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Clean up any files from previous tests to prevent interference
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
@@ -3988,9 +4041,8 @@ func TestRollbackScenarios(t *testing.T) {
|
||||
|
||||
// Test YAMLConfig "From" functionality
|
||||
func TestYAMLConfigFrom(t *testing.T) {
|
||||
testDir := createTestDir(t)
|
||||
defer cleanupTestDir(t, testDir)
|
||||
|
||||
testDir := getTestSubDir(t)
|
||||
|
||||
// Ensure we're working within the project directory
|
||||
ensureInProjectDir(t, testDir)
|
||||
|
||||
|
Reference in New Issue
Block a user