diff options
Diffstat (limited to 'compiler_wrapper/remote_build_flag_test.go')
-rw-r--r-- | compiler_wrapper/remote_build_flag_test.go | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/compiler_wrapper/remote_build_flag_test.go b/compiler_wrapper/remote_build_flag_test.go new file mode 100644 index 00000000..4a894179 --- /dev/null +++ b/compiler_wrapper/remote_build_flag_test.go @@ -0,0 +1,251 @@ +// Copyright 2019 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package main + +import ( + "os" + "path" + "reflect" + "testing" +) + +func TestCommandlineFlagParsing(t *testing.T) { + withTestContext(t, func(ctx *testContext) { + type testCase struct { + extraFlags []string + // If this is nonempty, expectedValue is ignored. Otherwise, expectedValue + // has the expected value for the flag, and expectedCommand has the expected + // (extra) flags in the builder after filtering. + expectedError string + expectedValue string + expectedExtraFlags []string + } + + const flagName = "--flag" + testCases := []testCase{ + { + extraFlags: nil, + expectedError: errNoSuchCmdlineArg.Error(), + }, + { + extraFlags: []string{flagName + "a"}, + expectedError: errNoSuchCmdlineArg.Error(), + }, + { + extraFlags: []string{flagName}, + expectedError: "flag \"" + flagName + "\" requires a value", + }, + { + extraFlags: []string{flagName, "foo"}, + expectedValue: "foo", + expectedExtraFlags: nil, + }, + { + extraFlags: []string{flagName + "=foo"}, + expectedValue: "foo", + expectedExtraFlags: nil, + }, + { + extraFlags: []string{flagName + "="}, + expectedValue: "", + expectedExtraFlags: nil, + }, + { + extraFlags: []string{flagName + "=foo", flagName + "=bar"}, + expectedValue: "foo", + expectedExtraFlags: []string{flagName + "=bar"}, + }, + } + + for _, testCase := range testCases { + cmd := ctx.newCommand(gccX86_64, testCase.extraFlags...) + builder, err := newCommandBuilder(ctx, ctx.cfg, cmd) + if err != nil { + t.Fatalf("Failed creating a command builder: %v", err) + } + + flagValue, err := removeOneUserCmdlineFlagWithValue(builder, flagName) + if err != nil { + if testCase.expectedError == "" { + t.Errorf("given extra flags %q, got unexpected error removing %q: %v", testCase.extraFlags, flagName, err) + continue + } + + if e := err.Error(); e != testCase.expectedError { + t.Errorf("given extra flags %q, got error %q; wanted %q", testCase.extraFlags, e, testCase.expectedError) + } + continue + } + + if testCase.expectedError != "" { + t.Errorf("given extra flags %q, got no error, but expected %q", testCase.extraFlags, testCase.expectedError) + continue + } + + if flagValue != testCase.expectedValue { + t.Errorf("given extra flags %q, got value %q, but expected %q", testCase.extraFlags, flagValue, testCase.expectedValue) + } + + currentFlags := []string{} + // Chop off the first arg, which should just be the compiler + for _, a := range builder.args { + currentFlags = append(currentFlags, a.value) + } + + sameFlags := (len(currentFlags) == 0 && len(testCase.expectedExtraFlags) == 0) || reflect.DeepEqual(currentFlags, testCase.expectedExtraFlags) + if !sameFlags { + t.Errorf("given extra flags %q, got post-removal flags %q, but expected %q", testCase.extraFlags, currentFlags, testCase.expectedExtraFlags) + } + } + }) +} + +func TestCallGomaccIfEnvIsGivenAndValid(t *testing.T) { + withGomaccTestContext(t, func(ctx *testContext, gomaPath string) { + ctx.env = []string{"GOMACC_PATH=" + gomaPath} + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc))) + if err := verifyPath(cmd, gomaPath); err != nil { + t.Error(err) + } + if err := verifyArgOrder(cmd, gccX86_64+".real", mainCc); err != nil { + t.Error(err) + } + }) +} + +func TestOmitGomaccIfEnvIsGivenButInvalid(t *testing.T) { + withGomaccTestContext(t, func(ctx *testContext, gomaPath string) { + if err := os.Remove(gomaPath); err != nil { + t.Fatalf("failed removing fake goma file at %q: %v", gomaPath, err) + } + + ctx.env = []string{"GOMACC_PATH=" + gomaPath} + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc))) + if err := verifyPath(cmd, gccX86_64+".real"); err != nil { + t.Error(err) + } + }) +} + +func TestCallGomaccIfArgIsGivenAndValid(t *testing.T) { + withGomaccTestContext(t, func(ctx *testContext, gomaPath string) { + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc, "--gomacc-path", gomaPath))) + if err := verifyPath(cmd, gomaPath); err != nil { + t.Error(err) + } + if err := verifyArgCount(cmd, 0, "--gomacc-path"); err != nil { + t.Error(err) + } + if err := verifyArgCount(cmd, 0, gomaPath); err != nil { + t.Error(err) + } + if err := verifyArgOrder(cmd, gccX86_64+".real", mainCc); err != nil { + t.Error(err) + } + }) +} + +func TestOmitGomaccIfArgIsGivenButInvalid(t *testing.T) { + withGomaccTestContext(t, func(ctx *testContext, gomaPath string) { + if err := os.Remove(gomaPath); err != nil { + t.Fatalf("failed removing fake goma file at %q: %v", gomaPath, err) + } + + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc, "--gomacc-path", gomaPath))) + if err := verifyPath(cmd, gccX86_64+".real"); err != nil { + t.Error(err) + } + }) +} + +func TestErrorOnGomaccArgWithoutValue(t *testing.T) { + withTestContext(t, func(ctx *testContext) { + stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc, "--gomacc-path"))) + if err := verifyNonInternalError(stderr, "flag \"--gomacc-path\" requires a value"); err != nil { + t.Error(err) + } + }) +} + +func TestOmitGomaccByDefault(t *testing.T) { + withTestContext(t, func(ctx *testContext) { + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc))) + if err := verifyPath(cmd, gccX86_64+".real"); err != nil { + t.Error(err) + } + }) +} + +func withGomaccTestContext(t *testing.T, f func(*testContext, string)) { + withTestContext(t, func(ctx *testContext) { + gomaPath := path.Join(ctx.tempDir, "gomacc") + // Create a file so the gomacc path is valid. + ctx.writeFile(gomaPath, "") + f(ctx, gomaPath) + }) +} + +func TestRewrapperDefersToTheWrapperProperly(t *testing.T) { + withTestContext(t, func(ctx *testContext) { + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc, "--rewrapper-path", "/rewrapper", "--rewrapper-cfg", "/some-cfg", "some", "other", "args"))) + if err := verifyPath(cmd, "/rewrapper"); err != nil { + t.Error(err) + } + if err := verifyArgOrder(cmd, "-cfg", "/some-cfg", gccX86_64+".real", mainCc, "some", "other", "args"); err != nil { + t.Error(err) + } + }) +} + +func TestRewrapperCfgMustBePrsentIfRewrapperPathIs(t *testing.T) { + withGomaccTestContext(t, func(ctx *testContext, gomaPath string) { + stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc, "--rewrapper-path", "/rewrapper"))) + if err := verifyNonInternalError(stderr, "--rewrapper-cfg must be specified if --rewrapper-path is"); err != nil { + t.Error(err) + } + }) +} + +func TestRewrapperPathMustBePrsentIfRewrapperCfgIs(t *testing.T) { + withGomaccTestContext(t, func(ctx *testContext, gomaPath string) { + stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc, "--rewrapper-cfg", "/some-cfg"))) + if err := verifyNonInternalError(stderr, "--rewrapper-path must be specified if --rewrapper-cfg is"); err != nil { + t.Error(err) + } + }) +} + +func TestRewrapperAndGomaAreMutuallyExclusive(t *testing.T) { + withGomaccTestContext(t, func(ctx *testContext, gomaPath string) { + stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc, "--rewrapper-path", "/rewrapper", "--rewrapper-cfg", "/some-cfg", "--gomacc-path", gomaPath))) + if err := verifyNonInternalError(stderr, "rewrapper and gomacc are mutually exclusive"); err != nil { + t.Error(err) + } + }) +} + +func TestRewrapperBlocksGomaInheritanceFromEnv(t *testing.T) { + withGomaccTestContext(t, func(ctx *testContext, gomaPath string) { + ctx.env = []string{"GOMACC_PATH=" + gomaPath} + cmd := ctx.must(callCompiler(ctx, ctx.cfg, + ctx.newCommand(gccX86_64, mainCc, "--rewrapper-path", "/rewrapper", "--rewrapper-cfg", "/some-cfg"))) + if err := verifyPath(cmd, "/rewrapper"); err != nil { + t.Error(err) + } + if err := verifyArgOrder(cmd, "-cfg", "/some-cfg", gccX86_64+".real", mainCc); err != nil { + t.Error(err) + } + }) +} |