package scanner import ( "context" "os/exec" "path/filepath" "testing" "gitea.oblak.solutions/dimitar/gitFlow/pkg/status" ) func newGitRepo(t *testing.T, dir string) string { t.Helper() if _, err := exec.LookPath("git"); err != nil { t.Skip("git not available") } cmd := exec.Command("git", "init", "-q", "-b", "main", filepath.Base(dir)) cmd.Dir = filepath.Dir(dir) if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("git init: %v\n%s", err, out) } cmd = exec.Command("git", "config", "user.email", "t@t") cmd.Dir = dir _ = cmd.Run() cmd = exec.Command("git", "config", "user.name", "t") cmd.Dir = dir _ = cmd.Run() return dir } func TestScannerScanMixed(t *testing.T) { root := t.TempDir() repo1 := newGitRepo(t, filepath.Join(root, "one")) repo2 := newGitRepo(t, filepath.Join(root, "two")) bogus := filepath.Join(root, "not-a-repo") s := NewScanner() infos, err := s.Scan(context.Background(), []string{repo1, repo2, bogus}) if err != nil { t.Fatalf("Scan: %v", err) } if len(infos) != 3 { t.Fatalf("Scan returned %d infos, want 3", len(infos)) } for _, info := range infos { switch info.Path { case repo1, repo2: if info.Status != status.StatusClean { t.Errorf("%s: Status = %v, want clean", info.Path, info.Status) } case bogus: if info.Status != status.StatusError { t.Errorf("bogus: Status = %v, want error", info.Status) } if info.Error == "" { t.Errorf("bogus: Error is empty") } } } } func TestScannerConcurrentErrors(t *testing.T) { // Many failing paths at low worker count: everything must come back as // StatusError and no goroutine may leak or race. root := t.TempDir() paths := make([]string, 20) for i := range paths { paths[i] = filepath.Join(root, "nope", "repo", string(rune('a'+i))) } s := NewScanner(WithWorkers(4)) infos, err := s.Scan(context.Background(), paths) if err != nil { t.Fatalf("Scan: %v", err) } if len(infos) != len(paths) { t.Fatalf("Scan returned %d infos, want %d", len(infos), len(paths)) } for i, info := range infos { if info.Status != status.StatusError { t.Errorf("path %d: Status = %v, want error", i, info.Status) } } } func TestScannerCancellation(t *testing.T) { root := t.TempDir() repo := newGitRepo(t, filepath.Join(root, "one")) paths := make([]string, 0, 10) for i := 0; i < 10; i++ { paths = append(paths, repo) } ctx, cancel := context.WithCancel(context.Background()) cancel() if _, err := NewScanner().Scan(ctx, paths); err == nil { t.Error("Scan(cancelled ctx) succeeded, want error") } }