// tools/tests/ci_agent_bridge_test.go // // Unit tests for ci-agent-bridge CLI. // Covers patch application, branch reverts, artifact summarization, and podman runner. // // Run with: // go test ./tools/tests -v -race -cover package tests import ( "encoding/json" "os" "path/filepath" "testing" // Import the bridge for direct function testing. // Adjust path if your project structure differs. bridge "github.com/fraktal/mev-beta/tools/bridge" ) // helper: create temporary directory with dummy artifact files func createDummyArtifacts(t *testing.T) string { dir, err := os.MkdirTemp("", "artifacts") if err != nil { t.Fatalf("failed to create temp dir: %v", err) } // write 2 dummy files if err := os.WriteFile(filepath.Join(dir, "a.log"), []byte("log-data-123"), 0644); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "b.txt"), []byte("text-data-456"), 0644); err != nil { t.Fatal(err) } return dir } func TestSummarizeArtifacts(t *testing.T) { dir := createDummyArtifacts(t) defer os.RemoveAll(dir) outFile := filepath.Join(dir, "summary.json") cfg := bridge.SummarizeConfig{ ArtifactsDir: dir, OutputFile: outFile, } if err := bridge.SummarizeArtifacts(cfg); err != nil { t.Fatalf("summarize failed: %v", err) } // verify JSON exists data, err := os.ReadFile(outFile) if err != nil { t.Fatalf("failed to read summary.json: %v", err) } var parsed bridge.SummarizeResult if err := json.Unmarshal(data, &parsed); err != nil { t.Fatalf("failed to unmarshal json: %v", err) } if len(parsed.Files) < 2 { t.Errorf("expected >=2 files, got %d", len(parsed.Files)) } if parsed.Timestamp.IsZero() { t.Errorf("expected timestamp set") } // verify ZIP archive created if _, err := os.Stat(filepath.Join(dir, "summary.zip")); os.IsNotExist(err) { t.Errorf("expected summary.zip archive, not found") } } func TestApplyPatch_MissingArgs(t *testing.T) { op := bridge.PatchOperation{} err := bridge.ApplyPatch(op) if err == nil { t.Fatal("expected error when patchfile/branch missing") } } func TestRevertBranch_MissingBranch(t *testing.T) { err := bridge.RevertBranch("") if err == nil { t.Fatal("expected error when branch missing") } } // Integration-like test with mock podman-compose func TestRunPodmanCompose(t *testing.T) { // simulate podman-compose using echo tmpPath := filepath.Join(os.TempDir(), "podman-compose") if err := os.WriteFile(tmpPath, []byte("#!/bin/sh\necho podman-compose-run"), 0755); err != nil { t.Fatal(err) } defer os.Remove(tmpPath) // put tmpPath at beginning of PATH oldPath := os.Getenv("PATH") os.Setenv("PATH", filepath.Dir(tmpPath)+":"+oldPath) defer os.Setenv("PATH", oldPath) err := bridge.RunPodmanCompose() if err != nil { t.Fatalf("expected mock podman-compose to succeed, got err: %v", err) } } // TestZipDir ensures ZIP creation works standalone func TestZipDir(t *testing.T) { dir := createDummyArtifacts(t) defer os.RemoveAll(dir) dest := filepath.Join(dir, "out.zip") if err := bridge.ZipDir(dir, dest); err != nil { t.Fatalf("zipdir failed: %v", err) } info, err := os.Stat(dest) if err != nil { t.Fatalf("zip file not found: %v", err) } if info.Size() == 0 { t.Errorf("zip file is empty") } } // Benchmark for artifact summarization performance func BenchmarkSummarizeArtifacts(b *testing.B) { dir := createDummyArtifacts(nil) defer os.RemoveAll(dir) cfg := bridge.SummarizeConfig{ ArtifactsDir: dir, OutputFile: filepath.Join(dir, "summary.json"), } for i := 0; i < b.N; i++ { if err := bridge.SummarizeArtifacts(cfg); err != nil { b.Fatal(err) } } } // Example usage doc test func ExampleSummarizeArtifacts() { // This example is for documentation purposes only and doesn't produce output in tests // because it uses temporary directories with random names. }