aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler_wrapper/bisect_flag.go30
-rw-r--r--compiler_wrapper/bisect_flag_test.go88
-rw-r--r--compiler_wrapper/compiler_wrapper.go16
-rw-r--r--compiler_wrapper/compiler_wrapper_test.go28
-rw-r--r--compiler_wrapper/oldwrapper.go14
-rw-r--r--compiler_wrapper/oldwrapper_test.go103
-rw-r--r--compiler_wrapper/rusage_flag_test.go2
7 files changed, 157 insertions, 124 deletions
diff --git a/compiler_wrapper/bisect_flag.go b/compiler_wrapper/bisect_flag.go
new file mode 100644
index 00000000..14d84cd4
--- /dev/null
+++ b/compiler_wrapper/bisect_flag.go
@@ -0,0 +1,30 @@
+package main
+
+import "path/filepath"
+
+const bisectPythonCommand = "import bisect_driver; sys.exit(bisect_driver.bisect_driver(sys.argv[1], sys.argv[2], sys.argv[3:]))"
+
+func getBisectStage(env env) string {
+ return env.getenv("BISECT_STAGE")
+}
+
+func calcBisectCommand(env env, bisectStage string, compilerCmd *command) *command {
+ bisectDir := env.getenv("BISECT_DIR")
+ if bisectDir == "" {
+ bisectDir = "/tmp/sysroot_bisect"
+ }
+ absCompilerPath := compilerCmd.path
+ if !filepath.IsAbs(absCompilerPath) {
+ absCompilerPath = filepath.Join(env.getwd(), absCompilerPath)
+ }
+ return &command{
+ path: "/usr/bin/python2",
+ args: append([]string{
+ "-c",
+ bisectPythonCommand,
+ bisectStage,
+ bisectDir,
+ absCompilerPath,
+ }, compilerCmd.args...),
+ }
+}
diff --git a/compiler_wrapper/bisect_flag_test.go b/compiler_wrapper/bisect_flag_test.go
new file mode 100644
index 00000000..2b099912
--- /dev/null
+++ b/compiler_wrapper/bisect_flag_test.go
@@ -0,0 +1,88 @@
+package main
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "testing"
+)
+
+func TestCallBisectDriver(t *testing.T) {
+ withBisectTestContext(t, func(ctx *testContext) {
+ ctx.env = []string{
+ "BISECT_STAGE=someBisectStage",
+ "BISECT_DIR=someBisectDir",
+ }
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
+ if err := verifyPath(cmd, "/usr/bin/python2"); err != nil {
+ t.Error(err)
+ }
+ if err := verifyArgOrder(cmd, "-c", regexp.QuoteMeta(bisectPythonCommand),
+ "someBisectStage", "someBisectDir", filepath.Join(ctx.tempDir, gccX86_64+".real"), "--sysroot=.*", mainCc); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+func TestDefaultBisectDir(t *testing.T) {
+ withBisectTestContext(t, func(ctx *testContext) {
+ ctx.env = []string{
+ "BISECT_STAGE=someBisectStage",
+ }
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
+ if err := verifyArgOrder(cmd, "-c", regexp.QuoteMeta(bisectPythonCommand),
+ "someBisectStage", "/tmp/sysroot_bisect"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+func TestForwardStdOutAndStdErrAndExitCodeFromBisect(t *testing.T) {
+ withBisectTestContext(t, func(ctx *testContext) {
+ ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
+ fmt.Fprint(stdout, "somemessage")
+ fmt.Fprint(stderr, "someerror")
+ return newExitCodeError(23)
+ }
+ exitCode := callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc))
+ if exitCode != 23 {
+ t.Errorf("unexpected exit code. Got: %d", exitCode)
+ }
+ if ctx.stdoutString() != "somemessage" {
+ t.Errorf("stdout was not forwarded. Got: %s", ctx.stdoutString())
+ }
+ if ctx.stderrString() != "someerror" {
+ t.Errorf("stderr was not forwarded. Got: %s", ctx.stderrString())
+ }
+ })
+}
+
+func TestForwardGeneralErrorFromBisect(t *testing.T) {
+ withBisectTestContext(t, func(ctx *testContext) {
+ ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
+ return errors.New("someerror")
+ }
+ stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg,
+ ctx.newCommand(gccX86_64, mainCc)))
+ if err := verifyInternalError(stderr); err != nil {
+ t.Fatal(err)
+ }
+ if !strings.Contains(stderr, "someerror") {
+ t.Errorf("unexpected error. Got: %s", stderr)
+ }
+ })
+}
+
+func withBisectTestContext(t *testing.T, work func(ctx *testContext)) {
+ withTestContext(t, func(ctx *testContext) {
+ // Disable comparing to the old wrapper as that calls the bisect_driver
+ // directly from python, and the new wrapper calls it via a separate
+ // sub command.
+ ctx.cfg.oldWrapperPath = ""
+ ctx.env = []string{"BISECT_STAGE=xyz"}
+ work(ctx)
+ })
+}
diff --git a/compiler_wrapper/compiler_wrapper.go b/compiler_wrapper/compiler_wrapper.go
index 8c5825e8..b0269abe 100644
--- a/compiler_wrapper/compiler_wrapper.go
+++ b/compiler_wrapper/compiler_wrapper.go
@@ -9,11 +9,7 @@ import (
func callCompiler(env env, cfg *config, inputCmd *command) int {
exitCode := 0
var compilerErr error
- if shouldForwardToOldWrapper(env, inputCmd) {
- // TODO: Once this is only checking for bisect, create a command
- // that directly calls the bisect driver in calcCompilerCommand.
- exitCode, compilerErr = forwardToOldWrapper(env, cfg, inputCmd)
- } else if cfg.oldWrapperPath != "" {
+ if cfg.oldWrapperPath != "" {
exitCode, compilerErr = callCompilerWithRunAndCompareToOldWrapper(env, cfg, inputCmd)
} else {
exitCode, compilerErr = callCompilerInternal(env, cfg, inputCmd)
@@ -75,15 +71,25 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
compilerCmd = calcGccCommand(mainBuilder)
}
rusageLogfileName := getRusageLogFilename(env)
+ bisectStage := getBisectStage(env)
if shouldForceDisableWError(env) {
if rusageLogfileName != "" {
return 0, newUserErrorf("GETRUSAGE is meaningless with FORCE_DISABLE_WERROR")
}
+ if bisectStage != "" {
+ return 0, newUserErrorf("BISECT_STAGE is meaningless with FORCE_DISABLE_WERROR")
+ }
return doubleBuildWithWNoError(env, cfg, compilerCmd)
}
if rusageLogfileName != "" {
+ if bisectStage != "" {
+ return 0, newUserErrorf("BISECT_STAGE is meaningless with GETRUSAGE")
+ }
return logRusage(env, rusageLogfileName, compilerCmd)
}
+ if bisectStage != "" {
+ compilerCmd = calcBisectCommand(env, bisectStage, compilerCmd)
+ }
// Note: We return an exit code only if the underlying env is not
// really doing an exec, e.g. commandRecordingEnv.
return wrapSubprocessErrorWithSourceLoc(compilerCmd, env.exec(compilerCmd))
diff --git a/compiler_wrapper/compiler_wrapper_test.go b/compiler_wrapper/compiler_wrapper_test.go
index 0a041fe8..5e347ec1 100644
--- a/compiler_wrapper/compiler_wrapper_test.go
+++ b/compiler_wrapper/compiler_wrapper_test.go
@@ -128,7 +128,7 @@ func TestErrorOnLogRusageAndForceDisableWError(t *testing.T) {
withTestContext(t, func(ctx *testContext) {
ctx.env = []string{
"FORCE_DISABLE_WERROR=1",
- "GETRUSAGE=" + filepath.Join(ctx.tempDir, "rusage.log"),
+ "GETRUSAGE=rusage.log",
}
stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
if err := verifyNonInternalError(stderr, "GETRUSAGE is meaningless with FORCE_DISABLE_WERROR"); err != nil {
@@ -137,6 +137,32 @@ func TestErrorOnLogRusageAndForceDisableWError(t *testing.T) {
})
}
+func TestErrorOnLogRusageAndBisect(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ ctx.env = []string{
+ "BISECT_STAGE=xyz",
+ "GETRUSAGE=rusage.log",
+ }
+ stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
+ if err := verifyNonInternalError(stderr, "BISECT_STAGE is meaningless with GETRUSAGE"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+func TestErrorOnBisectAndForceDisableWError(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ ctx.env = []string{
+ "BISECT_STAGE=xyz",
+ "FORCE_DISABLE_WERROR=1",
+ }
+ stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
+ if err := verifyNonInternalError(stderr, "BISECT_STAGE is meaningless with FORCE_DISABLE_WERROR"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
func TestPrintUserCompilerError(t *testing.T) {
buffer := bytes.Buffer{}
printCompilerError(&buffer, newUserErrorf("abcd"))
diff --git a/compiler_wrapper/oldwrapper.go b/compiler_wrapper/oldwrapper.go
index 1b510f6c..e4ec0b81 100644
--- a/compiler_wrapper/oldwrapper.go
+++ b/compiler_wrapper/oldwrapper.go
@@ -17,20 +17,6 @@ import (
const forwardToOldWrapperFilePattern = "old_wrapper_forward"
const compareToOldWrapperFilePattern = "old_wrapper_compare"
-// Whether the command should be executed by the old wrapper as we don't
-// support it yet.
-func shouldForwardToOldWrapper(env env, inputCmd *command) bool {
- return env.getenv("BISECT_STAGE") != ""
-}
-
-func forwardToOldWrapper(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
- oldWrapperCfg, err := newOldWrapperConfig(env, cfg, inputCmd)
- if err != nil {
- return 0, err
- }
- return callOldWrapper(env, oldWrapperCfg, inputCmd, forwardToOldWrapperFilePattern, env.stdout(), env.stderr())
-}
-
func compareToOldWrapper(env env, cfg *config, inputCmd *command, newCmdResults []*commandResult, newExitCode int) error {
oldWrapperCfg, err := newOldWrapperConfig(env, cfg, inputCmd)
if err != nil {
diff --git a/compiler_wrapper/oldwrapper_test.go b/compiler_wrapper/oldwrapper_test.go
index 5c4b20c3..d981d0a9 100644
--- a/compiler_wrapper/oldwrapper_test.go
+++ b/compiler_wrapper/oldwrapper_test.go
@@ -2,8 +2,6 @@ package main
import (
"bytes"
- "errors"
- "fmt"
"io"
"path/filepath"
"strings"
@@ -11,107 +9,6 @@ import (
"text/template"
)
-func TestNoForwardToOldWrapperBecauseOfEnv(t *testing.T) {
- withTestContext(t, func(ctx *testContext) {
- testEnvs := []string{"PATH=abc"}
- for _, testEnv := range testEnvs {
- ctx.env = []string{testEnv}
- forwarded := false
- ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
- if isForwardToOldWrapperCmd(cmd) {
- forwarded = true
- }
- return nil
- }
- ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64)))
- if forwarded {
- t.Errorf("forwarded to old wrapper for env %s", testEnv)
- }
- }
- })
-}
-
-func TestForwardToOldWrapperBecauseOfEnv(t *testing.T) {
- withForwardToOldWrapperTestContext(t, func(ctx *testContext) {
- testEnvs := []string{
- "BISECT_STAGE=abc",
- }
- for _, testEnv := range testEnvs {
- ctx.env = []string{testEnv}
- forwarded := false
- ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
- forwarded = true
- if !isForwardToOldWrapperCmd(cmd) {
- return newErrorwithSourceLocf("expected call to old wrapper. Got: %s", cmd.path)
- }
- return nil
- }
- ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64)))
- if !forwarded {
- t.Errorf("not forwarded to old wrapper for env %s", testEnv)
- }
- }
- })
-}
-
-func TestForwardStdOutAndStderrFromOldWrapperOnSuccess(t *testing.T) {
- withForwardToOldWrapperTestContext(t, func(ctx *testContext) {
- ctx.env = []string{"BISECT_STAGE=abc"}
- ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
- fmt.Fprint(stdout, "somemessage")
- fmt.Fprint(stderr, "someerror")
- return nil
- }
-
- ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64)))
- if ctx.stdoutString() != "somemessage" {
- t.Errorf("stdout was not exactly forwarded. Got: %s", ctx.stdoutString())
- }
- if ctx.stderrString() != "someerror" {
- t.Errorf("stderr was not exactly forwarded. Got: %s", ctx.stderrString())
- }
- })
-}
-
-func TestReportExitCodeErrorsWhenForwardingToOldWrapper(t *testing.T) {
- withForwardToOldWrapperTestContext(t, func(ctx *testContext) {
- ctx.env = []string{"BISECT_STAGE=abc"}
- ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
- fmt.Fprint(stderr, "someerror")
- return newExitCodeError(2)
- }
-
- exitCode := callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64))
- if exitCode != 2 {
- t.Fatalf("Expected exit code 2. Got %d", exitCode)
- }
- if err := verifyNonInternalError(ctx.stderrString(), "someerror"); err != nil {
- t.Fatal(err)
- }
- })
-}
-
-func TestReportGeneralErrorsWhenForwardingToOldWrapper(t *testing.T) {
- withForwardToOldWrapperTestContext(t, func(ctx *testContext) {
- ctx.env = []string{"BISECT_STAGE=abc"}
- ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
- fmt.Fprint(stderr, "someoldwrappererror")
- return errors.New("someerror")
- }
-
- stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64)))
- if err := verifyInternalError(stderr); err != nil {
- t.Fatal(err)
- }
- if !strings.Contains(stderr, "someerror") {
- t.Errorf("error message was not forwarded. Got: %s", stderr)
- }
- if !strings.Contains(stderr, "someoldwrappererror") {
- t.Errorf("stderr was not forwarded. Got: %s", stderr)
- }
- })
-}
-
func TestCompareToOldWrapperCompilerCommand(t *testing.T) {
withTestContext(t, func(ctx *testContext) {
ctx.cfg.mockOldWrapperCmds = false
diff --git a/compiler_wrapper/rusage_flag_test.go b/compiler_wrapper/rusage_flag_test.go
index 4fb3133f..9e877458 100644
--- a/compiler_wrapper/rusage_flag_test.go
+++ b/compiler_wrapper/rusage_flag_test.go
@@ -143,7 +143,7 @@ func TestLogRusageAppendsToFile(t *testing.T) {
func withLogRusageTestContext(t *testing.T, work func(ctx *testContext)) {
withTestContext(t, func(ctx *testContext) {
- // Disable comparing to the old wrapper as we that uses fork + wait3
+ // Disable comparing to the old wrapper as that uses fork + wait3
// to calculate resource usage, and the new wrapper uses the getrusage
// syscall.
ctx.cfg.oldWrapperPath = ""