blob: b4c9e0eb60a80c088d0a400e631de81eada17792 [file] [log] [blame]
Colin Crossfeec25b2019-01-30 17:32:39 -08001// Copyright 2019 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18 "io/ioutil"
19 "os"
20 "path/filepath"
21 "reflect"
22 "testing"
23)
24
25func TestRuleBuilder(t *testing.T) {
26 rule := RuleBuilder{}
27
28 cmd := rule.Command().
29 Flag("Flag").
30 FlagWithArg("FlagWithArg=", "arg").
31 FlagWithInput("FlagWithInput=", "input").
32 FlagWithOutput("FlagWithOutput=", "output").
33 Implicit("Implicit").
34 ImplicitOutput("ImplicitOutput").
35 Input("Input").
36 Output("Output").
37 Text("Text").
38 Tool("Tool")
39
40 rule.Command().
41 Text("command2").
42 Input("input2").
43 Output("output2").
44 Tool("tool2")
45
46 // Test updates to the first command after the second command has been started
47 cmd.Text("after command2")
48 // Test updating a command when the previous update did not replace the cmd variable
49 cmd.Text("old cmd")
50
51 // Test a command that uses the output of a previous command as an input
52 rule.Command().
53 Text("command3").
54 Input("input3").
55 Input("output2").
56 Output("output3")
57
58 wantCommands := []string{
59 "Flag FlagWithArg=arg FlagWithInput=input FlagWithOutput=output Input Output Text Tool after command2 old cmd",
60 "command2 input2 output2 tool2",
61 "command3 input3 output2 output3",
62 }
63 wantInputs := []string{"Implicit", "Input", "input", "input2", "input3"}
64 wantOutputs := []string{"ImplicitOutput", "Output", "output", "output2", "output3"}
65 wantTools := []string{"Tool", "tool2"}
66
67 if !reflect.DeepEqual(rule.Commands(), wantCommands) {
68 t.Errorf("\nwant rule.Commands() = %#v\n got %#v", wantCommands, rule.Commands())
69 }
70 if !reflect.DeepEqual(rule.Inputs(), wantInputs) {
71 t.Errorf("\nwant rule.Inputs() = %#v\n got %#v", wantInputs, rule.Inputs())
72 }
73 if !reflect.DeepEqual(rule.Outputs(), wantOutputs) {
74 t.Errorf("\nwant rule.Outputs() = %#v\n got %#v", wantOutputs, rule.Outputs())
75 }
76 if !reflect.DeepEqual(rule.Tools(), wantTools) {
77 t.Errorf("\nwant rule.Tools() = %#v\n got %#v", wantTools, rule.Tools())
78 }
79}
80
81func testRuleBuilderFactory() Module {
82 module := &testRuleBuilderModule{}
83 module.AddProperties(&module.properties)
84 InitAndroidModule(module)
85 return module
86}
87
88type testRuleBuilderModule struct {
89 ModuleBase
90 properties struct {
91 Src string
92 }
93}
94
95func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
96 rule := RuleBuilder{}
97
98 in := PathForSource(ctx, t.properties.Src)
99 out := PathForModuleOut(ctx, ctx.ModuleName())
100
101 rule.Command().Tool("cp").Input(in.String()).Output(out.String())
102
103 rule.Build(pctx, ctx, "rule", "desc")
104}
105
106func TestRuleBuilder_Build(t *testing.T) {
107 buildDir, err := ioutil.TempDir("", "soong_test_rule_builder")
108 if err != nil {
109 t.Fatal(err)
110 }
111 defer os.RemoveAll(buildDir)
112
113 bp := `
114 rule_builder_test {
115 name: "foo",
116 src: "bar",
117 }
118 `
119
120 config := TestConfig(buildDir, nil)
121 ctx := NewTestContext()
122 ctx.MockFileSystem(map[string][]byte{
123 "Android.bp": []byte(bp),
124 "bar": nil,
125 "cp": nil,
126 })
127 ctx.RegisterModuleType("rule_builder_test", ModuleFactoryAdaptor(testRuleBuilderFactory))
128 ctx.Register()
129
130 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
131 FailIfErrored(t, errs)
132 _, errs = ctx.PrepareBuildActions(config)
133 FailIfErrored(t, errs)
134
135 foo := ctx.ModuleForTests("foo", "").Rule("rule")
136
137 // TODO: make RuleParams accessible to tests and verify rule.Command().Tools() ends up in CommandDeps
138
139 if len(foo.Implicits) != 1 || foo.Implicits[0].String() != "bar" {
140 t.Errorf("want foo.Implicits = [%q], got %q", "bar", foo.Implicits.Strings())
141 }
142
143 wantOutput := filepath.Join(buildDir, ".intermediates", "foo", "foo")
144 if len(foo.Outputs) != 1 || foo.Outputs[0].String() != wantOutput {
145 t.Errorf("want foo.Outputs = [%q], got %q", wantOutput, foo.Outputs.Strings())
146 }
147
148}