blob: d131e94f9f3aba1ad96004a12308dc725a9a21e4 [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 },
301
302 {
303 name: "error empty location",
304 prop: `
305 out: ["out"],
306 cmd: "$(location) > $(out)",
307 `,
308 err: "at least one `tools` or `tool_files` is required if $(location) is used",
309 },
310 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700311 name: "error empty location no files",
312 prop: `
313 tool_files: [":empty"],
314 out: ["out"],
315 cmd: "$(location) > $(out)",
316 `,
317 err: `default label ":empty" has no files`,
318 },
319 {
320 name: "error empty location multiple files",
321 prop: `
322 tool_files: [":tool_files"],
323 out: ["out"],
324 cmd: "$(location) > $(out)",
325 `,
326 err: `default label ":tool_files" has multiple files`,
327 },
328 {
Colin Cross2a076922018-10-04 23:28:25 -0700329 name: "error location",
330 prop: `
331 out: ["out"],
332 cmd: "echo foo > $(location missing)",
333 `,
334 err: `unknown location label "missing"`,
335 },
336 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700337 name: "error locations",
338 prop: `
339 out: ["out"],
340 cmd: "echo foo > $(locations missing)",
341 `,
342 err: `unknown locations label "missing"`,
343 },
344 {
345 name: "error location no files",
346 prop: `
347 out: ["out"],
348 srcs: [":empty"],
349 cmd: "echo $(location :empty) > $(out)",
350 `,
351 err: `label ":empty" has no files`,
352 },
353 {
354 name: "error locations no files",
355 prop: `
356 out: ["out"],
357 srcs: [":empty"],
358 cmd: "echo $(locations :empty) > $(out)",
359 `,
360 err: `label ":empty" has no files`,
361 },
362 {
363 name: "error location multiple files",
364 prop: `
365 out: ["out"],
366 srcs: [":ins"],
367 cmd: "echo $(location :ins) > $(out)",
368 `,
369 err: `label ":ins" has multiple files`,
370 },
371 {
Colin Cross2a076922018-10-04 23:28:25 -0700372 name: "error variable",
373 prop: `
374 out: ["out"],
375 srcs: ["in1"],
376 cmd: "echo $(foo) > $(out)",
377 `,
378 err: `unknown variable '$(foo)'`,
379 },
380 {
381 name: "error depfile",
382 prop: `
383 out: ["out"],
384 cmd: "echo foo > $(out) && touch $(depfile)",
385 `,
386 err: "$(depfile) used without depfile property",
387 },
388 {
389 name: "error no depfile",
390 prop: `
391 out: ["out"],
392 depfile: true,
393 cmd: "echo foo > $(out)",
394 `,
395 err: "specified depfile=true but did not include a reference to '${depfile}' in cmd",
396 },
397 {
398 name: "error no out",
399 prop: `
400 cmd: "echo foo > $(out)",
401 `,
402 err: "must have at least one output file",
403 },
Colin Crossba71a3f2019-03-18 12:12:48 -0700404 {
405 name: "srcs allow missing dependencies",
406 prop: `
407 srcs: [":missing"],
408 out: ["out"],
409 cmd: "cat $(location :missing) > $(out)",
410 `,
411
412 allowMissingDependencies: true,
413
Colin Crosse16ce362020-11-12 08:29:30 -0800414 expect: "cat ***missing srcs :missing*** > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700415 },
416 {
417 name: "tool allow missing dependencies",
418 prop: `
419 tools: [":missing"],
420 out: ["out"],
421 cmd: "$(location :missing) > $(out)",
422 `,
423
424 allowMissingDependencies: true,
425
Colin Crosse16ce362020-11-12 08:29:30 -0800426 expect: "***missing tool :missing*** > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700427 },
Colin Cross2a076922018-10-04 23:28:25 -0700428 }
429
430 for _, test := range testcases {
431 t.Run(test.name, func(t *testing.T) {
Colin Cross2a076922018-10-04 23:28:25 -0700432 bp := "genrule {\n"
433 bp += "name: \"gen\",\n"
434 bp += test.prop
435 bp += "}\n"
436
Paul Duffin672cb9f2021-03-03 02:30:37 +0000437 var expectedErrors []string
438 if test.err != "" {
439 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross2a076922018-10-04 23:28:25 -0700440 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000441
442 result := genruleFixtureFactory.Extend(
443 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
444 variables.Allow_missing_dependencies = proptools.BoolPtr(test.allowMissingDependencies)
445 }),
446 android.FixtureModifyContext(func(ctx *android.TestContext) {
447 ctx.SetAllowMissingDependencies(test.allowMissingDependencies)
448 }),
449 ).
450 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
451 RunTestWithBp(t, testGenruleBp()+bp)
452
453 if expectedErrors != nil {
Colin Cross2a076922018-10-04 23:28:25 -0700454 return
455 }
456
Paul Duffin672cb9f2021-03-03 02:30:37 +0000457 gen := result.Module("gen", "").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +0000458 android.AssertStringEquals(t, "raw commands", test.expect, gen.rawCommands[0])
Colin Cross2a076922018-10-04 23:28:25 -0700459 })
460 }
Colin Cross1a527682019-09-23 15:55:30 -0700461}
462
Bill Peckhamc087be12020-02-13 15:55:10 -0800463func TestGenruleHashInputs(t *testing.T) {
464
465 // The basic idea here is to verify that the sbox command (which is
466 // in the Command field of the generate rule) contains a hash of the
467 // inputs, but only if $(in) is not referenced in the genrule cmd
468 // property.
469
470 // By including a hash of the inputs, we cause the rule to re-run if
471 // the list of inputs changes (because the sbox command changes).
472
473 // However, if the genrule cmd property already contains $(in), then
474 // the dependency is already expressed, so we don't need to include the
475 // hash in that case.
476
477 bp := `
478 genrule {
479 name: "hash0",
480 srcs: ["in1.txt", "in2.txt"],
481 out: ["out"],
482 cmd: "echo foo > $(out)",
483 }
484 genrule {
485 name: "hash1",
486 srcs: ["*.txt"],
487 out: ["out"],
488 cmd: "echo bar > $(out)",
489 }
490 genrule {
491 name: "hash2",
492 srcs: ["*.txt"],
493 out: ["out"],
494 cmd: "echo $(in) > $(out)",
495 }
496 `
497 testcases := []struct {
498 name string
499 expectedHash string
500 }{
501 {
502 name: "hash0",
Colin Cross3d680512020-11-13 16:23:53 -0800503 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt' | sha256sum
504 expectedHash: "18da75b9b1cc74b09e365b4ca2e321b5d618f438cc632b387ad9dc2ab4b20e9d",
Bill Peckhamc087be12020-02-13 15:55:10 -0800505 },
506 {
507 name: "hash1",
Colin Cross3d680512020-11-13 16:23:53 -0800508 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
509 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
Bill Peckhamc087be12020-02-13 15:55:10 -0800510 },
511 {
512 name: "hash2",
Colin Cross3d680512020-11-13 16:23:53 -0800513 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
514 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
Bill Peckhamc087be12020-02-13 15:55:10 -0800515 },
516 }
517
Paul Duffin672cb9f2021-03-03 02:30:37 +0000518 result := genruleFixtureFactory.RunTestWithBp(t, testGenruleBp()+bp)
Bill Peckhamc087be12020-02-13 15:55:10 -0800519
520 for _, test := range testcases {
521 t.Run(test.name, func(t *testing.T) {
Paul Duffine84b1332021-03-12 11:59:43 +0000522 gen := result.ModuleForTests(test.name, "")
Colin Crosse16ce362020-11-12 08:29:30 -0800523 manifest := android.RuleBuilderSboxProtoForTests(t, gen.Output("genrule.sbox.textproto"))
524 hash := manifest.Commands[0].GetInputHash()
Bill Peckhamc087be12020-02-13 15:55:10 -0800525
Paul Duffine84b1332021-03-12 11:59:43 +0000526 android.AssertStringEquals(t, "hash", test.expectedHash, hash)
Bill Peckhamc087be12020-02-13 15:55:10 -0800527 })
528 }
529}
530
Colin Cross1a527682019-09-23 15:55:30 -0700531func TestGenSrcs(t *testing.T) {
532 testcases := []struct {
533 name string
534 prop string
535
536 allowMissingDependencies bool
537
538 err string
539 cmds []string
540 deps []string
541 files []string
542 }{
543 {
544 name: "gensrcs",
545 prop: `
546 tools: ["tool"],
547 srcs: ["in1.txt", "in2.txt"],
548 cmd: "$(location) $(in) > $(out)",
549 `,
550 cmds: []string{
Colin Crossba9e4032020-11-24 16:32:22 -0800551 "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 -0700552 },
Paul Duffine66946b2021-03-16 12:38:33 +0000553 deps: []string{
554 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
555 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
556 },
557 files: []string{
558 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
559 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
560 },
Colin Cross1a527682019-09-23 15:55:30 -0700561 },
562 {
563 name: "shards",
564 prop: `
565 tools: ["tool"],
566 srcs: ["in1.txt", "in2.txt", "in3.txt"],
567 cmd: "$(location) $(in) > $(out)",
568 shard_size: 2,
569 `,
570 cmds: []string{
Colin Crossba9e4032020-11-24 16:32:22 -0800571 "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'",
572 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in3.txt > __SBOX_SANDBOX_DIR__/out/in3.h'",
Colin Cross1a527682019-09-23 15:55:30 -0700573 },
Paul Duffine66946b2021-03-16 12:38:33 +0000574 deps: []string{
575 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
576 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
577 "out/soong/.intermediates/gen/gen/gensrcs/in3.h",
578 },
579 files: []string{
580 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
581 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
582 "out/soong/.intermediates/gen/gen/gensrcs/in3.h",
583 },
Colin Cross1a527682019-09-23 15:55:30 -0700584 },
585 }
586
587 for _, test := range testcases {
588 t.Run(test.name, func(t *testing.T) {
Colin Cross1a527682019-09-23 15:55:30 -0700589 bp := "gensrcs {\n"
590 bp += `name: "gen",` + "\n"
591 bp += `output_extension: "h",` + "\n"
592 bp += test.prop
593 bp += "}\n"
594
Paul Duffin672cb9f2021-03-03 02:30:37 +0000595 var expectedErrors []string
596 if test.err != "" {
597 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross1a527682019-09-23 15:55:30 -0700598 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000599
600 result := genruleFixtureFactory.
601 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
602 RunTestWithBp(t, testGenruleBp()+bp)
603
604 if expectedErrors != nil {
Colin Cross1a527682019-09-23 15:55:30 -0700605 return
606 }
607
Paul Duffin672cb9f2021-03-03 02:30:37 +0000608 gen := result.Module("gen", "").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +0000609 android.AssertDeepEquals(t, "cmd", test.cmds, gen.rawCommands)
Colin Cross1a527682019-09-23 15:55:30 -0700610
Paul Duffine66946b2021-03-16 12:38:33 +0000611 android.AssertPathsRelativeToTopEquals(t, "deps", test.deps, gen.outputDeps)
Colin Cross1a527682019-09-23 15:55:30 -0700612
Paul Duffine66946b2021-03-16 12:38:33 +0000613 android.AssertPathsRelativeToTopEquals(t, "files", test.files, gen.outputFiles)
Colin Cross1a527682019-09-23 15:55:30 -0700614 })
615 }
Colin Cross2a076922018-10-04 23:28:25 -0700616}
617
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800618func TestGenruleDefaults(t *testing.T) {
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800619 bp := `
620 genrule_defaults {
621 name: "gen_defaults1",
622 cmd: "cp $(in) $(out)",
623 }
624
625 genrule_defaults {
626 name: "gen_defaults2",
627 srcs: ["in1"],
628 }
629
630 genrule {
631 name: "gen",
632 out: ["out"],
633 defaults: ["gen_defaults1", "gen_defaults2"],
634 }
635 `
Paul Duffin672cb9f2021-03-03 02:30:37 +0000636
637 result := genruleFixtureFactory.RunTestWithBp(t, testGenruleBp()+bp)
638
639 gen := result.Module("gen", "").(*Module)
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800640
Colin Crosse16ce362020-11-12 08:29:30 -0800641 expectedCmd := "cp in1 __SBOX_SANDBOX_DIR__/out/out"
Paul Duffine84b1332021-03-12 11:59:43 +0000642 android.AssertStringEquals(t, "cmd", expectedCmd, gen.rawCommands[0])
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800643
644 expectedSrcs := []string{"in1"}
Paul Duffine84b1332021-03-12 11:59:43 +0000645 android.AssertDeepEquals(t, "srcs", expectedSrcs, gen.properties.Srcs)
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800646}
647
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400648func TestGenruleWithBazel(t *testing.T) {
649 bp := `
650 genrule {
651 name: "foo",
652 out: ["one.txt", "two.txt"],
Chris Parsonsaa8be052020-10-14 16:22:37 -0400653 bazel_module: { label: "//foo/bar:bar" },
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400654 }
655 `
656
Paul Duffin672cb9f2021-03-03 02:30:37 +0000657 result := genruleFixtureFactory.Extend(android.FixtureModifyConfig(func(config android.Config) {
658 config.BazelContext = android.MockBazelContext{
659 AllFiles: map[string][]string{
660 "//foo/bar:bar": []string{"bazelone.txt", "bazeltwo.txt"}}}
661 })).RunTestWithBp(t, testGenruleBp()+bp)
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400662
Paul Duffin672cb9f2021-03-03 02:30:37 +0000663 gen := result.Module("foo", "").(*Module)
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400664
Chris Parsonsdbcb1ff2020-12-10 17:19:18 -0500665 expectedOutputFiles := []string{"outputbase/execroot/__main__/bazelone.txt",
666 "outputbase/execroot/__main__/bazeltwo.txt"}
Paul Duffine84b1332021-03-12 11:59:43 +0000667 android.AssertDeepEquals(t, "output files", expectedOutputFiles, gen.outputFiles.Strings())
668 android.AssertDeepEquals(t, "output deps", expectedOutputFiles, gen.outputDeps.Strings())
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400669}
670
Colin Cross2a076922018-10-04 23:28:25 -0700671type testTool struct {
672 android.ModuleBase
673 outputFile android.Path
674}
675
676func toolFactory() android.Module {
677 module := &testTool{}
678 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
679 return module
680}
681
Colin Cross2a076922018-10-04 23:28:25 -0700682func (t *testTool) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crossba9e4032020-11-24 16:32:22 -0800683 t.outputFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), android.PathForOutput(ctx, ctx.ModuleName()))
Colin Cross2a076922018-10-04 23:28:25 -0700684}
685
686func (t *testTool) HostToolPath() android.OptionalPath {
687 return android.OptionalPathForPath(t.outputFile)
688}
689
Colin Crossfe17f6f2019-03-28 19:30:56 -0700690var _ android.HostToolProvider = (*testTool)(nil)