aboutsummaryrefslogtreecommitdiffstats
path: root/android/rule_builder_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'android/rule_builder_test.go')
-rw-r--r--android/rule_builder_test.go239
1 files changed, 167 insertions, 72 deletions
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index 7bad0258..d122a429 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -22,6 +22,10 @@ import (
"reflect"
"strings"
"testing"
+
+ "github.com/google/blueprint"
+
+ "android/soong/shared"
)
func pathContext() PathContext {
@@ -234,8 +238,6 @@ func ExampleRuleBuilderCommand_FlagWithList() {
}
func TestRuleBuilder(t *testing.T) {
- rule := NewRuleBuilder()
-
fs := map[string][]byte{
"dep_fixer": nil,
"input": nil,
@@ -249,73 +251,114 @@ func TestRuleBuilder(t *testing.T) {
ctx := PathContextForTesting(TestConfig("out", nil), fs)
- cmd := rule.Command().
- DepFile(PathForOutput(ctx, "DepFile")).
- Flag("Flag").
- FlagWithArg("FlagWithArg=", "arg").
- FlagWithDepFile("FlagWithDepFile=", PathForOutput(ctx, "depfile")).
- FlagWithInput("FlagWithInput=", PathForSource(ctx, "input")).
- FlagWithOutput("FlagWithOutput=", PathForOutput(ctx, "output")).
- Implicit(PathForSource(ctx, "Implicit")).
- ImplicitDepFile(PathForOutput(ctx, "ImplicitDepFile")).
- ImplicitOutput(PathForOutput(ctx, "ImplicitOutput")).
- Input(PathForSource(ctx, "Input")).
- Output(PathForOutput(ctx, "Output")).
- Text("Text").
- Tool(PathForSource(ctx, "Tool"))
-
- rule.Command().
- Text("command2").
- DepFile(PathForOutput(ctx, "depfile2")).
- Input(PathForSource(ctx, "input2")).
- Output(PathForOutput(ctx, "output2")).
- Tool(PathForSource(ctx, "tool2"))
-
- // Test updates to the first command after the second command has been started
- cmd.Text("after command2")
- // Test updating a command when the previous update did not replace the cmd variable
- cmd.Text("old cmd")
-
- // Test a command that uses the output of a previous command as an input
- rule.Command().
- Text("command3").
- Input(PathForSource(ctx, "input3")).
- Input(PathForOutput(ctx, "output2")).
- Output(PathForOutput(ctx, "output3"))
-
- wantCommands := []string{
- "out/DepFile Flag FlagWithArg=arg FlagWithDepFile=out/depfile FlagWithInput=input FlagWithOutput=out/output Input out/Output Text Tool after command2 old cmd",
- "command2 out/depfile2 input2 out/output2 tool2",
- "command3 input3 out/output2 out/output3",
+ addCommands := func(rule *RuleBuilder) {
+ cmd := rule.Command().
+ DepFile(PathForOutput(ctx, "DepFile")).
+ Flag("Flag").
+ FlagWithArg("FlagWithArg=", "arg").
+ FlagWithDepFile("FlagWithDepFile=", PathForOutput(ctx, "depfile")).
+ FlagWithInput("FlagWithInput=", PathForSource(ctx, "input")).
+ FlagWithOutput("FlagWithOutput=", PathForOutput(ctx, "output")).
+ Implicit(PathForSource(ctx, "Implicit")).
+ ImplicitDepFile(PathForOutput(ctx, "ImplicitDepFile")).
+ ImplicitOutput(PathForOutput(ctx, "ImplicitOutput")).
+ Input(PathForSource(ctx, "Input")).
+ Output(PathForOutput(ctx, "Output")).
+ Text("Text").
+ Tool(PathForSource(ctx, "Tool"))
+
+ rule.Command().
+ Text("command2").
+ DepFile(PathForOutput(ctx, "depfile2")).
+ Input(PathForSource(ctx, "input2")).
+ Output(PathForOutput(ctx, "output2")).
+ Tool(PathForSource(ctx, "tool2"))
+
+ // Test updates to the first command after the second command has been started
+ cmd.Text("after command2")
+ // Test updating a command when the previous update did not replace the cmd variable
+ cmd.Text("old cmd")
+
+ // Test a command that uses the output of a previous command as an input
+ rule.Command().
+ Text("command3").
+ Input(PathForSource(ctx, "input3")).
+ Input(PathForOutput(ctx, "output2")).
+ Output(PathForOutput(ctx, "output3"))
}
- wantDepMergerCommand := "out/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer out/DepFile out/depfile out/ImplicitDepFile out/depfile2"
-
wantInputs := PathsForSource(ctx, []string{"Implicit", "Input", "input", "input2", "input3"})
wantOutputs := PathsForOutput(ctx, []string{"ImplicitOutput", "Output", "output", "output2", "output3"})
wantDepFiles := PathsForOutput(ctx, []string{"DepFile", "depfile", "ImplicitDepFile", "depfile2"})
wantTools := PathsForSource(ctx, []string{"Tool", "tool2"})
- if g, w := rule.Commands(), wantCommands; !reflect.DeepEqual(g, w) {
- t.Errorf("\nwant rule.Commands() = %#v\n got %#v", w, g)
- }
+ t.Run("normal", func(t *testing.T) {
+ rule := NewRuleBuilder()
+ addCommands(rule)
- if g, w := rule.depFileMergerCmd(ctx, rule.DepFiles()).String(), wantDepMergerCommand; g != w {
- t.Errorf("\nwant rule.depFileMergerCmd() = %#v\n got %#v", w, g)
- }
+ wantCommands := []string{
+ "out/DepFile Flag FlagWithArg=arg FlagWithDepFile=out/depfile FlagWithInput=input FlagWithOutput=out/output Input out/Output Text Tool after command2 old cmd",
+ "command2 out/depfile2 input2 out/output2 tool2",
+ "command3 input3 out/output2 out/output3",
+ }
- if g, w := rule.Inputs(), wantInputs; !reflect.DeepEqual(w, g) {
- t.Errorf("\nwant rule.Inputs() = %#v\n got %#v", w, g)
- }
- if g, w := rule.Outputs(), wantOutputs; !reflect.DeepEqual(w, g) {
- t.Errorf("\nwant rule.Outputs() = %#v\n got %#v", w, g)
- }
- if g, w := rule.DepFiles(), wantDepFiles; !reflect.DeepEqual(w, g) {
- t.Errorf("\nwant rule.DepFiles() = %#v\n got %#v", w, g)
- }
- if g, w := rule.Tools(), wantTools; !reflect.DeepEqual(w, g) {
- t.Errorf("\nwant rule.Tools() = %#v\n got %#v", w, g)
- }
+ wantDepMergerCommand := "out/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer out/DepFile out/depfile out/ImplicitDepFile out/depfile2"
+
+ if g, w := rule.Commands(), wantCommands; !reflect.DeepEqual(g, w) {
+ t.Errorf("\nwant rule.Commands() = %#v\n got %#v", w, g)
+ }
+
+ if g, w := rule.Inputs(), wantInputs; !reflect.DeepEqual(w, g) {
+ t.Errorf("\nwant rule.Inputs() = %#v\n got %#v", w, g)
+ }
+ if g, w := rule.Outputs(), wantOutputs; !reflect.DeepEqual(w, g) {
+ t.Errorf("\nwant rule.Outputs() = %#v\n got %#v", w, g)
+ }
+ if g, w := rule.DepFiles(), wantDepFiles; !reflect.DeepEqual(w, g) {
+ t.Errorf("\nwant rule.DepFiles() = %#v\n got %#v", w, g)
+ }
+ if g, w := rule.Tools(), wantTools; !reflect.DeepEqual(w, g) {
+ t.Errorf("\nwant rule.Tools() = %#v\n got %#v", w, g)
+ }
+
+ if g, w := rule.depFileMergerCmd(ctx, rule.DepFiles()).String(), wantDepMergerCommand; g != w {
+ t.Errorf("\nwant rule.depFileMergerCmd() = %#v\n got %#v", w, g)
+ }
+ })
+
+ t.Run("sbox", func(t *testing.T) {
+ rule := NewRuleBuilder().Sbox(PathForOutput(ctx))
+ addCommands(rule)
+
+ wantCommands := []string{
+ "__SBOX_OUT_DIR__/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_OUT_DIR__/depfile FlagWithInput=input FlagWithOutput=__SBOX_OUT_DIR__/output Input __SBOX_OUT_DIR__/Output Text Tool after command2 old cmd",
+ "command2 __SBOX_OUT_DIR__/depfile2 input2 __SBOX_OUT_DIR__/output2 tool2",
+ "command3 input3 __SBOX_OUT_DIR__/output2 __SBOX_OUT_DIR__/output3",
+ }
+
+ wantDepMergerCommand := "out/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer __SBOX_OUT_DIR__/DepFile __SBOX_OUT_DIR__/depfile __SBOX_OUT_DIR__/ImplicitDepFile __SBOX_OUT_DIR__/depfile2"
+
+ if g, w := rule.Commands(), wantCommands; !reflect.DeepEqual(g, w) {
+ t.Errorf("\nwant rule.Commands() = %#v\n got %#v", w, g)
+ }
+
+ if g, w := rule.Inputs(), wantInputs; !reflect.DeepEqual(w, g) {
+ t.Errorf("\nwant rule.Inputs() = %#v\n got %#v", w, g)
+ }
+ if g, w := rule.Outputs(), wantOutputs; !reflect.DeepEqual(w, g) {
+ t.Errorf("\nwant rule.Outputs() = %#v\n got %#v", w, g)
+ }
+ if g, w := rule.DepFiles(), wantDepFiles; !reflect.DeepEqual(w, g) {
+ t.Errorf("\nwant rule.DepFiles() = %#v\n got %#v", w, g)
+ }
+ if g, w := rule.Tools(), wantTools; !reflect.DeepEqual(w, g) {
+ t.Errorf("\nwant rule.Tools() = %#v\n got %#v", w, g)
+ }
+
+ if g, w := rule.depFileMergerCmd(ctx, rule.DepFiles()).String(), wantDepMergerCommand; g != w {
+ t.Errorf("\nwant rule.depFileMergerCmd() = %#v\n got %#v", w, g)
+ }
+ })
}
func testRuleBuilderFactory() Module {
@@ -329,14 +372,19 @@ type testRuleBuilderModule struct {
ModuleBase
properties struct {
Src string
+
+ Restat bool
+ Sbox bool
}
}
func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
in := PathForSource(ctx, t.properties.Src)
out := PathForModuleOut(ctx, ctx.ModuleName())
+ outDep := PathForModuleOut(ctx, ctx.ModuleName()+".d")
+ outDir := PathForModuleOut(ctx)
- testRuleBuilder_Build(ctx, in, out)
+ testRuleBuilder_Build(ctx, in, out, outDep, outDir, t.properties.Restat, t.properties.Sbox)
}
type testRuleBuilderSingleton struct{}
@@ -348,15 +396,23 @@ func testRuleBuilderSingletonFactory() Singleton {
func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) {
in := PathForSource(ctx, "bar")
out := PathForOutput(ctx, "baz")
- testRuleBuilder_Build(ctx, in, out)
+ outDep := PathForOutput(ctx, "baz.d")
+ outDir := PathForOutput(ctx)
+ testRuleBuilder_Build(ctx, in, out, outDep, outDir, true, false)
}
-func testRuleBuilder_Build(ctx BuilderContext, in Path, out WritablePath) {
+func testRuleBuilder_Build(ctx BuilderContext, in Path, out, outDep, outDir WritablePath, restat, sbox bool) {
rule := NewRuleBuilder()
- rule.Command().Tool(PathForSource(ctx, "cp")).Input(in).Output(out)
+ if sbox {
+ rule.Sbox(outDir)
+ }
+
+ rule.Command().Tool(PathForSource(ctx, "cp")).Input(in).Output(out).ImplicitDepFile(outDep)
- rule.Restat()
+ if restat {
+ rule.Restat()
+ }
rule.Build(pctx, ctx, "rule", "desc")
}
@@ -372,6 +428,12 @@ func TestRuleBuilder_Build(t *testing.T) {
rule_builder_test {
name: "foo",
src: "bar",
+ restat: true,
+ }
+ rule_builder_test {
+ name: "foo_sbox",
+ src: "bar",
+ sbox: true,
}
`
@@ -391,9 +453,19 @@ func TestRuleBuilder_Build(t *testing.T) {
_, errs = ctx.PrepareBuildActions(config)
FailIfErrored(t, errs)
- check := func(t *testing.T, params TestingBuildParams, wantOutput string) {
- if len(params.RuleParams.CommandDeps) != 1 || params.RuleParams.CommandDeps[0] != "cp" {
- t.Errorf("want RuleParams.CommandDeps = [%q], got %q", "cp", params.RuleParams.CommandDeps)
+ check := func(t *testing.T, params TestingBuildParams, wantCommand, wantOutput, wantDepfile string, wantRestat bool, extraCmdDeps []string) {
+ t.Helper()
+ if params.RuleParams.Command != wantCommand {
+ t.Errorf("\nwant RuleParams.Command = %q\n got %q", wantCommand, params.RuleParams.Command)
+ }
+
+ wantDeps := append([]string{"cp"}, extraCmdDeps...)
+ if !reflect.DeepEqual(params.RuleParams.CommandDeps, wantDeps) {
+ t.Errorf("\nwant RuleParams.CommandDeps = %q\n got %q", wantDeps, params.RuleParams.CommandDeps)
+ }
+
+ if params.RuleParams.Restat != wantRestat {
+ t.Errorf("want RuleParams.Restat = %v, got %v", wantRestat, params.RuleParams.Restat)
}
if len(params.Implicits) != 1 || params.Implicits[0].String() != "bar" {
@@ -404,17 +476,40 @@ func TestRuleBuilder_Build(t *testing.T) {
t.Errorf("want Output = %q, got %q", wantOutput, params.Output)
}
- if !params.RuleParams.Restat {
- t.Errorf("want RuleParams.Restat = true, got %v", params.RuleParams.Restat)
+ if len(params.ImplicitOutputs) != 0 {
+ t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings())
+ }
+
+ if params.Depfile.String() != wantDepfile {
+ t.Errorf("want Depfile = %q, got %q", wantDepfile, params.Depfile)
+ }
+
+ if params.Deps != blueprint.DepsGCC {
+ t.Errorf("want Deps = %q, got %q", blueprint.DepsGCC, params.Deps)
}
}
t.Run("module", func(t *testing.T) {
+ outFile := filepath.Join(buildDir, ".intermediates", "foo", "foo")
check(t, ctx.ModuleForTests("foo", "").Rule("rule"),
- filepath.Join(buildDir, ".intermediates", "foo", "foo"))
+ "cp bar "+outFile,
+ outFile, outFile+".d", true, nil)
+ })
+ t.Run("sbox", func(t *testing.T) {
+ outDir := filepath.Join(buildDir, ".intermediates", "foo_sbox")
+ outFile := filepath.Join(outDir, "foo_sbox")
+ depFile := filepath.Join(outDir, "foo_sbox.d")
+ sbox := filepath.Join(buildDir, "host", config.PrebuiltOS(), "bin/sbox")
+ sandboxPath := shared.TempDirForOutDir(buildDir)
+
+ cmd := sbox + ` -c 'cp bar __SBOX_OUT_DIR__/foo_sbox' --sandbox-path ` + sandboxPath + " --output-root " + outDir + " --depfile-out " + depFile + " __SBOX_OUT_DIR__/foo_sbox"
+
+ check(t, ctx.ModuleForTests("foo_sbox", "").Rule("rule"),
+ cmd, outFile, depFile, false, []string{sbox})
})
t.Run("singleton", func(t *testing.T) {
+ outFile := filepath.Join(buildDir, "baz")
check(t, ctx.SingletonForTests("rule_builder_test").Rule("rule"),
- filepath.Join(buildDir, "baz"))
+ "cp bar "+outFile, outFile, outFile+".d", true, nil)
})
}