blob: bb17e8e054c0121d69e249178bf7590c75168a46 [file] [log] [blame]
Colin Cross2a076922018-10-04 23:28:25 -07001// Copyright 2018 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 genrule
16
17import (
Colin Cross2a076922018-10-04 23:28:25 -070018 "os"
Paul Duffin672cb9f2021-03-03 02:30:37 +000019 "regexp"
Colin Cross2a076922018-10-04 23:28:25 -070020 "testing"
21
22 "android/soong/android"
Colin Crossba71a3f2019-03-18 12:12:48 -070023
24 "github.com/google/blueprint/proptools"
Colin Cross2a076922018-10-04 23:28:25 -070025)
26
Colin Cross2a076922018-10-04 23:28:25 -070027func TestMain(m *testing.M) {
Paul Duffine66946b2021-03-16 12:38:33 +000028 os.Exit(m.Run())
Colin Cross2a076922018-10-04 23:28:25 -070029}
30
Paul Duffin89648f92021-03-20 00:36:55 +000031var prepareForGenRuleTest = android.GroupFixturePreparers(
Paul Duffin672cb9f2021-03-03 02:30:37 +000032 android.PrepareForTestWithArchMutator,
33 android.PrepareForTestWithDefaults,
Colin Cross2a076922018-10-04 23:28:25 -070034
Paul Duffin672cb9f2021-03-03 02:30:37 +000035 android.PrepareForTestWithFilegroup,
36 PrepareForTestWithGenRuleBuildComponents,
37 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
38 ctx.RegisterModuleType("tool", toolFactory)
39 }),
40 android.FixtureMergeMockFs(android.MockFS{
41 "tool": nil,
42 "tool_file1": nil,
43 "tool_file2": nil,
44 "in1": nil,
45 "in2": nil,
46 "in1.txt": nil,
47 "in2.txt": nil,
48 "in3.txt": nil,
49 }),
50)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000051
Paul Duffin672cb9f2021-03-03 02:30:37 +000052func testGenruleBp() string {
53 return `
Colin Cross2a076922018-10-04 23:28:25 -070054 tool {
55 name: "tool",
56 }
57
58 filegroup {
59 name: "tool_files",
60 srcs: [
61 "tool_file1",
62 "tool_file2",
63 ],
64 }
65
66 filegroup {
67 name: "1tool_file",
68 srcs: [
69 "tool_file1",
70 ],
71 }
72
73 filegroup {
74 name: "ins",
75 srcs: [
76 "in1",
77 "in2",
78 ],
79 }
80
81 filegroup {
82 name: "1in",
83 srcs: [
84 "in1",
85 ],
86 }
87
88 filegroup {
89 name: "empty",
90 }
91 `
Colin Cross2a076922018-10-04 23:28:25 -070092}
93
94func TestGenruleCmd(t *testing.T) {
95 testcases := []struct {
96 name string
97 prop string
98
Colin Crossba71a3f2019-03-18 12:12:48 -070099 allowMissingDependencies bool
100
Colin Cross2a076922018-10-04 23:28:25 -0700101 err string
102 expect string
103 }{
104 {
105 name: "empty location tool",
106 prop: `
107 tools: ["tool"],
108 out: ["out"],
109 cmd: "$(location) > $(out)",
110 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800111 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700112 },
113 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700114 name: "empty location tool2",
115 prop: `
116 tools: [":tool"],
117 out: ["out"],
118 cmd: "$(location) > $(out)",
119 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800120 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700121 },
122 {
Colin Cross2a076922018-10-04 23:28:25 -0700123 name: "empty location tool file",
124 prop: `
125 tool_files: ["tool_file1"],
126 out: ["out"],
127 cmd: "$(location) > $(out)",
128 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800129 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700130 },
131 {
132 name: "empty location tool file fg",
133 prop: `
134 tool_files: [":1tool_file"],
135 out: ["out"],
136 cmd: "$(location) > $(out)",
137 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800138 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700139 },
140 {
141 name: "empty location tool and tool file",
142 prop: `
143 tools: ["tool"],
144 tool_files: ["tool_file1"],
145 out: ["out"],
146 cmd: "$(location) > $(out)",
147 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800148 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700149 },
150 {
151 name: "tool",
152 prop: `
153 tools: ["tool"],
154 out: ["out"],
155 cmd: "$(location tool) > $(out)",
156 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800157 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700158 },
159 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700160 name: "tool2",
161 prop: `
162 tools: [":tool"],
163 out: ["out"],
164 cmd: "$(location :tool) > $(out)",
165 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800166 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700167 },
168 {
Colin Cross2a076922018-10-04 23:28:25 -0700169 name: "tool file",
170 prop: `
171 tool_files: ["tool_file1"],
172 out: ["out"],
173 cmd: "$(location tool_file1) > $(out)",
174 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800175 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700176 },
177 {
178 name: "tool file fg",
179 prop: `
180 tool_files: [":1tool_file"],
181 out: ["out"],
Colin Cross08f15ab2018-10-04 23:29:14 -0700182 cmd: "$(location :1tool_file) > $(out)",
Colin Cross2a076922018-10-04 23:28:25 -0700183 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800184 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700185 },
186 {
187 name: "tool files",
188 prop: `
189 tool_files: [":tool_files"],
190 out: ["out"],
Colin Cross08f15ab2018-10-04 23:29:14 -0700191 cmd: "$(locations :tool_files) > $(out)",
Colin Cross2a076922018-10-04 23:28:25 -0700192 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800193 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 __SBOX_SANDBOX_DIR__/tools/src/tool_file2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700194 },
195 {
196 name: "in1",
197 prop: `
198 srcs: ["in1"],
199 out: ["out"],
200 cmd: "cat $(in) > $(out)",
201 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800202 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700203 },
204 {
205 name: "in1 fg",
206 prop: `
207 srcs: [":1in"],
208 out: ["out"],
209 cmd: "cat $(in) > $(out)",
210 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800211 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700212 },
213 {
214 name: "ins",
215 prop: `
216 srcs: ["in1", "in2"],
217 out: ["out"],
218 cmd: "cat $(in) > $(out)",
219 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800220 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700221 },
222 {
223 name: "ins fg",
224 prop: `
225 srcs: [":ins"],
226 out: ["out"],
227 cmd: "cat $(in) > $(out)",
228 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800229 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700230 },
231 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700232 name: "location in1",
233 prop: `
234 srcs: ["in1"],
235 out: ["out"],
236 cmd: "cat $(location in1) > $(out)",
237 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800238 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700239 },
240 {
241 name: "location in1 fg",
242 prop: `
243 srcs: [":1in"],
244 out: ["out"],
245 cmd: "cat $(location :1in) > $(out)",
246 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800247 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700248 },
249 {
250 name: "location ins",
251 prop: `
252 srcs: ["in1", "in2"],
253 out: ["out"],
254 cmd: "cat $(location in1) > $(out)",
255 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800256 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700257 },
258 {
259 name: "location ins fg",
260 prop: `
261 srcs: [":ins"],
262 out: ["out"],
263 cmd: "cat $(locations :ins) > $(out)",
264 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800265 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700266 },
267 {
Colin Cross2a076922018-10-04 23:28:25 -0700268 name: "outs",
269 prop: `
270 out: ["out", "out2"],
271 cmd: "echo foo > $(out)",
272 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800273 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out __SBOX_SANDBOX_DIR__/out/out2",
Colin Cross2a076922018-10-04 23:28:25 -0700274 },
275 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700276 name: "location out",
277 prop: `
278 out: ["out", "out2"],
279 cmd: "echo foo > $(location out2)",
280 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800281 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out2",
Colin Cross08f15ab2018-10-04 23:29:14 -0700282 },
283 {
Colin Cross2a076922018-10-04 23:28:25 -0700284 name: "depfile",
285 prop: `
286 out: ["out"],
287 depfile: true,
288 cmd: "echo foo > $(out) && touch $(depfile)",
289 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800290 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out && touch __SBOX_DEPFILE__",
Colin Cross2a076922018-10-04 23:28:25 -0700291 },
292 {
293 name: "gendir",
294 prop: `
295 out: ["out"],
296 cmd: "echo foo > $(genDir)/foo && cp $(genDir)/foo $(out)",
297 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800298 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/foo && cp __SBOX_SANDBOX_DIR__/out/foo __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700299 },
Colin Cross70c47412021-03-12 17:48:14 -0800300 {
301 name: "$",
302 prop: `
303 out: ["out"],
304 cmd: "echo $$ > $(out)",
305 `,
306 expect: "echo $ > __SBOX_SANDBOX_DIR__/out/out",
307 },
Colin Cross2a076922018-10-04 23:28:25 -0700308
309 {
310 name: "error empty location",
311 prop: `
312 out: ["out"],
313 cmd: "$(location) > $(out)",
314 `,
315 err: "at least one `tools` or `tool_files` is required if $(location) is used",
316 },
317 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700318 name: "error empty location no files",
319 prop: `
320 tool_files: [":empty"],
321 out: ["out"],
322 cmd: "$(location) > $(out)",
323 `,
324 err: `default label ":empty" has no files`,
325 },
326 {
327 name: "error empty location multiple files",
328 prop: `
329 tool_files: [":tool_files"],
330 out: ["out"],
331 cmd: "$(location) > $(out)",
332 `,
333 err: `default label ":tool_files" has multiple files`,
334 },
335 {
Colin Cross2a076922018-10-04 23:28:25 -0700336 name: "error location",
337 prop: `
338 out: ["out"],
339 cmd: "echo foo > $(location missing)",
340 `,
341 err: `unknown location label "missing"`,
342 },
343 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700344 name: "error locations",
345 prop: `
346 out: ["out"],
347 cmd: "echo foo > $(locations missing)",
348 `,
349 err: `unknown locations label "missing"`,
350 },
351 {
352 name: "error location no files",
353 prop: `
354 out: ["out"],
355 srcs: [":empty"],
356 cmd: "echo $(location :empty) > $(out)",
357 `,
358 err: `label ":empty" has no files`,
359 },
360 {
361 name: "error locations no files",
362 prop: `
363 out: ["out"],
364 srcs: [":empty"],
365 cmd: "echo $(locations :empty) > $(out)",
366 `,
367 err: `label ":empty" has no files`,
368 },
369 {
370 name: "error location multiple files",
371 prop: `
372 out: ["out"],
373 srcs: [":ins"],
374 cmd: "echo $(location :ins) > $(out)",
375 `,
376 err: `label ":ins" has multiple files`,
377 },
378 {
Colin Cross2a076922018-10-04 23:28:25 -0700379 name: "error variable",
380 prop: `
381 out: ["out"],
382 srcs: ["in1"],
383 cmd: "echo $(foo) > $(out)",
384 `,
385 err: `unknown variable '$(foo)'`,
386 },
387 {
388 name: "error depfile",
389 prop: `
390 out: ["out"],
391 cmd: "echo foo > $(out) && touch $(depfile)",
392 `,
393 err: "$(depfile) used without depfile property",
394 },
395 {
396 name: "error no depfile",
397 prop: `
398 out: ["out"],
399 depfile: true,
400 cmd: "echo foo > $(out)",
401 `,
402 err: "specified depfile=true but did not include a reference to '${depfile}' in cmd",
403 },
404 {
405 name: "error no out",
406 prop: `
407 cmd: "echo foo > $(out)",
408 `,
409 err: "must have at least one output file",
410 },
Colin Crossba71a3f2019-03-18 12:12:48 -0700411 {
412 name: "srcs allow missing dependencies",
413 prop: `
414 srcs: [":missing"],
415 out: ["out"],
416 cmd: "cat $(location :missing) > $(out)",
417 `,
418
419 allowMissingDependencies: true,
420
Colin Crosse16ce362020-11-12 08:29:30 -0800421 expect: "cat ***missing srcs :missing*** > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700422 },
423 {
424 name: "tool allow missing dependencies",
425 prop: `
426 tools: [":missing"],
427 out: ["out"],
428 cmd: "$(location :missing) > $(out)",
429 `,
430
431 allowMissingDependencies: true,
432
Colin Crosse16ce362020-11-12 08:29:30 -0800433 expect: "***missing tool :missing*** > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700434 },
Colin Cross2a076922018-10-04 23:28:25 -0700435 }
436
437 for _, test := range testcases {
438 t.Run(test.name, func(t *testing.T) {
Colin Cross2a076922018-10-04 23:28:25 -0700439 bp := "genrule {\n"
440 bp += "name: \"gen\",\n"
441 bp += test.prop
442 bp += "}\n"
443
Paul Duffin672cb9f2021-03-03 02:30:37 +0000444 var expectedErrors []string
445 if test.err != "" {
446 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross2a076922018-10-04 23:28:25 -0700447 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000448
Paul Duffin89648f92021-03-20 00:36:55 +0000449 result := android.GroupFixturePreparers(
450 prepareForGenRuleTest,
Paul Duffin672cb9f2021-03-03 02:30:37 +0000451 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
452 variables.Allow_missing_dependencies = proptools.BoolPtr(test.allowMissingDependencies)
453 }),
454 android.FixtureModifyContext(func(ctx *android.TestContext) {
455 ctx.SetAllowMissingDependencies(test.allowMissingDependencies)
456 }),
457 ).
458 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
459 RunTestWithBp(t, testGenruleBp()+bp)
460
461 if expectedErrors != nil {
Colin Cross2a076922018-10-04 23:28:25 -0700462 return
463 }
464
Paul Duffin672cb9f2021-03-03 02:30:37 +0000465 gen := result.Module("gen", "").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +0000466 android.AssertStringEquals(t, "raw commands", test.expect, gen.rawCommands[0])
Colin Cross2a076922018-10-04 23:28:25 -0700467 })
468 }
Colin Cross1a527682019-09-23 15:55:30 -0700469}
470
Bill Peckhamc087be12020-02-13 15:55:10 -0800471func TestGenruleHashInputs(t *testing.T) {
472
473 // The basic idea here is to verify that the sbox command (which is
474 // in the Command field of the generate rule) contains a hash of the
475 // inputs, but only if $(in) is not referenced in the genrule cmd
476 // property.
477
478 // By including a hash of the inputs, we cause the rule to re-run if
479 // the list of inputs changes (because the sbox command changes).
480
481 // However, if the genrule cmd property already contains $(in), then
482 // the dependency is already expressed, so we don't need to include the
483 // hash in that case.
484
485 bp := `
486 genrule {
487 name: "hash0",
488 srcs: ["in1.txt", "in2.txt"],
489 out: ["out"],
490 cmd: "echo foo > $(out)",
491 }
492 genrule {
493 name: "hash1",
494 srcs: ["*.txt"],
495 out: ["out"],
496 cmd: "echo bar > $(out)",
497 }
498 genrule {
499 name: "hash2",
500 srcs: ["*.txt"],
501 out: ["out"],
502 cmd: "echo $(in) > $(out)",
503 }
504 `
505 testcases := []struct {
506 name string
507 expectedHash string
508 }{
509 {
510 name: "hash0",
Colin Cross3d680512020-11-13 16:23:53 -0800511 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt' | sha256sum
512 expectedHash: "18da75b9b1cc74b09e365b4ca2e321b5d618f438cc632b387ad9dc2ab4b20e9d",
Bill Peckhamc087be12020-02-13 15:55:10 -0800513 },
514 {
515 name: "hash1",
Colin Cross3d680512020-11-13 16:23:53 -0800516 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
517 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
Bill Peckhamc087be12020-02-13 15:55:10 -0800518 },
519 {
520 name: "hash2",
Colin Cross3d680512020-11-13 16:23:53 -0800521 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
522 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
Bill Peckhamc087be12020-02-13 15:55:10 -0800523 },
524 }
525
Paul Duffin89648f92021-03-20 00:36:55 +0000526 result := prepareForGenRuleTest.RunTestWithBp(t, testGenruleBp()+bp)
Bill Peckhamc087be12020-02-13 15:55:10 -0800527
528 for _, test := range testcases {
529 t.Run(test.name, func(t *testing.T) {
Paul Duffine84b1332021-03-12 11:59:43 +0000530 gen := result.ModuleForTests(test.name, "")
Colin Crosse16ce362020-11-12 08:29:30 -0800531 manifest := android.RuleBuilderSboxProtoForTests(t, gen.Output("genrule.sbox.textproto"))
532 hash := manifest.Commands[0].GetInputHash()
Bill Peckhamc087be12020-02-13 15:55:10 -0800533
Paul Duffine84b1332021-03-12 11:59:43 +0000534 android.AssertStringEquals(t, "hash", test.expectedHash, hash)
Bill Peckhamc087be12020-02-13 15:55:10 -0800535 })
536 }
537}
538
Colin Cross1a527682019-09-23 15:55:30 -0700539func TestGenSrcs(t *testing.T) {
540 testcases := []struct {
541 name string
542 prop string
543
544 allowMissingDependencies bool
545
546 err string
547 cmds []string
548 deps []string
549 files []string
550 }{
551 {
552 name: "gensrcs",
553 prop: `
554 tools: ["tool"],
555 srcs: ["in1.txt", "in2.txt"],
556 cmd: "$(location) $(in) > $(out)",
557 `,
558 cmds: []string{
Colin Crossba9e4032020-11-24 16:32:22 -0800559 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in1.txt > __SBOX_SANDBOX_DIR__/out/in1.h' && bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in2.txt > __SBOX_SANDBOX_DIR__/out/in2.h'",
Colin Cross1a527682019-09-23 15:55:30 -0700560 },
Paul Duffine66946b2021-03-16 12:38:33 +0000561 deps: []string{
562 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
563 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
564 },
565 files: []string{
566 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
567 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
568 },
Colin Cross1a527682019-09-23 15:55:30 -0700569 },
570 {
571 name: "shards",
572 prop: `
573 tools: ["tool"],
574 srcs: ["in1.txt", "in2.txt", "in3.txt"],
575 cmd: "$(location) $(in) > $(out)",
576 shard_size: 2,
577 `,
578 cmds: []string{
Colin Crossba9e4032020-11-24 16:32:22 -0800579 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in1.txt > __SBOX_SANDBOX_DIR__/out/in1.h' && bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in2.txt > __SBOX_SANDBOX_DIR__/out/in2.h'",
580 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in3.txt > __SBOX_SANDBOX_DIR__/out/in3.h'",
Colin Cross1a527682019-09-23 15:55:30 -0700581 },
Paul Duffine66946b2021-03-16 12:38:33 +0000582 deps: []string{
583 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
584 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
585 "out/soong/.intermediates/gen/gen/gensrcs/in3.h",
586 },
587 files: []string{
588 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
589 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
590 "out/soong/.intermediates/gen/gen/gensrcs/in3.h",
591 },
Colin Cross1a527682019-09-23 15:55:30 -0700592 },
593 }
594
595 for _, test := range testcases {
596 t.Run(test.name, func(t *testing.T) {
Colin Cross1a527682019-09-23 15:55:30 -0700597 bp := "gensrcs {\n"
598 bp += `name: "gen",` + "\n"
599 bp += `output_extension: "h",` + "\n"
600 bp += test.prop
601 bp += "}\n"
602
Paul Duffin672cb9f2021-03-03 02:30:37 +0000603 var expectedErrors []string
604 if test.err != "" {
605 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross1a527682019-09-23 15:55:30 -0700606 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000607
Paul Duffin89648f92021-03-20 00:36:55 +0000608 result := prepareForGenRuleTest.
Paul Duffin672cb9f2021-03-03 02:30:37 +0000609 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
610 RunTestWithBp(t, testGenruleBp()+bp)
611
612 if expectedErrors != nil {
Colin Cross1a527682019-09-23 15:55:30 -0700613 return
614 }
615
Paul Duffin672cb9f2021-03-03 02:30:37 +0000616 gen := result.Module("gen", "").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +0000617 android.AssertDeepEquals(t, "cmd", test.cmds, gen.rawCommands)
Colin Cross1a527682019-09-23 15:55:30 -0700618
Paul Duffine66946b2021-03-16 12:38:33 +0000619 android.AssertPathsRelativeToTopEquals(t, "deps", test.deps, gen.outputDeps)
Colin Cross1a527682019-09-23 15:55:30 -0700620
Paul Duffine66946b2021-03-16 12:38:33 +0000621 android.AssertPathsRelativeToTopEquals(t, "files", test.files, gen.outputFiles)
Colin Cross1a527682019-09-23 15:55:30 -0700622 })
623 }
Colin Cross2a076922018-10-04 23:28:25 -0700624}
625
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800626func TestGenruleDefaults(t *testing.T) {
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800627 bp := `
628 genrule_defaults {
629 name: "gen_defaults1",
630 cmd: "cp $(in) $(out)",
631 }
632
633 genrule_defaults {
634 name: "gen_defaults2",
635 srcs: ["in1"],
636 }
637
638 genrule {
639 name: "gen",
640 out: ["out"],
641 defaults: ["gen_defaults1", "gen_defaults2"],
642 }
643 `
Paul Duffin672cb9f2021-03-03 02:30:37 +0000644
Paul Duffin89648f92021-03-20 00:36:55 +0000645 result := prepareForGenRuleTest.RunTestWithBp(t, testGenruleBp()+bp)
Paul Duffin672cb9f2021-03-03 02:30:37 +0000646
647 gen := result.Module("gen", "").(*Module)
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800648
Colin Crosse16ce362020-11-12 08:29:30 -0800649 expectedCmd := "cp in1 __SBOX_SANDBOX_DIR__/out/out"
Paul Duffine84b1332021-03-12 11:59:43 +0000650 android.AssertStringEquals(t, "cmd", expectedCmd, gen.rawCommands[0])
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800651
652 expectedSrcs := []string{"in1"}
Paul Duffine84b1332021-03-12 11:59:43 +0000653 android.AssertDeepEquals(t, "srcs", expectedSrcs, gen.properties.Srcs)
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800654}
655
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400656func TestGenruleWithBazel(t *testing.T) {
657 bp := `
658 genrule {
659 name: "foo",
660 out: ["one.txt", "two.txt"],
Chris Parsonsaa8be052020-10-14 16:22:37 -0400661 bazel_module: { label: "//foo/bar:bar" },
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400662 }
663 `
664
Paul Duffin89648f92021-03-20 00:36:55 +0000665 result := android.GroupFixturePreparers(
666 prepareForGenRuleTest, android.FixtureModifyConfig(func(config android.Config) {
667 config.BazelContext = android.MockBazelContext{
668 AllFiles: map[string][]string{
669 "//foo/bar:bar": []string{"bazelone.txt", "bazeltwo.txt"}}}
670 })).RunTestWithBp(t, testGenruleBp()+bp)
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400671
Paul Duffin672cb9f2021-03-03 02:30:37 +0000672 gen := result.Module("foo", "").(*Module)
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400673
Chris Parsonsdbcb1ff2020-12-10 17:19:18 -0500674 expectedOutputFiles := []string{"outputbase/execroot/__main__/bazelone.txt",
675 "outputbase/execroot/__main__/bazeltwo.txt"}
Paul Duffine84b1332021-03-12 11:59:43 +0000676 android.AssertDeepEquals(t, "output files", expectedOutputFiles, gen.outputFiles.Strings())
677 android.AssertDeepEquals(t, "output deps", expectedOutputFiles, gen.outputDeps.Strings())
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400678}
679
Colin Cross2a076922018-10-04 23:28:25 -0700680type testTool struct {
681 android.ModuleBase
682 outputFile android.Path
683}
684
685func toolFactory() android.Module {
686 module := &testTool{}
687 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
688 return module
689}
690
Colin Cross2a076922018-10-04 23:28:25 -0700691func (t *testTool) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crossba9e4032020-11-24 16:32:22 -0800692 t.outputFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), android.PathForOutput(ctx, ctx.ModuleName()))
Colin Cross2a076922018-10-04 23:28:25 -0700693}
694
695func (t *testTool) HostToolPath() android.OptionalPath {
696 return android.OptionalPathForPath(t.outputFile)
697}
698
Colin Crossfe17f6f2019-03-28 19:30:56 -0700699var _ android.HostToolProvider = (*testTool)(nil)