package stack import ( "os" "path/filepath" "testing" "gitea.oxpoe.qzz.io/oxpoe/tia-love/internal/docker" ) func TestScanFS(t *testing.T) { root := t.TempDir() mk := func(rel string) string { p := filepath.Join(root, rel) if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(p, []byte("services: {}\n"), 0o644); err != nil { t.Fatal(err) } return p } mk("webapp/compose.yaml") mk("db/docker-compose.yml") mk("legacy/docker-compose.yaml") mk("modern/compose.yml") _ = os.MkdirAll(filepath.Join(root, "bukan-stack"), 0o755) // folder tanpa compose _ = os.WriteFile(filepath.Join(root, "file-nyasar.yaml"), []byte(""), 0o644) // file, bukan dir stacks, err := ScanFS(root) if err != nil { t.Fatalf("ScanFS: %v", err) } if len(stacks) != 4 { t.Fatalf("harusnya 4 stack, dapat %d: %+v", len(stacks), stacks) } // terurut nama want := []string{"db", "legacy", "modern", "webapp"} for i, s := range stacks { if s.Name != want[i] { t.Fatalf("urutan/nama salah: %v", stacks) } if s.Status != StatusCreatedFile { t.Fatalf("status awal harus CREATED_FILE: %+v", s) } } // folder tidak ada → kosong tanpa error if got, err := ScanFS(filepath.Join(root, "tidak-ada")); err != nil || len(got) != 0 { t.Fatalf("folder tidak ada: %v %v", got, err) } } func TestReconcile(t *testing.T) { stacks := []Stack{ {Name: "web", Status: StatusCreatedFile}, {Name: "db", Status: StatusCreatedFile}, {Name: "other", Status: StatusCreatedFile}, } projects := []docker.ComposeProject{ {Name: "web", Status: "running(2)"}, {Name: "db", Status: "exited(1)"}, {Name: "asing", Status: "running(5)"}, // tidak ada di disk → diabaikan } out := Reconcile(stacks, projects) if out[0].Status != StatusRunning || out[1].Status != StatusExited { t.Fatalf("overlay salah: %+v", out) } if out[2].Status != StatusCreatedFile { t.Fatalf("stack tak dikenal harus tetap CREATED_FILE: %+v", out[2]) } } func TestParseComposeStatus(t *testing.T) { cases := map[string]Status{ "running(2)": StatusRunning, "exited(0)": StatusExited, "created": StatusCreatedStack, "restarting": StatusUnknown, } for in, want := range cases { if got := parseComposeStatus(in); got != want { t.Errorf("%q → %v, mau %v", in, got, want) } } }