-
Notifications
You must be signed in to change notification settings - Fork 0
test: improve gitvolume package coverage #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6647c0c
ff2f1df
c1cee32
070e4dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| package gitvolume | ||
|
|
||
| import ( | ||
| "os" | ||
| "path/filepath" | ||
| "runtime" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| func TestCopyFile(t *testing.T) { | ||
| tmpDir := t.TempDir() | ||
| src := filepath.Join(tmpDir, "source.txt") | ||
| dst := filepath.Join(tmpDir, "dest.txt") | ||
|
|
||
| // 1. Normal copy | ||
| err := os.WriteFile(src, []byte("hello"), 0644) | ||
| require.NoError(t, err) | ||
|
|
||
| err = copyFile(src, dst) | ||
| require.NoError(t, err) | ||
|
|
||
| content, err := os.ReadFile(dst) | ||
| require.NoError(t, err) | ||
| assert.Equal(t, "hello", string(content)) | ||
|
|
||
| info, err := os.Stat(dst) | ||
| require.NoError(t, err) | ||
| if runtime.GOOS != "windows" { | ||
| assert.Equal(t, os.FileMode(0644), info.Mode().Perm()) | ||
| } | ||
|
|
||
| // 2. Source missing | ||
| err = copyFile(filepath.Join(tmpDir, "missing"), dst) | ||
| assert.Error(t, err) | ||
|
|
||
| // 3. Dest read-only (directory) | ||
| // Create a directory where the file should be to trigger error | ||
| err = os.Mkdir(filepath.Join(tmpDir, "readonly"), 0755) | ||
| require.NoError(t, err) | ||
| err = copyFile(src, filepath.Join(tmpDir, "readonly")) | ||
| assert.Error(t, err) | ||
| } | ||
|
|
||
| func TestCopyDir(t *testing.T) { | ||
| tmpDir := t.TempDir() | ||
| src := filepath.Join(tmpDir, "src") | ||
| dst := filepath.Join(tmpDir, "dst") | ||
|
|
||
| // Setup source structure | ||
| require.NoError(t, os.MkdirAll(filepath.Join(src, "subdir"), 0755)) | ||
| require.NoError(t, os.WriteFile(filepath.Join(src, "file1.txt"), []byte("file1"), 0644)) | ||
| require.NoError(t, os.WriteFile(filepath.Join(src, "subdir", "file2.txt"), []byte("file2"), 0644)) | ||
|
|
||
| // 1. Normal recursive copy | ||
| err := copyDir(src, dst) | ||
| require.NoError(t, err) | ||
|
|
||
| assert.FileExists(t, filepath.Join(dst, "file1.txt")) | ||
| assert.FileExists(t, filepath.Join(dst, "subdir", "file2.txt")) | ||
|
|
||
| // 2. Symlink in source (should fail) | ||
| symLinkSrc := filepath.Join(tmpDir, "symsrc") | ||
| require.NoError(t, os.Mkdir(symLinkSrc, 0755)) | ||
| require.NoError(t, os.Symlink(dst, filepath.Join(symLinkSrc, "link"))) | ||
|
|
||
| err = copyDir(symLinkSrc, filepath.Join(tmpDir, "symdst")) | ||
| assert.Error(t, err) | ||
| assert.Contains(t, err.Error(), "symlink, which is not allowed") | ||
|
|
||
| // 3. Target exists and is not a directory | ||
| isFile := filepath.Join(tmpDir, "isFile") | ||
| require.NoError(t, os.WriteFile(isFile, []byte("data"), 0644)) | ||
| err = copyDir(src, isFile) | ||
| assert.Error(t, err) | ||
| // Error message differs by OS for MkdirAll on existing file | ||
| // Linux/Mac: "not a directory" | ||
| } | ||
|
|
||
| func TestHashAndVerify(t *testing.T) { | ||
| tmpDir := t.TempDir() | ||
| file1 := filepath.Join(tmpDir, "file1.txt") | ||
| file2 := filepath.Join(tmpDir, "file2.txt") | ||
|
|
||
| require.NoError(t, os.WriteFile(file1, []byte("content"), 0644)) | ||
| require.NoError(t, os.WriteFile(file2, []byte("content"), 0644)) | ||
|
|
||
| // 1. hashFile | ||
| h1, err := hashFile(file1) | ||
| require.NoError(t, err) | ||
| h2, err := hashFile(file2) | ||
| require.NoError(t, err) | ||
| assert.Equal(t, h1, h2) | ||
|
|
||
| // 2. verifyHash matches | ||
| match, err := verifyHash(file1, file2) | ||
| require.NoError(t, err) | ||
| assert.True(t, match) | ||
|
|
||
| // 3. verifyHash mismatch | ||
| require.NoError(t, os.WriteFile(file2, []byte("diff"), 0644)) | ||
| match, err = verifyHash(file1, file2) | ||
| require.NoError(t, err) | ||
| assert.False(t, match) | ||
|
|
||
| // 4. Missing file | ||
| _, err = hashFile(filepath.Join(tmpDir, "missing")) | ||
| assert.Error(t, err) | ||
| } | ||
|
|
||
| func TestCleanEmptyParents(t *testing.T) { | ||
| tmpDir := t.TempDir() | ||
| nested := filepath.Join(tmpDir, "a", "b", "c") | ||
| require.NoError(t, os.MkdirAll(nested, 0755)) | ||
|
|
||
| // 1. Clean up empty dirs logic | ||
| // Remove 'c', then cleanEmptyParents should remove 'b' and 'a' but stop at tmpDir | ||
| err := os.Remove(nested) | ||
| require.NoError(t, err) | ||
|
|
||
| cleanEmptyParents(filepath.Join(tmpDir, "a", "b"), tmpDir) | ||
|
|
||
| assert.NoDirExists(t, filepath.Join(tmpDir, "a", "b")) | ||
| assert.NoDirExists(t, filepath.Join(tmpDir, "a")) | ||
| assert.DirExists(t, tmpDir) | ||
|
|
||
| // 2. Stop if not empty | ||
| require.NoError(t, os.MkdirAll(nested, 0755)) | ||
| require.NoError(t, os.WriteFile(filepath.Join(tmpDir, "a", "file.txt"), []byte("keep"), 0644)) | ||
|
|
||
| err = os.Remove(nested) | ||
| require.NoError(t, err) | ||
|
|
||
| cleanEmptyParents(filepath.Join(tmpDir, "a", "b"), tmpDir) | ||
|
|
||
| assert.NoDirExists(t, filepath.Join(tmpDir, "a", "b")) | ||
| assert.DirExists(t, filepath.Join(tmpDir, "a")) // Should exist because of file.txt | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,114 @@ | ||||||||||||||||||
| package gitvolume | ||||||||||||||||||
|
|
||||||||||||||||||
| import ( | ||||||||||||||||||
| "os" | ||||||||||||||||||
| "os/exec" | ||||||||||||||||||
| "path/filepath" | ||||||||||||||||||
| "testing" | ||||||||||||||||||
|
|
||||||||||||||||||
| "github.com/stretchr/testify/assert" | ||||||||||||||||||
| "github.com/stretchr/testify/require" | ||||||||||||||||||
| ) | ||||||||||||||||||
|
|
||||||||||||||||||
| func TestFindCommonDir_Repro(t *testing.T) { | ||||||||||||||||||
| // Create a temporary directory for our test environment | ||||||||||||||||||
| tmpDir, err := os.MkdirTemp("", "git-volume-repro-*") | ||||||||||||||||||
| require.NoError(t, err) | ||||||||||||||||||
| defer os.RemoveAll(tmpDir) | ||||||||||||||||||
|
Comment on lines
+15
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For modern Go tests (1.15+), it is recommended to use
Suggested change
References
|
||||||||||||||||||
|
|
||||||||||||||||||
| // 1. Test Case: Bare Repository + Worktree | ||||||||||||||||||
| t.Run("Bare Repository with Worktree", func(t *testing.T) { | ||||||||||||||||||
| bareRepo := filepath.Join(tmpDir, "bare.git") | ||||||||||||||||||
| worktree := filepath.Join(tmpDir, "worktree") | ||||||||||||||||||
|
|
||||||||||||||||||
| // Create a non-bare origin repo with an initial commit, | ||||||||||||||||||
| // then clone it as bare. | ||||||||||||||||||
|
|
||||||||||||||||||
| origin := filepath.Join(tmpDir, "origin") | ||||||||||||||||||
| require.NoError(t, os.MkdirAll(origin, 0755)) | ||||||||||||||||||
| cmd := exec.Command("git", "init", origin) | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
|
|
||||||||||||||||||
| // config user | ||||||||||||||||||
| cmd = exec.Command("git", "-C", origin, "config", "user.email", "test@example.com") | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
| cmd = exec.Command("git", "-C", origin, "config", "user.name", "Test User") | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
|
|
||||||||||||||||||
| // commit | ||||||||||||||||||
| require.NoError(t, os.WriteFile(filepath.Join(origin, "README.md"), []byte("test"), 0644)) | ||||||||||||||||||
| cmd = exec.Command("git", "-C", origin, "add", ".") | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
| cmd = exec.Command("git", "-C", origin, "commit", "-m", "initial") | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
|
|
||||||||||||||||||
| // Clone as bare (this creates the bareRepo directory) | ||||||||||||||||||
| cmd = exec.Command("git", "clone", "--bare", origin, bareRepo) | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
|
|
||||||||||||||||||
| cmd = exec.Command("git", "-C", bareRepo, "worktree", "add", "-b", "bare-worktree", worktree) | ||||||||||||||||||
| if out, err := cmd.CombinedOutput(); err != nil { | ||||||||||||||||||
| t.Fatalf("git worktree add failed: %s, output: %s", err, out) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| // Resolve symlinks for accurate comparison | ||||||||||||||||||
| bareRepo, err = filepath.EvalSymlinks(bareRepo) | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||
| require.NoError(t, err) | ||||||||||||||||||
|
|
||||||||||||||||||
| // Run findCommonDir from worktree root | ||||||||||||||||||
| commonDir, err := findCommonDir(worktree) | ||||||||||||||||||
| require.NoError(t, err) | ||||||||||||||||||
|
|
||||||||||||||||||
| // For bare repo, common dir should be the bare repo path itself | ||||||||||||||||||
| assert.Equal(t, bareRepo, commonDir, "Should identify bare repo root as common dir") | ||||||||||||||||||
|
|
||||||||||||||||||
| // Run findCommonDir from subdirectory of worktree | ||||||||||||||||||
| subDir := filepath.Join(worktree, "subdir") | ||||||||||||||||||
| require.NoError(t, os.MkdirAll(subDir, 0755)) | ||||||||||||||||||
|
|
||||||||||||||||||
| commonDirSub, err := findCommonDir(subDir) | ||||||||||||||||||
| require.NoError(t, err) | ||||||||||||||||||
| assert.Equal(t, bareRepo, commonDirSub, "Should identify bare repo root from subdirectory") | ||||||||||||||||||
| }) | ||||||||||||||||||
|
|
||||||||||||||||||
| // 2. Test Case: Regular Repository + Worktree | ||||||||||||||||||
| t.Run("Regular Repository with Worktree", func(t *testing.T) { | ||||||||||||||||||
| mainRepo := filepath.Join(tmpDir, "main") | ||||||||||||||||||
| worktree := filepath.Join(tmpDir, "main-worktree") | ||||||||||||||||||
|
|
||||||||||||||||||
| // Initialize main repo | ||||||||||||||||||
| require.NoError(t, os.MkdirAll(mainRepo, 0755)) | ||||||||||||||||||
| cmd := exec.Command("git", "init", mainRepo) | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
|
|
||||||||||||||||||
| // config user | ||||||||||||||||||
| cmd = exec.Command("git", "-C", mainRepo, "config", "user.email", "test@example.com") | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
| cmd = exec.Command("git", "-C", mainRepo, "config", "user.name", "Test User") | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
|
|
||||||||||||||||||
| // commit | ||||||||||||||||||
| require.NoError(t, os.WriteFile(filepath.Join(mainRepo, "README.md"), []byte("test"), 0644)) | ||||||||||||||||||
| cmd = exec.Command("git", "-C", mainRepo, "add", ".") | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
| cmd = exec.Command("git", "-C", mainRepo, "commit", "-m", "initial") | ||||||||||||||||||
| require.NoError(t, cmd.Run()) | ||||||||||||||||||
|
|
||||||||||||||||||
| cmd = exec.Command("git", "-C", mainRepo, "worktree", "add", "-b", "main-worktree-branch", worktree) | ||||||||||||||||||
| if out, err := cmd.CombinedOutput(); err != nil { | ||||||||||||||||||
| t.Fatalf("git worktree add failed: %s, output: %s", err, out) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| // Resolve symlinks | ||||||||||||||||||
| mainRepo, err = filepath.EvalSymlinks(mainRepo) | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||
| require.NoError(t, err) | ||||||||||||||||||
|
|
||||||||||||||||||
| // Run findCommonDir from worktree root | ||||||||||||||||||
| commonDir, err := findCommonDir(worktree) | ||||||||||||||||||
| require.NoError(t, err) | ||||||||||||||||||
|
|
||||||||||||||||||
| // For regular repo, common dir is .git dir, so root is parent of .git | ||||||||||||||||||
| // BUT findCommonDir returns the ROOT of the main repo, not the .git dir. | ||||||||||||||||||
| assert.Equal(t, mainRepo, commonDir, "Should identify main repo root") | ||||||||||||||||||
| }) | ||||||||||||||||||
| } | ||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.