@@ -0,0 +1,83 @@
|
||||
package gitops
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNormalizeRejectsUnsafeStackAndRepositoryArguments(t *testing.T) {
|
||||
cases := []Input{
|
||||
{StackName: "../escape", RepoURL: "https://example.invalid/repo.git"},
|
||||
{StackName: "demo", RepoURL: "--upload-pack=evil"},
|
||||
{StackName: "demo", RepoURL: "https://example.invalid/repo.git\n--option"},
|
||||
}
|
||||
for _, in := range cases {
|
||||
if err := normalize(&in); err == nil {
|
||||
t.Fatalf("expected unsafe input to be rejected: %#v", in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncManagedTreePreservesUnmanagedDataAndRemovesStaleGitFiles(t *testing.T) {
|
||||
dst := t.TempDir()
|
||||
stage1 := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(stage1, "compose.yaml"), []byte("services: {}\n"), 0640); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(stage1, "config"), 0750); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(stage1, "config", "old.txt"), []byte("old"), 0640); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := syncManagedTree(stage1, dst); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(dst, "data"), 0750); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(dst, "data", "runtime.db"), []byte("keep"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stage2 := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(stage2, "compose.yaml"), []byte("services:\n web:\n image: nginx\n"), 0640); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(stage2, "config"), 0750); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(stage2, "config", "new.txt"), []byte("new"), 0640); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := syncManagedTree(stage2, dst); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if b, err := os.ReadFile(filepath.Join(dst, "data", "runtime.db")); err != nil || string(b) != "keep" {
|
||||
t.Fatalf("unmanaged data was not preserved: %q %v", b, err)
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dst, "config", "old.txt")); !os.IsNotExist(err) {
|
||||
t.Fatalf("stale Git-managed file still exists: %v", err)
|
||||
}
|
||||
if b, err := os.ReadFile(filepath.Join(dst, "config", "new.txt")); err != nil || string(b) != "new" {
|
||||
t.Fatalf("new Git file missing: %q %v", b, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncManagedTreeRejectsSymlinkDestination(t *testing.T) {
|
||||
parent := t.TempDir()
|
||||
outside := t.TempDir()
|
||||
dst := filepath.Join(parent, "demo")
|
||||
if err := os.Symlink(outside, dst); err != nil {
|
||||
t.Skipf("symlinks unavailable: %v", err)
|
||||
}
|
||||
stage := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(stage, "compose.yaml"), []byte("services: {}\n"), 0640); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := syncManagedTree(stage, dst); err == nil {
|
||||
t.Fatal("expected symlink Git destination to be rejected")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user