diff options
Diffstat (limited to 'compiler_wrapper/clang_tidy_flag_test.go')
-rw-r--r-- | compiler_wrapper/clang_tidy_flag_test.go | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/compiler_wrapper/clang_tidy_flag_test.go b/compiler_wrapper/clang_tidy_flag_test.go index baf5219e..4293bb21 100644 --- a/compiler_wrapper/clang_tidy_flag_test.go +++ b/compiler_wrapper/clang_tidy_flag_test.go @@ -273,6 +273,176 @@ func TestPartiallyOmitGomaWithClangTidy(t *testing.T) { }) } +func TestTriciumClangTidyIsProperlyDetectedFromEnv(t *testing.T) { + withClangTidyTestContext(t, func(ctx *testContext) { + ctx.env = []string{"WITH_TIDY=tricium"} + ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error { + switch ctx.cmdCount { + case 1: + if err := verifyPath(cmd, "usr/bin/clang"); err != nil { + t.Error(err) + } + return nil + case 2: + if err := verifyPath(cmd, "usr/bin/clang-tidy"); err != nil { + return err + } + + hasFixesFile := false + for _, arg := range cmd.Args { + if path := strings.TrimPrefix(arg, "--export-fixes="); path != arg { + hasFixesFile = true + if !strings.HasPrefix(path, ctx.cfg.triciumNitsDir+"/") { + t.Errorf("fixes file was %q; expected it to be in %q", path, ctx.cfg.triciumNitsDir) + } + break + } + } + + if !hasFixesFile { + t.Error("no fixes file was provided to a tricium invocation") + } + + return nil + default: + return nil + } + } + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(clangX86_64, mainCc))) + if ctx.cmdCount != 3 { + t.Errorf("expected 3 calls. Got: %d", ctx.cmdCount) + } + if err := verifyPath(cmd, "usr/bin/clang"); err != nil { + t.Error(err) + } + }) +} + +func TestTriciumClangTidySkipsProtobufFiles(t *testing.T) { + withClangTidyTestContext(t, func(ctx *testContext) { + ctx.env = []string{"WITH_TIDY=tricium"} + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(clangX86_64, mainCc+".pb.cc"))) + if ctx.cmdCount != 1 { + t.Errorf("expected tricium clang-tidy to not execute on a protobuf file") + } + if err := verifyPath(cmd, "usr/bin/clang"); err != nil { + t.Error(err) + } + }) +} + +func testClangTidyFiltersClangTidySpecificFlagsWithPresetEnv(t *testing.T, ctx *testContext) { + addedFlag := "--some_clang_tidy=flag" + ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error { + switch ctx.cmdCount { + case 1: + if err := verifyPath(cmd, "usr/bin/clang"); err != nil { + t.Error(err) + } else if err := verifyArgCount(cmd, 0, addedFlag); err != nil { + t.Error(err) + } + return nil + case 2: + if err := verifyPath(cmd, "usr/bin/clang-tidy"); err != nil { + t.Error(err) + } else if verifyArgCount(cmd, 1, addedFlag); err != nil { + t.Error(err) + } + return nil + default: + return nil + } + } + cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc, "-clang-tidy-flag="+addedFlag))) + if ctx.cmdCount != 3 { + t.Errorf("expected 3 calls. Got: %d", ctx.cmdCount) + } + if err := verifyPath(cmd, "usr/bin/clang"); err != nil { + t.Error(err) + } +} + +func TestClangTidyFiltersClangTidySpecificFlagsForTricium(t *testing.T) { + withClangTidyTestContext(t, func(ctx *testContext) { + ctx.env = []string{"WITH_TIDY=tricium"} + testClangTidyFiltersClangTidySpecificFlagsWithPresetEnv(t, ctx) + }) +} + +func TestClangTidyFiltersClangTidySpecificFlags(t *testing.T) { + withClangTidyTestContext(t, func(ctx *testContext) { + testClangTidyFiltersClangTidySpecificFlagsWithPresetEnv(t, ctx) + }) +} + +func TestClangTidyFlagsAreFilteredFromGccInvocations(t *testing.T) { + withTestContext(t, func(ctx *testContext) { + cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc, "-clang-tidy-flag=--foo"))) + if err := verifyArgCount(cmd, 0, ".*--foo.*"); err != nil { + t.Error(err) + } + }) +} + +func TestTriciumReportsClangTidyCrashesGracefully(t *testing.T) { + withClangTidyTestContext(t, func(ctx *testContext) { + ctx.env = []string{"WITH_TIDY=tricium"} + ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error { + switch ctx.cmdCount { + case 1: + if err := verifyPath(cmd, "usr/bin/clang"); err != nil { + t.Error(err) + } + return nil + case 2: + if err := verifyPath(cmd, "usr/bin/clang-tidy"); err != nil { + return err + } + + if _, err := io.WriteString(stdout, clangTidyCrashSubstring); err != nil { + return err + } + return nil + case 3: + if err := verifyPath(cmd, "usr/bin/clang"); err != nil { + t.Error(err) + } + + args := cmd.Args + if len(args) < 3 { + t.Errorf("insufficient number of args provided; got %d; want at least 3", len(args)) + return nil + } + + lastArgs := args[len(args)-3:] + eArg, oArg, outFileArg := lastArgs[0], lastArgs[1], lastArgs[2] + if eArg != "-E" { + t.Errorf("got eArg=%q; wanted -E", eArg) + } + + if oArg != "-o" { + t.Errorf("got oArg=%q; wanted -o", oArg) + } + + wantPrefix := path.Join(ctx.cfg.crashArtifactsDir, "clang-tidy") + if !strings.HasPrefix(outFileArg, wantPrefix) { + t.Errorf("got out file %q; wanted one starting with %q", outFileArg, wantPrefix) + } + + return nil + default: + return nil + } + } + ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc))) + if ctx.cmdCount != 4 { + t.Errorf("expected 3 calls. Got: %d", ctx.cmdCount) + } + }) +} + func withClangTidyTestContext(t *testing.T, work func(ctx *testContext)) { withTestContext(t, func(ctx *testContext) { ctx.env = []string{"WITH_TIDY=1"} |