diff options
Diffstat (limited to 'internal/file/file_test.go')
| -rw-r--r-- | internal/file/file_test.go | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/internal/file/file_test.go b/internal/file/file_test.go deleted file mode 100644 index a6488ce..0000000 --- a/internal/file/file_test.go +++ /dev/null @@ -1,417 +0,0 @@ -package file - -import ( - "os" - "path/filepath" - "strings" - "testing" -) - -func TestGetChecksum(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "test.txt") - - if err := os.WriteFile(path, []byte("hello"), 0o644); err != nil { - t.Fatal(err) - } - checksum := getChecksum(path) - if checksum == [32]byte{} { - t.Error("expected non-zero checksum") - } - - zeroChecksum := getChecksum(filepath.Join(dir, "no-such-file")) - var expectedZero [32]byte - if zeroChecksum != expectedZero { - t.Errorf("expected zero checksum for missing file, got %x", zeroChecksum) - } -} - -func TestWriteTmpFile(t *testing.T) { - dir := t.TempDir() - tmpPath := filepath.Join(dir, "test.tmp") - content := []byte("temp content") - - if err := writeTmpFile(tmpPath, content, 0o644); err != nil { - t.Fatalf("unexpected error: %v", err) - } - - got, err := os.ReadFile(tmpPath) - if err != nil { - t.Fatalf("reading tmp file: %v", err) - } - if string(got) != string(content) { - t.Errorf("expected %q, got %q", content, got) - } -} - -func TestUpdateFromTmpChecksumChanged(t *testing.T) { - dir := t.TempDir() - tmpPath := filepath.Join(dir, "test.tmp") - path := filepath.Join(dir, "test.txt") - - if err := os.WriteFile(tmpPath, []byte("new content"), 0o644); err != nil { - t.Fatal(err) - } - - if err := updateFromTmp(tmpPath, path, true); err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if _, err := os.Stat(tmpPath); err == nil { - t.Error("tmp file should have been removed") - } - got, err := os.ReadFile(path) - if err != nil { - t.Fatalf("reading target file: %v", err) - } - if string(got) != "new content" { - t.Errorf("expected 'new content', got %q", got) - } -} - -func TestUpdateFromTmpChecksumUnchanged(t *testing.T) { - dir := t.TempDir() - tmpPath := filepath.Join(dir, "test.tmp") - path := filepath.Join(dir, "test.txt") - - if err := os.WriteFile(tmpPath, []byte("same"), 0o644); err != nil { - t.Fatal(err) - } - if err := os.WriteFile(path, []byte("same"), 0o644); err != nil { - t.Fatal(err) - } - - if err := updateFromTmp(tmpPath, path, false); err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if _, err := os.Stat(tmpPath); err == nil { - t.Error("tmp file should have been removed") - } - got, err := os.ReadFile(path) - if err != nil { - t.Fatalf("reading target file: %v", err) - } - if string(got) != "same" { - t.Errorf("expected 'same', got %q", got) - } -} - -func TestHaveStringCreateNewFile(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "new.txt") - - Have(path, WithContent("hello world")) - - got, err := os.ReadFile(path) - if err != nil { - t.Fatalf("reading file: %v", err) - } - if string(got) != "hello world" { - t.Errorf("expected 'hello world', got %q", got) - } -} - -func TestHaveMode(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "mode.txt") - mode := os.FileMode(0o600) - - Have(path, WithContent("mode test"), WithMode(mode)) - - info, err := os.Stat(path) - if err != nil { - t.Fatal(err) - } - // Mask to check only permission bits - if info.Mode().Perm() != mode { - t.Errorf("expected mode %v, got %v", mode, info.Mode().Perm()) - } -} - -func TestHaveSourceFile(t *testing.T) { - dir := t.TempDir() - sourcePath := filepath.Join("..", "..", "assets", "testfiles", "test.txt") - targetPath := filepath.Join(dir, "target.txt") - - Have(targetPath, WithSource(sourcePath)) - - got, err := os.ReadFile(targetPath) - if err != nil { - t.Fatalf("reading file: %v", err) - } - expected, _ := os.ReadFile(sourcePath) - if string(got) != string(expected) { - t.Errorf("expected %q, got %q", string(expected), string(got)) - } -} - -func TestHaveTemplateFile(t *testing.T) { - dir := t.TempDir() - sourcePath := filepath.Join("..", "..", "assets", "testfiles", "test.tmpl") - targetPath := filepath.Join(dir, "target.conf") - - Have(targetPath, WithSource(sourcePath)) - - got, err := os.ReadFile(targetPath) - if err != nil { - t.Fatalf("reading file: %v", err) - } - - expectedParam := sourcePath - if !strings.Contains(string(got), expectedParam) { - t.Errorf("expected content to contain Param %q, got %q", expectedParam, string(got)) - } -} - -func TestHaveDirectoryCreate(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "sub", "nested") - - Have(path, IsDirectory()) - - info, err := os.Stat(path) - if err != nil { - t.Fatalf("stat: %v", err) - } - if !info.IsDir() { - t.Errorf("expected a directory at %s", path) - } - if info.Mode().Perm() != 0o750 { - t.Errorf("expected default dir mode 0750, got %v", info.Mode().Perm()) - } -} - -func TestHaveDirectoryIdempotentWithMode(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "d") - - // Call the resource logic directly to exercise idempotency without the - // one-per-process resource registry rejecting a duplicate registration. - f1 := &File{path: path, mode: 0o755} - if err := f1.haveDirectory(); err != nil { - t.Fatalf("first apply: %v", err) - } - f2 := &File{path: path, mode: 0o700} - if err := f2.haveDirectory(); err != nil { - t.Fatalf("second apply: %v", err) - } - - info, err := os.Stat(path) - if err != nil { - t.Fatal(err) - } - if info.Mode().Perm() != 0o700 { - t.Errorf("expected mode 0700 enforced, got %v", info.Mode().Perm()) - } -} - -func TestHaveDirectoryFailsWhenFileExists(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "afile") - if err := os.WriteFile(path, []byte("x"), 0o644); err != nil { - t.Fatal(err) - } - - if _, err := have(path, IsDirectory()); err == nil { - t.Error("expected error when a regular file is in the way of a directory") - } -} - -func TestHaveSymlinkCreateAndIdempotent(t *testing.T) { - dir := t.TempDir() - target := filepath.Join(dir, "target.txt") - link := filepath.Join(dir, "link.txt") - if err := os.WriteFile(target, []byte("t"), 0o644); err != nil { - t.Fatal(err) - } - - Have(link, IsSymlink(target)) - got, err := os.Readlink(link) - if err != nil { - t.Fatalf("readlink: %v", err) - } - if got != target { - t.Errorf("expected link -> %s, got %s", target, got) - } - - // Re-applying the same link should be a no-op (tested directly to avoid the - // one-per-process resource registry rejecting a duplicate registration). - f := &File{path: link, symlink: true, symlinkTarget: target} - if err := f.haveSymlink(); err != nil { - t.Fatalf("idempotent apply: %v", err) - } -} - -func TestHaveSymlinkRepoints(t *testing.T) { - dir := t.TempDir() - old := filepath.Join(dir, "old.txt") - newT := filepath.Join(dir, "new.txt") - link := filepath.Join(dir, "link") - for _, p := range []string{old, newT} { - if err := os.WriteFile(p, []byte("x"), 0o644); err != nil { - t.Fatal(err) - } - } - if err := os.Symlink(old, link); err != nil { - t.Fatal(err) - } - - Have(link, IsSymlink(newT)) - got, err := os.Readlink(link) - if err != nil { - t.Fatal(err) - } - if got != newT { - t.Errorf("expected repoint to %s, got %s", newT, got) - } -} - -func TestHaveSymlinkMovesRealFileAside(t *testing.T) { - dir := t.TempDir() - target := filepath.Join(dir, "target.txt") - link := filepath.Join(dir, "real") - if err := os.WriteFile(target, []byte("t"), 0o644); err != nil { - t.Fatal(err) - } - if err := os.WriteFile(link, []byte("original"), 0o644); err != nil { - t.Fatal(err) - } - - Have(link, IsSymlink(target)) - - got, err := os.Readlink(link) - if err != nil { - t.Fatalf("expected %s to be a symlink: %v", link, err) - } - if got != target { - t.Errorf("expected link -> %s, got %s", target, got) - } - if data, err := os.ReadFile(link + ".old"); err != nil || string(data) != "original" { - t.Errorf("expected original content preserved in %s.old, got %q err %v", link, string(data), err) - } -} - -func TestHaveAbsent(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "gone.txt") - if err := os.WriteFile(path, []byte("bye"), 0o644); err != nil { - t.Fatal(err) - } - - Have(path, IsAbsent()) - if _, err := os.Stat(path); !os.IsNotExist(err) { - t.Errorf("expected %s to be removed", path) - } - - // Idempotent: removing a missing file is not an error (direct call to avoid - // duplicate registration in the one-per-process registry). - f := &File{path: path} - if err := f.haveAbsent(); err != nil { - t.Fatalf("absent on missing file: %v", err) - } -} - -func TestHaveHardlinkCreateAndIdempotent(t *testing.T) { - dir := t.TempDir() - target := filepath.Join(dir, "target.txt") - link := filepath.Join(dir, "link.txt") - if err := os.WriteFile(target, []byte("payload"), 0o644); err != nil { - t.Fatal(err) - } - - Have(link, IsHardlink(target)) - - ti, err := os.Stat(target) - if err != nil { - t.Fatal(err) - } - li, err := os.Stat(link) - if err != nil { - t.Fatal(err) - } - if !sameInode(ti, li) { - t.Errorf("expected %s and %s to share an inode", link, target) - } - - // Re-applying the same link should be a no-op (direct call to avoid the - // one-per-process resource registry rejecting a duplicate registration). - f := &File{path: link, hardlink: true, hardlinkTarget: target} - if err := f.haveHardlink(); err != nil { - t.Fatalf("idempotent apply: %v", err) - } -} - -func TestHaveHardlinkMovesRealFileAside(t *testing.T) { - dir := t.TempDir() - target := filepath.Join(dir, "target.txt") - link := filepath.Join(dir, "real") - if err := os.WriteFile(target, []byte("payload"), 0o644); err != nil { - t.Fatal(err) - } - if err := os.WriteFile(link, []byte("original"), 0o644); err != nil { - t.Fatal(err) - } - - Have(link, IsHardlink(target)) - - ti, err := os.Stat(target) - if err != nil { - t.Fatal(err) - } - li, err := os.Stat(link) - if err != nil { - t.Fatal(err) - } - if !sameInode(ti, li) { - t.Errorf("expected %s to be hardlinked to %s", link, target) - } - if data, err := os.ReadFile(link + ".old"); err != nil || string(data) != "original" { - t.Errorf("expected original content preserved in %s.old, got %q err %v", link, string(data), err) - } -} - -func TestHaveHardlinkMissingTarget(t *testing.T) { - dir := t.TempDir() - link := filepath.Join(dir, "link") - if _, err := have(link, IsHardlink(filepath.Join(dir, "nope"))); err == nil { - t.Error("expected error when hardlink target does not exist") - } -} - -func TestHaveAbsentNonEmptyDirWithoutPruneFails(t *testing.T) { - dir := t.TempDir() - target := filepath.Join(dir, "d") - if err := os.MkdirAll(filepath.Join(target, "sub"), 0o755); err != nil { - t.Fatal(err) - } - - if _, err := have(target, IsAbsent()); err == nil { - t.Error("expected error removing a non-empty directory without PruneDirectory()") - } - if _, err := os.Stat(target); err != nil { - t.Errorf("expected %s to still exist, got %v", target, err) - } -} - -func TestHaveAbsentPruneDirectoryRecursive(t *testing.T) { - dir := t.TempDir() - target := filepath.Join(dir, "d") - if err := os.MkdirAll(filepath.Join(target, "sub", "deep"), 0o755); err != nil { - t.Fatal(err) - } - if err := os.WriteFile(filepath.Join(target, "sub", "f.txt"), []byte("x"), 0o644); err != nil { - t.Fatal(err) - } - - Have(target, IsAbsent(), PruneDirectory()) - if _, err := os.Stat(target); !os.IsNotExist(err) { - t.Errorf("expected %s to be removed recursively", target) - } - - // Idempotent: removing a missing tree is not an error. - f := &File{path: target, absent: true, pruneDirectory: true} - if err := f.haveAbsent(); err != nil { - t.Fatalf("prune on missing tree: %v", err) - } -} |
