blob: d099f65022243457e08f605c7d5704a9028c5a84 [file] [log] [blame]
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001// Copyright 2015 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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Dan Willemsen34cc69e2015-09-23 15:26:20 -070016
17import (
18 "errors"
19 "fmt"
20 "reflect"
Colin Cross27027c72020-02-28 15:34:17 -080021 "strconv"
Dan Willemsen34cc69e2015-09-23 15:26:20 -070022 "strings"
23 "testing"
Dan Willemsen00269f22017-07-06 16:59:48 -070024
Colin Cross8a497952019-03-05 22:25:09 -080025 "github.com/google/blueprint/proptools"
Dan Willemsen34cc69e2015-09-23 15:26:20 -070026)
27
28type strsTestCase struct {
29 in []string
30 out string
31 err []error
32}
33
34var commonValidatePathTestCases = []strsTestCase{
35 {
36 in: []string{""},
37 out: "",
38 },
39 {
40 in: []string{"a/b"},
41 out: "a/b",
42 },
43 {
44 in: []string{"a/b", "c"},
45 out: "a/b/c",
46 },
47 {
48 in: []string{"a/.."},
49 out: ".",
50 },
51 {
52 in: []string{"."},
53 out: ".",
54 },
55 {
56 in: []string{".."},
57 out: "",
58 err: []error{errors.New("Path is outside directory: ..")},
59 },
60 {
61 in: []string{"../a"},
62 out: "",
63 err: []error{errors.New("Path is outside directory: ../a")},
64 },
65 {
66 in: []string{"b/../../a"},
67 out: "",
68 err: []error{errors.New("Path is outside directory: ../a")},
69 },
70 {
71 in: []string{"/a"},
72 out: "",
73 err: []error{errors.New("Path is outside directory: /a")},
74 },
Dan Willemsen80a7c2a2015-12-21 14:57:11 -080075 {
76 in: []string{"a", "../b"},
77 out: "",
78 err: []error{errors.New("Path is outside directory: ../b")},
79 },
80 {
81 in: []string{"a", "b/../../c"},
82 out: "",
83 err: []error{errors.New("Path is outside directory: ../c")},
84 },
85 {
86 in: []string{"a", "./.."},
87 out: "",
88 err: []error{errors.New("Path is outside directory: ..")},
89 },
Dan Willemsen34cc69e2015-09-23 15:26:20 -070090}
91
92var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
93 {
94 in: []string{"$host/../$a"},
95 out: "$a",
96 },
97}...)
98
99var validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
100 {
101 in: []string{"$host/../$a"},
102 out: "",
103 err: []error{errors.New("Path contains invalid character($): $host/../$a")},
104 },
105 {
106 in: []string{"$host/.."},
107 out: "",
108 err: []error{errors.New("Path contains invalid character($): $host/..")},
109 },
110}...)
111
112func TestValidateSafePath(t *testing.T) {
113 for _, testCase := range validateSafePathTestCases {
Colin Crossdc75ae72018-02-22 13:48:13 -0800114 t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
115 ctx := &configErrorWrapper{}
Colin Cross1ccfcc32018-02-22 13:54:26 -0800116 out, err := validateSafePath(testCase.in...)
117 if err != nil {
118 reportPathError(ctx, err)
119 }
Colin Crossdc75ae72018-02-22 13:48:13 -0800120 check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
121 })
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700122 }
123}
124
125func TestValidatePath(t *testing.T) {
126 for _, testCase := range validatePathTestCases {
Colin Crossdc75ae72018-02-22 13:48:13 -0800127 t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
128 ctx := &configErrorWrapper{}
Colin Cross1ccfcc32018-02-22 13:54:26 -0800129 out, err := validatePath(testCase.in...)
130 if err != nil {
131 reportPathError(ctx, err)
132 }
Colin Crossdc75ae72018-02-22 13:48:13 -0800133 check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
134 })
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700135 }
136}
137
138func TestOptionalPath(t *testing.T) {
139 var path OptionalPath
140 checkInvalidOptionalPath(t, path)
141
142 path = OptionalPathForPath(nil)
143 checkInvalidOptionalPath(t, path)
144}
145
146func checkInvalidOptionalPath(t *testing.T, path OptionalPath) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800147 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700148 if path.Valid() {
149 t.Errorf("Uninitialized OptionalPath should not be valid")
150 }
151 if path.String() != "" {
152 t.Errorf("Uninitialized OptionalPath String() should return \"\", not %q", path.String())
153 }
154 defer func() {
155 if r := recover(); r == nil {
156 t.Errorf("Expected a panic when calling Path() on an uninitialized OptionalPath")
157 }
158 }()
159 path.Path()
160}
161
162func check(t *testing.T, testType, testString string,
163 got interface{}, err []error,
164 expected interface{}, expectedErr []error) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800165 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700166
167 printedTestCase := false
168 e := func(s string, expected, got interface{}) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800169 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700170 if !printedTestCase {
171 t.Errorf("test case %s: %s", testType, testString)
172 printedTestCase = true
173 }
174 t.Errorf("incorrect %s", s)
175 t.Errorf(" expected: %s", p(expected))
176 t.Errorf(" got: %s", p(got))
177 }
178
179 if !reflect.DeepEqual(expectedErr, err) {
180 e("errors:", expectedErr, err)
181 }
182
183 if !reflect.DeepEqual(expected, got) {
184 e("output:", expected, got)
185 }
186}
187
188func p(in interface{}) string {
189 if v, ok := in.([]interface{}); ok {
190 s := make([]string, len(v))
191 for i := range v {
192 s[i] = fmt.Sprintf("%#v", v[i])
193 }
194 return "[" + strings.Join(s, ", ") + "]"
195 } else {
196 return fmt.Sprintf("%#v", in)
197 }
198}
Dan Willemsen00269f22017-07-06 16:59:48 -0700199
200type moduleInstallPathContextImpl struct {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700201 baseModuleContext
Dan Willemsen00269f22017-07-06 16:59:48 -0700202
203 inData bool
Jaewoong Jung0949f312019-09-11 10:25:18 -0700204 inTestcases bool
Dan Willemsen00269f22017-07-06 16:59:48 -0700205 inSanitizerDir bool
Yifan Hong1b3348d2020-01-21 15:53:22 -0800206 inRamdisk bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900207 inRecovery bool
Colin Cross90ba5f42019-10-02 11:10:58 -0700208 inRoot bool
Colin Cross6e359402020-02-10 15:29:54 -0800209 forceOS *OsType
Jiyong Park87788b52020-09-01 12:37:45 +0900210 forceArch *ArchType
Dan Willemsen00269f22017-07-06 16:59:48 -0700211}
212
Colin Crossaabf6792017-11-29 00:27:14 -0800213func (m moduleInstallPathContextImpl) Config() Config {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700214 return m.baseModuleContext.config
Dan Willemsen00269f22017-07-06 16:59:48 -0700215}
216
217func (moduleInstallPathContextImpl) AddNinjaFileDeps(deps ...string) {}
218
219func (m moduleInstallPathContextImpl) InstallInData() bool {
220 return m.inData
221}
222
Jaewoong Jung0949f312019-09-11 10:25:18 -0700223func (m moduleInstallPathContextImpl) InstallInTestcases() bool {
224 return m.inTestcases
225}
226
Dan Willemsen00269f22017-07-06 16:59:48 -0700227func (m moduleInstallPathContextImpl) InstallInSanitizerDir() bool {
228 return m.inSanitizerDir
229}
230
Yifan Hong1b3348d2020-01-21 15:53:22 -0800231func (m moduleInstallPathContextImpl) InstallInRamdisk() bool {
232 return m.inRamdisk
233}
234
Jiyong Parkf9332f12018-02-01 00:54:12 +0900235func (m moduleInstallPathContextImpl) InstallInRecovery() bool {
236 return m.inRecovery
237}
238
Colin Cross90ba5f42019-10-02 11:10:58 -0700239func (m moduleInstallPathContextImpl) InstallInRoot() bool {
240 return m.inRoot
241}
242
Colin Cross607d8582019-07-29 16:44:46 -0700243func (m moduleInstallPathContextImpl) InstallBypassMake() bool {
244 return false
245}
246
Jiyong Park87788b52020-09-01 12:37:45 +0900247func (m moduleInstallPathContextImpl) InstallForceOS() (*OsType, *ArchType) {
248 return m.forceOS, m.forceArch
Colin Cross6e359402020-02-10 15:29:54 -0800249}
250
Colin Cross98be1bb2019-12-13 20:41:13 -0800251func pathTestConfig(buildDir string) Config {
252 return TestConfig(buildDir, nil, "", nil)
253}
254
Dan Willemsen00269f22017-07-06 16:59:48 -0700255func TestPathForModuleInstall(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800256 testConfig := pathTestConfig("")
Dan Willemsen00269f22017-07-06 16:59:48 -0700257
Jiyong Park87788b52020-09-01 12:37:45 +0900258 hostTarget := Target{Os: Linux, Arch: Arch{ArchType: X86}}
259 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
Dan Willemsen00269f22017-07-06 16:59:48 -0700260
261 testCases := []struct {
262 name string
263 ctx *moduleInstallPathContextImpl
264 in []string
265 out string
266 }{
267 {
268 name: "host binary",
269 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700270 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800271 os: hostTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700272 target: hostTarget,
273 },
274 },
275 in: []string{"bin", "my_test"},
276 out: "host/linux-x86/bin/my_test",
277 },
278
279 {
280 name: "system binary",
281 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700282 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800283 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700284 target: deviceTarget,
285 },
286 },
287 in: []string{"bin", "my_test"},
288 out: "target/product/test_device/system/bin/my_test",
289 },
290 {
291 name: "vendor binary",
292 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700293 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800294 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700295 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800296 earlyModuleContext: earlyModuleContext{
297 kind: socSpecificModule,
298 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700299 },
300 },
301 in: []string{"bin", "my_test"},
302 out: "target/product/test_device/vendor/bin/my_test",
303 },
Jiyong Park2db76922017-11-08 16:03:48 +0900304 {
305 name: "odm binary",
306 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700307 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800308 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900309 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800310 earlyModuleContext: earlyModuleContext{
311 kind: deviceSpecificModule,
312 },
Jiyong Park2db76922017-11-08 16:03:48 +0900313 },
314 },
315 in: []string{"bin", "my_test"},
316 out: "target/product/test_device/odm/bin/my_test",
317 },
318 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900319 name: "product binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900320 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700321 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800322 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900323 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800324 earlyModuleContext: earlyModuleContext{
325 kind: productSpecificModule,
326 },
Jiyong Park2db76922017-11-08 16:03:48 +0900327 },
328 },
329 in: []string{"bin", "my_test"},
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900330 out: "target/product/test_device/product/bin/my_test",
Jiyong Park2db76922017-11-08 16:03:48 +0900331 },
Dario Frenifd05a742018-05-29 13:28:54 +0100332 {
Justin Yund5f6c822019-06-25 16:47:17 +0900333 name: "system_ext binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100334 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700335 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800336 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100337 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800338 earlyModuleContext: earlyModuleContext{
339 kind: systemExtSpecificModule,
340 },
Dario Frenifd05a742018-05-29 13:28:54 +0100341 },
342 },
343 in: []string{"bin", "my_test"},
Justin Yund5f6c822019-06-25 16:47:17 +0900344 out: "target/product/test_device/system_ext/bin/my_test",
Dario Frenifd05a742018-05-29 13:28:54 +0100345 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700346 {
347 name: "root binary",
348 ctx: &moduleInstallPathContextImpl{
349 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800350 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700351 target: deviceTarget,
352 },
353 inRoot: true,
354 },
355 in: []string{"my_test"},
356 out: "target/product/test_device/root/my_test",
357 },
358 {
359 name: "recovery binary",
360 ctx: &moduleInstallPathContextImpl{
361 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800362 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700363 target: deviceTarget,
364 },
365 inRecovery: true,
366 },
367 in: []string{"bin/my_test"},
368 out: "target/product/test_device/recovery/root/system/bin/my_test",
369 },
370 {
371 name: "recovery root binary",
372 ctx: &moduleInstallPathContextImpl{
373 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800374 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700375 target: deviceTarget,
376 },
377 inRecovery: true,
378 inRoot: true,
379 },
380 in: []string{"my_test"},
381 out: "target/product/test_device/recovery/root/my_test",
382 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700383
384 {
385 name: "system native test binary",
386 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700387 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800388 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700389 target: deviceTarget,
390 },
391 inData: true,
392 },
393 in: []string{"nativetest", "my_test"},
394 out: "target/product/test_device/data/nativetest/my_test",
395 },
396 {
397 name: "vendor native test binary",
398 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700399 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800400 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700401 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800402 earlyModuleContext: earlyModuleContext{
403 kind: socSpecificModule,
404 },
Jiyong Park2db76922017-11-08 16:03:48 +0900405 },
406 inData: true,
407 },
408 in: []string{"nativetest", "my_test"},
409 out: "target/product/test_device/data/nativetest/my_test",
410 },
411 {
412 name: "odm native test binary",
413 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700414 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800415 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900416 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800417 earlyModuleContext: earlyModuleContext{
418 kind: deviceSpecificModule,
419 },
Jiyong Park2db76922017-11-08 16:03:48 +0900420 },
421 inData: true,
422 },
423 in: []string{"nativetest", "my_test"},
424 out: "target/product/test_device/data/nativetest/my_test",
425 },
426 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900427 name: "product native test binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900428 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700429 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800430 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900431 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800432 earlyModuleContext: earlyModuleContext{
433 kind: productSpecificModule,
434 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700435 },
436 inData: true,
437 },
438 in: []string{"nativetest", "my_test"},
439 out: "target/product/test_device/data/nativetest/my_test",
440 },
441
442 {
Justin Yund5f6c822019-06-25 16:47:17 +0900443 name: "system_ext native test binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100444 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700445 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800446 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100447 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800448 earlyModuleContext: earlyModuleContext{
449 kind: systemExtSpecificModule,
450 },
Dario Frenifd05a742018-05-29 13:28:54 +0100451 },
452 inData: true,
453 },
454 in: []string{"nativetest", "my_test"},
455 out: "target/product/test_device/data/nativetest/my_test",
456 },
457
458 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700459 name: "sanitized system binary",
460 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700461 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800462 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700463 target: deviceTarget,
464 },
465 inSanitizerDir: true,
466 },
467 in: []string{"bin", "my_test"},
468 out: "target/product/test_device/data/asan/system/bin/my_test",
469 },
470 {
471 name: "sanitized vendor binary",
472 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700473 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800474 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700475 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800476 earlyModuleContext: earlyModuleContext{
477 kind: socSpecificModule,
478 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700479 },
480 inSanitizerDir: true,
481 },
482 in: []string{"bin", "my_test"},
483 out: "target/product/test_device/data/asan/vendor/bin/my_test",
484 },
Jiyong Park2db76922017-11-08 16:03:48 +0900485 {
486 name: "sanitized odm binary",
487 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700488 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800489 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900490 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800491 earlyModuleContext: earlyModuleContext{
492 kind: deviceSpecificModule,
493 },
Jiyong Park2db76922017-11-08 16:03:48 +0900494 },
495 inSanitizerDir: true,
496 },
497 in: []string{"bin", "my_test"},
498 out: "target/product/test_device/data/asan/odm/bin/my_test",
499 },
500 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900501 name: "sanitized product binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900502 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700503 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800504 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900505 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800506 earlyModuleContext: earlyModuleContext{
507 kind: productSpecificModule,
508 },
Jiyong Park2db76922017-11-08 16:03:48 +0900509 },
510 inSanitizerDir: true,
511 },
512 in: []string{"bin", "my_test"},
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900513 out: "target/product/test_device/data/asan/product/bin/my_test",
Jiyong Park2db76922017-11-08 16:03:48 +0900514 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700515
516 {
Justin Yund5f6c822019-06-25 16:47:17 +0900517 name: "sanitized system_ext binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100518 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700519 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800520 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100521 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800522 earlyModuleContext: earlyModuleContext{
523 kind: systemExtSpecificModule,
524 },
Dario Frenifd05a742018-05-29 13:28:54 +0100525 },
526 inSanitizerDir: true,
527 },
528 in: []string{"bin", "my_test"},
Justin Yund5f6c822019-06-25 16:47:17 +0900529 out: "target/product/test_device/data/asan/system_ext/bin/my_test",
Dario Frenifd05a742018-05-29 13:28:54 +0100530 },
531
532 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700533 name: "sanitized system native test binary",
534 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700535 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800536 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700537 target: deviceTarget,
538 },
539 inData: true,
540 inSanitizerDir: true,
541 },
542 in: []string{"nativetest", "my_test"},
543 out: "target/product/test_device/data/asan/data/nativetest/my_test",
544 },
545 {
546 name: "sanitized vendor native test binary",
547 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700548 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800549 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700550 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800551 earlyModuleContext: earlyModuleContext{
552 kind: socSpecificModule,
553 },
Jiyong Park2db76922017-11-08 16:03:48 +0900554 },
555 inData: true,
556 inSanitizerDir: true,
557 },
558 in: []string{"nativetest", "my_test"},
559 out: "target/product/test_device/data/asan/data/nativetest/my_test",
560 },
561 {
562 name: "sanitized odm native test binary",
563 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700564 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800565 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900566 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800567 earlyModuleContext: earlyModuleContext{
568 kind: deviceSpecificModule,
569 },
Jiyong Park2db76922017-11-08 16:03:48 +0900570 },
571 inData: true,
572 inSanitizerDir: true,
573 },
574 in: []string{"nativetest", "my_test"},
575 out: "target/product/test_device/data/asan/data/nativetest/my_test",
576 },
577 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900578 name: "sanitized product native test binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900579 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700580 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800581 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900582 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800583 earlyModuleContext: earlyModuleContext{
584 kind: productSpecificModule,
585 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700586 },
587 inData: true,
588 inSanitizerDir: true,
589 },
590 in: []string{"nativetest", "my_test"},
591 out: "target/product/test_device/data/asan/data/nativetest/my_test",
592 },
Dario Frenifd05a742018-05-29 13:28:54 +0100593 {
Justin Yund5f6c822019-06-25 16:47:17 +0900594 name: "sanitized system_ext native test binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100595 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700596 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800597 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100598 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800599 earlyModuleContext: earlyModuleContext{
600 kind: systemExtSpecificModule,
601 },
Dario Frenifd05a742018-05-29 13:28:54 +0100602 },
603 inData: true,
604 inSanitizerDir: true,
605 },
606 in: []string{"nativetest", "my_test"},
607 out: "target/product/test_device/data/asan/data/nativetest/my_test",
Colin Cross6e359402020-02-10 15:29:54 -0800608 }, {
609 name: "device testcases",
610 ctx: &moduleInstallPathContextImpl{
611 baseModuleContext: baseModuleContext{
612 os: deviceTarget.Os,
613 target: deviceTarget,
614 },
615 inTestcases: true,
616 },
617 in: []string{"my_test", "my_test_bin"},
618 out: "target/product/test_device/testcases/my_test/my_test_bin",
619 }, {
620 name: "host testcases",
621 ctx: &moduleInstallPathContextImpl{
622 baseModuleContext: baseModuleContext{
623 os: hostTarget.Os,
624 target: hostTarget,
625 },
626 inTestcases: true,
627 },
628 in: []string{"my_test", "my_test_bin"},
629 out: "host/linux-x86/testcases/my_test/my_test_bin",
630 }, {
631 name: "forced host testcases",
632 ctx: &moduleInstallPathContextImpl{
633 baseModuleContext: baseModuleContext{
634 os: deviceTarget.Os,
635 target: deviceTarget,
636 },
637 inTestcases: true,
638 forceOS: &Linux,
Jiyong Park87788b52020-09-01 12:37:45 +0900639 forceArch: &X86,
Colin Cross6e359402020-02-10 15:29:54 -0800640 },
641 in: []string{"my_test", "my_test_bin"},
642 out: "host/linux-x86/testcases/my_test/my_test_bin",
Dario Frenifd05a742018-05-29 13:28:54 +0100643 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700644 }
645
646 for _, tc := range testCases {
647 t.Run(tc.name, func(t *testing.T) {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700648 tc.ctx.baseModuleContext.config = testConfig
Dan Willemsen00269f22017-07-06 16:59:48 -0700649 output := PathForModuleInstall(tc.ctx, tc.in...)
650 if output.basePath.path != tc.out {
651 t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
652 output.basePath.path,
653 tc.out)
654 }
655 })
656 }
657}
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700658
659func TestDirectorySortedPaths(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800660 config := TestConfig("out", nil, "", map[string][]byte{
661 "Android.bp": nil,
662 "a.txt": nil,
663 "a/txt": nil,
664 "a/b/c": nil,
665 "a/b/d": nil,
666 "b": nil,
667 "b/b.txt": nil,
668 "a/a.txt": nil,
Colin Cross07e51612019-03-05 12:46:40 -0800669 })
670
Colin Cross98be1bb2019-12-13 20:41:13 -0800671 ctx := PathContextForTesting(config)
672
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700673 makePaths := func() Paths {
674 return Paths{
Colin Cross07e51612019-03-05 12:46:40 -0800675 PathForSource(ctx, "a.txt"),
676 PathForSource(ctx, "a/txt"),
677 PathForSource(ctx, "a/b/c"),
678 PathForSource(ctx, "a/b/d"),
679 PathForSource(ctx, "b"),
680 PathForSource(ctx, "b/b.txt"),
681 PathForSource(ctx, "a/a.txt"),
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700682 }
683 }
684
685 expected := []string{
686 "a.txt",
687 "a/a.txt",
688 "a/b/c",
689 "a/b/d",
690 "a/txt",
691 "b",
692 "b/b.txt",
693 }
694
695 paths := makePaths()
Colin Crossa140bb02018-04-17 10:52:26 -0700696 reversePaths := ReversePaths(paths)
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700697
698 sortedPaths := PathsToDirectorySortedPaths(paths)
699 reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
700
701 if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
702 t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
703 }
704
705 if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
706 t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
707 }
708
709 expectedA := []string{
710 "a/a.txt",
711 "a/b/c",
712 "a/b/d",
713 "a/txt",
714 }
715
716 inA := sortedPaths.PathsInDirectory("a")
717 if !reflect.DeepEqual(inA.Strings(), expectedA) {
718 t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
719 }
720
721 expectedA_B := []string{
722 "a/b/c",
723 "a/b/d",
724 }
725
726 inA_B := sortedPaths.PathsInDirectory("a/b")
727 if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
728 t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
729 }
730
731 expectedB := []string{
732 "b/b.txt",
733 }
734
735 inB := sortedPaths.PathsInDirectory("b")
736 if !reflect.DeepEqual(inB.Strings(), expectedB) {
737 t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
738 }
739}
Colin Cross43f08db2018-11-12 10:13:39 -0800740
741func TestMaybeRel(t *testing.T) {
742 testCases := []struct {
743 name string
744 base string
745 target string
746 out string
747 isRel bool
748 }{
749 {
750 name: "normal",
751 base: "a/b/c",
752 target: "a/b/c/d",
753 out: "d",
754 isRel: true,
755 },
756 {
757 name: "parent",
758 base: "a/b/c/d",
759 target: "a/b/c",
760 isRel: false,
761 },
762 {
763 name: "not relative",
764 base: "a/b",
765 target: "c/d",
766 isRel: false,
767 },
768 {
769 name: "abs1",
770 base: "/a",
771 target: "a",
772 isRel: false,
773 },
774 {
775 name: "abs2",
776 base: "a",
777 target: "/a",
778 isRel: false,
779 },
780 }
781
782 for _, testCase := range testCases {
783 t.Run(testCase.name, func(t *testing.T) {
784 ctx := &configErrorWrapper{}
785 out, isRel := MaybeRel(ctx, testCase.base, testCase.target)
786 if len(ctx.errors) > 0 {
787 t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v",
788 testCase.base, testCase.target, ctx.errors)
789 }
790 if isRel != testCase.isRel || out != testCase.out {
791 t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v",
792 testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel)
793 }
794 })
795 }
796}
Colin Cross7b3dcc32019-01-24 13:14:39 -0800797
798func TestPathForSource(t *testing.T) {
799 testCases := []struct {
800 name string
801 buildDir string
802 src string
803 err string
804 }{
805 {
806 name: "normal",
807 buildDir: "out",
808 src: "a/b/c",
809 },
810 {
811 name: "abs",
812 buildDir: "out",
813 src: "/a/b/c",
814 err: "is outside directory",
815 },
816 {
817 name: "in out dir",
818 buildDir: "out",
819 src: "out/a/b/c",
820 err: "is in output",
821 },
822 }
823
824 funcs := []struct {
825 name string
826 f func(ctx PathContext, pathComponents ...string) (SourcePath, error)
827 }{
828 {"pathForSource", pathForSource},
829 {"safePathForSource", safePathForSource},
830 }
831
832 for _, f := range funcs {
833 t.Run(f.name, func(t *testing.T) {
834 for _, test := range testCases {
835 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800836 testConfig := pathTestConfig(test.buildDir)
Colin Cross7b3dcc32019-01-24 13:14:39 -0800837 ctx := &configErrorWrapper{config: testConfig}
838 _, err := f.f(ctx, test.src)
839 if len(ctx.errors) > 0 {
840 t.Fatalf("unexpected errors %v", ctx.errors)
841 }
842 if err != nil {
843 if test.err == "" {
844 t.Fatalf("unexpected error %q", err.Error())
845 } else if !strings.Contains(err.Error(), test.err) {
846 t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
847 }
848 } else {
849 if test.err != "" {
850 t.Fatalf("missing error %q", test.err)
851 }
852 }
853 })
854 }
855 })
856 }
857}
Colin Cross8854a5a2019-02-11 14:14:16 -0800858
Colin Cross8a497952019-03-05 22:25:09 -0800859type pathForModuleSrcTestModule struct {
Colin Cross937664a2019-03-06 10:17:32 -0800860 ModuleBase
861 props struct {
862 Srcs []string `android:"path"`
863 Exclude_srcs []string `android:"path"`
Colin Cross8a497952019-03-05 22:25:09 -0800864
865 Src *string `android:"path"`
Colin Crossba71a3f2019-03-18 12:12:48 -0700866
867 Module_handles_missing_deps bool
Colin Cross937664a2019-03-06 10:17:32 -0800868 }
869
Colin Cross8a497952019-03-05 22:25:09 -0800870 src string
871 rel string
872
873 srcs []string
Colin Cross937664a2019-03-06 10:17:32 -0800874 rels []string
Colin Cross8a497952019-03-05 22:25:09 -0800875
876 missingDeps []string
Colin Cross937664a2019-03-06 10:17:32 -0800877}
878
Colin Cross8a497952019-03-05 22:25:09 -0800879func pathForModuleSrcTestModuleFactory() Module {
880 module := &pathForModuleSrcTestModule{}
Colin Cross937664a2019-03-06 10:17:32 -0800881 module.AddProperties(&module.props)
882 InitAndroidModule(module)
883 return module
884}
885
Colin Cross8a497952019-03-05 22:25:09 -0800886func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Crossba71a3f2019-03-18 12:12:48 -0700887 var srcs Paths
888 if p.props.Module_handles_missing_deps {
889 srcs, p.missingDeps = PathsAndMissingDepsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
890 } else {
891 srcs = PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
892 }
Colin Cross8a497952019-03-05 22:25:09 -0800893 p.srcs = srcs.Strings()
Colin Cross937664a2019-03-06 10:17:32 -0800894
Colin Cross8a497952019-03-05 22:25:09 -0800895 for _, src := range srcs {
Colin Cross937664a2019-03-06 10:17:32 -0800896 p.rels = append(p.rels, src.Rel())
897 }
Colin Cross8a497952019-03-05 22:25:09 -0800898
899 if p.props.Src != nil {
900 src := PathForModuleSrc(ctx, *p.props.Src)
901 if src != nil {
902 p.src = src.String()
903 p.rel = src.Rel()
904 }
905 }
906
Colin Crossba71a3f2019-03-18 12:12:48 -0700907 if !p.props.Module_handles_missing_deps {
908 p.missingDeps = ctx.GetMissingDependencies()
909 }
Colin Cross6c4f21f2019-06-06 15:41:36 -0700910
911 ctx.Build(pctx, BuildParams{
912 Rule: Touch,
913 Output: PathForModuleOut(ctx, "output"),
914 })
Colin Cross8a497952019-03-05 22:25:09 -0800915}
916
Colin Cross41955e82019-05-29 14:40:35 -0700917type pathForModuleSrcOutputFileProviderModule struct {
918 ModuleBase
919 props struct {
920 Outs []string
921 Tagged []string
922 }
923
924 outs Paths
925 tagged Paths
926}
927
928func pathForModuleSrcOutputFileProviderModuleFactory() Module {
929 module := &pathForModuleSrcOutputFileProviderModule{}
930 module.AddProperties(&module.props)
931 InitAndroidModule(module)
932 return module
933}
934
935func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
936 for _, out := range p.props.Outs {
937 p.outs = append(p.outs, PathForModuleOut(ctx, out))
938 }
939
940 for _, tagged := range p.props.Tagged {
941 p.tagged = append(p.tagged, PathForModuleOut(ctx, tagged))
942 }
943}
944
945func (p *pathForModuleSrcOutputFileProviderModule) OutputFiles(tag string) (Paths, error) {
946 switch tag {
947 case "":
948 return p.outs, nil
949 case ".tagged":
950 return p.tagged, nil
951 default:
952 return nil, fmt.Errorf("unsupported tag %q", tag)
953 }
954}
955
Colin Cross8a497952019-03-05 22:25:09 -0800956type pathForModuleSrcTestCase struct {
957 name string
958 bp string
959 srcs []string
960 rels []string
961 src string
962 rel string
963}
964
965func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSrcTestCase) {
966 for _, test := range tests {
967 t.Run(test.name, func(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -0800968 ctx := NewTestContext()
969
Colin Cross4b49b762019-11-22 15:25:03 -0800970 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
971 ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
972 ctx.RegisterModuleType("filegroup", FileGroupFactory)
Colin Cross8a497952019-03-05 22:25:09 -0800973
974 fgBp := `
975 filegroup {
976 name: "a",
977 srcs: ["src/a"],
978 }
979 `
980
Colin Cross41955e82019-05-29 14:40:35 -0700981 ofpBp := `
982 output_file_provider {
983 name: "b",
984 outs: ["gen/b"],
985 tagged: ["gen/c"],
986 }
987 `
988
Colin Cross8a497952019-03-05 22:25:09 -0800989 mockFS := map[string][]byte{
990 "fg/Android.bp": []byte(fgBp),
991 "foo/Android.bp": []byte(test.bp),
Colin Cross41955e82019-05-29 14:40:35 -0700992 "ofp/Android.bp": []byte(ofpBp),
Colin Cross8a497952019-03-05 22:25:09 -0800993 "fg/src/a": nil,
994 "foo/src/b": nil,
995 "foo/src/c": nil,
996 "foo/src/d": nil,
997 "foo/src/e/e": nil,
998 "foo/src_special/$": nil,
999 }
1000
Colin Cross98be1bb2019-12-13 20:41:13 -08001001 config := TestConfig(buildDir, nil, "", mockFS)
Colin Cross8a497952019-03-05 22:25:09 -08001002
Colin Cross98be1bb2019-12-13 20:41:13 -08001003 ctx.Register(config)
Colin Cross41955e82019-05-29 14:40:35 -07001004 _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp", "ofp/Android.bp"})
Colin Cross8a497952019-03-05 22:25:09 -08001005 FailIfErrored(t, errs)
1006 _, errs = ctx.PrepareBuildActions(config)
1007 FailIfErrored(t, errs)
1008
1009 m := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1010
1011 if g, w := m.srcs, test.srcs; !reflect.DeepEqual(g, w) {
1012 t.Errorf("want srcs %q, got %q", w, g)
1013 }
1014
1015 if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) {
1016 t.Errorf("want rels %q, got %q", w, g)
1017 }
1018
1019 if g, w := m.src, test.src; g != w {
1020 t.Errorf("want src %q, got %q", w, g)
1021 }
1022
1023 if g, w := m.rel, test.rel; g != w {
1024 t.Errorf("want rel %q, got %q", w, g)
1025 }
1026 })
1027 }
Colin Cross937664a2019-03-06 10:17:32 -08001028}
1029
Colin Cross8a497952019-03-05 22:25:09 -08001030func TestPathsForModuleSrc(t *testing.T) {
1031 tests := []pathForModuleSrcTestCase{
Colin Cross937664a2019-03-06 10:17:32 -08001032 {
1033 name: "path",
1034 bp: `
1035 test {
1036 name: "foo",
1037 srcs: ["src/b"],
1038 }`,
1039 srcs: []string{"foo/src/b"},
1040 rels: []string{"src/b"},
1041 },
1042 {
1043 name: "glob",
1044 bp: `
1045 test {
1046 name: "foo",
1047 srcs: [
1048 "src/*",
1049 "src/e/*",
1050 ],
1051 }`,
1052 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1053 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1054 },
1055 {
1056 name: "recursive glob",
1057 bp: `
1058 test {
1059 name: "foo",
1060 srcs: ["src/**/*"],
1061 }`,
1062 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1063 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1064 },
1065 {
1066 name: "filegroup",
1067 bp: `
1068 test {
1069 name: "foo",
1070 srcs: [":a"],
1071 }`,
1072 srcs: []string{"fg/src/a"},
1073 rels: []string{"src/a"},
1074 },
1075 {
Colin Cross41955e82019-05-29 14:40:35 -07001076 name: "output file provider",
1077 bp: `
1078 test {
1079 name: "foo",
1080 srcs: [":b"],
1081 }`,
1082 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"},
1083 rels: []string{"gen/b"},
1084 },
1085 {
1086 name: "output file provider tagged",
1087 bp: `
1088 test {
1089 name: "foo",
1090 srcs: [":b{.tagged}"],
1091 }`,
1092 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/c"},
1093 rels: []string{"gen/c"},
1094 },
1095 {
Jooyung Han7607dd32020-07-05 10:23:14 +09001096 name: "output file provider with exclude",
1097 bp: `
1098 test {
1099 name: "foo",
1100 srcs: [":b", ":c"],
1101 exclude_srcs: [":c"]
1102 }
1103 output_file_provider {
1104 name: "c",
1105 outs: ["gen/c"],
1106 }`,
1107 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"},
1108 rels: []string{"gen/b"},
1109 },
1110 {
Colin Cross937664a2019-03-06 10:17:32 -08001111 name: "special characters glob",
1112 bp: `
1113 test {
1114 name: "foo",
1115 srcs: ["src_special/*"],
1116 }`,
1117 srcs: []string{"foo/src_special/$"},
1118 rels: []string{"src_special/$"},
1119 },
1120 }
1121
Colin Cross41955e82019-05-29 14:40:35 -07001122 testPathForModuleSrc(t, buildDir, tests)
1123}
1124
1125func TestPathForModuleSrc(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001126 tests := []pathForModuleSrcTestCase{
1127 {
1128 name: "path",
1129 bp: `
1130 test {
1131 name: "foo",
1132 src: "src/b",
1133 }`,
1134 src: "foo/src/b",
1135 rel: "src/b",
1136 },
1137 {
1138 name: "glob",
1139 bp: `
1140 test {
1141 name: "foo",
1142 src: "src/e/*",
1143 }`,
1144 src: "foo/src/e/e",
1145 rel: "src/e/e",
1146 },
1147 {
1148 name: "filegroup",
1149 bp: `
1150 test {
1151 name: "foo",
1152 src: ":a",
1153 }`,
1154 src: "fg/src/a",
1155 rel: "src/a",
1156 },
1157 {
Colin Cross41955e82019-05-29 14:40:35 -07001158 name: "output file provider",
1159 bp: `
1160 test {
1161 name: "foo",
1162 src: ":b",
1163 }`,
1164 src: buildDir + "/.intermediates/ofp/b/gen/b",
1165 rel: "gen/b",
1166 },
1167 {
1168 name: "output file provider tagged",
1169 bp: `
1170 test {
1171 name: "foo",
1172 src: ":b{.tagged}",
1173 }`,
1174 src: buildDir + "/.intermediates/ofp/b/gen/c",
1175 rel: "gen/c",
1176 },
1177 {
Colin Cross8a497952019-03-05 22:25:09 -08001178 name: "special characters glob",
1179 bp: `
1180 test {
1181 name: "foo",
1182 src: "src_special/*",
1183 }`,
1184 src: "foo/src_special/$",
1185 rel: "src_special/$",
1186 },
1187 }
1188
Colin Cross8a497952019-03-05 22:25:09 -08001189 testPathForModuleSrc(t, buildDir, tests)
1190}
Colin Cross937664a2019-03-06 10:17:32 -08001191
Colin Cross8a497952019-03-05 22:25:09 -08001192func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001193 bp := `
1194 test {
1195 name: "foo",
1196 srcs: [":a"],
1197 exclude_srcs: [":b"],
1198 src: ":c",
1199 }
Colin Crossba71a3f2019-03-18 12:12:48 -07001200
1201 test {
1202 name: "bar",
1203 srcs: [":d"],
1204 exclude_srcs: [":e"],
1205 module_handles_missing_deps: true,
1206 }
Colin Cross8a497952019-03-05 22:25:09 -08001207 `
1208
Colin Cross98be1bb2019-12-13 20:41:13 -08001209 config := TestConfig(buildDir, nil, bp, nil)
1210 config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
Colin Cross8a497952019-03-05 22:25:09 -08001211
Colin Cross98be1bb2019-12-13 20:41:13 -08001212 ctx := NewTestContext()
1213 ctx.SetAllowMissingDependencies(true)
Colin Cross8a497952019-03-05 22:25:09 -08001214
Colin Cross98be1bb2019-12-13 20:41:13 -08001215 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1216
1217 ctx.Register(config)
1218
Colin Cross8a497952019-03-05 22:25:09 -08001219 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
1220 FailIfErrored(t, errs)
1221 _, errs = ctx.PrepareBuildActions(config)
1222 FailIfErrored(t, errs)
1223
1224 foo := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1225
1226 if g, w := foo.missingDeps, []string{"a", "b", "c"}; !reflect.DeepEqual(g, w) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001227 t.Errorf("want foo missing deps %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001228 }
1229
1230 if g, w := foo.srcs, []string{}; !reflect.DeepEqual(g, w) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001231 t.Errorf("want foo srcs %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001232 }
1233
1234 if g, w := foo.src, ""; g != w {
Colin Crossba71a3f2019-03-18 12:12:48 -07001235 t.Errorf("want foo src %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001236 }
1237
Colin Crossba71a3f2019-03-18 12:12:48 -07001238 bar := ctx.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
1239
1240 if g, w := bar.missingDeps, []string{"d", "e"}; !reflect.DeepEqual(g, w) {
1241 t.Errorf("want bar missing deps %q, got %q", w, g)
1242 }
1243
1244 if g, w := bar.srcs, []string{}; !reflect.DeepEqual(g, w) {
1245 t.Errorf("want bar srcs %q, got %q", w, g)
1246 }
Colin Cross937664a2019-03-06 10:17:32 -08001247}
1248
Colin Cross8854a5a2019-02-11 14:14:16 -08001249func ExampleOutputPath_ReplaceExtension() {
1250 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001251 config: TestConfig("out", nil, "", nil),
Colin Cross8854a5a2019-02-11 14:14:16 -08001252 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001253 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross8854a5a2019-02-11 14:14:16 -08001254 p2 := p.ReplaceExtension(ctx, "oat")
1255 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001256 fmt.Println(p.Rel(), p2.Rel())
Colin Cross8854a5a2019-02-11 14:14:16 -08001257
1258 // Output:
1259 // out/system/framework/boot.art out/system/framework/boot.oat
Colin Cross2cdd5df2019-02-25 10:25:24 -08001260 // boot.art boot.oat
Colin Cross8854a5a2019-02-11 14:14:16 -08001261}
Colin Cross40e33732019-02-15 11:08:35 -08001262
1263func ExampleOutputPath_FileInSameDir() {
1264 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001265 config: TestConfig("out", nil, "", nil),
Colin Cross40e33732019-02-15 11:08:35 -08001266 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001267 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross40e33732019-02-15 11:08:35 -08001268 p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
1269 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001270 fmt.Println(p.Rel(), p2.Rel())
Colin Cross40e33732019-02-15 11:08:35 -08001271
1272 // Output:
1273 // out/system/framework/boot.art out/system/framework/oat/arm/boot.vdex
Colin Cross2cdd5df2019-02-25 10:25:24 -08001274 // boot.art oat/arm/boot.vdex
Colin Cross40e33732019-02-15 11:08:35 -08001275}
Colin Cross27027c72020-02-28 15:34:17 -08001276
1277func BenchmarkFirstUniquePaths(b *testing.B) {
1278 implementations := []struct {
1279 name string
1280 f func(Paths) Paths
1281 }{
1282 {
1283 name: "list",
1284 f: firstUniquePathsList,
1285 },
1286 {
1287 name: "map",
1288 f: firstUniquePathsMap,
1289 },
1290 }
1291 const maxSize = 1024
1292 uniquePaths := make(Paths, maxSize)
1293 for i := range uniquePaths {
1294 uniquePaths[i] = PathForTesting(strconv.Itoa(i))
1295 }
1296 samePath := make(Paths, maxSize)
1297 for i := range samePath {
1298 samePath[i] = uniquePaths[0]
1299 }
1300
1301 f := func(b *testing.B, imp func(Paths) Paths, paths Paths) {
1302 for i := 0; i < b.N; i++ {
1303 b.ReportAllocs()
1304 paths = append(Paths(nil), paths...)
1305 imp(paths)
1306 }
1307 }
1308
1309 for n := 1; n <= maxSize; n <<= 1 {
1310 b.Run(strconv.Itoa(n), func(b *testing.B) {
1311 for _, implementation := range implementations {
1312 b.Run(implementation.name, func(b *testing.B) {
1313 b.Run("same", func(b *testing.B) {
1314 f(b, implementation.f, samePath[:n])
1315 })
1316 b.Run("unique", func(b *testing.B) {
1317 f(b, implementation.f, uniquePaths[:n])
1318 })
1319 })
1320 }
1321 })
1322 }
1323}