blob: 199a7df7b9b7143cb01d3001d87010493fe1b078 [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 Duffin672cb9f2021-03-03 02:30:37 +000031var genruleFixtureFactory = android.NewFixtureFactory(
Paul Duffine66946b2021-03-16 12:38:33 +000032 nil,
Paul Duffin672cb9f2021-03-03 02:30:37 +000033 android.PrepareForTestWithArchMutator,
34 android.PrepareForTestWithDefaults,
Colin Cross2a076922018-10-04 23:28:25 -070035
Paul Duffin672cb9f2021-03-03 02:30:37 +000036 android.PrepareForTestWithFilegroup,
37 PrepareForTestWithGenRuleBuildComponents,
38 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
39 ctx.RegisterModuleType("tool", toolFactory)
40 }),
41 android.FixtureMergeMockFs(android.MockFS{
42 "tool": nil,
43 "tool_file1": nil,
44 "tool_file2": nil,
45 "in1": nil,
46 "in2": nil,
47 "in1.txt": nil,
48 "in2.txt": nil,
49 "in3.txt": nil,
50 }),
51)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000052
Paul Duffin672cb9f2021-03-03 02:30:37 +000053func testGenruleBp() string {
54 return `
Colin Cross2a076922018-10-04 23:28:25 -070055 tool {
56 name: "tool",
57 }
58
59 filegroup {
60 name: "tool_files",
61 srcs: [
62 "tool_file1",
63 "tool_file2",
64 ],
65 }
66
67 filegroup {
68 name: "1tool_file",
69 srcs: [
70 "tool_file1",
71 ],
72 }
73
74 filegroup {
75 name: "ins",
76 srcs: [
77 "in1",
78 "in2",
79 ],
80 }
81
82 filegroup {
83 name: "1in",
84 srcs: [
85 "in1",
86 ],
87 }
88
89 filegroup {
90 name: "empty",
91 }
92 `
Colin Cross2a076922018-10-04 23:28:25 -070093}
94
95func TestGenruleCmd(t *testing.T) {
96 testcases := []struct {
97 name string
98 prop string
99
Colin Crossba71a3f2019-03-18 12:12:48 -0700100 allowMissingDependencies bool
101
Colin Cross2a076922018-10-04 23:28:25 -0700102 err string
103 expect string
104 }{
105 {
106 name: "empty location tool",
107 prop: `
108 tools: ["tool"],
109 out: ["out"],
110 cmd: "$(location) > $(out)",
111 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800112 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700113 },
114 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700115 name: "empty location tool2",
116 prop: `
117 tools: [":tool"],
118 out: ["out"],
119 cmd: "$(location) > $(out)",
120 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800121 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700122 },
123 {
Colin Cross2a076922018-10-04 23:28:25 -0700124 name: "empty location tool file",
125 prop: `
126 tool_files: ["tool_file1"],
127 out: ["out"],
128 cmd: "$(location) > $(out)",
129 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800130 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700131 },
132 {
133 name: "empty location tool file fg",
134 prop: `
135 tool_files: [":1tool_file"],
136 out: ["out"],
137 cmd: "$(location) > $(out)",
138 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800139 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700140 },
141 {
142 name: "empty location tool and tool file",
143 prop: `
144 tools: ["tool"],
145 tool_files: ["tool_file1"],
146 out: ["out"],
147 cmd: "$(location) > $(out)",
148 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800149 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700150 },
151 {
152 name: "tool",
153 prop: `
154 tools: ["tool"],
155 out: ["out"],
156 cmd: "$(location tool) > $(out)",
157 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800158 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700159 },
160 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700161 name: "tool2",
162 prop: `
163 tools: [":tool"],
164 out: ["out"],
165 cmd: "$(location :tool) > $(out)",
166 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800167 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700168 },
169 {
Colin Cross2a076922018-10-04 23:28:25 -0700170 name: "tool file",
171 prop: `
172 tool_files: ["tool_file1"],
173 out: ["out"],
174 cmd: "$(location tool_file1) > $(out)",
175 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800176 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700177 },
178 {
179 name: "tool file fg",
180 prop: `
181 tool_files: [":1tool_file"],
182 out: ["out"],
Colin Cross08f15ab2018-10-04 23:29:14 -0700183 cmd: "$(location :1tool_file) > $(out)",
Colin Cross2a076922018-10-04 23:28:25 -0700184 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800185 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700186 },
187 {
188 name: "tool files",
189 prop: `
190 tool_files: [":tool_files"],
191 out: ["out"],
Colin Cross08f15ab2018-10-04 23:29:14 -0700192 cmd: "$(locations :tool_files) > $(out)",
Colin Cross2a076922018-10-04 23:28:25 -0700193 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800194 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 -0700195 },
196 {
197 name: "in1",
198 prop: `
199 srcs: ["in1"],
200 out: ["out"],
201 cmd: "cat $(in) > $(out)",
202 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800203 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700204 },
205 {
206 name: "in1 fg",
207 prop: `
208 srcs: [":1in"],
209 out: ["out"],
210 cmd: "cat $(in) > $(out)",
211 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800212 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700213 },
214 {
215 name: "ins",
216 prop: `
217 srcs: ["in1", "in2"],
218 out: ["out"],
219 cmd: "cat $(in) > $(out)",
220 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800221 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700222 },
223 {
224 name: "ins fg",
225 prop: `
226 srcs: [":ins"],
227 out: ["out"],
228 cmd: "cat $(in) > $(out)",
229 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800230 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700231 },
232 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700233 name: "location in1",
234 prop: `
235 srcs: ["in1"],
236 out: ["out"],
237 cmd: "cat $(location in1) > $(out)",
238 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800239 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700240 },
241 {
242 name: "location in1 fg",
243 prop: `
244 srcs: [":1in"],
245 out: ["out"],
246 cmd: "cat $(location :1in) > $(out)",
247 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800248 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700249 },
250 {
251 name: "location ins",
252 prop: `
253 srcs: ["in1", "in2"],
254 out: ["out"],
255 cmd: "cat $(location in1) > $(out)",
256 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800257 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700258 },
259 {
260 name: "location ins fg",
261 prop: `
262 srcs: [":ins"],
263 out: ["out"],
264 cmd: "cat $(locations :ins) > $(out)",
265 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800266 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700267 },
268 {
Colin Cross2a076922018-10-04 23:28:25 -0700269 name: "outs",
270 prop: `
271 out: ["out", "out2"],
272 cmd: "echo foo > $(out)",
273 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800274 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out __SBOX_SANDBOX_DIR__/out/out2",
Colin Cross2a076922018-10-04 23:28:25 -0700275 },
276 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700277 name: "location out",
278 prop: `
279 out: ["out", "out2"],
280 cmd: "echo foo > $(location out2)",
281 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800282 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out2",
Colin Cross08f15ab2018-10-04 23:29:14 -0700283 },
284 {
Colin Cross2a076922018-10-04 23:28:25 -0700285 name: "depfile",
286 prop: `
287 out: ["out"],
288 depfile: true,
289 cmd: "echo foo > $(out) && touch $(depfile)",
290 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800291 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out && touch __SBOX_DEPFILE__",
Colin Cross2a076922018-10-04 23:28:25 -0700292 },
293 {
294 name: "gendir",
295 prop: `
296 out: ["out"],
297 cmd: "echo foo > $(genDir)/foo && cp $(genDir)/foo $(out)",
298 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800299 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 -0700300 },
Colin Cross70c47412021-03-12 17:48:14 -0800301 {
302 name: "$",
303 prop: `
304 out: ["out"],
305 cmd: "echo $$ > $(out)",
306 `,
307 expect: "echo $ > __SBOX_SANDBOX_DIR__/out/out",
308 },
Colin Cross2a076922018-10-04 23:28:25 -0700309
310 {
311 name: "error empty location",
312 prop: `
313 out: ["out"],
314 cmd: "$(location) > $(out)",
315 `,
316 err: "at least one `tools` or `tool_files` is required if $(location) is used",
317 },
318 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700319 name: "error empty location no files",
320 prop: `
321 tool_files: [":empty"],
322 out: ["out"],
323 cmd: "$(location) > $(out)",
324 `,
325 err: `default label ":empty" has no files`,
326 },
327 {
328 name: "error empty location multiple files",
329 prop: `
330 tool_files: [":tool_files"],
331 out: ["out"],
332 cmd: "$(location) > $(out)",
333 `,
334 err: `default label ":tool_files" has multiple files`,
335 },
336 {
Colin Cross2a076922018-10-04 23:28:25 -0700337 name: "error location",
338 prop: `
339 out: ["out"],
340 cmd: "echo foo > $(location missing)",
341 `,
342 err: `unknown location label "missing"`,
343 },
344 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700345 name: "error locations",
346 prop: `
347 out: ["out"],
348 cmd: "echo foo > $(locations missing)",
349 `,
350 err: `unknown locations label "missing"`,
351 },
352 {
353 name: "error location no files",
354 prop: `
355 out: ["out"],
356 srcs: [":empty"],
357 cmd: "echo $(location :empty) > $(out)",
358 `,
359 err: `label ":empty" has no files`,
360 },
361 {
362 name: "error locations no files",
363 prop: `
364 out: ["out"],
365 srcs: [":empty"],
366 cmd: "echo $(locations :empty) > $(out)",
367 `,
368 err: `label ":empty" has no files`,
369 },
370 {
371 name: "error location multiple files",
372 prop: `
373 out: ["out"],
374 srcs: [":ins"],
375 cmd: "echo $(location :ins) > $(out)",
376 `,
377 err: `label ":ins" has multiple files`,
378 },
379 {
Colin Cross2a076922018-10-04 23:28:25 -0700380 name: "error variable",
381 prop: `
382 out: ["out"],
383 srcs: ["in1"],
384 cmd: "echo $(foo) > $(out)",
385 `,
386 err: `unknown variable '$(foo)'`,
387 },
388 {
389 name: "error depfile",
390 prop: `
391 out: ["out"],
392 cmd: "echo foo > $(out) && touch $(depfile)",
393 `,
394 err: "$(depfile) used without depfile property",
395 },
396 {
397 name: "error no depfile",
398 prop: `
399 out: ["out"],
400 depfile: true,
401 cmd: "echo foo > $(out)",
402 `,
403 err: "specified depfile=true but did not include a reference to '${depfile}' in cmd",
404 },
405 {
406 name: "error no out",
407 prop: `
408 cmd: "echo foo > $(out)",
409 `,
410 err: "must have at least one output file",
411 },
Colin Crossba71a3f2019-03-18 12:12:48 -0700412 {
413 name: "srcs allow missing dependencies",
414 prop: `
415 srcs: [":missing"],
416 out: ["out"],
417 cmd: "cat $(location :missing) > $(out)",
418 `,
419
420 allowMissingDependencies: true,
421
Colin Crosse16ce362020-11-12 08:29:30 -0800422 expect: "cat ***missing srcs :missing*** > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700423 },
424 {
425 name: "tool allow missing dependencies",
426 prop: `
427 tools: [":missing"],
428 out: ["out"],
429 cmd: "$(location :missing) > $(out)",
430 `,
431
432 allowMissingDependencies: true,
433
Colin Crosse16ce362020-11-12 08:29:30 -0800434 expect: "***missing tool :missing*** > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700435 },
Colin Cross2a076922018-10-04 23:28:25 -0700436 }
437
438 for _, test := range testcases {
439 t.Run(test.name, func(t *testing.T) {
Colin Cross2a076922018-10-04 23:28:25 -0700440 bp := "genrule {\n"
441 bp += "name: \"gen\",\n"
442 bp += test.prop
443 bp += "}\n"
444
Paul Duffin672cb9f2021-03-03 02:30:37 +0000445 var expectedErrors []string
446 if test.err != "" {
447 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross2a076922018-10-04 23:28:25 -0700448 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000449
450 result := genruleFixtureFactory.Extend(
451 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 Duffin672cb9f2021-03-03 02:30:37 +0000526 result := genruleFixtureFactory.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
608 result := genruleFixtureFactory.
609 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
645 result := genruleFixtureFactory.RunTestWithBp(t, testGenruleBp()+bp)
646
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 Duffin672cb9f2021-03-03 02:30:37 +0000665 result := genruleFixtureFactory.Extend(android.FixtureModifyConfig(func(config android.Config) {
666 config.BazelContext = android.MockBazelContext{
667 AllFiles: map[string][]string{
668 "//foo/bar:bar": []string{"bazelone.txt", "bazeltwo.txt"}}}
669 })).RunTestWithBp(t, testGenruleBp()+bp)
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400670
Paul Duffin672cb9f2021-03-03 02:30:37 +0000671 gen := result.Module("foo", "").(*Module)
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400672
Chris Parsonsdbcb1ff2020-12-10 17:19:18 -0500673 expectedOutputFiles := []string{"outputbase/execroot/__main__/bazelone.txt",
674 "outputbase/execroot/__main__/bazeltwo.txt"}
Paul Duffine84b1332021-03-12 11:59:43 +0000675 android.AssertDeepEquals(t, "output files", expectedOutputFiles, gen.outputFiles.Strings())
676 android.AssertDeepEquals(t, "output deps", expectedOutputFiles, gen.outputDeps.Strings())
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400677}
678
Colin Cross2a076922018-10-04 23:28:25 -0700679type testTool struct {
680 android.ModuleBase
681 outputFile android.Path
682}
683
684func toolFactory() android.Module {
685 module := &testTool{}
686 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
687 return module
688}
689
Colin Cross2a076922018-10-04 23:28:25 -0700690func (t *testTool) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crossba9e4032020-11-24 16:32:22 -0800691 t.outputFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), android.PathForOutput(ctx, ctx.ModuleName()))
Colin Cross2a076922018-10-04 23:28:25 -0700692}
693
694func (t *testTool) HostToolPath() android.OptionalPath {
695 return android.OptionalPathForPath(t.outputFile)
696}
697
Colin Crossfe17f6f2019-03-28 19:30:56 -0700698var _ android.HostToolProvider = (*testTool)(nil)