Initial commit on Forgejo
Fresh repository history for elektrine/tarakan-client hosted at https://git.elektrine.com/elektrine/tarakan-client.
This commit is contained in:
commit
58b29a7f84
70 changed files with 12994 additions and 0 deletions
140
internal/snapshot/snapshot_test.go
Normal file
140
internal/snapshot/snapshot_test.go
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
package snapshot
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCreatePinsCommitWithoutGitMetadataAndDetectsChanges(t *testing.T) {
|
||||
repository := createTestRepository(t)
|
||||
commit := gitOutput(t, repository, "rev-parse", "HEAD")
|
||||
|
||||
snapshot, err := Create(repository, commit)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root := snapshot.Root
|
||||
t.Cleanup(func() { _ = snapshot.Close() })
|
||||
|
||||
if _, err := os.Stat(filepath.Join(root, ".git")); !os.IsNotExist(err) {
|
||||
t.Fatalf("snapshot retains Git metadata: %v", err)
|
||||
}
|
||||
changed, err := snapshot.Changed()
|
||||
if err != nil || changed {
|
||||
t.Fatalf("unchanged snapshot: changed=%v err=%v", changed, err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(root, "README.md"), []byte("changed\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
changed, err = snapshot.Changed()
|
||||
if err != nil || !changed {
|
||||
t.Fatalf("changed snapshot: changed=%v err=%v", changed, err)
|
||||
}
|
||||
|
||||
if err := snapshot.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := os.Stat(root); !os.IsNotExist(err) {
|
||||
t.Fatalf("snapshot was not destroyed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateRejectsUnavailableCommit(t *testing.T) {
|
||||
repository := createTestRepository(t)
|
||||
_, err := Create(repository, "dead000000000000000000000000000000000000")
|
||||
if !errors.Is(err, ErrCommitUnavailable) {
|
||||
t.Fatalf("error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateNeutralizesExternalAndEscapingSymlinks(t *testing.T) {
|
||||
repository := createTestRepository(t)
|
||||
|
||||
// Absolute external pointer (common "works on my Mac" vendor path).
|
||||
if err := os.Symlink("/Users/someone/Desktop/secret", filepath.Join(repository, "external-abs")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Relative path that escapes the tree.
|
||||
if err := os.Symlink("../host-secret", filepath.Join(repository, "escape")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Safe in-tree relative link must be kept.
|
||||
if err := os.Symlink("README.md", filepath.Join(repository, "readme-link")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runGitTest(t, repository, "add", "external-abs", "escape", "readme-link")
|
||||
runGitTest(t, repository, "-c", "user.name=Tarakan Test", "-c", "user.email=test@tarakan.invalid", "commit", "-m", "symlinks")
|
||||
|
||||
commit := gitOutput(t, repository, "rev-parse", "HEAD")
|
||||
snap, err := Create(repository, commit)
|
||||
if err != nil {
|
||||
t.Fatalf("Create should neutralize external symlinks, got: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { _ = snap.Close() })
|
||||
|
||||
// Escaping / absolute links become ordinary files with the original target.
|
||||
for _, name := range []string{"external-abs", "escape"} {
|
||||
info, err := os.Lstat(filepath.Join(snap.Root, name))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
t.Fatalf("%s still a symlink", name)
|
||||
}
|
||||
body, err := os.ReadFile(filepath.Join(snap.Root, name))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(body), "neutralized external symlink") {
|
||||
t.Fatalf("%s body = %q", name, body)
|
||||
}
|
||||
}
|
||||
|
||||
// In-tree relative symlink preserved.
|
||||
target, err := os.Readlink(filepath.Join(snap.Root, "readme-link"))
|
||||
if err != nil {
|
||||
t.Fatalf("safe symlink should remain: %v", err)
|
||||
}
|
||||
if target != "README.md" {
|
||||
t.Fatalf("safe symlink target = %q", target)
|
||||
}
|
||||
|
||||
changed, err := snap.Changed()
|
||||
if err != nil || changed {
|
||||
t.Fatalf("unchanged after neutralize: changed=%v err=%v", changed, err)
|
||||
}
|
||||
}
|
||||
|
||||
func createTestRepository(t *testing.T) string {
|
||||
t.Helper()
|
||||
repository := t.TempDir()
|
||||
runGitTest(t, repository, "init", "-b", "main")
|
||||
if err := os.WriteFile(filepath.Join(repository, "README.md"), []byte("pinned\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runGitTest(t, repository, "add", "README.md")
|
||||
runGitTest(t, repository, "-c", "user.name=Tarakan Test", "-c", "user.email=test@tarakan.invalid", "commit", "-m", "initial")
|
||||
return repository
|
||||
}
|
||||
|
||||
func runGitTest(t *testing.T, directory string, arguments ...string) {
|
||||
t.Helper()
|
||||
command := exec.Command("git", append([]string{"-C", directory}, arguments...)...)
|
||||
if output, err := command.CombinedOutput(); err != nil {
|
||||
t.Fatalf("git %v: %v: %s", arguments, err, output)
|
||||
}
|
||||
}
|
||||
|
||||
func gitOutput(t *testing.T, directory string, arguments ...string) string {
|
||||
t.Helper()
|
||||
command := exec.Command("git", append([]string{"-C", directory}, arguments...)...)
|
||||
output, err := command.Output()
|
||||
if err != nil {
|
||||
t.Fatalf("git %v: %v", arguments, err)
|
||||
}
|
||||
return strings.TrimSpace(string(output))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue