blob: 9ecf4a1e88c9d6ca2320757607039570929b42ce [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
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700203 inData bool
204 inTestcases bool
205 inSanitizerDir bool
206 inRamdisk bool
207 inVendorRamdisk bool
208 inRecovery bool
209 inRoot bool
210 forceOS *OsType
211 forceArch *ArchType
Dan Willemsen00269f22017-07-06 16:59:48 -0700212}
213
Colin Crossaabf6792017-11-29 00:27:14 -0800214func (m moduleInstallPathContextImpl) Config() Config {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700215 return m.baseModuleContext.config
Dan Willemsen00269f22017-07-06 16:59:48 -0700216}
217
218func (moduleInstallPathContextImpl) AddNinjaFileDeps(deps ...string) {}
219
220func (m moduleInstallPathContextImpl) InstallInData() bool {
221 return m.inData
222}
223
Jaewoong Jung0949f312019-09-11 10:25:18 -0700224func (m moduleInstallPathContextImpl) InstallInTestcases() bool {
225 return m.inTestcases
226}
227
Dan Willemsen00269f22017-07-06 16:59:48 -0700228func (m moduleInstallPathContextImpl) InstallInSanitizerDir() bool {
229 return m.inSanitizerDir
230}
231
Yifan Hong1b3348d2020-01-21 15:53:22 -0800232func (m moduleInstallPathContextImpl) InstallInRamdisk() bool {
233 return m.inRamdisk
234}
235
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700236func (m moduleInstallPathContextImpl) InstallInVendorRamdisk() bool {
237 return m.inVendorRamdisk
238}
239
Jiyong Parkf9332f12018-02-01 00:54:12 +0900240func (m moduleInstallPathContextImpl) InstallInRecovery() bool {
241 return m.inRecovery
242}
243
Colin Cross90ba5f42019-10-02 11:10:58 -0700244func (m moduleInstallPathContextImpl) InstallInRoot() bool {
245 return m.inRoot
246}
247
Colin Cross607d8582019-07-29 16:44:46 -0700248func (m moduleInstallPathContextImpl) InstallBypassMake() bool {
249 return false
250}
251
Jiyong Park87788b52020-09-01 12:37:45 +0900252func (m moduleInstallPathContextImpl) InstallForceOS() (*OsType, *ArchType) {
253 return m.forceOS, m.forceArch
Colin Cross6e359402020-02-10 15:29:54 -0800254}
255
Colin Cross98be1bb2019-12-13 20:41:13 -0800256func pathTestConfig(buildDir string) Config {
257 return TestConfig(buildDir, nil, "", nil)
258}
259
Dan Willemsen00269f22017-07-06 16:59:48 -0700260func TestPathForModuleInstall(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800261 testConfig := pathTestConfig("")
Dan Willemsen00269f22017-07-06 16:59:48 -0700262
Jiyong Park87788b52020-09-01 12:37:45 +0900263 hostTarget := Target{Os: Linux, Arch: Arch{ArchType: X86}}
264 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
Dan Willemsen00269f22017-07-06 16:59:48 -0700265
266 testCases := []struct {
267 name string
268 ctx *moduleInstallPathContextImpl
269 in []string
270 out string
271 }{
272 {
273 name: "host binary",
274 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700275 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800276 os: hostTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700277 target: hostTarget,
278 },
279 },
280 in: []string{"bin", "my_test"},
281 out: "host/linux-x86/bin/my_test",
282 },
283
284 {
285 name: "system binary",
286 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700287 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800288 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700289 target: deviceTarget,
290 },
291 },
292 in: []string{"bin", "my_test"},
293 out: "target/product/test_device/system/bin/my_test",
294 },
295 {
296 name: "vendor binary",
297 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700298 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800299 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700300 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800301 earlyModuleContext: earlyModuleContext{
302 kind: socSpecificModule,
303 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700304 },
305 },
306 in: []string{"bin", "my_test"},
307 out: "target/product/test_device/vendor/bin/my_test",
308 },
Jiyong Park2db76922017-11-08 16:03:48 +0900309 {
310 name: "odm binary",
311 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700312 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800313 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900314 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800315 earlyModuleContext: earlyModuleContext{
316 kind: deviceSpecificModule,
317 },
Jiyong Park2db76922017-11-08 16:03:48 +0900318 },
319 },
320 in: []string{"bin", "my_test"},
321 out: "target/product/test_device/odm/bin/my_test",
322 },
323 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900324 name: "product binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900325 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700326 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800327 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900328 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800329 earlyModuleContext: earlyModuleContext{
330 kind: productSpecificModule,
331 },
Jiyong Park2db76922017-11-08 16:03:48 +0900332 },
333 },
334 in: []string{"bin", "my_test"},
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900335 out: "target/product/test_device/product/bin/my_test",
Jiyong Park2db76922017-11-08 16:03:48 +0900336 },
Dario Frenifd05a742018-05-29 13:28:54 +0100337 {
Justin Yund5f6c822019-06-25 16:47:17 +0900338 name: "system_ext binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100339 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700340 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800341 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100342 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800343 earlyModuleContext: earlyModuleContext{
344 kind: systemExtSpecificModule,
345 },
Dario Frenifd05a742018-05-29 13:28:54 +0100346 },
347 },
348 in: []string{"bin", "my_test"},
Justin Yund5f6c822019-06-25 16:47:17 +0900349 out: "target/product/test_device/system_ext/bin/my_test",
Dario Frenifd05a742018-05-29 13:28:54 +0100350 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700351 {
352 name: "root binary",
353 ctx: &moduleInstallPathContextImpl{
354 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800355 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700356 target: deviceTarget,
357 },
358 inRoot: true,
359 },
360 in: []string{"my_test"},
361 out: "target/product/test_device/root/my_test",
362 },
363 {
364 name: "recovery binary",
365 ctx: &moduleInstallPathContextImpl{
366 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800367 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700368 target: deviceTarget,
369 },
370 inRecovery: true,
371 },
372 in: []string{"bin/my_test"},
373 out: "target/product/test_device/recovery/root/system/bin/my_test",
374 },
375 {
376 name: "recovery root binary",
377 ctx: &moduleInstallPathContextImpl{
378 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800379 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700380 target: deviceTarget,
381 },
382 inRecovery: true,
383 inRoot: true,
384 },
385 in: []string{"my_test"},
386 out: "target/product/test_device/recovery/root/my_test",
387 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700388
389 {
390 name: "system native test binary",
391 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700392 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800393 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700394 target: deviceTarget,
395 },
396 inData: true,
397 },
398 in: []string{"nativetest", "my_test"},
399 out: "target/product/test_device/data/nativetest/my_test",
400 },
401 {
402 name: "vendor native test binary",
403 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700404 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800405 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700406 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800407 earlyModuleContext: earlyModuleContext{
408 kind: socSpecificModule,
409 },
Jiyong Park2db76922017-11-08 16:03:48 +0900410 },
411 inData: true,
412 },
413 in: []string{"nativetest", "my_test"},
414 out: "target/product/test_device/data/nativetest/my_test",
415 },
416 {
417 name: "odm native test binary",
418 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700419 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800420 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900421 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800422 earlyModuleContext: earlyModuleContext{
423 kind: deviceSpecificModule,
424 },
Jiyong Park2db76922017-11-08 16:03:48 +0900425 },
426 inData: true,
427 },
428 in: []string{"nativetest", "my_test"},
429 out: "target/product/test_device/data/nativetest/my_test",
430 },
431 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900432 name: "product native test binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900433 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700434 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800435 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900436 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800437 earlyModuleContext: earlyModuleContext{
438 kind: productSpecificModule,
439 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700440 },
441 inData: true,
442 },
443 in: []string{"nativetest", "my_test"},
444 out: "target/product/test_device/data/nativetest/my_test",
445 },
446
447 {
Justin Yund5f6c822019-06-25 16:47:17 +0900448 name: "system_ext native test binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100449 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700450 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800451 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100452 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800453 earlyModuleContext: earlyModuleContext{
454 kind: systemExtSpecificModule,
455 },
Dario Frenifd05a742018-05-29 13:28:54 +0100456 },
457 inData: true,
458 },
459 in: []string{"nativetest", "my_test"},
460 out: "target/product/test_device/data/nativetest/my_test",
461 },
462
463 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700464 name: "sanitized system binary",
465 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700466 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800467 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700468 target: deviceTarget,
469 },
470 inSanitizerDir: true,
471 },
472 in: []string{"bin", "my_test"},
473 out: "target/product/test_device/data/asan/system/bin/my_test",
474 },
475 {
476 name: "sanitized vendor binary",
477 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700478 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800479 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700480 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800481 earlyModuleContext: earlyModuleContext{
482 kind: socSpecificModule,
483 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700484 },
485 inSanitizerDir: true,
486 },
487 in: []string{"bin", "my_test"},
488 out: "target/product/test_device/data/asan/vendor/bin/my_test",
489 },
Jiyong Park2db76922017-11-08 16:03:48 +0900490 {
491 name: "sanitized odm binary",
492 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700493 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800494 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900495 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800496 earlyModuleContext: earlyModuleContext{
497 kind: deviceSpecificModule,
498 },
Jiyong Park2db76922017-11-08 16:03:48 +0900499 },
500 inSanitizerDir: true,
501 },
502 in: []string{"bin", "my_test"},
503 out: "target/product/test_device/data/asan/odm/bin/my_test",
504 },
505 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900506 name: "sanitized product binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900507 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700508 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800509 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900510 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800511 earlyModuleContext: earlyModuleContext{
512 kind: productSpecificModule,
513 },
Jiyong Park2db76922017-11-08 16:03:48 +0900514 },
515 inSanitizerDir: true,
516 },
517 in: []string{"bin", "my_test"},
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900518 out: "target/product/test_device/data/asan/product/bin/my_test",
Jiyong Park2db76922017-11-08 16:03:48 +0900519 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700520
521 {
Justin Yund5f6c822019-06-25 16:47:17 +0900522 name: "sanitized system_ext binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100523 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700524 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800525 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100526 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800527 earlyModuleContext: earlyModuleContext{
528 kind: systemExtSpecificModule,
529 },
Dario Frenifd05a742018-05-29 13:28:54 +0100530 },
531 inSanitizerDir: true,
532 },
533 in: []string{"bin", "my_test"},
Justin Yund5f6c822019-06-25 16:47:17 +0900534 out: "target/product/test_device/data/asan/system_ext/bin/my_test",
Dario Frenifd05a742018-05-29 13:28:54 +0100535 },
536
537 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700538 name: "sanitized system native test binary",
539 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700540 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800541 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700542 target: deviceTarget,
543 },
544 inData: true,
545 inSanitizerDir: true,
546 },
547 in: []string{"nativetest", "my_test"},
548 out: "target/product/test_device/data/asan/data/nativetest/my_test",
549 },
550 {
551 name: "sanitized vendor native test binary",
552 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700553 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800554 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700555 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800556 earlyModuleContext: earlyModuleContext{
557 kind: socSpecificModule,
558 },
Jiyong Park2db76922017-11-08 16:03:48 +0900559 },
560 inData: true,
561 inSanitizerDir: true,
562 },
563 in: []string{"nativetest", "my_test"},
564 out: "target/product/test_device/data/asan/data/nativetest/my_test",
565 },
566 {
567 name: "sanitized odm native test binary",
568 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700569 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800570 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900571 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800572 earlyModuleContext: earlyModuleContext{
573 kind: deviceSpecificModule,
574 },
Jiyong Park2db76922017-11-08 16:03:48 +0900575 },
576 inData: true,
577 inSanitizerDir: true,
578 },
579 in: []string{"nativetest", "my_test"},
580 out: "target/product/test_device/data/asan/data/nativetest/my_test",
581 },
582 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900583 name: "sanitized product native test binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900584 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700585 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800586 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900587 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800588 earlyModuleContext: earlyModuleContext{
589 kind: productSpecificModule,
590 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700591 },
592 inData: true,
593 inSanitizerDir: true,
594 },
595 in: []string{"nativetest", "my_test"},
596 out: "target/product/test_device/data/asan/data/nativetest/my_test",
597 },
Dario Frenifd05a742018-05-29 13:28:54 +0100598 {
Justin Yund5f6c822019-06-25 16:47:17 +0900599 name: "sanitized system_ext native test binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100600 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700601 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800602 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100603 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800604 earlyModuleContext: earlyModuleContext{
605 kind: systemExtSpecificModule,
606 },
Dario Frenifd05a742018-05-29 13:28:54 +0100607 },
608 inData: true,
609 inSanitizerDir: true,
610 },
611 in: []string{"nativetest", "my_test"},
612 out: "target/product/test_device/data/asan/data/nativetest/my_test",
Colin Cross6e359402020-02-10 15:29:54 -0800613 }, {
614 name: "device testcases",
615 ctx: &moduleInstallPathContextImpl{
616 baseModuleContext: baseModuleContext{
617 os: deviceTarget.Os,
618 target: deviceTarget,
619 },
620 inTestcases: true,
621 },
622 in: []string{"my_test", "my_test_bin"},
623 out: "target/product/test_device/testcases/my_test/my_test_bin",
624 }, {
625 name: "host testcases",
626 ctx: &moduleInstallPathContextImpl{
627 baseModuleContext: baseModuleContext{
628 os: hostTarget.Os,
629 target: hostTarget,
630 },
631 inTestcases: true,
632 },
633 in: []string{"my_test", "my_test_bin"},
634 out: "host/linux-x86/testcases/my_test/my_test_bin",
635 }, {
636 name: "forced host testcases",
637 ctx: &moduleInstallPathContextImpl{
638 baseModuleContext: baseModuleContext{
639 os: deviceTarget.Os,
640 target: deviceTarget,
641 },
642 inTestcases: true,
643 forceOS: &Linux,
Jiyong Park87788b52020-09-01 12:37:45 +0900644 forceArch: &X86,
Colin Cross6e359402020-02-10 15:29:54 -0800645 },
646 in: []string{"my_test", "my_test_bin"},
647 out: "host/linux-x86/testcases/my_test/my_test_bin",
Dario Frenifd05a742018-05-29 13:28:54 +0100648 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700649 }
650
651 for _, tc := range testCases {
652 t.Run(tc.name, func(t *testing.T) {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700653 tc.ctx.baseModuleContext.config = testConfig
Dan Willemsen00269f22017-07-06 16:59:48 -0700654 output := PathForModuleInstall(tc.ctx, tc.in...)
655 if output.basePath.path != tc.out {
656 t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
657 output.basePath.path,
658 tc.out)
659 }
660 })
661 }
662}
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700663
664func TestDirectorySortedPaths(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800665 config := TestConfig("out", nil, "", map[string][]byte{
666 "Android.bp": nil,
667 "a.txt": nil,
668 "a/txt": nil,
669 "a/b/c": nil,
670 "a/b/d": nil,
671 "b": nil,
672 "b/b.txt": nil,
673 "a/a.txt": nil,
Colin Cross07e51612019-03-05 12:46:40 -0800674 })
675
Colin Cross98be1bb2019-12-13 20:41:13 -0800676 ctx := PathContextForTesting(config)
677
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700678 makePaths := func() Paths {
679 return Paths{
Colin Cross07e51612019-03-05 12:46:40 -0800680 PathForSource(ctx, "a.txt"),
681 PathForSource(ctx, "a/txt"),
682 PathForSource(ctx, "a/b/c"),
683 PathForSource(ctx, "a/b/d"),
684 PathForSource(ctx, "b"),
685 PathForSource(ctx, "b/b.txt"),
686 PathForSource(ctx, "a/a.txt"),
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700687 }
688 }
689
690 expected := []string{
691 "a.txt",
692 "a/a.txt",
693 "a/b/c",
694 "a/b/d",
695 "a/txt",
696 "b",
697 "b/b.txt",
698 }
699
700 paths := makePaths()
Colin Crossa140bb02018-04-17 10:52:26 -0700701 reversePaths := ReversePaths(paths)
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700702
703 sortedPaths := PathsToDirectorySortedPaths(paths)
704 reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
705
706 if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
707 t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
708 }
709
710 if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
711 t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
712 }
713
714 expectedA := []string{
715 "a/a.txt",
716 "a/b/c",
717 "a/b/d",
718 "a/txt",
719 }
720
721 inA := sortedPaths.PathsInDirectory("a")
722 if !reflect.DeepEqual(inA.Strings(), expectedA) {
723 t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
724 }
725
726 expectedA_B := []string{
727 "a/b/c",
728 "a/b/d",
729 }
730
731 inA_B := sortedPaths.PathsInDirectory("a/b")
732 if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
733 t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
734 }
735
736 expectedB := []string{
737 "b/b.txt",
738 }
739
740 inB := sortedPaths.PathsInDirectory("b")
741 if !reflect.DeepEqual(inB.Strings(), expectedB) {
742 t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
743 }
744}
Colin Cross43f08db2018-11-12 10:13:39 -0800745
746func TestMaybeRel(t *testing.T) {
747 testCases := []struct {
748 name string
749 base string
750 target string
751 out string
752 isRel bool
753 }{
754 {
755 name: "normal",
756 base: "a/b/c",
757 target: "a/b/c/d",
758 out: "d",
759 isRel: true,
760 },
761 {
762 name: "parent",
763 base: "a/b/c/d",
764 target: "a/b/c",
765 isRel: false,
766 },
767 {
768 name: "not relative",
769 base: "a/b",
770 target: "c/d",
771 isRel: false,
772 },
773 {
774 name: "abs1",
775 base: "/a",
776 target: "a",
777 isRel: false,
778 },
779 {
780 name: "abs2",
781 base: "a",
782 target: "/a",
783 isRel: false,
784 },
785 }
786
787 for _, testCase := range testCases {
788 t.Run(testCase.name, func(t *testing.T) {
789 ctx := &configErrorWrapper{}
790 out, isRel := MaybeRel(ctx, testCase.base, testCase.target)
791 if len(ctx.errors) > 0 {
792 t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v",
793 testCase.base, testCase.target, ctx.errors)
794 }
795 if isRel != testCase.isRel || out != testCase.out {
796 t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v",
797 testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel)
798 }
799 })
800 }
801}
Colin Cross7b3dcc32019-01-24 13:14:39 -0800802
803func TestPathForSource(t *testing.T) {
804 testCases := []struct {
805 name string
806 buildDir string
807 src string
808 err string
809 }{
810 {
811 name: "normal",
812 buildDir: "out",
813 src: "a/b/c",
814 },
815 {
816 name: "abs",
817 buildDir: "out",
818 src: "/a/b/c",
819 err: "is outside directory",
820 },
821 {
822 name: "in out dir",
823 buildDir: "out",
824 src: "out/a/b/c",
825 err: "is in output",
826 },
827 }
828
829 funcs := []struct {
830 name string
831 f func(ctx PathContext, pathComponents ...string) (SourcePath, error)
832 }{
833 {"pathForSource", pathForSource},
834 {"safePathForSource", safePathForSource},
835 }
836
837 for _, f := range funcs {
838 t.Run(f.name, func(t *testing.T) {
839 for _, test := range testCases {
840 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800841 testConfig := pathTestConfig(test.buildDir)
Colin Cross7b3dcc32019-01-24 13:14:39 -0800842 ctx := &configErrorWrapper{config: testConfig}
843 _, err := f.f(ctx, test.src)
844 if len(ctx.errors) > 0 {
845 t.Fatalf("unexpected errors %v", ctx.errors)
846 }
847 if err != nil {
848 if test.err == "" {
849 t.Fatalf("unexpected error %q", err.Error())
850 } else if !strings.Contains(err.Error(), test.err) {
851 t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
852 }
853 } else {
854 if test.err != "" {
855 t.Fatalf("missing error %q", test.err)
856 }
857 }
858 })
859 }
860 })
861 }
862}
Colin Cross8854a5a2019-02-11 14:14:16 -0800863
Colin Cross8a497952019-03-05 22:25:09 -0800864type pathForModuleSrcTestModule struct {
Colin Cross937664a2019-03-06 10:17:32 -0800865 ModuleBase
866 props struct {
867 Srcs []string `android:"path"`
868 Exclude_srcs []string `android:"path"`
Colin Cross8a497952019-03-05 22:25:09 -0800869
870 Src *string `android:"path"`
Colin Crossba71a3f2019-03-18 12:12:48 -0700871
872 Module_handles_missing_deps bool
Colin Cross937664a2019-03-06 10:17:32 -0800873 }
874
Colin Cross8a497952019-03-05 22:25:09 -0800875 src string
876 rel string
877
878 srcs []string
Colin Cross937664a2019-03-06 10:17:32 -0800879 rels []string
Colin Cross8a497952019-03-05 22:25:09 -0800880
881 missingDeps []string
Colin Cross937664a2019-03-06 10:17:32 -0800882}
883
Colin Cross8a497952019-03-05 22:25:09 -0800884func pathForModuleSrcTestModuleFactory() Module {
885 module := &pathForModuleSrcTestModule{}
Colin Cross937664a2019-03-06 10:17:32 -0800886 module.AddProperties(&module.props)
887 InitAndroidModule(module)
888 return module
889}
890
Colin Cross8a497952019-03-05 22:25:09 -0800891func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Crossba71a3f2019-03-18 12:12:48 -0700892 var srcs Paths
893 if p.props.Module_handles_missing_deps {
894 srcs, p.missingDeps = PathsAndMissingDepsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
895 } else {
896 srcs = PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
897 }
Colin Cross8a497952019-03-05 22:25:09 -0800898 p.srcs = srcs.Strings()
Colin Cross937664a2019-03-06 10:17:32 -0800899
Colin Cross8a497952019-03-05 22:25:09 -0800900 for _, src := range srcs {
Colin Cross937664a2019-03-06 10:17:32 -0800901 p.rels = append(p.rels, src.Rel())
902 }
Colin Cross8a497952019-03-05 22:25:09 -0800903
904 if p.props.Src != nil {
905 src := PathForModuleSrc(ctx, *p.props.Src)
906 if src != nil {
907 p.src = src.String()
908 p.rel = src.Rel()
909 }
910 }
911
Colin Crossba71a3f2019-03-18 12:12:48 -0700912 if !p.props.Module_handles_missing_deps {
913 p.missingDeps = ctx.GetMissingDependencies()
914 }
Colin Cross6c4f21f2019-06-06 15:41:36 -0700915
916 ctx.Build(pctx, BuildParams{
917 Rule: Touch,
918 Output: PathForModuleOut(ctx, "output"),
919 })
Colin Cross8a497952019-03-05 22:25:09 -0800920}
921
Colin Cross41955e82019-05-29 14:40:35 -0700922type pathForModuleSrcOutputFileProviderModule struct {
923 ModuleBase
924 props struct {
925 Outs []string
926 Tagged []string
927 }
928
929 outs Paths
930 tagged Paths
931}
932
933func pathForModuleSrcOutputFileProviderModuleFactory() Module {
934 module := &pathForModuleSrcOutputFileProviderModule{}
935 module.AddProperties(&module.props)
936 InitAndroidModule(module)
937 return module
938}
939
940func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
941 for _, out := range p.props.Outs {
942 p.outs = append(p.outs, PathForModuleOut(ctx, out))
943 }
944
945 for _, tagged := range p.props.Tagged {
946 p.tagged = append(p.tagged, PathForModuleOut(ctx, tagged))
947 }
948}
949
950func (p *pathForModuleSrcOutputFileProviderModule) OutputFiles(tag string) (Paths, error) {
951 switch tag {
952 case "":
953 return p.outs, nil
954 case ".tagged":
955 return p.tagged, nil
956 default:
957 return nil, fmt.Errorf("unsupported tag %q", tag)
958 }
959}
960
Colin Cross8a497952019-03-05 22:25:09 -0800961type pathForModuleSrcTestCase struct {
962 name string
963 bp string
964 srcs []string
965 rels []string
966 src string
967 rel string
968}
969
970func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSrcTestCase) {
971 for _, test := range tests {
972 t.Run(test.name, func(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -0800973 ctx := NewTestContext()
974
Colin Cross4b49b762019-11-22 15:25:03 -0800975 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
976 ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
977 ctx.RegisterModuleType("filegroup", FileGroupFactory)
Colin Cross8a497952019-03-05 22:25:09 -0800978
979 fgBp := `
980 filegroup {
981 name: "a",
982 srcs: ["src/a"],
983 }
984 `
985
Colin Cross41955e82019-05-29 14:40:35 -0700986 ofpBp := `
987 output_file_provider {
988 name: "b",
989 outs: ["gen/b"],
990 tagged: ["gen/c"],
991 }
992 `
993
Colin Cross8a497952019-03-05 22:25:09 -0800994 mockFS := map[string][]byte{
995 "fg/Android.bp": []byte(fgBp),
996 "foo/Android.bp": []byte(test.bp),
Colin Cross41955e82019-05-29 14:40:35 -0700997 "ofp/Android.bp": []byte(ofpBp),
Colin Cross8a497952019-03-05 22:25:09 -0800998 "fg/src/a": nil,
999 "foo/src/b": nil,
1000 "foo/src/c": nil,
1001 "foo/src/d": nil,
1002 "foo/src/e/e": nil,
1003 "foo/src_special/$": nil,
1004 }
1005
Colin Cross98be1bb2019-12-13 20:41:13 -08001006 config := TestConfig(buildDir, nil, "", mockFS)
Colin Cross8a497952019-03-05 22:25:09 -08001007
Colin Cross98be1bb2019-12-13 20:41:13 -08001008 ctx.Register(config)
Colin Cross41955e82019-05-29 14:40:35 -07001009 _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp", "ofp/Android.bp"})
Colin Cross8a497952019-03-05 22:25:09 -08001010 FailIfErrored(t, errs)
1011 _, errs = ctx.PrepareBuildActions(config)
1012 FailIfErrored(t, errs)
1013
1014 m := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1015
1016 if g, w := m.srcs, test.srcs; !reflect.DeepEqual(g, w) {
1017 t.Errorf("want srcs %q, got %q", w, g)
1018 }
1019
1020 if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) {
1021 t.Errorf("want rels %q, got %q", w, g)
1022 }
1023
1024 if g, w := m.src, test.src; g != w {
1025 t.Errorf("want src %q, got %q", w, g)
1026 }
1027
1028 if g, w := m.rel, test.rel; g != w {
1029 t.Errorf("want rel %q, got %q", w, g)
1030 }
1031 })
1032 }
Colin Cross937664a2019-03-06 10:17:32 -08001033}
1034
Colin Cross8a497952019-03-05 22:25:09 -08001035func TestPathsForModuleSrc(t *testing.T) {
1036 tests := []pathForModuleSrcTestCase{
Colin Cross937664a2019-03-06 10:17:32 -08001037 {
1038 name: "path",
1039 bp: `
1040 test {
1041 name: "foo",
1042 srcs: ["src/b"],
1043 }`,
1044 srcs: []string{"foo/src/b"},
1045 rels: []string{"src/b"},
1046 },
1047 {
1048 name: "glob",
1049 bp: `
1050 test {
1051 name: "foo",
1052 srcs: [
1053 "src/*",
1054 "src/e/*",
1055 ],
1056 }`,
1057 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1058 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1059 },
1060 {
1061 name: "recursive glob",
1062 bp: `
1063 test {
1064 name: "foo",
1065 srcs: ["src/**/*"],
1066 }`,
1067 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1068 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1069 },
1070 {
1071 name: "filegroup",
1072 bp: `
1073 test {
1074 name: "foo",
1075 srcs: [":a"],
1076 }`,
1077 srcs: []string{"fg/src/a"},
1078 rels: []string{"src/a"},
1079 },
1080 {
Colin Cross41955e82019-05-29 14:40:35 -07001081 name: "output file provider",
1082 bp: `
1083 test {
1084 name: "foo",
1085 srcs: [":b"],
1086 }`,
1087 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"},
1088 rels: []string{"gen/b"},
1089 },
1090 {
1091 name: "output file provider tagged",
1092 bp: `
1093 test {
1094 name: "foo",
1095 srcs: [":b{.tagged}"],
1096 }`,
1097 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/c"},
1098 rels: []string{"gen/c"},
1099 },
1100 {
Jooyung Han7607dd32020-07-05 10:23:14 +09001101 name: "output file provider with exclude",
1102 bp: `
1103 test {
1104 name: "foo",
1105 srcs: [":b", ":c"],
1106 exclude_srcs: [":c"]
1107 }
1108 output_file_provider {
1109 name: "c",
1110 outs: ["gen/c"],
1111 }`,
1112 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"},
1113 rels: []string{"gen/b"},
1114 },
1115 {
Colin Cross937664a2019-03-06 10:17:32 -08001116 name: "special characters glob",
1117 bp: `
1118 test {
1119 name: "foo",
1120 srcs: ["src_special/*"],
1121 }`,
1122 srcs: []string{"foo/src_special/$"},
1123 rels: []string{"src_special/$"},
1124 },
1125 }
1126
Colin Cross41955e82019-05-29 14:40:35 -07001127 testPathForModuleSrc(t, buildDir, tests)
1128}
1129
1130func TestPathForModuleSrc(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001131 tests := []pathForModuleSrcTestCase{
1132 {
1133 name: "path",
1134 bp: `
1135 test {
1136 name: "foo",
1137 src: "src/b",
1138 }`,
1139 src: "foo/src/b",
1140 rel: "src/b",
1141 },
1142 {
1143 name: "glob",
1144 bp: `
1145 test {
1146 name: "foo",
1147 src: "src/e/*",
1148 }`,
1149 src: "foo/src/e/e",
1150 rel: "src/e/e",
1151 },
1152 {
1153 name: "filegroup",
1154 bp: `
1155 test {
1156 name: "foo",
1157 src: ":a",
1158 }`,
1159 src: "fg/src/a",
1160 rel: "src/a",
1161 },
1162 {
Colin Cross41955e82019-05-29 14:40:35 -07001163 name: "output file provider",
1164 bp: `
1165 test {
1166 name: "foo",
1167 src: ":b",
1168 }`,
1169 src: buildDir + "/.intermediates/ofp/b/gen/b",
1170 rel: "gen/b",
1171 },
1172 {
1173 name: "output file provider tagged",
1174 bp: `
1175 test {
1176 name: "foo",
1177 src: ":b{.tagged}",
1178 }`,
1179 src: buildDir + "/.intermediates/ofp/b/gen/c",
1180 rel: "gen/c",
1181 },
1182 {
Colin Cross8a497952019-03-05 22:25:09 -08001183 name: "special characters glob",
1184 bp: `
1185 test {
1186 name: "foo",
1187 src: "src_special/*",
1188 }`,
1189 src: "foo/src_special/$",
1190 rel: "src_special/$",
1191 },
1192 }
1193
Colin Cross8a497952019-03-05 22:25:09 -08001194 testPathForModuleSrc(t, buildDir, tests)
1195}
Colin Cross937664a2019-03-06 10:17:32 -08001196
Colin Cross8a497952019-03-05 22:25:09 -08001197func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001198 bp := `
1199 test {
1200 name: "foo",
1201 srcs: [":a"],
1202 exclude_srcs: [":b"],
1203 src: ":c",
1204 }
Colin Crossba71a3f2019-03-18 12:12:48 -07001205
1206 test {
1207 name: "bar",
1208 srcs: [":d"],
1209 exclude_srcs: [":e"],
1210 module_handles_missing_deps: true,
1211 }
Colin Cross8a497952019-03-05 22:25:09 -08001212 `
1213
Colin Cross98be1bb2019-12-13 20:41:13 -08001214 config := TestConfig(buildDir, nil, bp, nil)
1215 config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
Colin Cross8a497952019-03-05 22:25:09 -08001216
Colin Cross98be1bb2019-12-13 20:41:13 -08001217 ctx := NewTestContext()
1218 ctx.SetAllowMissingDependencies(true)
Colin Cross8a497952019-03-05 22:25:09 -08001219
Colin Cross98be1bb2019-12-13 20:41:13 -08001220 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1221
1222 ctx.Register(config)
1223
Colin Cross8a497952019-03-05 22:25:09 -08001224 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
1225 FailIfErrored(t, errs)
1226 _, errs = ctx.PrepareBuildActions(config)
1227 FailIfErrored(t, errs)
1228
1229 foo := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1230
1231 if g, w := foo.missingDeps, []string{"a", "b", "c"}; !reflect.DeepEqual(g, w) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001232 t.Errorf("want foo missing deps %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001233 }
1234
1235 if g, w := foo.srcs, []string{}; !reflect.DeepEqual(g, w) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001236 t.Errorf("want foo srcs %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001237 }
1238
1239 if g, w := foo.src, ""; g != w {
Colin Crossba71a3f2019-03-18 12:12:48 -07001240 t.Errorf("want foo src %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001241 }
1242
Colin Crossba71a3f2019-03-18 12:12:48 -07001243 bar := ctx.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
1244
1245 if g, w := bar.missingDeps, []string{"d", "e"}; !reflect.DeepEqual(g, w) {
1246 t.Errorf("want bar missing deps %q, got %q", w, g)
1247 }
1248
1249 if g, w := bar.srcs, []string{}; !reflect.DeepEqual(g, w) {
1250 t.Errorf("want bar srcs %q, got %q", w, g)
1251 }
Colin Cross937664a2019-03-06 10:17:32 -08001252}
1253
Colin Cross8854a5a2019-02-11 14:14:16 -08001254func ExampleOutputPath_ReplaceExtension() {
1255 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001256 config: TestConfig("out", nil, "", nil),
Colin Cross8854a5a2019-02-11 14:14:16 -08001257 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001258 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross8854a5a2019-02-11 14:14:16 -08001259 p2 := p.ReplaceExtension(ctx, "oat")
1260 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001261 fmt.Println(p.Rel(), p2.Rel())
Colin Cross8854a5a2019-02-11 14:14:16 -08001262
1263 // Output:
1264 // out/system/framework/boot.art out/system/framework/boot.oat
Colin Cross2cdd5df2019-02-25 10:25:24 -08001265 // boot.art boot.oat
Colin Cross8854a5a2019-02-11 14:14:16 -08001266}
Colin Cross40e33732019-02-15 11:08:35 -08001267
Colin Cross41b46762020-10-09 19:26:32 -07001268func ExampleOutputPath_InSameDir() {
Colin Cross40e33732019-02-15 11:08:35 -08001269 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001270 config: TestConfig("out", nil, "", nil),
Colin Cross40e33732019-02-15 11:08:35 -08001271 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001272 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross40e33732019-02-15 11:08:35 -08001273 p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
1274 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001275 fmt.Println(p.Rel(), p2.Rel())
Colin Cross40e33732019-02-15 11:08:35 -08001276
1277 // Output:
1278 // out/system/framework/boot.art out/system/framework/oat/arm/boot.vdex
Colin Cross2cdd5df2019-02-25 10:25:24 -08001279 // boot.art oat/arm/boot.vdex
Colin Cross40e33732019-02-15 11:08:35 -08001280}
Colin Cross27027c72020-02-28 15:34:17 -08001281
1282func BenchmarkFirstUniquePaths(b *testing.B) {
1283 implementations := []struct {
1284 name string
1285 f func(Paths) Paths
1286 }{
1287 {
1288 name: "list",
1289 f: firstUniquePathsList,
1290 },
1291 {
1292 name: "map",
1293 f: firstUniquePathsMap,
1294 },
1295 }
1296 const maxSize = 1024
1297 uniquePaths := make(Paths, maxSize)
1298 for i := range uniquePaths {
1299 uniquePaths[i] = PathForTesting(strconv.Itoa(i))
1300 }
1301 samePath := make(Paths, maxSize)
1302 for i := range samePath {
1303 samePath[i] = uniquePaths[0]
1304 }
1305
1306 f := func(b *testing.B, imp func(Paths) Paths, paths Paths) {
1307 for i := 0; i < b.N; i++ {
1308 b.ReportAllocs()
1309 paths = append(Paths(nil), paths...)
1310 imp(paths)
1311 }
1312 }
1313
1314 for n := 1; n <= maxSize; n <<= 1 {
1315 b.Run(strconv.Itoa(n), func(b *testing.B) {
1316 for _, implementation := range implementations {
1317 b.Run(implementation.name, func(b *testing.B) {
1318 b.Run("same", func(b *testing.B) {
1319 f(b, implementation.f, samePath[:n])
1320 })
1321 b.Run("unique", func(b *testing.B) {
1322 f(b, implementation.f, uniquePaths[:n])
1323 })
1324 })
1325 }
1326 })
1327 }
1328}