package app import ( "archive/tar" "compress/gzip" "errors" "io" "os" "path/filepath" "strings" "sync" "testing" ) // TestWriteBundleDocs covers the primitive shared by both consumers — // BuildSupportBundle (support-bundle archive root) and blackboxWorker.syncCycle // (removable-media boot-folder root) — since a blackbox capture has no // manifest.txt/tar-archive test harness to drive syncCycle end-to-end, but // both call this same function at their respective root. func TestWriteBundleDocs(t *testing.T) { root := t.TempDir() if err := writeBundleDocs(root); err != nil { t.Fatalf("writeBundleDocs: %v", err) } readme, err := os.ReadFile(filepath.Join(root, "README.md")) if err != nil { t.Fatalf("read README.md: %v", err) } if !strings.Contains(string(readme), "bee-audit.json") { t.Fatalf("README.md should explain where the hardware inventory lives:\n%s", readme) } if !strings.Contains(string(readme), "overall_status") { t.Fatalf("README.md should explain how to check SAT pass/fail:\n%s", readme) } } func TestCreateSupportTarGzUsesIndependentFilesConcurrently(t *testing.T) { tempDir := t.TempDir() srcDir := filepath.Join(tempDir, "bee-support-stage-test") if err := os.Mkdir(srcDir, 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(srcDir, "evidence.txt"), []byte("complete evidence\n"), 0644); err != nil { t.Fatal(err) } const builds = 4 paths := make(chan string, builds) errs := make(chan error, builds) var wg sync.WaitGroup for range builds { wg.Add(1) go func() { defer wg.Done() path, err := createSupportTarGz(tempDir, "bundle", srcDir) if err != nil { errs <- err return } paths <- path }() } wg.Wait() close(paths) close(errs) for err := range errs { t.Fatalf("create archive: %v", err) } seen := make(map[string]struct{}, builds) for path := range paths { if !strings.HasSuffix(path, ".tar.gz") { t.Fatalf("archive path %q does not end in .tar.gz", path) } if _, exists := seen[path]; exists { t.Fatalf("duplicate archive path %q", path) } seen[path] = struct{}{} assertSupportArchiveEntry(t, path, "bee-support-stage-test/evidence.txt", "complete evidence\n") } if len(seen) != builds { t.Fatalf("archive count = %d, want %d", len(seen), builds) } partials, err := filepath.Glob(filepath.Join(tempDir, "*.partial")) if err != nil { t.Fatal(err) } if len(partials) != 0 { t.Fatalf("unpublished partial archives remain: %v", partials) } } func assertSupportArchiveEntry(t *testing.T, path, wantName, wantBody string) { t.Helper() file, err := os.Open(path) if err != nil { t.Fatal(err) } defer file.Close() gz, err := gzip.NewReader(file) if err != nil { t.Fatal(err) } defer gz.Close() tr := tar.NewReader(gz) for { header, err := tr.Next() if errors.Is(err, io.EOF) { break } if err != nil { t.Fatal(err) } if header.Name != wantName { continue } body, err := io.ReadAll(tr) if err != nil { t.Fatal(err) } if string(body) != wantBody { t.Fatalf("entry body = %q, want %q", body, wantBody) } return } t.Fatalf("archive %q is missing %q", path, wantName) }