blob: 00b0a5752c0ebcea5cdc4af268113f0460267a30 [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 (
Colin Cross758290d2019-02-01 16:42:32 -080018 "fmt"
Colin Crossfeec25b2019-01-30 17:32:39 -080019 "path/filepath"
Colin Cross3d680512020-11-13 16:23:53 -080020 "regexp"
Colin Cross758290d2019-02-01 16:42:32 -080021 "strings"
Colin Crossfeec25b2019-01-30 17:32:39 -080022 "testing"
Dan Willemsen633c5022019-04-12 11:11:38 -070023
24 "github.com/google/blueprint"
25
26 "android/soong/shared"
Colin Crossfeec25b2019-01-30 17:32:39 -080027)
28
Colin Crossf1a035e2020-11-16 17:32:30 -080029func builderContext() BuilderContext {
30 return BuilderContextForTesting(TestConfig("out", nil, "", map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -080031 "ld": nil,
32 "a.o": nil,
33 "b.o": nil,
34 "cp": nil,
35 "a": nil,
36 "b": nil,
37 "ls": nil,
Jingwen Chence679d22020-09-23 04:30:02 +000038 "ln": nil,
Colin Cross98be1bb2019-12-13 20:41:13 -080039 "turbine": nil,
40 "java": nil,
41 "javac": nil,
42 }))
Colin Cross69f59a32019-02-15 10:39:37 -080043}
44
Colin Cross758290d2019-02-01 16:42:32 -080045func ExampleRuleBuilder() {
Colin Crossf1a035e2020-11-16 17:32:30 -080046 ctx := builderContext()
Colin Cross758290d2019-02-01 16:42:32 -080047
Colin Crossf1a035e2020-11-16 17:32:30 -080048 rule := NewRuleBuilder(pctx, ctx)
Colin Cross69f59a32019-02-15 10:39:37 -080049
50 rule.Command().
51 Tool(PathForSource(ctx, "ld")).
52 Inputs(PathsForTesting("a.o", "b.o")).
53 FlagWithOutput("-o ", PathForOutput(ctx, "linked"))
Colin Cross758290d2019-02-01 16:42:32 -080054 rule.Command().Text("echo success")
55
56 // To add the command to the build graph:
Colin Crossf1a035e2020-11-16 17:32:30 -080057 // rule.Build("link", "link")
Colin Cross758290d2019-02-01 16:42:32 -080058
59 fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && "))
60 fmt.Printf("tools: %q\n", rule.Tools())
61 fmt.Printf("inputs: %q\n", rule.Inputs())
62 fmt.Printf("outputs: %q\n", rule.Outputs())
63
64 // Output:
Colin Cross69f59a32019-02-15 10:39:37 -080065 // commands: "ld a.o b.o -o out/linked && echo success"
Colin Cross758290d2019-02-01 16:42:32 -080066 // tools: ["ld"]
67 // inputs: ["a.o" "b.o"]
Colin Cross69f59a32019-02-15 10:39:37 -080068 // outputs: ["out/linked"]
Colin Cross758290d2019-02-01 16:42:32 -080069}
70
Jingwen Chence679d22020-09-23 04:30:02 +000071func ExampleRuleBuilder_SymlinkOutputs() {
Colin Crossf1a035e2020-11-16 17:32:30 -080072 ctx := builderContext()
Jingwen Chence679d22020-09-23 04:30:02 +000073
Colin Crossf1a035e2020-11-16 17:32:30 -080074 rule := NewRuleBuilder(pctx, ctx)
Jingwen Chence679d22020-09-23 04:30:02 +000075
76 rule.Command().
77 Tool(PathForSource(ctx, "ln")).
78 FlagWithInput("-s ", PathForTesting("a.o")).
79 SymlinkOutput(PathForOutput(ctx, "a"))
80 rule.Command().Text("cp out/a out/b").
81 ImplicitSymlinkOutput(PathForOutput(ctx, "b"))
82
83 fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && "))
84 fmt.Printf("tools: %q\n", rule.Tools())
85 fmt.Printf("inputs: %q\n", rule.Inputs())
86 fmt.Printf("outputs: %q\n", rule.Outputs())
87 fmt.Printf("symlink_outputs: %q\n", rule.SymlinkOutputs())
88
89 // Output:
90 // commands: "ln -s a.o out/a && cp out/a out/b"
91 // tools: ["ln"]
92 // inputs: ["a.o"]
93 // outputs: ["out/a" "out/b"]
94 // symlink_outputs: ["out/a" "out/b"]
95}
96
Colin Cross5cb5b092019-02-02 21:25:18 -080097func ExampleRuleBuilder_Temporary() {
Colin Crossf1a035e2020-11-16 17:32:30 -080098 ctx := builderContext()
Colin Cross5cb5b092019-02-02 21:25:18 -080099
Colin Crossf1a035e2020-11-16 17:32:30 -0800100 rule := NewRuleBuilder(pctx, ctx)
Colin Cross69f59a32019-02-15 10:39:37 -0800101
102 rule.Command().
103 Tool(PathForSource(ctx, "cp")).
104 Input(PathForSource(ctx, "a")).
105 Output(PathForOutput(ctx, "b"))
106 rule.Command().
107 Tool(PathForSource(ctx, "cp")).
108 Input(PathForOutput(ctx, "b")).
109 Output(PathForOutput(ctx, "c"))
110 rule.Temporary(PathForOutput(ctx, "b"))
Colin Cross5cb5b092019-02-02 21:25:18 -0800111
112 fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && "))
113 fmt.Printf("tools: %q\n", rule.Tools())
114 fmt.Printf("inputs: %q\n", rule.Inputs())
115 fmt.Printf("outputs: %q\n", rule.Outputs())
116
117 // Output:
Colin Cross69f59a32019-02-15 10:39:37 -0800118 // commands: "cp a out/b && cp out/b out/c"
Colin Cross5cb5b092019-02-02 21:25:18 -0800119 // tools: ["cp"]
120 // inputs: ["a"]
Colin Cross69f59a32019-02-15 10:39:37 -0800121 // outputs: ["out/c"]
Colin Cross5cb5b092019-02-02 21:25:18 -0800122}
123
124func ExampleRuleBuilder_DeleteTemporaryFiles() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800125 ctx := builderContext()
Colin Cross5cb5b092019-02-02 21:25:18 -0800126
Colin Crossf1a035e2020-11-16 17:32:30 -0800127 rule := NewRuleBuilder(pctx, ctx)
Colin Cross69f59a32019-02-15 10:39:37 -0800128
129 rule.Command().
130 Tool(PathForSource(ctx, "cp")).
131 Input(PathForSource(ctx, "a")).
132 Output(PathForOutput(ctx, "b"))
133 rule.Command().
134 Tool(PathForSource(ctx, "cp")).
135 Input(PathForOutput(ctx, "b")).
136 Output(PathForOutput(ctx, "c"))
137 rule.Temporary(PathForOutput(ctx, "b"))
Colin Cross5cb5b092019-02-02 21:25:18 -0800138 rule.DeleteTemporaryFiles()
139
140 fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && "))
141 fmt.Printf("tools: %q\n", rule.Tools())
142 fmt.Printf("inputs: %q\n", rule.Inputs())
143 fmt.Printf("outputs: %q\n", rule.Outputs())
144
145 // Output:
Colin Cross69f59a32019-02-15 10:39:37 -0800146 // commands: "cp a out/b && cp out/b out/c && rm -f out/b"
Colin Cross5cb5b092019-02-02 21:25:18 -0800147 // tools: ["cp"]
148 // inputs: ["a"]
Colin Cross69f59a32019-02-15 10:39:37 -0800149 // outputs: ["out/c"]
Colin Cross5cb5b092019-02-02 21:25:18 -0800150}
151
Colin Crossdeabb942019-02-11 14:11:09 -0800152func ExampleRuleBuilder_Installs() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800153 ctx := builderContext()
Colin Crossdeabb942019-02-11 14:11:09 -0800154
Colin Crossf1a035e2020-11-16 17:32:30 -0800155 rule := NewRuleBuilder(pctx, ctx)
Colin Cross69f59a32019-02-15 10:39:37 -0800156
157 out := PathForOutput(ctx, "linked")
158
159 rule.Command().
160 Tool(PathForSource(ctx, "ld")).
161 Inputs(PathsForTesting("a.o", "b.o")).
162 FlagWithOutput("-o ", out)
163 rule.Install(out, "/bin/linked")
164 rule.Install(out, "/sbin/linked")
Colin Crossdeabb942019-02-11 14:11:09 -0800165
166 fmt.Printf("rule.Installs().String() = %q\n", rule.Installs().String())
167
168 // Output:
Colin Cross69f59a32019-02-15 10:39:37 -0800169 // rule.Installs().String() = "out/linked:/bin/linked out/linked:/sbin/linked"
Colin Crossdeabb942019-02-11 14:11:09 -0800170}
171
Colin Cross758290d2019-02-01 16:42:32 -0800172func ExampleRuleBuilderCommand() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800173 ctx := builderContext()
Colin Cross758290d2019-02-01 16:42:32 -0800174
Colin Crossf1a035e2020-11-16 17:32:30 -0800175 rule := NewRuleBuilder(pctx, ctx)
Colin Cross69f59a32019-02-15 10:39:37 -0800176
Colin Cross758290d2019-02-01 16:42:32 -0800177 // chained
Colin Cross69f59a32019-02-15 10:39:37 -0800178 rule.Command().
179 Tool(PathForSource(ctx, "ld")).
180 Inputs(PathsForTesting("a.o", "b.o")).
181 FlagWithOutput("-o ", PathForOutput(ctx, "linked"))
Colin Cross758290d2019-02-01 16:42:32 -0800182
183 // unchained
184 cmd := rule.Command()
Colin Cross69f59a32019-02-15 10:39:37 -0800185 cmd.Tool(PathForSource(ctx, "ld"))
186 cmd.Inputs(PathsForTesting("a.o", "b.o"))
187 cmd.FlagWithOutput("-o ", PathForOutput(ctx, "linked"))
Colin Cross758290d2019-02-01 16:42:32 -0800188
189 // mixed:
Colin Cross69f59a32019-02-15 10:39:37 -0800190 cmd = rule.Command().Tool(PathForSource(ctx, "ld"))
191 cmd.Inputs(PathsForTesting("a.o", "b.o"))
192 cmd.FlagWithOutput("-o ", PathForOutput(ctx, "linked"))
Colin Cross758290d2019-02-01 16:42:32 -0800193}
194
195func ExampleRuleBuilderCommand_Flag() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800196 ctx := builderContext()
197 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross69f59a32019-02-15 10:39:37 -0800198 Tool(PathForSource(ctx, "ls")).Flag("-l"))
Colin Cross758290d2019-02-01 16:42:32 -0800199 // Output:
200 // ls -l
201}
202
Colin Cross92b7d582019-03-29 15:32:51 -0700203func ExampleRuleBuilderCommand_Flags() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800204 ctx := builderContext()
205 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross92b7d582019-03-29 15:32:51 -0700206 Tool(PathForSource(ctx, "ls")).Flags([]string{"-l", "-a"}))
207 // Output:
208 // ls -l -a
209}
210
Colin Cross758290d2019-02-01 16:42:32 -0800211func ExampleRuleBuilderCommand_FlagWithArg() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800212 ctx := builderContext()
213 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross69f59a32019-02-15 10:39:37 -0800214 Tool(PathForSource(ctx, "ls")).
Colin Cross758290d2019-02-01 16:42:32 -0800215 FlagWithArg("--sort=", "time"))
216 // Output:
217 // ls --sort=time
218}
219
Colin Crossc7ed0042019-02-11 14:11:09 -0800220func ExampleRuleBuilderCommand_FlagForEachArg() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800221 ctx := builderContext()
222 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross69f59a32019-02-15 10:39:37 -0800223 Tool(PathForSource(ctx, "ls")).
Colin Crossc7ed0042019-02-11 14:11:09 -0800224 FlagForEachArg("--sort=", []string{"time", "size"}))
225 // Output:
226 // ls --sort=time --sort=size
227}
228
Colin Cross758290d2019-02-01 16:42:32 -0800229func ExampleRuleBuilderCommand_FlagForEachInput() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800230 ctx := builderContext()
231 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross69f59a32019-02-15 10:39:37 -0800232 Tool(PathForSource(ctx, "turbine")).
233 FlagForEachInput("--classpath ", PathsForTesting("a.jar", "b.jar")))
Colin Cross758290d2019-02-01 16:42:32 -0800234 // Output:
235 // turbine --classpath a.jar --classpath b.jar
236}
237
238func ExampleRuleBuilderCommand_FlagWithInputList() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800239 ctx := builderContext()
240 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross69f59a32019-02-15 10:39:37 -0800241 Tool(PathForSource(ctx, "java")).
242 FlagWithInputList("-classpath=", PathsForTesting("a.jar", "b.jar"), ":"))
Colin Cross758290d2019-02-01 16:42:32 -0800243 // Output:
244 // java -classpath=a.jar:b.jar
245}
246
247func ExampleRuleBuilderCommand_FlagWithInput() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800248 ctx := builderContext()
249 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross69f59a32019-02-15 10:39:37 -0800250 Tool(PathForSource(ctx, "java")).
251 FlagWithInput("-classpath=", PathForSource(ctx, "a")))
Colin Cross758290d2019-02-01 16:42:32 -0800252 // Output:
253 // java -classpath=a
254}
255
256func ExampleRuleBuilderCommand_FlagWithList() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800257 ctx := builderContext()
258 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross69f59a32019-02-15 10:39:37 -0800259 Tool(PathForSource(ctx, "ls")).
Colin Cross758290d2019-02-01 16:42:32 -0800260 FlagWithList("--sort=", []string{"time", "size"}, ","))
261 // Output:
262 // ls --sort=time,size
263}
264
Colin Cross0cb0d7b2019-07-11 10:59:15 -0700265func ExampleRuleBuilderCommand_FlagWithRspFileInputList() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800266 ctx := builderContext()
267 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross0cb0d7b2019-07-11 10:59:15 -0700268 Tool(PathForSource(ctx, "javac")).
Colin Cross70c47412021-03-12 17:48:14 -0800269 FlagWithRspFileInputList("@", PathForOutput(ctx, "foo.rsp"), PathsForTesting("a.java", "b.java")).
270 String())
Colin Cross0cb0d7b2019-07-11 10:59:15 -0700271 // Output:
Colin Cross70c47412021-03-12 17:48:14 -0800272 // javac @out/foo.rsp
Colin Cross0cb0d7b2019-07-11 10:59:15 -0700273}
274
275func ExampleRuleBuilderCommand_String() {
Colin Crossf1a035e2020-11-16 17:32:30 -0800276 ctx := builderContext()
277 fmt.Println(NewRuleBuilder(pctx, ctx).Command().
Colin Cross0cb0d7b2019-07-11 10:59:15 -0700278 Text("FOO=foo").
279 Text("echo $FOO").
280 String())
281 // Output:
282 // FOO=foo echo $FOO
283}
284
Colin Crossfeec25b2019-01-30 17:32:39 -0800285func TestRuleBuilder(t *testing.T) {
Colin Cross69f59a32019-02-15 10:39:37 -0800286 fs := map[string][]byte{
Colin Crossda71eda2020-02-21 16:55:19 -0800287 "dep_fixer": nil,
288 "input": nil,
289 "Implicit": nil,
290 "Input": nil,
291 "OrderOnly": nil,
292 "OrderOnlys": nil,
293 "Tool": nil,
294 "input2": nil,
295 "tool2": nil,
296 "input3": nil,
Colin Cross69f59a32019-02-15 10:39:37 -0800297 }
298
Colin Crossab020a72021-03-12 17:52:23 -0800299 pathCtx := PathContextForTesting(TestConfig("out_local", nil, "", fs))
Colin Crossf1a035e2020-11-16 17:32:30 -0800300 ctx := builderContextForTests{
301 PathContext: pathCtx,
302 }
Colin Cross69f59a32019-02-15 10:39:37 -0800303
Dan Willemsen633c5022019-04-12 11:11:38 -0700304 addCommands := func(rule *RuleBuilder) {
305 cmd := rule.Command().
Colin Crossab020a72021-03-12 17:52:23 -0800306 DepFile(PathForOutput(ctx, "module/DepFile")).
Dan Willemsen633c5022019-04-12 11:11:38 -0700307 Flag("Flag").
308 FlagWithArg("FlagWithArg=", "arg").
Colin Crossab020a72021-03-12 17:52:23 -0800309 FlagWithDepFile("FlagWithDepFile=", PathForOutput(ctx, "module/depfile")).
Dan Willemsen633c5022019-04-12 11:11:38 -0700310 FlagWithInput("FlagWithInput=", PathForSource(ctx, "input")).
Colin Crossab020a72021-03-12 17:52:23 -0800311 FlagWithOutput("FlagWithOutput=", PathForOutput(ctx, "module/output")).
312 FlagWithRspFileInputList("FlagWithRspFileInputList=", PathForOutput(ctx, "rsp"),
313 Paths{
314 PathForSource(ctx, "RspInput"),
315 PathForOutput(ctx, "other/RspOutput2"),
316 }).
Dan Willemsen633c5022019-04-12 11:11:38 -0700317 Implicit(PathForSource(ctx, "Implicit")).
Colin Crossab020a72021-03-12 17:52:23 -0800318 ImplicitDepFile(PathForOutput(ctx, "module/ImplicitDepFile")).
319 ImplicitOutput(PathForOutput(ctx, "module/ImplicitOutput")).
Dan Willemsen633c5022019-04-12 11:11:38 -0700320 Input(PathForSource(ctx, "Input")).
Colin Crossab020a72021-03-12 17:52:23 -0800321 Output(PathForOutput(ctx, "module/Output")).
Colin Crossda71eda2020-02-21 16:55:19 -0800322 OrderOnly(PathForSource(ctx, "OrderOnly")).
Colin Crossab020a72021-03-12 17:52:23 -0800323 SymlinkOutput(PathForOutput(ctx, "module/SymlinkOutput")).
324 ImplicitSymlinkOutput(PathForOutput(ctx, "module/ImplicitSymlinkOutput")).
Dan Willemsen633c5022019-04-12 11:11:38 -0700325 Text("Text").
326 Tool(PathForSource(ctx, "Tool"))
Colin Crossfeec25b2019-01-30 17:32:39 -0800327
Dan Willemsen633c5022019-04-12 11:11:38 -0700328 rule.Command().
329 Text("command2").
Colin Crossab020a72021-03-12 17:52:23 -0800330 DepFile(PathForOutput(ctx, "module/depfile2")).
Dan Willemsen633c5022019-04-12 11:11:38 -0700331 Input(PathForSource(ctx, "input2")).
Colin Crossab020a72021-03-12 17:52:23 -0800332 Output(PathForOutput(ctx, "module/output2")).
Colin Crossda71eda2020-02-21 16:55:19 -0800333 OrderOnlys(PathsForSource(ctx, []string{"OrderOnlys"})).
Dan Willemsen633c5022019-04-12 11:11:38 -0700334 Tool(PathForSource(ctx, "tool2"))
Colin Crossfeec25b2019-01-30 17:32:39 -0800335
Dan Willemsen633c5022019-04-12 11:11:38 -0700336 // Test updates to the first command after the second command has been started
337 cmd.Text("after command2")
338 // Test updating a command when the previous update did not replace the cmd variable
339 cmd.Text("old cmd")
Colin Crossfeec25b2019-01-30 17:32:39 -0800340
Dan Willemsen633c5022019-04-12 11:11:38 -0700341 // Test a command that uses the output of a previous command as an input
342 rule.Command().
343 Text("command3").
344 Input(PathForSource(ctx, "input3")).
Colin Crossab020a72021-03-12 17:52:23 -0800345 Input(PathForOutput(ctx, "module/output2")).
346 Output(PathForOutput(ctx, "module/output3")).
347 Text(cmd.PathForInput(PathForSource(ctx, "input3"))).
348 Text(cmd.PathForOutput(PathForOutput(ctx, "module/output2")))
Colin Crossfeec25b2019-01-30 17:32:39 -0800349 }
Colin Cross1d2cf042019-03-29 15:33:06 -0700350
Colin Cross69f59a32019-02-15 10:39:37 -0800351 wantInputs := PathsForSource(ctx, []string{"Implicit", "Input", "input", "input2", "input3"})
Colin Crossab020a72021-03-12 17:52:23 -0800352 wantRspFileInputs := Paths{PathForSource(ctx, "RspInput"),
353 PathForOutput(ctx, "other/RspOutput2")}
354 wantOutputs := PathsForOutput(ctx, []string{
355 "module/ImplicitOutput", "module/ImplicitSymlinkOutput", "module/Output", "module/SymlinkOutput",
356 "module/output", "module/output2", "module/output3"})
357 wantDepFiles := PathsForOutput(ctx, []string{
358 "module/DepFile", "module/depfile", "module/ImplicitDepFile", "module/depfile2"})
Colin Cross69f59a32019-02-15 10:39:37 -0800359 wantTools := PathsForSource(ctx, []string{"Tool", "tool2"})
Colin Crossda71eda2020-02-21 16:55:19 -0800360 wantOrderOnlys := PathsForSource(ctx, []string{"OrderOnly", "OrderOnlys"})
Colin Crossab020a72021-03-12 17:52:23 -0800361 wantSymlinkOutputs := PathsForOutput(ctx, []string{
362 "module/ImplicitSymlinkOutput", "module/SymlinkOutput"})
Colin Crossfeec25b2019-01-30 17:32:39 -0800363
Dan Willemsen633c5022019-04-12 11:11:38 -0700364 t.Run("normal", func(t *testing.T) {
Colin Crossf1a035e2020-11-16 17:32:30 -0800365 rule := NewRuleBuilder(pctx, ctx)
Dan Willemsen633c5022019-04-12 11:11:38 -0700366 addCommands(rule)
Colin Cross1d2cf042019-03-29 15:33:06 -0700367
Dan Willemsen633c5022019-04-12 11:11:38 -0700368 wantCommands := []string{
Colin Crossab020a72021-03-12 17:52:23 -0800369 "out_local/module/DepFile Flag FlagWithArg=arg FlagWithDepFile=out_local/module/depfile " +
370 "FlagWithInput=input FlagWithOutput=out_local/module/output FlagWithRspFileInputList=out_local/rsp " +
371 "Input out_local/module/Output out_local/module/SymlinkOutput Text Tool after command2 old cmd",
372 "command2 out_local/module/depfile2 input2 out_local/module/output2 tool2",
373 "command3 input3 out_local/module/output2 out_local/module/output3 input3 out_local/module/output2",
Dan Willemsen633c5022019-04-12 11:11:38 -0700374 }
Colin Cross1d2cf042019-03-29 15:33:06 -0700375
Colin Crossab020a72021-03-12 17:52:23 -0800376 wantDepMergerCommand := "out_local/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer " +
377 "out_local/module/DepFile out_local/module/depfile out_local/module/ImplicitDepFile out_local/module/depfile2"
378
379 wantRspFileContent := "$in"
Dan Willemsen633c5022019-04-12 11:11:38 -0700380
Paul Duffind250ff62021-03-16 21:51:29 +0000381 AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands())
Dan Willemsen633c5022019-04-12 11:11:38 -0700382
Paul Duffind250ff62021-03-16 21:51:29 +0000383 AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs())
Colin Crossab020a72021-03-12 17:52:23 -0800384 AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs())
Paul Duffind250ff62021-03-16 21:51:29 +0000385 AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs())
386 AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs())
387 AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles())
388 AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools())
389 AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys())
Dan Willemsen633c5022019-04-12 11:11:38 -0700390
Paul Duffind250ff62021-03-16 21:51:29 +0000391 AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String())
Colin Crossab020a72021-03-12 17:52:23 -0800392
393 AssertSame(t, "rule.composeRspFileContent()", wantRspFileContent, rule.composeRspFileContent(rule.RspFileInputs()))
Dan Willemsen633c5022019-04-12 11:11:38 -0700394 })
395
396 t.Run("sbox", func(t *testing.T) {
Colin Crossab020a72021-03-12 17:52:23 -0800397 rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"),
Colin Crosse16ce362020-11-12 08:29:30 -0800398 PathForOutput(ctx, "sbox.textproto"))
Dan Willemsen633c5022019-04-12 11:11:38 -0700399 addCommands(rule)
400
401 wantCommands := []string{
Colin Crossab020a72021-03-12 17:52:23 -0800402 "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " +
403 "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " +
404 "FlagWithRspFileInputList=out_local/rsp Input __SBOX_SANDBOX_DIR__/out/Output " +
405 "__SBOX_SANDBOX_DIR__/out/SymlinkOutput Text Tool after command2 old cmd",
Colin Crosse16ce362020-11-12 08:29:30 -0800406 "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 tool2",
Colin Crossab020a72021-03-12 17:52:23 -0800407 "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2",
Dan Willemsen633c5022019-04-12 11:11:38 -0700408 }
409
Colin Crossab020a72021-03-12 17:52:23 -0800410 wantDepMergerCommand := "out_local/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2"
411
412 wantRspFileContent := "$in"
Dan Willemsen633c5022019-04-12 11:11:38 -0700413
Paul Duffind250ff62021-03-16 21:51:29 +0000414 AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands())
Dan Willemsen633c5022019-04-12 11:11:38 -0700415
Paul Duffind250ff62021-03-16 21:51:29 +0000416 AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs())
Colin Crossab020a72021-03-12 17:52:23 -0800417 AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs())
Paul Duffind250ff62021-03-16 21:51:29 +0000418 AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs())
Colin Crossab020a72021-03-12 17:52:23 -0800419 AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs())
Paul Duffind250ff62021-03-16 21:51:29 +0000420 AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles())
421 AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools())
422 AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys())
Dan Willemsen633c5022019-04-12 11:11:38 -0700423
Paul Duffind250ff62021-03-16 21:51:29 +0000424 AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String())
Colin Crossab020a72021-03-12 17:52:23 -0800425
426 AssertSame(t, "rule.composeRspFileContent()", wantRspFileContent, rule.composeRspFileContent(rule.RspFileInputs()))
Dan Willemsen633c5022019-04-12 11:11:38 -0700427 })
Colin Crossba9e4032020-11-24 16:32:22 -0800428
429 t.Run("sbox tools", func(t *testing.T) {
Colin Crossab020a72021-03-12 17:52:23 -0800430 rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"),
Colin Crossba9e4032020-11-24 16:32:22 -0800431 PathForOutput(ctx, "sbox.textproto")).SandboxTools()
432 addCommands(rule)
433
434 wantCommands := []string{
Colin Crossab020a72021-03-12 17:52:23 -0800435 "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " +
436 "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " +
437 "FlagWithRspFileInputList=out_local/rsp Input __SBOX_SANDBOX_DIR__/out/Output " +
438 "__SBOX_SANDBOX_DIR__/out/SymlinkOutput Text __SBOX_SANDBOX_DIR__/tools/src/Tool after command2 old cmd",
Colin Crossba9e4032020-11-24 16:32:22 -0800439 "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/tools/src/tool2",
Colin Crossab020a72021-03-12 17:52:23 -0800440 "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2",
Colin Crossba9e4032020-11-24 16:32:22 -0800441 }
442
443 wantDepMergerCommand := "__SBOX_SANDBOX_DIR__/tools/out/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2"
444
Colin Crossab020a72021-03-12 17:52:23 -0800445 wantRspFileContent := "$in"
446
Paul Duffind250ff62021-03-16 21:51:29 +0000447 AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands())
Colin Crossba9e4032020-11-24 16:32:22 -0800448
Paul Duffind250ff62021-03-16 21:51:29 +0000449 AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs())
Colin Crossab020a72021-03-12 17:52:23 -0800450 AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs())
Paul Duffind250ff62021-03-16 21:51:29 +0000451 AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs())
Colin Crossab020a72021-03-12 17:52:23 -0800452 AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs())
Paul Duffind250ff62021-03-16 21:51:29 +0000453 AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles())
454 AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools())
455 AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys())
Colin Crossba9e4032020-11-24 16:32:22 -0800456
Paul Duffind250ff62021-03-16 21:51:29 +0000457 AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String())
Colin Crossab020a72021-03-12 17:52:23 -0800458
459 AssertSame(t, "rule.composeRspFileContent()", wantRspFileContent, rule.composeRspFileContent(rule.RspFileInputs()))
Colin Crossba9e4032020-11-24 16:32:22 -0800460 })
Colin Cross045bfd92021-03-24 16:38:03 -0700461
462 t.Run("sbox inputs", func(t *testing.T) {
463 rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"),
464 PathForOutput(ctx, "sbox.textproto")).SandboxInputs()
465 addCommands(rule)
466
467 wantCommands := []string{
468 "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " +
469 "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " +
470 "FlagWithRspFileInputList=__SBOX_SANDBOX_DIR__/out/rsp Input __SBOX_SANDBOX_DIR__/out/Output " +
471 "__SBOX_SANDBOX_DIR__/out/SymlinkOutput Text __SBOX_SANDBOX_DIR__/tools/src/Tool after command2 old cmd",
472 "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/tools/src/tool2",
473 "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2",
474 }
475
476 wantDepMergerCommand := "__SBOX_SANDBOX_DIR__/tools/out/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2"
477
478 AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands())
479
480 AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs())
481 AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs())
482 AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs())
483 AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs())
484 AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles())
485 AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools())
486 AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys())
487
488 AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String())
489 })
Colin Crossfeec25b2019-01-30 17:32:39 -0800490}
491
492func testRuleBuilderFactory() Module {
493 module := &testRuleBuilderModule{}
494 module.AddProperties(&module.properties)
495 InitAndroidModule(module)
496 return module
497}
498
499type testRuleBuilderModule struct {
500 ModuleBase
501 properties struct {
Colin Cross3d680512020-11-13 16:23:53 -0800502 Srcs []string
Dan Willemsen633c5022019-04-12 11:11:38 -0700503
504 Restat bool
505 Sbox bool
Colin Crossfeec25b2019-01-30 17:32:39 -0800506 }
507}
508
509func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Cross3d680512020-11-13 16:23:53 -0800510 in := PathsForSource(ctx, t.properties.Srcs)
Colin Crosse16ce362020-11-12 08:29:30 -0800511 out := PathForModuleOut(ctx, "gen", ctx.ModuleName())
512 outDep := PathForModuleOut(ctx, "gen", ctx.ModuleName()+".d")
513 outDir := PathForModuleOut(ctx, "gen")
514 manifestPath := PathForModuleOut(ctx, "sbox.textproto")
Colin Crossfeec25b2019-01-30 17:32:39 -0800515
Colin Crosse16ce362020-11-12 08:29:30 -0800516 testRuleBuilder_Build(ctx, in, out, outDep, outDir, manifestPath, t.properties.Restat, t.properties.Sbox)
Colin Cross786cd6d2019-02-01 16:41:11 -0800517}
518
519type testRuleBuilderSingleton struct{}
520
521func testRuleBuilderSingletonFactory() Singleton {
522 return &testRuleBuilderSingleton{}
523}
524
525func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) {
526 in := PathForSource(ctx, "bar")
Colin Crosse16ce362020-11-12 08:29:30 -0800527 out := PathForOutput(ctx, "singleton/gen/baz")
528 outDep := PathForOutput(ctx, "singleton/gen/baz.d")
529 outDir := PathForOutput(ctx, "singleton/gen")
530 manifestPath := PathForOutput(ctx, "singleton/sbox.textproto")
531 testRuleBuilder_Build(ctx, Paths{in}, out, outDep, outDir, manifestPath, true, false)
Colin Cross786cd6d2019-02-01 16:41:11 -0800532}
533
Colin Crosse16ce362020-11-12 08:29:30 -0800534func testRuleBuilder_Build(ctx BuilderContext, in Paths, out, outDep, outDir, manifestPath WritablePath, restat, sbox bool) {
Colin Crossf1a035e2020-11-16 17:32:30 -0800535 rule := NewRuleBuilder(pctx, ctx)
Colin Cross786cd6d2019-02-01 16:41:11 -0800536
Dan Willemsen633c5022019-04-12 11:11:38 -0700537 if sbox {
Colin Crosse16ce362020-11-12 08:29:30 -0800538 rule.Sbox(outDir, manifestPath)
Dan Willemsen633c5022019-04-12 11:11:38 -0700539 }
Colin Crossfeec25b2019-01-30 17:32:39 -0800540
Colin Cross3d680512020-11-13 16:23:53 -0800541 rule.Command().Tool(PathForSource(ctx, "cp")).Inputs(in).Output(out).ImplicitDepFile(outDep)
Dan Willemsen633c5022019-04-12 11:11:38 -0700542
543 if restat {
544 rule.Restat()
545 }
Colin Crossbaa676f2019-02-25 14:56:01 -0800546
Colin Crossf1a035e2020-11-16 17:32:30 -0800547 rule.Build("rule", "desc")
Colin Crossfeec25b2019-01-30 17:32:39 -0800548}
549
Paul Duffind250ff62021-03-16 21:51:29 +0000550var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) {
551 ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory)
552 ctx.RegisterSingletonType("rule_builder_test", testRuleBuilderSingletonFactory)
553})
554
Colin Crossfeec25b2019-01-30 17:32:39 -0800555func TestRuleBuilder_Build(t *testing.T) {
Paul Duffind250ff62021-03-16 21:51:29 +0000556 fs := MockFS{
Colin Cross98be1bb2019-12-13 20:41:13 -0800557 "bar": nil,
558 "cp": nil,
559 }
560
Colin Crossfeec25b2019-01-30 17:32:39 -0800561 bp := `
562 rule_builder_test {
563 name: "foo",
Colin Cross3d680512020-11-13 16:23:53 -0800564 srcs: ["bar"],
Dan Willemsen633c5022019-04-12 11:11:38 -0700565 restat: true,
566 }
567 rule_builder_test {
568 name: "foo_sbox",
Colin Cross3d680512020-11-13 16:23:53 -0800569 srcs: ["bar"],
Dan Willemsen633c5022019-04-12 11:11:38 -0700570 sbox: true,
Colin Crossfeec25b2019-01-30 17:32:39 -0800571 }
572 `
573
Paul Duffin30ac3e72021-03-20 00:36:14 +0000574 result := GroupFixturePreparers(
Paul Duffind250ff62021-03-16 21:51:29 +0000575 prepareForRuleBuilderTest,
576 FixtureWithRootAndroidBp(bp),
577 fs.AddToFixture(),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000578 ).RunTest(t)
Colin Crossfeec25b2019-01-30 17:32:39 -0800579
Colin Crosse16ce362020-11-12 08:29:30 -0800580 check := func(t *testing.T, params TestingBuildParams, wantCommand, wantOutput, wantDepfile string, wantRestat bool, extraImplicits, extraCmdDeps []string) {
Dan Willemsenc89b6f12019-08-29 14:47:40 -0700581 t.Helper()
Colin Cross3d680512020-11-13 16:23:53 -0800582 command := params.RuleParams.Command
Colin Crosse16ce362020-11-12 08:29:30 -0800583 re := regexp.MustCompile(" # hash of input list: [a-z0-9]*$")
Colin Cross3d680512020-11-13 16:23:53 -0800584 command = re.ReplaceAllLiteralString(command, "")
Paul Duffind250ff62021-03-16 21:51:29 +0000585
586 AssertStringEquals(t, "RuleParams.Command", wantCommand, command)
Dan Willemsen633c5022019-04-12 11:11:38 -0700587
588 wantDeps := append([]string{"cp"}, extraCmdDeps...)
Paul Duffind250ff62021-03-16 21:51:29 +0000589 AssertArrayString(t, "RuleParams.CommandDeps", wantDeps, params.RuleParams.CommandDeps)
Dan Willemsen633c5022019-04-12 11:11:38 -0700590
Paul Duffind250ff62021-03-16 21:51:29 +0000591 AssertBoolEquals(t, "RuleParams.Restat", wantRestat, params.RuleParams.Restat)
Colin Crossfeec25b2019-01-30 17:32:39 -0800592
Colin Crosse16ce362020-11-12 08:29:30 -0800593 wantImplicits := append([]string{"bar"}, extraImplicits...)
Paul Duffin709e0e32021-03-22 10:09:02 +0000594 AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits)
Colin Crossfeec25b2019-01-30 17:32:39 -0800595
Paul Duffin709e0e32021-03-22 10:09:02 +0000596 AssertPathRelativeToTopEquals(t, "Output", wantOutput, params.Output)
Colin Crossbaa676f2019-02-25 14:56:01 -0800597
Dan Willemsen633c5022019-04-12 11:11:38 -0700598 if len(params.ImplicitOutputs) != 0 {
599 t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings())
600 }
601
Paul Duffin709e0e32021-03-22 10:09:02 +0000602 AssertPathRelativeToTopEquals(t, "Depfile", wantDepfile, params.Depfile)
Dan Willemsen633c5022019-04-12 11:11:38 -0700603
604 if params.Deps != blueprint.DepsGCC {
605 t.Errorf("want Deps = %q, got %q", blueprint.DepsGCC, params.Deps)
Colin Crossbaa676f2019-02-25 14:56:01 -0800606 }
Colin Crossfeec25b2019-01-30 17:32:39 -0800607 }
608
Colin Cross4c83e5c2019-02-25 14:54:28 -0800609 t.Run("module", func(t *testing.T) {
Paul Duffin709e0e32021-03-22 10:09:02 +0000610 outFile := "out/soong/.intermediates/foo/gen/foo"
611 check(t, result.ModuleForTests("foo", "").Rule("rule").RelativeToTop(),
Dan Willemsen633c5022019-04-12 11:11:38 -0700612 "cp bar "+outFile,
Colin Crosse16ce362020-11-12 08:29:30 -0800613 outFile, outFile+".d", true, nil, nil)
Dan Willemsen633c5022019-04-12 11:11:38 -0700614 })
615 t.Run("sbox", func(t *testing.T) {
Paul Duffin709e0e32021-03-22 10:09:02 +0000616 outDir := "out/soong/.intermediates/foo_sbox"
Colin Crosse16ce362020-11-12 08:29:30 -0800617 outFile := filepath.Join(outDir, "gen/foo_sbox")
618 depFile := filepath.Join(outDir, "gen/foo_sbox.d")
619 manifest := filepath.Join(outDir, "sbox.textproto")
Paul Duffin709e0e32021-03-22 10:09:02 +0000620 sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox")
621 sandboxPath := shared.TempDirForOutDir("out/soong")
Dan Willemsen633c5022019-04-12 11:11:38 -0700622
Colin Crosse16ce362020-11-12 08:29:30 -0800623 cmd := `rm -rf ` + outDir + `/gen && ` +
624 sbox + ` --sandbox-path ` + sandboxPath + ` --manifest ` + manifest
Dan Willemsen633c5022019-04-12 11:11:38 -0700625
Paul Duffin709e0e32021-03-22 10:09:02 +0000626 check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox").RelativeToTop(),
Colin Crosse16ce362020-11-12 08:29:30 -0800627 cmd, outFile, depFile, false, []string{manifest}, []string{sbox})
Colin Cross4c83e5c2019-02-25 14:54:28 -0800628 })
629 t.Run("singleton", func(t *testing.T) {
Paul Duffin709e0e32021-03-22 10:09:02 +0000630 outFile := filepath.Join("out/soong/singleton/gen/baz")
631 check(t, result.SingletonForTests("rule_builder_test").Rule("rule").RelativeToTop(),
Colin Crosse16ce362020-11-12 08:29:30 -0800632 "cp bar "+outFile, outFile, outFile+".d", true, nil, nil)
Colin Cross4c83e5c2019-02-25 14:54:28 -0800633 })
Colin Crossfeec25b2019-01-30 17:32:39 -0800634}
Colin Cross0cb0d7b2019-07-11 10:59:15 -0700635
Colin Cross3d680512020-11-13 16:23:53 -0800636func TestRuleBuilderHashInputs(t *testing.T) {
637 // The basic idea here is to verify that the command (in the case of a
638 // non-sbox rule) or the sbox textproto manifest contain a hash of the
639 // inputs.
640
641 // By including a hash of the inputs, we cause the rule to re-run if
642 // the list of inputs changes because the command line or a dependency
643 // changes.
644
645 bp := `
646 rule_builder_test {
647 name: "hash0",
648 srcs: ["in1.txt", "in2.txt"],
649 }
650 rule_builder_test {
651 name: "hash0_sbox",
652 srcs: ["in1.txt", "in2.txt"],
653 sbox: true,
654 }
655 rule_builder_test {
656 name: "hash1",
657 srcs: ["in1.txt", "in2.txt", "in3.txt"],
658 }
659 rule_builder_test {
660 name: "hash1_sbox",
661 srcs: ["in1.txt", "in2.txt", "in3.txt"],
662 sbox: true,
663 }
664 `
665 testcases := []struct {
666 name string
667 expectedHash string
668 }{
669 {
670 name: "hash0",
671 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt' | sha256sum
672 expectedHash: "18da75b9b1cc74b09e365b4ca2e321b5d618f438cc632b387ad9dc2ab4b20e9d",
673 },
674 {
675 name: "hash1",
676 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
677 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
678 },
679 }
680
Paul Duffin30ac3e72021-03-20 00:36:14 +0000681 result := GroupFixturePreparers(
Paul Duffind250ff62021-03-16 21:51:29 +0000682 prepareForRuleBuilderTest,
683 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000684 ).RunTest(t)
Colin Cross3d680512020-11-13 16:23:53 -0800685
686 for _, test := range testcases {
687 t.Run(test.name, func(t *testing.T) {
688 t.Run("sbox", func(t *testing.T) {
Paul Duffind250ff62021-03-16 21:51:29 +0000689 gen := result.ModuleForTests(test.name+"_sbox", "")
Colin Crosse16ce362020-11-12 08:29:30 -0800690 manifest := RuleBuilderSboxProtoForTests(t, gen.Output("sbox.textproto"))
691 hash := manifest.Commands[0].GetInputHash()
692
Paul Duffind250ff62021-03-16 21:51:29 +0000693 AssertStringEquals(t, "hash", test.expectedHash, hash)
Colin Cross3d680512020-11-13 16:23:53 -0800694 })
695 t.Run("", func(t *testing.T) {
Paul Duffind250ff62021-03-16 21:51:29 +0000696 gen := result.ModuleForTests(test.name+"", "")
Colin Crosse16ce362020-11-12 08:29:30 -0800697 command := gen.Output("gen/" + test.name).RuleParams.Command
Colin Cross3d680512020-11-13 16:23:53 -0800698 if g, w := command, " # hash of input list: "+test.expectedHash; !strings.HasSuffix(g, w) {
699 t.Errorf("Expected command line to end with %q, got %q", w, g)
700 }
701 })
702 })
703 }
704}