| | |
| | |
| | |
| |
|
| | package main_test |
| |
|
| | import ( |
| | cmdcovdata "cmd/covdata" |
| | "flag" |
| | "fmt" |
| | "internal/coverage/pods" |
| | "internal/testenv" |
| | "log" |
| | "os" |
| | "path/filepath" |
| | "regexp" |
| | "strconv" |
| | "strings" |
| | "sync" |
| | "testing" |
| | ) |
| |
|
| | |
| | var testTempDir string |
| |
|
| | |
| | var preserveTmp = flag.Bool("preservetmp", false, "keep tmpdir files for debugging") |
| |
|
| | |
| | |
| | |
| | func TestMain(m *testing.M) { |
| | |
| | |
| | |
| | |
| | if os.Getenv("CMDCOVDATA_TEST_RUN_MAIN") != "" { |
| | cmdcovdata.Main() |
| | os.Exit(0) |
| | } |
| | flag.Parse() |
| | topTmpdir, err := os.MkdirTemp("", "cmd-covdata-test-") |
| | if err != nil { |
| | log.Fatal(err) |
| | } |
| | testTempDir = topTmpdir |
| | if !*preserveTmp { |
| | defer os.RemoveAll(topTmpdir) |
| | } else { |
| | fmt.Fprintf(os.Stderr, "debug: preserving tmpdir %s\n", topTmpdir) |
| | } |
| | os.Setenv("CMDCOVDATA_TEST_RUN_MAIN", "true") |
| | os.Exit(m.Run()) |
| | } |
| |
|
| | var tdmu sync.Mutex |
| | var tdcount int |
| |
|
| | func tempDir(t *testing.T) string { |
| | tdmu.Lock() |
| | dir := filepath.Join(testTempDir, fmt.Sprintf("%03d", tdcount)) |
| | tdcount++ |
| | if err := os.Mkdir(dir, 0777); err != nil { |
| | t.Fatal(err) |
| | } |
| | defer tdmu.Unlock() |
| | return dir |
| | } |
| |
|
| | const debugtrace = false |
| |
|
| | func gobuild(t *testing.T, indir string, bargs []string) { |
| | t.Helper() |
| |
|
| | if debugtrace { |
| | if indir != "" { |
| | t.Logf("in dir %s: ", indir) |
| | } |
| | t.Logf("cmd: %s %+v\n", testenv.GoToolPath(t), bargs) |
| | } |
| | cmd := testenv.Command(t, testenv.GoToolPath(t), bargs...) |
| | cmd.Dir = indir |
| | b, err := cmd.CombinedOutput() |
| | if len(b) != 0 { |
| | t.Logf("## build output:\n%s", b) |
| | } |
| | if err != nil { |
| | t.Fatalf("build error: %v", err) |
| | } |
| | } |
| |
|
| | func emitFile(t *testing.T, dst, src string) { |
| | payload, err := os.ReadFile(src) |
| | if err != nil { |
| | t.Fatalf("error reading %q: %v", src, err) |
| | } |
| | if err := os.WriteFile(dst, payload, 0666); err != nil { |
| | t.Fatalf("writing %q: %v", dst, err) |
| | } |
| | } |
| |
|
| | const mainPkgPath = "prog" |
| |
|
| | func buildProg(t *testing.T, prog string, dir string, tag string, flags []string) (string, string) { |
| | |
| | subdir := filepath.Join(dir, prog+"dir"+tag) |
| | if err := os.Mkdir(subdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", subdir, err) |
| | } |
| | depdir := filepath.Join(subdir, "dep") |
| | if err := os.Mkdir(depdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", depdir, err) |
| | } |
| |
|
| | |
| | insrc := filepath.Join("testdata", prog+".go") |
| | src := filepath.Join(subdir, prog+".go") |
| | emitFile(t, src, insrc) |
| | indep := filepath.Join("testdata", "dep.go") |
| | dep := filepath.Join(depdir, "dep.go") |
| | emitFile(t, dep, indep) |
| |
|
| | |
| | mod := filepath.Join(subdir, "go.mod") |
| | modsrc := "\nmodule " + mainPkgPath + "\n\ngo 1.19\n" |
| | if err := os.WriteFile(mod, []byte(modsrc), 0666); err != nil { |
| | t.Fatal(err) |
| | } |
| | exepath := filepath.Join(subdir, prog+".exe") |
| | bargs := []string{"build", "-cover", "-o", exepath} |
| | bargs = append(bargs, flags...) |
| | gobuild(t, subdir, bargs) |
| | return exepath, subdir |
| | } |
| |
|
| | type state struct { |
| | dir string |
| | exedir1 string |
| | exedir2 string |
| | exedir3 string |
| | exepath1 string |
| | exepath2 string |
| | exepath3 string |
| | tool string |
| | outdirs [4]string |
| | } |
| |
|
| | const debugWorkDir = false |
| |
|
| | func TestCovTool(t *testing.T) { |
| | testenv.MustHaveGoBuild(t) |
| | dir := tempDir(t) |
| | if testing.Short() { |
| | t.Skip() |
| | } |
| | if debugWorkDir { |
| | |
| | dir = "/tmp/qqq" |
| | os.RemoveAll(dir) |
| | os.Mkdir(dir, 0777) |
| | } |
| |
|
| | s := state{ |
| | dir: dir, |
| | } |
| | s.exepath1, s.exedir1 = buildProg(t, "prog1", dir, "", nil) |
| | s.exepath2, s.exedir2 = buildProg(t, "prog2", dir, "", nil) |
| | flags := []string{"-covermode=atomic"} |
| | s.exepath3, s.exedir3 = buildProg(t, "prog1", dir, "atomic", flags) |
| |
|
| | |
| | s.tool = testenv.Executable(t) |
| |
|
| | |
| | for i := 0; i < 4; i++ { |
| | d := filepath.Join(dir, fmt.Sprintf("covdata%d", i)) |
| | s.outdirs[i] = d |
| | if err := os.Mkdir(d, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", d, err) |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | for m := 0; m < 2; m++ { |
| | for k := 0; k < 2; k++ { |
| | args := []string{} |
| | if k != 0 { |
| | args = append(args, "foo", "bar") |
| | } |
| | for i := 0; i <= k; i++ { |
| | exepath := s.exepath1 |
| | if m != 0 { |
| | exepath = s.exepath3 |
| | } |
| | cmd := testenv.Command(t, exepath, args...) |
| | cmd.Env = append(cmd.Env, "GOCOVERDIR="+s.outdirs[m*2+k]) |
| | b, err := cmd.CombinedOutput() |
| | if len(b) != 0 { |
| | t.Logf("## instrumented run output:\n%s", b) |
| | } |
| | if err != nil { |
| | t.Fatalf("instrumented run error: %v", err) |
| | } |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | t.Run("MergeSimple", func(t *testing.T) { |
| | t.Parallel() |
| | testMergeSimple(t, s, s.outdirs[0], s.outdirs[1], "set") |
| | testMergeSimple(t, s, s.outdirs[2], s.outdirs[3], "atomic") |
| | }) |
| | t.Run("MergeSelect", func(t *testing.T) { |
| | t.Parallel() |
| | testMergeSelect(t, s, s.outdirs[0], s.outdirs[1], "set") |
| | testMergeSelect(t, s, s.outdirs[2], s.outdirs[3], "atomic") |
| | }) |
| | t.Run("MergePcombine", func(t *testing.T) { |
| | t.Parallel() |
| | testMergeCombinePrograms(t, s) |
| | }) |
| | t.Run("Dump", func(t *testing.T) { |
| | t.Parallel() |
| | testDump(t, s) |
| | }) |
| | t.Run("Percent", func(t *testing.T) { |
| | t.Parallel() |
| | testPercent(t, s) |
| | }) |
| | t.Run("PkgList", func(t *testing.T) { |
| | t.Parallel() |
| | testPkgList(t, s) |
| | }) |
| | t.Run("Textfmt", func(t *testing.T) { |
| | t.Parallel() |
| | testTextfmt(t, s) |
| | }) |
| | t.Run("Subtract", func(t *testing.T) { |
| | t.Parallel() |
| | testSubtract(t, s) |
| | }) |
| | t.Run("Intersect", func(t *testing.T) { |
| | t.Parallel() |
| | testIntersect(t, s, s.outdirs[0], s.outdirs[1], "set") |
| | testIntersect(t, s, s.outdirs[2], s.outdirs[3], "atomic") |
| | }) |
| | t.Run("CounterClash", func(t *testing.T) { |
| | t.Parallel() |
| | testCounterClash(t, s) |
| | }) |
| | t.Run("TestEmpty", func(t *testing.T) { |
| | t.Parallel() |
| | testEmpty(t, s) |
| | }) |
| | t.Run("TestCommandLineErrors", func(t *testing.T) { |
| | t.Parallel() |
| | testCommandLineErrors(t, s, s.outdirs[0]) |
| | }) |
| | } |
| |
|
| | const showToolInvocations = true |
| |
|
| | func runToolOp(t *testing.T, s state, op string, args []string) []string { |
| | |
| | t.Helper() |
| | args = append([]string{op}, args...) |
| | if showToolInvocations { |
| | t.Logf("%s cmd is: %s %+v", op, s.tool, args) |
| | } |
| | cmd := testenv.Command(t, s.tool, args...) |
| | b, err := cmd.CombinedOutput() |
| | if err != nil { |
| | fmt.Fprintf(os.Stderr, "## %s output: %s\n", op, b) |
| | t.Fatalf("%q run error: %v", op, err) |
| | } |
| | output := strings.TrimSpace(string(b)) |
| | lines := strings.Split(output, "\n") |
| | if len(lines) == 1 && lines[0] == "" { |
| | lines = nil |
| | } |
| | return lines |
| | } |
| |
|
| | func testDump(t *testing.T, s state) { |
| | |
| | dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + s.outdirs[0] + "," + s.outdirs[1]} |
| | lines := runToolOp(t, s, "debugdump", dargs) |
| |
|
| | |
| | testpoints := []struct { |
| | tag string |
| | re *regexp.Regexp |
| | }{ |
| | { |
| | "args", |
| | regexp.MustCompile(`^data file .+ GOOS=.+ GOARCH=.+ program args: .+$`), |
| | }, |
| | { |
| | "main package", |
| | regexp.MustCompile(`^Package path: ` + mainPkgPath + `\s*$`), |
| | }, |
| | { |
| | "main function", |
| | regexp.MustCompile(`^Func: main\s*$`), |
| | }, |
| | } |
| |
|
| | bad := false |
| | for _, testpoint := range testpoints { |
| | found := false |
| | for _, line := range lines { |
| | if m := testpoint.re.FindStringSubmatch(line); m != nil { |
| | found = true |
| | break |
| | } |
| | } |
| | if !found { |
| | t.Errorf("dump output regexp match failed for %q", testpoint.tag) |
| | bad = true |
| | } |
| | } |
| | if bad { |
| | dumplines(lines) |
| | } |
| | } |
| |
|
| | func testPercent(t *testing.T, s state) { |
| | |
| | dargs := []string{"-pkg=" + mainPkgPath, "-i=" + s.outdirs[0] + "," + s.outdirs[1]} |
| | lines := runToolOp(t, s, "percent", dargs) |
| |
|
| | |
| | testpoints := []struct { |
| | tag string |
| | re *regexp.Regexp |
| | }{ |
| | { |
| | "statement coverage percent", |
| | regexp.MustCompile(`coverage: \d+\.\d% of statements\s*$`), |
| | }, |
| | } |
| |
|
| | bad := false |
| | for _, testpoint := range testpoints { |
| | found := false |
| | for _, line := range lines { |
| | if m := testpoint.re.FindStringSubmatch(line); m != nil { |
| | found = true |
| | break |
| | } |
| | } |
| | if !found { |
| | t.Errorf("percent output regexp match failed for %s", testpoint.tag) |
| | bad = true |
| | } |
| | } |
| | if bad { |
| | dumplines(lines) |
| | } |
| | } |
| |
|
| | func testPkgList(t *testing.T, s state) { |
| | dargs := []string{"-i=" + s.outdirs[0] + "," + s.outdirs[1]} |
| | lines := runToolOp(t, s, "pkglist", dargs) |
| |
|
| | want := []string{mainPkgPath, mainPkgPath + "/dep"} |
| | bad := false |
| | if len(lines) != 2 { |
| | t.Errorf("expect pkglist to return two lines") |
| | bad = true |
| | } else { |
| | for i := 0; i < 2; i++ { |
| | lines[i] = strings.TrimSpace(lines[i]) |
| | if want[i] != lines[i] { |
| | t.Errorf("line %d want %s got %s", i, want[i], lines[i]) |
| | bad = true |
| | } |
| | } |
| | } |
| | if bad { |
| | dumplines(lines) |
| | } |
| | } |
| |
|
| | func testTextfmt(t *testing.T, s state) { |
| | outf := s.dir + "/" + "t.txt" |
| | dargs := []string{"-pkg=" + mainPkgPath, "-i=" + s.outdirs[0] + "," + s.outdirs[1], |
| | "-o", outf} |
| | lines := runToolOp(t, s, "textfmt", dargs) |
| |
|
| | |
| | if len(lines) != 0 { |
| | dumplines(lines) |
| | t.Errorf("unexpected output from go tool covdata textfmt") |
| | } |
| |
|
| | |
| | payload, err := os.ReadFile(outf) |
| | if err != nil { |
| | t.Errorf("opening %s: %v\n", outf, err) |
| | } |
| | lines = strings.Split(string(payload), "\n") |
| | want0 := "mode: set" |
| | if lines[0] != want0 { |
| | dumplines(lines[0:10]) |
| | t.Errorf("textfmt: want %s got %s", want0, lines[0]) |
| | } |
| | want1 := mainPkgPath + "/prog1.go:13.14,15.2 1 1" |
| | if lines[1] != want1 { |
| | dumplines(lines[0:10]) |
| | t.Errorf("textfmt: want %s got %s", want1, lines[1]) |
| | } |
| | } |
| |
|
| | func dumplines(lines []string) { |
| | for i := range lines { |
| | fmt.Fprintf(os.Stderr, "%s\n", lines[i]) |
| | } |
| | } |
| |
|
| | type dumpCheck struct { |
| | tag string |
| | re *regexp.Regexp |
| | negate bool |
| | nonzero bool |
| | zero bool |
| | } |
| |
|
| | |
| | |
| | |
| | func runDumpChecks(t *testing.T, s state, dir string, flags []string, checks []dumpCheck) { |
| | dargs := []string{"-i", dir} |
| | dargs = append(dargs, flags...) |
| | lines := runToolOp(t, s, "debugdump", dargs) |
| | if len(lines) == 0 { |
| | t.Fatalf("dump run produced no output") |
| | } |
| |
|
| | bad := false |
| | for _, check := range checks { |
| | found := false |
| | for _, line := range lines { |
| | if m := check.re.FindStringSubmatch(line); m != nil { |
| | found = true |
| | if check.negate { |
| | t.Errorf("tag %q: unexpected match", check.tag) |
| | bad = true |
| |
|
| | } |
| | if check.nonzero || check.zero { |
| | if len(m) < 2 { |
| | t.Errorf("tag %s: submatch failed (short m)", check.tag) |
| | bad = true |
| | continue |
| | } |
| | if m[1] == "" { |
| | t.Errorf("tag %s: submatch failed", check.tag) |
| | bad = true |
| | continue |
| | } |
| | i, err := strconv.Atoi(m[1]) |
| | if err != nil { |
| | t.Errorf("tag %s: match Atoi failed on %s", |
| | check.tag, m[1]) |
| | continue |
| | } |
| | if check.zero && i != 0 { |
| | t.Errorf("tag %s: match zero failed on %s", |
| | check.tag, m[1]) |
| | } else if check.nonzero && i == 0 { |
| | t.Errorf("tag %s: match nonzero failed on %s", |
| | check.tag, m[1]) |
| | } |
| | } |
| | break |
| | } |
| | } |
| | if !found && !check.negate { |
| | t.Errorf("dump output regexp match failed for %s", check.tag) |
| | bad = true |
| | } |
| | } |
| | if bad { |
| | fmt.Printf("output from 'dump' run:\n") |
| | dumplines(lines) |
| | } |
| | } |
| |
|
| | func testMergeSimple(t *testing.T, s state, indir1, indir2, tag string) { |
| | outdir := filepath.Join(s.dir, "simpleMergeOut"+tag) |
| | if err := os.Mkdir(outdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", outdir, err) |
| | } |
| |
|
| | |
| | ins := fmt.Sprintf("-i=%s,%s", indir1, indir2) |
| | out := fmt.Sprintf("-o=%s", outdir) |
| | margs := []string{ins, out} |
| | lines := runToolOp(t, s, "merge", margs) |
| | if len(lines) != 0 { |
| | t.Errorf("merge run produced %d lines of unexpected output", len(lines)) |
| | dumplines(lines) |
| | } |
| |
|
| | |
| | |
| | |
| | podlist, err := pods.CollectPods([]string{outdir}, true) |
| | if err != nil { |
| | t.Fatal(err) |
| | } |
| | if len(podlist) != 1 { |
| | t.Fatalf("expected 1 pod, got %d pods", len(podlist)) |
| | } |
| | ncdfs := len(podlist[0].CounterDataFiles) |
| | if ncdfs != 1 { |
| | t.Fatalf("expected 1 counter data file, got %d", ncdfs) |
| | } |
| |
|
| | |
| | |
| | |
| | testpoints := []dumpCheck{ |
| | { |
| | tag: "first function", |
| | re: regexp.MustCompile(`^Func: first\s*$`), |
| | }, |
| | { |
| | tag: "second function", |
| | re: regexp.MustCompile(`^Func: second\s*$`), |
| | }, |
| | { |
| | tag: "third function", |
| | re: regexp.MustCompile(`^Func: third\s*$`), |
| | }, |
| | { |
| | tag: "third function unit 0", |
| | re: regexp.MustCompile(`^0: L23:C23 -- L24:C12 NS=1 = (\d+)$`), |
| | nonzero: true, |
| | }, |
| | { |
| | tag: "third function unit 1", |
| | re: regexp.MustCompile(`^1: L27:C2 -- L28:C10 NS=2 = (\d+)$`), |
| | nonzero: true, |
| | }, |
| | { |
| | tag: "third function unit 2", |
| | re: regexp.MustCompile(`^2: L24:C12 -- L26:C3 NS=1 = (\d+)$`), |
| | nonzero: true, |
| | }, |
| | } |
| | flags := []string{"-live", "-pkg=" + mainPkgPath} |
| | runDumpChecks(t, s, outdir, flags, testpoints) |
| | } |
| |
|
| | func testMergeSelect(t *testing.T, s state, indir1, indir2 string, tag string) { |
| | outdir := filepath.Join(s.dir, "selectMergeOut"+tag) |
| | if err := os.Mkdir(outdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", outdir, err) |
| | } |
| |
|
| | |
| | |
| | ins := fmt.Sprintf("-i=%s,%s", indir1, indir2) |
| | out := fmt.Sprintf("-o=%s", outdir) |
| | margs := []string{"-pkg=" + mainPkgPath + "/dep", ins, out} |
| | lines := runToolOp(t, s, "merge", margs) |
| | if len(lines) != 0 { |
| | t.Errorf("merge run produced %d lines of unexpected output", len(lines)) |
| | dumplines(lines) |
| | } |
| |
|
| | |
| | |
| | dargs := []string{"-i=" + outdir} |
| | lines = runToolOp(t, s, "debugdump", dargs) |
| | if len(lines) == 0 { |
| | t.Fatalf("dump run produced no output") |
| | } |
| | want := map[string]int{ |
| | "Package path: " + mainPkgPath + "/dep": 0, |
| | "Func: Dep1": 0, |
| | "Func: PDep": 0, |
| | } |
| | bad := false |
| | for _, line := range lines { |
| | if v, ok := want[line]; ok { |
| | if v != 0 { |
| | t.Errorf("duplicate line %s", line) |
| | bad = true |
| | break |
| | } |
| | want[line] = 1 |
| | continue |
| | } |
| | |
| | if strings.HasPrefix(line, "Func:") || strings.HasPrefix(line, "Package path:") { |
| | t.Errorf("unexpected line: %s", line) |
| | bad = true |
| | break |
| | } |
| | } |
| | if bad { |
| | dumplines(lines) |
| | } |
| | } |
| |
|
| | func testMergeCombinePrograms(t *testing.T, s state) { |
| |
|
| | |
| | |
| | runout := [2]string{} |
| | for k := 0; k < 2; k++ { |
| | runout[k] = filepath.Join(s.dir, fmt.Sprintf("newcovdata%d", k)) |
| | if err := os.Mkdir(runout[k], 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", runout[k], err) |
| | } |
| | args := []string{} |
| | if k != 0 { |
| | args = append(args, "foo", "bar") |
| | } |
| | cmd := testenv.Command(t, s.exepath2, args...) |
| | cmd.Env = append(cmd.Env, "GOCOVERDIR="+runout[k]) |
| | b, err := cmd.CombinedOutput() |
| | if len(b) != 0 { |
| | t.Logf("## instrumented run output:\n%s", b) |
| | } |
| | if err != nil { |
| | t.Fatalf("instrumented run error: %v", err) |
| | } |
| | } |
| |
|
| | |
| | moutdir := filepath.Join(s.dir, "mergeCombineOut") |
| | if err := os.Mkdir(moutdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", moutdir, err) |
| | } |
| |
|
| | |
| | |
| | ins := fmt.Sprintf("-i=%s,%s,%s,%s", s.outdirs[0], s.outdirs[1], |
| | runout[0], runout[1]) |
| | out := fmt.Sprintf("-o=%s", moutdir) |
| | margs := []string{"-pcombine", ins, out} |
| | lines := runToolOp(t, s, "merge", margs) |
| | if len(lines) != 0 { |
| | t.Errorf("merge run produced unexpected output: %v", lines) |
| | } |
| |
|
| | |
| | |
| | |
| | podlist, err := pods.CollectPods([]string{moutdir}, true) |
| | if err != nil { |
| | t.Fatal(err) |
| | } |
| | if len(podlist) != 1 { |
| | t.Fatalf("expected 1 pod, got %d pods", len(podlist)) |
| | } |
| | ncdfs := len(podlist[0].CounterDataFiles) |
| | if ncdfs != 1 { |
| | t.Fatalf("expected 1 counter data file, got %d", ncdfs) |
| | } |
| |
|
| | |
| | testpoints := []dumpCheck{ |
| | { |
| | tag: "first function", |
| | re: regexp.MustCompile(`^Func: first\s*$`), |
| | }, |
| | { |
| | tag: "sixth function", |
| | re: regexp.MustCompile(`^Func: sixth\s*$`), |
| | }, |
| | } |
| |
|
| | flags := []string{"-live", "-pkg=" + mainPkgPath} |
| | runDumpChecks(t, s, moutdir, flags, testpoints) |
| | } |
| |
|
| | func testSubtract(t *testing.T, s state) { |
| | |
| | soutdir := filepath.Join(s.dir, "subtractOut") |
| | if err := os.Mkdir(soutdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", soutdir, err) |
| | } |
| |
|
| | |
| | ins := fmt.Sprintf("-i=%s,%s", s.outdirs[0], s.outdirs[1]) |
| | out := fmt.Sprintf("-o=%s", soutdir) |
| | sargs := []string{ins, out} |
| | lines := runToolOp(t, s, "subtract", sargs) |
| | if len(lines) != 0 { |
| | t.Errorf("subtract run produced unexpected output: %+v", lines) |
| | } |
| |
|
| | |
| | dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + soutdir} |
| | lines = runToolOp(t, s, "debugdump", dargs) |
| | if len(lines) == 0 { |
| | t.Errorf("dump run produced no output") |
| | } |
| |
|
| | |
| | testpoints := []dumpCheck{ |
| | { |
| | tag: "first function", |
| | re: regexp.MustCompile(`^Func: first\s*$`), |
| | }, |
| | { |
| | tag: "dep function", |
| | re: regexp.MustCompile(`^Func: Dep1\s*$`), |
| | }, |
| | { |
| | tag: "third function", |
| | re: regexp.MustCompile(`^Func: third\s*$`), |
| | }, |
| | { |
| | tag: "third function unit 0", |
| | re: regexp.MustCompile(`^0: L23:C23 -- L24:C12 NS=1 = (\d+)$`), |
| | zero: true, |
| | }, |
| | { |
| | tag: "third function unit 1", |
| | re: regexp.MustCompile(`^1: L27:C2 -- L28:C10 NS=2 = (\d+)$`), |
| | nonzero: true, |
| | }, |
| | { |
| | tag: "third function unit 2", |
| | re: regexp.MustCompile(`^2: L24:C12 -- L26:C3 NS=1 = (\d+)$`), |
| | zero: true, |
| | }, |
| | } |
| | flags := []string{} |
| | runDumpChecks(t, s, soutdir, flags, testpoints) |
| | } |
| |
|
| | func testIntersect(t *testing.T, s state, indir1, indir2, tag string) { |
| | |
| | ioutdir := filepath.Join(s.dir, "intersectOut"+tag) |
| | if err := os.Mkdir(ioutdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", ioutdir, err) |
| | } |
| |
|
| | |
| | ins := fmt.Sprintf("-i=%s,%s", indir1, indir2) |
| | out := fmt.Sprintf("-o=%s", ioutdir) |
| | sargs := []string{ins, out} |
| | lines := runToolOp(t, s, "intersect", sargs) |
| | if len(lines) != 0 { |
| | t.Errorf("intersect run produced unexpected output: %+v", lines) |
| | } |
| |
|
| | |
| | dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + ioutdir} |
| | lines = runToolOp(t, s, "debugdump", dargs) |
| | if len(lines) == 0 { |
| | t.Errorf("dump run produced no output") |
| | } |
| |
|
| | |
| | testpoints := []dumpCheck{ |
| | { |
| | tag: "first function", |
| | re: regexp.MustCompile(`^Func: first\s*$`), |
| | negate: true, |
| | }, |
| | { |
| | tag: "third function", |
| | re: regexp.MustCompile(`^Func: third\s*$`), |
| | }, |
| | } |
| | flags := []string{"-live"} |
| | runDumpChecks(t, s, ioutdir, flags, testpoints) |
| | } |
| |
|
| | func testCounterClash(t *testing.T, s state) { |
| | |
| | ccoutdir := filepath.Join(s.dir, "ccOut") |
| | if err := os.Mkdir(ccoutdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", ccoutdir, err) |
| | } |
| |
|
| | |
| | |
| | |
| | ins := fmt.Sprintf("-i=%s,%s", s.outdirs[0], s.outdirs[3]) |
| | out := fmt.Sprintf("-o=%s", ccoutdir) |
| | args := append([]string{}, "merge", ins, out, "-pcombine") |
| | if debugtrace { |
| | t.Logf("cc merge command is %s %v\n", s.tool, args) |
| | } |
| | cmd := testenv.Command(t, s.tool, args...) |
| | b, err := cmd.CombinedOutput() |
| | t.Logf("%% output: %s\n", string(b)) |
| | if err != nil { |
| | t.Fatalf("clash merge failed: %v", err) |
| | } |
| |
|
| | |
| | |
| | out = "-o=" + filepath.Join(ccoutdir, "file.txt") |
| | args = append([]string{}, "textfmt", ins, out) |
| | if debugtrace { |
| | t.Logf("clash textfmt command is %s %v\n", s.tool, args) |
| | } |
| | cmd = testenv.Command(t, s.tool, args...) |
| | b, err = cmd.CombinedOutput() |
| | t.Logf("%% output: %s\n", string(b)) |
| | if err == nil { |
| | t.Fatalf("expected mode clash") |
| | } |
| | got := string(b) |
| | want := "counter mode clash while reading meta-data" |
| | if !strings.Contains(got, want) { |
| | t.Errorf("counter clash textfmt: wanted %s got %s", want, got) |
| | } |
| | } |
| |
|
| | func testEmpty(t *testing.T, s state) { |
| |
|
| | |
| | empty := filepath.Join(s.dir, "empty") |
| | if err := os.Mkdir(empty, 0777); err != nil { |
| | t.Fatalf("can't create dir %s: %v", empty, err) |
| | } |
| |
|
| | |
| | eoutdir := filepath.Join(s.dir, "emptyOut") |
| | if err := os.Mkdir(eoutdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", eoutdir, err) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | scenarios := []struct { |
| | tag string |
| | args []string |
| | }{ |
| | { |
| | tag: "merge", |
| | args: []string{"merge", "-o", eoutdir}, |
| | }, |
| | { |
| | tag: "textfmt", |
| | args: []string{"textfmt", "-o", filepath.Join(eoutdir, "foo.txt")}, |
| | }, |
| | { |
| | tag: "func", |
| | args: []string{"func"}, |
| | }, |
| | { |
| | tag: "pkglist", |
| | args: []string{"pkglist"}, |
| | }, |
| | { |
| | tag: "debugdump", |
| | args: []string{"debugdump"}, |
| | }, |
| | { |
| | tag: "percent", |
| | args: []string{"percent"}, |
| | }, |
| | } |
| |
|
| | for _, x := range scenarios { |
| | ins := fmt.Sprintf("-i=%s", empty) |
| | args := append([]string{}, x.args...) |
| | args = append(args, ins) |
| | if false { |
| | t.Logf("cmd is %s %v\n", s.tool, args) |
| | } |
| | cmd := testenv.Command(t, s.tool, args...) |
| | b, err := cmd.CombinedOutput() |
| | t.Logf("%% output: %s\n", string(b)) |
| | if err != nil { |
| | t.Fatalf("command %s %+v failed with %v", |
| | s.tool, x.args, err) |
| | } |
| | } |
| | } |
| |
|
| | func testCommandLineErrors(t *testing.T, s state, outdir string) { |
| |
|
| | |
| | eoutdir := filepath.Join(s.dir, "errorsOut") |
| | if err := os.Mkdir(eoutdir, 0777); err != nil { |
| | t.Fatalf("can't create outdir %s: %v", eoutdir, err) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | scenarios := []struct { |
| | tag string |
| | args []string |
| | exp string |
| | }{ |
| | { |
| | tag: "input missing", |
| | args: []string{"merge", "-o", eoutdir, "-i", "not there"}, |
| | exp: "error: reading inputs: ", |
| | }, |
| | { |
| | tag: "badv", |
| | args: []string{"textfmt", "-i", outdir, "-v=abc"}, |
| | }, |
| | } |
| |
|
| | for _, x := range scenarios { |
| | args := append([]string{}, x.args...) |
| | if false { |
| | t.Logf("cmd is %s %v\n", s.tool, args) |
| | } |
| | cmd := testenv.Command(t, s.tool, args...) |
| | b, err := cmd.CombinedOutput() |
| | if err == nil { |
| | t.Logf("%% output: %s\n", string(b)) |
| | t.Fatalf("command %s %+v unexpectedly succeeded", |
| | s.tool, x.args) |
| | } else { |
| | if !strings.Contains(string(b), x.exp) { |
| | t.Fatalf("command %s %+v:\ngot:\n%s\nwanted to see: %v\n", |
| | s.tool, x.args, string(b), x.exp) |
| | } |
| | } |
| | } |
| | } |
| |
|