blob: 0873704baf8bfc78195d5114fb18394f84448d29 [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 (
18 "io/ioutil"
19 "os"
Paul Duffin672cb9f2021-03-03 02:30:37 +000020 "regexp"
Colin Cross2a076922018-10-04 23:28:25 -070021 "testing"
22
23 "android/soong/android"
Colin Crossba71a3f2019-03-18 12:12:48 -070024
25 "github.com/google/blueprint/proptools"
Colin Cross2a076922018-10-04 23:28:25 -070026)
27
28var buildDir string
29
30func setUp() {
31 var err error
Colin Crossef354482018-10-23 11:27:50 -070032 buildDir, err = ioutil.TempDir("", "genrule_test")
Colin Cross2a076922018-10-04 23:28:25 -070033 if err != nil {
34 panic(err)
35 }
36}
37
38func tearDown() {
39 os.RemoveAll(buildDir)
40}
41
42func TestMain(m *testing.M) {
43 run := func() int {
44 setUp()
45 defer tearDown()
46
47 return m.Run()
48 }
49
50 os.Exit(run())
51}
52
Paul Duffin672cb9f2021-03-03 02:30:37 +000053var genruleFixtureFactory = android.NewFixtureFactory(
54 &buildDir,
55 android.PrepareForTestWithArchMutator,
56 android.PrepareForTestWithDefaults,
Colin Cross2a076922018-10-04 23:28:25 -070057
Paul Duffin672cb9f2021-03-03 02:30:37 +000058 android.PrepareForTestWithFilegroup,
59 PrepareForTestWithGenRuleBuildComponents,
60 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
61 ctx.RegisterModuleType("tool", toolFactory)
62 }),
63 android.FixtureMergeMockFs(android.MockFS{
64 "tool": nil,
65 "tool_file1": nil,
66 "tool_file2": nil,
67 "in1": nil,
68 "in2": nil,
69 "in1.txt": nil,
70 "in2.txt": nil,
71 "in3.txt": nil,
72 }),
73)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000074
Paul Duffin672cb9f2021-03-03 02:30:37 +000075func testGenruleBp() string {
76 return `
Colin Cross2a076922018-10-04 23:28:25 -070077 tool {
78 name: "tool",
79 }
80
81 filegroup {
82 name: "tool_files",
83 srcs: [
84 "tool_file1",
85 "tool_file2",
86 ],
87 }
88
89 filegroup {
90 name: "1tool_file",
91 srcs: [
92 "tool_file1",
93 ],
94 }
95
96 filegroup {
97 name: "ins",
98 srcs: [
99 "in1",
100 "in2",
101 ],
102 }
103
104 filegroup {
105 name: "1in",
106 srcs: [
107 "in1",
108 ],
109 }
110
111 filegroup {
112 name: "empty",
113 }
114 `
Colin Cross2a076922018-10-04 23:28:25 -0700115}
116
117func TestGenruleCmd(t *testing.T) {
118 testcases := []struct {
119 name string
120 prop string
121
Colin Crossba71a3f2019-03-18 12:12:48 -0700122 allowMissingDependencies bool
123
Colin Cross2a076922018-10-04 23:28:25 -0700124 err string
125 expect string
126 }{
127 {
128 name: "empty location tool",
129 prop: `
130 tools: ["tool"],
131 out: ["out"],
132 cmd: "$(location) > $(out)",
133 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800134 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700135 },
136 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700137 name: "empty location tool2",
138 prop: `
139 tools: [":tool"],
140 out: ["out"],
141 cmd: "$(location) > $(out)",
142 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800143 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700144 },
145 {
Colin Cross2a076922018-10-04 23:28:25 -0700146 name: "empty location tool file",
147 prop: `
148 tool_files: ["tool_file1"],
149 out: ["out"],
150 cmd: "$(location) > $(out)",
151 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800152 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700153 },
154 {
155 name: "empty location tool file fg",
156 prop: `
157 tool_files: [":1tool_file"],
158 out: ["out"],
159 cmd: "$(location) > $(out)",
160 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800161 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700162 },
163 {
164 name: "empty location tool and tool file",
165 prop: `
166 tools: ["tool"],
167 tool_files: ["tool_file1"],
168 out: ["out"],
169 cmd: "$(location) > $(out)",
170 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800171 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700172 },
173 {
174 name: "tool",
175 prop: `
176 tools: ["tool"],
177 out: ["out"],
178 cmd: "$(location tool) > $(out)",
179 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800180 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700181 },
182 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700183 name: "tool2",
184 prop: `
185 tools: [":tool"],
186 out: ["out"],
187 cmd: "$(location :tool) > $(out)",
188 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800189 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700190 },
191 {
Colin Cross2a076922018-10-04 23:28:25 -0700192 name: "tool file",
193 prop: `
194 tool_files: ["tool_file1"],
195 out: ["out"],
196 cmd: "$(location tool_file1) > $(out)",
197 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800198 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700199 },
200 {
201 name: "tool file fg",
202 prop: `
203 tool_files: [":1tool_file"],
204 out: ["out"],
Colin Cross08f15ab2018-10-04 23:29:14 -0700205 cmd: "$(location :1tool_file) > $(out)",
Colin Cross2a076922018-10-04 23:28:25 -0700206 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800207 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700208 },
209 {
210 name: "tool files",
211 prop: `
212 tool_files: [":tool_files"],
213 out: ["out"],
Colin Cross08f15ab2018-10-04 23:29:14 -0700214 cmd: "$(locations :tool_files) > $(out)",
Colin Cross2a076922018-10-04 23:28:25 -0700215 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800216 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 -0700217 },
218 {
219 name: "in1",
220 prop: `
221 srcs: ["in1"],
222 out: ["out"],
223 cmd: "cat $(in) > $(out)",
224 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800225 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700226 },
227 {
228 name: "in1 fg",
229 prop: `
230 srcs: [":1in"],
231 out: ["out"],
232 cmd: "cat $(in) > $(out)",
233 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800234 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700235 },
236 {
237 name: "ins",
238 prop: `
239 srcs: ["in1", "in2"],
240 out: ["out"],
241 cmd: "cat $(in) > $(out)",
242 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800243 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700244 },
245 {
246 name: "ins fg",
247 prop: `
248 srcs: [":ins"],
249 out: ["out"],
250 cmd: "cat $(in) > $(out)",
251 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800252 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700253 },
254 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700255 name: "location in1",
256 prop: `
257 srcs: ["in1"],
258 out: ["out"],
259 cmd: "cat $(location in1) > $(out)",
260 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800261 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700262 },
263 {
264 name: "location in1 fg",
265 prop: `
266 srcs: [":1in"],
267 out: ["out"],
268 cmd: "cat $(location :1in) > $(out)",
269 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800270 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700271 },
272 {
273 name: "location ins",
274 prop: `
275 srcs: ["in1", "in2"],
276 out: ["out"],
277 cmd: "cat $(location in1) > $(out)",
278 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800279 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700280 },
281 {
282 name: "location ins fg",
283 prop: `
284 srcs: [":ins"],
285 out: ["out"],
286 cmd: "cat $(locations :ins) > $(out)",
287 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800288 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700289 },
290 {
Colin Cross2a076922018-10-04 23:28:25 -0700291 name: "outs",
292 prop: `
293 out: ["out", "out2"],
294 cmd: "echo foo > $(out)",
295 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800296 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out __SBOX_SANDBOX_DIR__/out/out2",
Colin Cross2a076922018-10-04 23:28:25 -0700297 },
298 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700299 name: "location out",
300 prop: `
301 out: ["out", "out2"],
302 cmd: "echo foo > $(location out2)",
303 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800304 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out2",
Colin Cross08f15ab2018-10-04 23:29:14 -0700305 },
306 {
Colin Cross2a076922018-10-04 23:28:25 -0700307 name: "depfile",
308 prop: `
309 out: ["out"],
310 depfile: true,
311 cmd: "echo foo > $(out) && touch $(depfile)",
312 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800313 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out && touch __SBOX_DEPFILE__",
Colin Cross2a076922018-10-04 23:28:25 -0700314 },
315 {
316 name: "gendir",
317 prop: `
318 out: ["out"],
319 cmd: "echo foo > $(genDir)/foo && cp $(genDir)/foo $(out)",
320 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800321 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 -0700322 },
323
324 {
325 name: "error empty location",
326 prop: `
327 out: ["out"],
328 cmd: "$(location) > $(out)",
329 `,
330 err: "at least one `tools` or `tool_files` is required if $(location) is used",
331 },
332 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700333 name: "error empty location no files",
334 prop: `
335 tool_files: [":empty"],
336 out: ["out"],
337 cmd: "$(location) > $(out)",
338 `,
339 err: `default label ":empty" has no files`,
340 },
341 {
342 name: "error empty location multiple files",
343 prop: `
344 tool_files: [":tool_files"],
345 out: ["out"],
346 cmd: "$(location) > $(out)",
347 `,
348 err: `default label ":tool_files" has multiple files`,
349 },
350 {
Colin Cross2a076922018-10-04 23:28:25 -0700351 name: "error location",
352 prop: `
353 out: ["out"],
354 cmd: "echo foo > $(location missing)",
355 `,
356 err: `unknown location label "missing"`,
357 },
358 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700359 name: "error locations",
360 prop: `
361 out: ["out"],
362 cmd: "echo foo > $(locations missing)",
363 `,
364 err: `unknown locations label "missing"`,
365 },
366 {
367 name: "error location no files",
368 prop: `
369 out: ["out"],
370 srcs: [":empty"],
371 cmd: "echo $(location :empty) > $(out)",
372 `,
373 err: `label ":empty" has no files`,
374 },
375 {
376 name: "error locations no files",
377 prop: `
378 out: ["out"],
379 srcs: [":empty"],
380 cmd: "echo $(locations :empty) > $(out)",
381 `,
382 err: `label ":empty" has no files`,
383 },
384 {
385 name: "error location multiple files",
386 prop: `
387 out: ["out"],
388 srcs: [":ins"],
389 cmd: "echo $(location :ins) > $(out)",
390 `,
391 err: `label ":ins" has multiple files`,
392 },
393 {
Colin Cross2a076922018-10-04 23:28:25 -0700394 name: "error variable",
395 prop: `
396 out: ["out"],
397 srcs: ["in1"],
398 cmd: "echo $(foo) > $(out)",
399 `,
400 err: `unknown variable '$(foo)'`,
401 },
402 {
403 name: "error depfile",
404 prop: `
405 out: ["out"],
406 cmd: "echo foo > $(out) && touch $(depfile)",
407 `,
408 err: "$(depfile) used without depfile property",
409 },
410 {
411 name: "error no depfile",
412 prop: `
413 out: ["out"],
414 depfile: true,
415 cmd: "echo foo > $(out)",
416 `,
417 err: "specified depfile=true but did not include a reference to '${depfile}' in cmd",
418 },
419 {
420 name: "error no out",
421 prop: `
422 cmd: "echo foo > $(out)",
423 `,
424 err: "must have at least one output file",
425 },
Colin Crossba71a3f2019-03-18 12:12:48 -0700426 {
427 name: "srcs allow missing dependencies",
428 prop: `
429 srcs: [":missing"],
430 out: ["out"],
431 cmd: "cat $(location :missing) > $(out)",
432 `,
433
434 allowMissingDependencies: true,
435
Colin Crosse16ce362020-11-12 08:29:30 -0800436 expect: "cat ***missing srcs :missing*** > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700437 },
438 {
439 name: "tool allow missing dependencies",
440 prop: `
441 tools: [":missing"],
442 out: ["out"],
443 cmd: "$(location :missing) > $(out)",
444 `,
445
446 allowMissingDependencies: true,
447
Colin Crosse16ce362020-11-12 08:29:30 -0800448 expect: "***missing tool :missing*** > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700449 },
Colin Cross2a076922018-10-04 23:28:25 -0700450 }
451
452 for _, test := range testcases {
453 t.Run(test.name, func(t *testing.T) {
Colin Cross2a076922018-10-04 23:28:25 -0700454 bp := "genrule {\n"
455 bp += "name: \"gen\",\n"
456 bp += test.prop
457 bp += "}\n"
458
Paul Duffin672cb9f2021-03-03 02:30:37 +0000459 var expectedErrors []string
460 if test.err != "" {
461 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross2a076922018-10-04 23:28:25 -0700462 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000463
464 result := genruleFixtureFactory.Extend(
465 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
466 variables.Allow_missing_dependencies = proptools.BoolPtr(test.allowMissingDependencies)
467 }),
468 android.FixtureModifyContext(func(ctx *android.TestContext) {
469 ctx.SetAllowMissingDependencies(test.allowMissingDependencies)
470 }),
471 ).
472 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
473 RunTestWithBp(t, testGenruleBp()+bp)
474
475 if expectedErrors != nil {
Colin Cross2a076922018-10-04 23:28:25 -0700476 return
477 }
478
Paul Duffin672cb9f2021-03-03 02:30:37 +0000479 gen := result.Module("gen", "").(*Module)
480 result.AssertStringEquals("raw commands", test.expect, gen.rawCommands[0])
Colin Cross2a076922018-10-04 23:28:25 -0700481 })
482 }
Colin Cross1a527682019-09-23 15:55:30 -0700483}
484
Bill Peckhamc087be12020-02-13 15:55:10 -0800485func TestGenruleHashInputs(t *testing.T) {
486
487 // The basic idea here is to verify that the sbox command (which is
488 // in the Command field of the generate rule) contains a hash of the
489 // inputs, but only if $(in) is not referenced in the genrule cmd
490 // property.
491
492 // By including a hash of the inputs, we cause the rule to re-run if
493 // the list of inputs changes (because the sbox command changes).
494
495 // However, if the genrule cmd property already contains $(in), then
496 // the dependency is already expressed, so we don't need to include the
497 // hash in that case.
498
499 bp := `
500 genrule {
501 name: "hash0",
502 srcs: ["in1.txt", "in2.txt"],
503 out: ["out"],
504 cmd: "echo foo > $(out)",
505 }
506 genrule {
507 name: "hash1",
508 srcs: ["*.txt"],
509 out: ["out"],
510 cmd: "echo bar > $(out)",
511 }
512 genrule {
513 name: "hash2",
514 srcs: ["*.txt"],
515 out: ["out"],
516 cmd: "echo $(in) > $(out)",
517 }
518 `
519 testcases := []struct {
520 name string
521 expectedHash string
522 }{
523 {
524 name: "hash0",
Colin Cross3d680512020-11-13 16:23:53 -0800525 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt' | sha256sum
526 expectedHash: "18da75b9b1cc74b09e365b4ca2e321b5d618f438cc632b387ad9dc2ab4b20e9d",
Bill Peckhamc087be12020-02-13 15:55:10 -0800527 },
528 {
529 name: "hash1",
Colin Cross3d680512020-11-13 16:23:53 -0800530 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
531 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
Bill Peckhamc087be12020-02-13 15:55:10 -0800532 },
533 {
534 name: "hash2",
Colin Cross3d680512020-11-13 16:23:53 -0800535 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
536 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
Bill Peckhamc087be12020-02-13 15:55:10 -0800537 },
538 }
539
Paul Duffin672cb9f2021-03-03 02:30:37 +0000540 result := genruleFixtureFactory.RunTestWithBp(t, testGenruleBp()+bp)
Bill Peckhamc087be12020-02-13 15:55:10 -0800541
542 for _, test := range testcases {
543 t.Run(test.name, func(t *testing.T) {
Paul Duffin672cb9f2021-03-03 02:30:37 +0000544 subResult := result.ResultForSubTest(t)
545 gen := subResult.ModuleForTests(test.name, "")
Colin Crosse16ce362020-11-12 08:29:30 -0800546 manifest := android.RuleBuilderSboxProtoForTests(t, gen.Output("genrule.sbox.textproto"))
547 hash := manifest.Commands[0].GetInputHash()
Bill Peckhamc087be12020-02-13 15:55:10 -0800548
Paul Duffin672cb9f2021-03-03 02:30:37 +0000549 subResult.AssertStringEquals("hash", test.expectedHash, hash)
Bill Peckhamc087be12020-02-13 15:55:10 -0800550 })
551 }
552}
553
Colin Cross1a527682019-09-23 15:55:30 -0700554func TestGenSrcs(t *testing.T) {
555 testcases := []struct {
556 name string
557 prop string
558
559 allowMissingDependencies bool
560
561 err string
562 cmds []string
563 deps []string
564 files []string
565 }{
566 {
567 name: "gensrcs",
568 prop: `
569 tools: ["tool"],
570 srcs: ["in1.txt", "in2.txt"],
571 cmd: "$(location) $(in) > $(out)",
572 `,
573 cmds: []string{
Colin Crossba9e4032020-11-24 16:32:22 -0800574 "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 -0700575 },
576 deps: []string{buildDir + "/.intermediates/gen/gen/gensrcs/in1.h", buildDir + "/.intermediates/gen/gen/gensrcs/in2.h"},
577 files: []string{buildDir + "/.intermediates/gen/gen/gensrcs/in1.h", buildDir + "/.intermediates/gen/gen/gensrcs/in2.h"},
578 },
579 {
580 name: "shards",
581 prop: `
582 tools: ["tool"],
583 srcs: ["in1.txt", "in2.txt", "in3.txt"],
584 cmd: "$(location) $(in) > $(out)",
585 shard_size: 2,
586 `,
587 cmds: []string{
Colin Crossba9e4032020-11-24 16:32:22 -0800588 "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'",
589 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in3.txt > __SBOX_SANDBOX_DIR__/out/in3.h'",
Colin Cross1a527682019-09-23 15:55:30 -0700590 },
591 deps: []string{buildDir + "/.intermediates/gen/gen/gensrcs/in1.h", buildDir + "/.intermediates/gen/gen/gensrcs/in2.h", buildDir + "/.intermediates/gen/gen/gensrcs/in3.h"},
592 files: []string{buildDir + "/.intermediates/gen/gen/gensrcs/in1.h", buildDir + "/.intermediates/gen/gen/gensrcs/in2.h", buildDir + "/.intermediates/gen/gen/gensrcs/in3.h"},
593 },
594 }
595
596 for _, test := range testcases {
597 t.Run(test.name, func(t *testing.T) {
Colin Cross1a527682019-09-23 15:55:30 -0700598 bp := "gensrcs {\n"
599 bp += `name: "gen",` + "\n"
600 bp += `output_extension: "h",` + "\n"
601 bp += test.prop
602 bp += "}\n"
603
Paul Duffin672cb9f2021-03-03 02:30:37 +0000604 var expectedErrors []string
605 if test.err != "" {
606 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross1a527682019-09-23 15:55:30 -0700607 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000608
609 result := genruleFixtureFactory.
610 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
611 RunTestWithBp(t, testGenruleBp()+bp)
612
613 if expectedErrors != nil {
Colin Cross1a527682019-09-23 15:55:30 -0700614 return
615 }
616
Paul Duffin672cb9f2021-03-03 02:30:37 +0000617 gen := result.Module("gen", "").(*Module)
618 result.AssertDeepEquals("cmd", test.cmds, gen.rawCommands)
Colin Cross1a527682019-09-23 15:55:30 -0700619
Paul Duffin672cb9f2021-03-03 02:30:37 +0000620 result.AssertDeepEquals("deps", test.deps, gen.outputDeps.Strings())
Colin Cross1a527682019-09-23 15:55:30 -0700621
Paul Duffin672cb9f2021-03-03 02:30:37 +0000622 result.AssertDeepEquals("files", test.files, gen.outputFiles.Strings())
Colin Cross1a527682019-09-23 15:55:30 -0700623 })
624 }
Colin Cross2a076922018-10-04 23:28:25 -0700625}
626
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800627func TestGenruleDefaults(t *testing.T) {
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800628 bp := `
629 genrule_defaults {
630 name: "gen_defaults1",
631 cmd: "cp $(in) $(out)",
632 }
633
634 genrule_defaults {
635 name: "gen_defaults2",
636 srcs: ["in1"],
637 }
638
639 genrule {
640 name: "gen",
641 out: ["out"],
642 defaults: ["gen_defaults1", "gen_defaults2"],
643 }
644 `
Paul Duffin672cb9f2021-03-03 02:30:37 +0000645
646 result := genruleFixtureFactory.RunTestWithBp(t, testGenruleBp()+bp)
647
648 gen := result.Module("gen", "").(*Module)
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800649
Colin Crosse16ce362020-11-12 08:29:30 -0800650 expectedCmd := "cp in1 __SBOX_SANDBOX_DIR__/out/out"
Paul Duffin672cb9f2021-03-03 02:30:37 +0000651 result.AssertStringEquals("cmd", expectedCmd, gen.rawCommands[0])
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800652
653 expectedSrcs := []string{"in1"}
Paul Duffin672cb9f2021-03-03 02:30:37 +0000654 result.AssertDeepEquals("srcs", expectedSrcs, gen.properties.Srcs)
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800655}
656
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400657func TestGenruleWithBazel(t *testing.T) {
658 bp := `
659 genrule {
660 name: "foo",
661 out: ["one.txt", "two.txt"],
Chris Parsonsaa8be052020-10-14 16:22:37 -0400662 bazel_module: { label: "//foo/bar:bar" },
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400663 }
664 `
665
Paul Duffin672cb9f2021-03-03 02:30:37 +0000666 result := genruleFixtureFactory.Extend(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 Duffin672cb9f2021-03-03 02:30:37 +0000676 result.AssertDeepEquals("output files", expectedOutputFiles, gen.outputFiles.Strings())
677 result.AssertDeepEquals("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)