package testing_test import ( "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "os" "os/exec" "path/filepath" "strings" "testing" ) func TestPlanCLIProducesActions(t *testing.T) { root := repoRoot(t) dummy := filepath.Join(t.TempDir(), "dummy.img") if err := os.WriteFile(dummy, []byte("dummy"), 0o644); err != nil { t.Fatal(err) } checksum := sha256.Sum256(readFile(t, dummy)) invPath := filepath.Join(t.TempDir(), "inv.yaml") inv := fmt.Sprintf(`{ "classes": [ { "name": "test-class", "arch": "arm64", "os": "testos", "image": "file://%s", "checksum": "sha256:%s", "default_labels": {"role": "worker"} } ], "nodes": [ { "name": "node-a", "class": "test-class", "hostname": "node-a", "ip": "10.0.0.10", "k3s_role": "agent" } ] }`, dummy, hex.EncodeToString(checksum[:]), ) if err := os.WriteFile(invPath, []byte(inv), 0o644); err != nil { t.Fatal(err) } cmd := exec.Command("go", "run", "./cmd/metis", "plan", "--inventory", invPath, "--node", "node-a", "--device", "/dev/sdz", "--cache", filepath.Join(t.TempDir(), "cache")) cmd.Dir = root out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("plan command failed: %v\n%s", err, out) } var plan struct { Node string `json:"node"` Actions []struct { Type string `json:"type"` } `json:"actions"` } if err := json.Unmarshal(out, &plan); err != nil { t.Fatalf("decode plan: %v\n%s", err, out) } if plan.Node != "node-a" { t.Fatalf("node = %q", plan.Node) } for _, action := range plan.Actions { if action.Type == "fetch" { return } } t.Fatal("expected a fetch action") } func TestBurnDryRunPrintsPlan(t *testing.T) { root := repoRoot(t) dummy := filepath.Join(t.TempDir(), "dummy.img") if err := os.WriteFile(dummy, []byte("dummy"), 0o644); err != nil { t.Fatal(err) } checksum := sha256.Sum256(readFile(t, dummy)) invPath := filepath.Join(t.TempDir(), "inv.yaml") inv := fmt.Sprintf(`{ "classes": [ { "name": "test-class", "arch": "arm64", "os": "testos", "image": "file://%s", "checksum": "sha256:%s", "default_labels": {"role": "worker"} } ], "nodes": [ { "name": "node-a", "class": "test-class", "hostname": "node-a", "ip": "10.0.0.10", "k3s_role": "agent" } ] }`, dummy, hex.EncodeToString(checksum[:]), ) if err := os.WriteFile(invPath, []byte(inv), 0o644); err != nil { t.Fatal(err) } cmd := exec.Command("go", "run", "./cmd/metis", "burn", "--inventory", invPath, "--node", "node-a", "--device", "/dev/sdz", "--cache", filepath.Join(t.TempDir(), "cache")) cmd.Dir = root out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("burn command failed: %v\n%s", err, out) } got := string(out) if !strings.Contains(got, "Dry run") && !strings.Contains(got, "Plan for") { t.Fatalf("unexpected output: %s", got) } }