blob: f1908ac1d11e51d199c6358d02c46df756c26220 [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"
21 "strings"
22 "testing"
Dan Willemsen00269f22017-07-06 16:59:48 -070023
Colin Cross8a497952019-03-05 22:25:09 -080024 "github.com/google/blueprint/proptools"
Dan Willemsen34cc69e2015-09-23 15:26:20 -070025)
26
27type strsTestCase struct {
28 in []string
29 out string
30 err []error
31}
32
33var commonValidatePathTestCases = []strsTestCase{
34 {
35 in: []string{""},
36 out: "",
37 },
38 {
39 in: []string{"a/b"},
40 out: "a/b",
41 },
42 {
43 in: []string{"a/b", "c"},
44 out: "a/b/c",
45 },
46 {
47 in: []string{"a/.."},
48 out: ".",
49 },
50 {
51 in: []string{"."},
52 out: ".",
53 },
54 {
55 in: []string{".."},
56 out: "",
57 err: []error{errors.New("Path is outside directory: ..")},
58 },
59 {
60 in: []string{"../a"},
61 out: "",
62 err: []error{errors.New("Path is outside directory: ../a")},
63 },
64 {
65 in: []string{"b/../../a"},
66 out: "",
67 err: []error{errors.New("Path is outside directory: ../a")},
68 },
69 {
70 in: []string{"/a"},
71 out: "",
72 err: []error{errors.New("Path is outside directory: /a")},
73 },
Dan Willemsen80a7c2a2015-12-21 14:57:11 -080074 {
75 in: []string{"a", "../b"},
76 out: "",
77 err: []error{errors.New("Path is outside directory: ../b")},
78 },
79 {
80 in: []string{"a", "b/../../c"},
81 out: "",
82 err: []error{errors.New("Path is outside directory: ../c")},
83 },
84 {
85 in: []string{"a", "./.."},
86 out: "",
87 err: []error{errors.New("Path is outside directory: ..")},
88 },
Dan Willemsen34cc69e2015-09-23 15:26:20 -070089}
90
91var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
92 {
93 in: []string{"$host/../$a"},
94 out: "$a",
95 },
96}...)
97
98var validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
99 {
100 in: []string{"$host/../$a"},
101 out: "",
102 err: []error{errors.New("Path contains invalid character($): $host/../$a")},
103 },
104 {
105 in: []string{"$host/.."},
106 out: "",
107 err: []error{errors.New("Path contains invalid character($): $host/..")},
108 },
109}...)
110
111func TestValidateSafePath(t *testing.T) {
112 for _, testCase := range validateSafePathTestCases {
Colin Crossdc75ae72018-02-22 13:48:13 -0800113 t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
114 ctx := &configErrorWrapper{}
Colin Cross1ccfcc32018-02-22 13:54:26 -0800115 out, err := validateSafePath(testCase.in...)
116 if err != nil {
117 reportPathError(ctx, err)
118 }
Colin Crossdc75ae72018-02-22 13:48:13 -0800119 check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
120 })
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700121 }
122}
123
124func TestValidatePath(t *testing.T) {
125 for _, testCase := range validatePathTestCases {
Colin Crossdc75ae72018-02-22 13:48:13 -0800126 t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
127 ctx := &configErrorWrapper{}
Colin Cross1ccfcc32018-02-22 13:54:26 -0800128 out, err := validatePath(testCase.in...)
129 if err != nil {
130 reportPathError(ctx, err)
131 }
Colin Crossdc75ae72018-02-22 13:48:13 -0800132 check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
133 })
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700134 }
135}
136
137func TestOptionalPath(t *testing.T) {
138 var path OptionalPath
139 checkInvalidOptionalPath(t, path)
140
141 path = OptionalPathForPath(nil)
142 checkInvalidOptionalPath(t, path)
143}
144
145func checkInvalidOptionalPath(t *testing.T, path OptionalPath) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800146 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700147 if path.Valid() {
148 t.Errorf("Uninitialized OptionalPath should not be valid")
149 }
150 if path.String() != "" {
151 t.Errorf("Uninitialized OptionalPath String() should return \"\", not %q", path.String())
152 }
153 defer func() {
154 if r := recover(); r == nil {
155 t.Errorf("Expected a panic when calling Path() on an uninitialized OptionalPath")
156 }
157 }()
158 path.Path()
159}
160
161func check(t *testing.T, testType, testString string,
162 got interface{}, err []error,
163 expected interface{}, expectedErr []error) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800164 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700165
166 printedTestCase := false
167 e := func(s string, expected, got interface{}) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800168 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700169 if !printedTestCase {
170 t.Errorf("test case %s: %s", testType, testString)
171 printedTestCase = true
172 }
173 t.Errorf("incorrect %s", s)
174 t.Errorf(" expected: %s", p(expected))
175 t.Errorf(" got: %s", p(got))
176 }
177
178 if !reflect.DeepEqual(expectedErr, err) {
179 e("errors:", expectedErr, err)
180 }
181
182 if !reflect.DeepEqual(expected, got) {
183 e("output:", expected, got)
184 }
185}
186
187func p(in interface{}) string {
188 if v, ok := in.([]interface{}); ok {
189 s := make([]string, len(v))
190 for i := range v {
191 s[i] = fmt.Sprintf("%#v", v[i])
192 }
193 return "[" + strings.Join(s, ", ") + "]"
194 } else {
195 return fmt.Sprintf("%#v", in)
196 }
197}
Dan Willemsen00269f22017-07-06 16:59:48 -0700198
199type moduleInstallPathContextImpl struct {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700200 baseModuleContext
Dan Willemsen00269f22017-07-06 16:59:48 -0700201
202 inData bool
Jaewoong Jung0949f312019-09-11 10:25:18 -0700203 inTestcases bool
Dan Willemsen00269f22017-07-06 16:59:48 -0700204 inSanitizerDir bool
Yifan Hong1b3348d2020-01-21 15:53:22 -0800205 inRamdisk bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900206 inRecovery bool
Colin Cross90ba5f42019-10-02 11:10:58 -0700207 inRoot bool
Colin Cross6e359402020-02-10 15:29:54 -0800208 forceOS *OsType
Dan Willemsen00269f22017-07-06 16:59:48 -0700209}
210
Colin Crossaabf6792017-11-29 00:27:14 -0800211func (m moduleInstallPathContextImpl) Config() Config {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700212 return m.baseModuleContext.config
Dan Willemsen00269f22017-07-06 16:59:48 -0700213}
214
215func (moduleInstallPathContextImpl) AddNinjaFileDeps(deps ...string) {}
216
217func (m moduleInstallPathContextImpl) InstallInData() bool {
218 return m.inData
219}
220
Jaewoong Jung0949f312019-09-11 10:25:18 -0700221func (m moduleInstallPathContextImpl) InstallInTestcases() bool {
222 return m.inTestcases
223}
224
Dan Willemsen00269f22017-07-06 16:59:48 -0700225func (m moduleInstallPathContextImpl) InstallInSanitizerDir() bool {
226 return m.inSanitizerDir
227}
228
Yifan Hong1b3348d2020-01-21 15:53:22 -0800229func (m moduleInstallPathContextImpl) InstallInRamdisk() bool {
230 return m.inRamdisk
231}
232
Jiyong Parkf9332f12018-02-01 00:54:12 +0900233func (m moduleInstallPathContextImpl) InstallInRecovery() bool {
234 return m.inRecovery
235}
236
Colin Cross90ba5f42019-10-02 11:10:58 -0700237func (m moduleInstallPathContextImpl) InstallInRoot() bool {
238 return m.inRoot
239}
240
Colin Cross607d8582019-07-29 16:44:46 -0700241func (m moduleInstallPathContextImpl) InstallBypassMake() bool {
242 return false
243}
244
Colin Cross6e359402020-02-10 15:29:54 -0800245func (m moduleInstallPathContextImpl) InstallForceOS() *OsType {
246 return m.forceOS
247}
248
Colin Cross98be1bb2019-12-13 20:41:13 -0800249func pathTestConfig(buildDir string) Config {
250 return TestConfig(buildDir, nil, "", nil)
251}
252
Dan Willemsen00269f22017-07-06 16:59:48 -0700253func TestPathForModuleInstall(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800254 testConfig := pathTestConfig("")
Dan Willemsen00269f22017-07-06 16:59:48 -0700255
256 hostTarget := Target{Os: Linux}
257 deviceTarget := Target{Os: Android}
258
259 testCases := []struct {
260 name string
261 ctx *moduleInstallPathContextImpl
262 in []string
263 out string
264 }{
265 {
266 name: "host binary",
267 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700268 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800269 os: hostTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700270 target: hostTarget,
271 },
272 },
273 in: []string{"bin", "my_test"},
274 out: "host/linux-x86/bin/my_test",
275 },
276
277 {
278 name: "system binary",
279 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700280 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800281 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700282 target: deviceTarget,
283 },
284 },
285 in: []string{"bin", "my_test"},
286 out: "target/product/test_device/system/bin/my_test",
287 },
288 {
289 name: "vendor binary",
290 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700291 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800292 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700293 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800294 earlyModuleContext: earlyModuleContext{
295 kind: socSpecificModule,
296 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700297 },
298 },
299 in: []string{"bin", "my_test"},
300 out: "target/product/test_device/vendor/bin/my_test",
301 },
Jiyong Park2db76922017-11-08 16:03:48 +0900302 {
303 name: "odm binary",
304 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700305 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800306 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900307 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800308 earlyModuleContext: earlyModuleContext{
309 kind: deviceSpecificModule,
310 },
Jiyong Park2db76922017-11-08 16:03:48 +0900311 },
312 },
313 in: []string{"bin", "my_test"},
314 out: "target/product/test_device/odm/bin/my_test",
315 },
316 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900317 name: "product binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900318 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700319 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800320 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900321 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800322 earlyModuleContext: earlyModuleContext{
323 kind: productSpecificModule,
324 },
Jiyong Park2db76922017-11-08 16:03:48 +0900325 },
326 },
327 in: []string{"bin", "my_test"},
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900328 out: "target/product/test_device/product/bin/my_test",
Jiyong Park2db76922017-11-08 16:03:48 +0900329 },
Dario Frenifd05a742018-05-29 13:28:54 +0100330 {
Justin Yund5f6c822019-06-25 16:47:17 +0900331 name: "system_ext binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100332 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700333 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800334 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100335 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800336 earlyModuleContext: earlyModuleContext{
337 kind: systemExtSpecificModule,
338 },
Dario Frenifd05a742018-05-29 13:28:54 +0100339 },
340 },
341 in: []string{"bin", "my_test"},
Justin Yund5f6c822019-06-25 16:47:17 +0900342 out: "target/product/test_device/system_ext/bin/my_test",
Dario Frenifd05a742018-05-29 13:28:54 +0100343 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700344 {
345 name: "root binary",
346 ctx: &moduleInstallPathContextImpl{
347 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800348 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700349 target: deviceTarget,
350 },
351 inRoot: true,
352 },
353 in: []string{"my_test"},
354 out: "target/product/test_device/root/my_test",
355 },
356 {
357 name: "recovery binary",
358 ctx: &moduleInstallPathContextImpl{
359 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800360 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700361 target: deviceTarget,
362 },
363 inRecovery: true,
364 },
365 in: []string{"bin/my_test"},
366 out: "target/product/test_device/recovery/root/system/bin/my_test",
367 },
368 {
369 name: "recovery root binary",
370 ctx: &moduleInstallPathContextImpl{
371 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800372 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700373 target: deviceTarget,
374 },
375 inRecovery: true,
376 inRoot: true,
377 },
378 in: []string{"my_test"},
379 out: "target/product/test_device/recovery/root/my_test",
380 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700381
382 {
383 name: "system native test binary",
384 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700385 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800386 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700387 target: deviceTarget,
388 },
389 inData: true,
390 },
391 in: []string{"nativetest", "my_test"},
392 out: "target/product/test_device/data/nativetest/my_test",
393 },
394 {
395 name: "vendor native test binary",
396 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700397 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800398 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700399 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800400 earlyModuleContext: earlyModuleContext{
401 kind: socSpecificModule,
402 },
Jiyong Park2db76922017-11-08 16:03:48 +0900403 },
404 inData: true,
405 },
406 in: []string{"nativetest", "my_test"},
407 out: "target/product/test_device/data/nativetest/my_test",
408 },
409 {
410 name: "odm native test binary",
411 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700412 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800413 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900414 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800415 earlyModuleContext: earlyModuleContext{
416 kind: deviceSpecificModule,
417 },
Jiyong Park2db76922017-11-08 16:03:48 +0900418 },
419 inData: true,
420 },
421 in: []string{"nativetest", "my_test"},
422 out: "target/product/test_device/data/nativetest/my_test",
423 },
424 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900425 name: "product native test binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900426 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700427 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800428 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900429 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800430 earlyModuleContext: earlyModuleContext{
431 kind: productSpecificModule,
432 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700433 },
434 inData: true,
435 },
436 in: []string{"nativetest", "my_test"},
437 out: "target/product/test_device/data/nativetest/my_test",
438 },
439
440 {
Justin Yund5f6c822019-06-25 16:47:17 +0900441 name: "system_ext native test binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100442 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700443 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800444 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100445 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800446 earlyModuleContext: earlyModuleContext{
447 kind: systemExtSpecificModule,
448 },
Dario Frenifd05a742018-05-29 13:28:54 +0100449 },
450 inData: true,
451 },
452 in: []string{"nativetest", "my_test"},
453 out: "target/product/test_device/data/nativetest/my_test",
454 },
455
456 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700457 name: "sanitized system binary",
458 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700459 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800460 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700461 target: deviceTarget,
462 },
463 inSanitizerDir: true,
464 },
465 in: []string{"bin", "my_test"},
466 out: "target/product/test_device/data/asan/system/bin/my_test",
467 },
468 {
469 name: "sanitized vendor binary",
470 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700471 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800472 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700473 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800474 earlyModuleContext: earlyModuleContext{
475 kind: socSpecificModule,
476 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700477 },
478 inSanitizerDir: true,
479 },
480 in: []string{"bin", "my_test"},
481 out: "target/product/test_device/data/asan/vendor/bin/my_test",
482 },
Jiyong Park2db76922017-11-08 16:03:48 +0900483 {
484 name: "sanitized odm binary",
485 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700486 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800487 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900488 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800489 earlyModuleContext: earlyModuleContext{
490 kind: deviceSpecificModule,
491 },
Jiyong Park2db76922017-11-08 16:03:48 +0900492 },
493 inSanitizerDir: true,
494 },
495 in: []string{"bin", "my_test"},
496 out: "target/product/test_device/data/asan/odm/bin/my_test",
497 },
498 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900499 name: "sanitized product binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900500 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700501 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800502 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900503 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800504 earlyModuleContext: earlyModuleContext{
505 kind: productSpecificModule,
506 },
Jiyong Park2db76922017-11-08 16:03:48 +0900507 },
508 inSanitizerDir: true,
509 },
510 in: []string{"bin", "my_test"},
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900511 out: "target/product/test_device/data/asan/product/bin/my_test",
Jiyong Park2db76922017-11-08 16:03:48 +0900512 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700513
514 {
Justin Yund5f6c822019-06-25 16:47:17 +0900515 name: "sanitized system_ext binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100516 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700517 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800518 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100519 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800520 earlyModuleContext: earlyModuleContext{
521 kind: systemExtSpecificModule,
522 },
Dario Frenifd05a742018-05-29 13:28:54 +0100523 },
524 inSanitizerDir: true,
525 },
526 in: []string{"bin", "my_test"},
Justin Yund5f6c822019-06-25 16:47:17 +0900527 out: "target/product/test_device/data/asan/system_ext/bin/my_test",
Dario Frenifd05a742018-05-29 13:28:54 +0100528 },
529
530 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700531 name: "sanitized system native test binary",
532 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700533 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800534 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700535 target: deviceTarget,
536 },
537 inData: true,
538 inSanitizerDir: true,
539 },
540 in: []string{"nativetest", "my_test"},
541 out: "target/product/test_device/data/asan/data/nativetest/my_test",
542 },
543 {
544 name: "sanitized vendor native test binary",
545 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700546 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800547 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700548 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800549 earlyModuleContext: earlyModuleContext{
550 kind: socSpecificModule,
551 },
Jiyong Park2db76922017-11-08 16:03:48 +0900552 },
553 inData: true,
554 inSanitizerDir: true,
555 },
556 in: []string{"nativetest", "my_test"},
557 out: "target/product/test_device/data/asan/data/nativetest/my_test",
558 },
559 {
560 name: "sanitized odm native test binary",
561 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700562 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800563 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900564 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800565 earlyModuleContext: earlyModuleContext{
566 kind: deviceSpecificModule,
567 },
Jiyong Park2db76922017-11-08 16:03:48 +0900568 },
569 inData: true,
570 inSanitizerDir: true,
571 },
572 in: []string{"nativetest", "my_test"},
573 out: "target/product/test_device/data/asan/data/nativetest/my_test",
574 },
575 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900576 name: "sanitized product native test binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900577 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700578 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800579 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900580 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800581 earlyModuleContext: earlyModuleContext{
582 kind: productSpecificModule,
583 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700584 },
585 inData: true,
586 inSanitizerDir: true,
587 },
588 in: []string{"nativetest", "my_test"},
589 out: "target/product/test_device/data/asan/data/nativetest/my_test",
590 },
Dario Frenifd05a742018-05-29 13:28:54 +0100591 {
Justin Yund5f6c822019-06-25 16:47:17 +0900592 name: "sanitized system_ext native test binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100593 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700594 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800595 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100596 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800597 earlyModuleContext: earlyModuleContext{
598 kind: systemExtSpecificModule,
599 },
Dario Frenifd05a742018-05-29 13:28:54 +0100600 },
601 inData: true,
602 inSanitizerDir: true,
603 },
604 in: []string{"nativetest", "my_test"},
605 out: "target/product/test_device/data/asan/data/nativetest/my_test",
Colin Cross6e359402020-02-10 15:29:54 -0800606 }, {
607 name: "device testcases",
608 ctx: &moduleInstallPathContextImpl{
609 baseModuleContext: baseModuleContext{
610 os: deviceTarget.Os,
611 target: deviceTarget,
612 },
613 inTestcases: true,
614 },
615 in: []string{"my_test", "my_test_bin"},
616 out: "target/product/test_device/testcases/my_test/my_test_bin",
617 }, {
618 name: "host testcases",
619 ctx: &moduleInstallPathContextImpl{
620 baseModuleContext: baseModuleContext{
621 os: hostTarget.Os,
622 target: hostTarget,
623 },
624 inTestcases: true,
625 },
626 in: []string{"my_test", "my_test_bin"},
627 out: "host/linux-x86/testcases/my_test/my_test_bin",
628 }, {
629 name: "forced host testcases",
630 ctx: &moduleInstallPathContextImpl{
631 baseModuleContext: baseModuleContext{
632 os: deviceTarget.Os,
633 target: deviceTarget,
634 },
635 inTestcases: true,
636 forceOS: &Linux,
637 },
638 in: []string{"my_test", "my_test_bin"},
639 out: "host/linux-x86/testcases/my_test/my_test_bin",
Dario Frenifd05a742018-05-29 13:28:54 +0100640 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700641 }
642
643 for _, tc := range testCases {
644 t.Run(tc.name, func(t *testing.T) {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700645 tc.ctx.baseModuleContext.config = testConfig
Dan Willemsen00269f22017-07-06 16:59:48 -0700646 output := PathForModuleInstall(tc.ctx, tc.in...)
647 if output.basePath.path != tc.out {
648 t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
649 output.basePath.path,
650 tc.out)
651 }
652 })
653 }
654}
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700655
656func TestDirectorySortedPaths(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800657 config := TestConfig("out", nil, "", map[string][]byte{
658 "Android.bp": nil,
659 "a.txt": nil,
660 "a/txt": nil,
661 "a/b/c": nil,
662 "a/b/d": nil,
663 "b": nil,
664 "b/b.txt": nil,
665 "a/a.txt": nil,
Colin Cross07e51612019-03-05 12:46:40 -0800666 })
667
Colin Cross98be1bb2019-12-13 20:41:13 -0800668 ctx := PathContextForTesting(config)
669
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700670 makePaths := func() Paths {
671 return Paths{
Colin Cross07e51612019-03-05 12:46:40 -0800672 PathForSource(ctx, "a.txt"),
673 PathForSource(ctx, "a/txt"),
674 PathForSource(ctx, "a/b/c"),
675 PathForSource(ctx, "a/b/d"),
676 PathForSource(ctx, "b"),
677 PathForSource(ctx, "b/b.txt"),
678 PathForSource(ctx, "a/a.txt"),
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700679 }
680 }
681
682 expected := []string{
683 "a.txt",
684 "a/a.txt",
685 "a/b/c",
686 "a/b/d",
687 "a/txt",
688 "b",
689 "b/b.txt",
690 }
691
692 paths := makePaths()
Colin Crossa140bb02018-04-17 10:52:26 -0700693 reversePaths := ReversePaths(paths)
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700694
695 sortedPaths := PathsToDirectorySortedPaths(paths)
696 reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
697
698 if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
699 t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
700 }
701
702 if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
703 t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
704 }
705
706 expectedA := []string{
707 "a/a.txt",
708 "a/b/c",
709 "a/b/d",
710 "a/txt",
711 }
712
713 inA := sortedPaths.PathsInDirectory("a")
714 if !reflect.DeepEqual(inA.Strings(), expectedA) {
715 t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
716 }
717
718 expectedA_B := []string{
719 "a/b/c",
720 "a/b/d",
721 }
722
723 inA_B := sortedPaths.PathsInDirectory("a/b")
724 if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
725 t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
726 }
727
728 expectedB := []string{
729 "b/b.txt",
730 }
731
732 inB := sortedPaths.PathsInDirectory("b")
733 if !reflect.DeepEqual(inB.Strings(), expectedB) {
734 t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
735 }
736}
Colin Cross43f08db2018-11-12 10:13:39 -0800737
738func TestMaybeRel(t *testing.T) {
739 testCases := []struct {
740 name string
741 base string
742 target string
743 out string
744 isRel bool
745 }{
746 {
747 name: "normal",
748 base: "a/b/c",
749 target: "a/b/c/d",
750 out: "d",
751 isRel: true,
752 },
753 {
754 name: "parent",
755 base: "a/b/c/d",
756 target: "a/b/c",
757 isRel: false,
758 },
759 {
760 name: "not relative",
761 base: "a/b",
762 target: "c/d",
763 isRel: false,
764 },
765 {
766 name: "abs1",
767 base: "/a",
768 target: "a",
769 isRel: false,
770 },
771 {
772 name: "abs2",
773 base: "a",
774 target: "/a",
775 isRel: false,
776 },
777 }
778
779 for _, testCase := range testCases {
780 t.Run(testCase.name, func(t *testing.T) {
781 ctx := &configErrorWrapper{}
782 out, isRel := MaybeRel(ctx, testCase.base, testCase.target)
783 if len(ctx.errors) > 0 {
784 t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v",
785 testCase.base, testCase.target, ctx.errors)
786 }
787 if isRel != testCase.isRel || out != testCase.out {
788 t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v",
789 testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel)
790 }
791 })
792 }
793}
Colin Cross7b3dcc32019-01-24 13:14:39 -0800794
795func TestPathForSource(t *testing.T) {
796 testCases := []struct {
797 name string
798 buildDir string
799 src string
800 err string
801 }{
802 {
803 name: "normal",
804 buildDir: "out",
805 src: "a/b/c",
806 },
807 {
808 name: "abs",
809 buildDir: "out",
810 src: "/a/b/c",
811 err: "is outside directory",
812 },
813 {
814 name: "in out dir",
815 buildDir: "out",
816 src: "out/a/b/c",
817 err: "is in output",
818 },
819 }
820
821 funcs := []struct {
822 name string
823 f func(ctx PathContext, pathComponents ...string) (SourcePath, error)
824 }{
825 {"pathForSource", pathForSource},
826 {"safePathForSource", safePathForSource},
827 }
828
829 for _, f := range funcs {
830 t.Run(f.name, func(t *testing.T) {
831 for _, test := range testCases {
832 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800833 testConfig := pathTestConfig(test.buildDir)
Colin Cross7b3dcc32019-01-24 13:14:39 -0800834 ctx := &configErrorWrapper{config: testConfig}
835 _, err := f.f(ctx, test.src)
836 if len(ctx.errors) > 0 {
837 t.Fatalf("unexpected errors %v", ctx.errors)
838 }
839 if err != nil {
840 if test.err == "" {
841 t.Fatalf("unexpected error %q", err.Error())
842 } else if !strings.Contains(err.Error(), test.err) {
843 t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
844 }
845 } else {
846 if test.err != "" {
847 t.Fatalf("missing error %q", test.err)
848 }
849 }
850 })
851 }
852 })
853 }
854}
Colin Cross8854a5a2019-02-11 14:14:16 -0800855
Colin Cross8a497952019-03-05 22:25:09 -0800856type pathForModuleSrcTestModule struct {
Colin Cross937664a2019-03-06 10:17:32 -0800857 ModuleBase
858 props struct {
859 Srcs []string `android:"path"`
860 Exclude_srcs []string `android:"path"`
Colin Cross8a497952019-03-05 22:25:09 -0800861
862 Src *string `android:"path"`
Colin Crossba71a3f2019-03-18 12:12:48 -0700863
864 Module_handles_missing_deps bool
Colin Cross937664a2019-03-06 10:17:32 -0800865 }
866
Colin Cross8a497952019-03-05 22:25:09 -0800867 src string
868 rel string
869
870 srcs []string
Colin Cross937664a2019-03-06 10:17:32 -0800871 rels []string
Colin Cross8a497952019-03-05 22:25:09 -0800872
873 missingDeps []string
Colin Cross937664a2019-03-06 10:17:32 -0800874}
875
Colin Cross8a497952019-03-05 22:25:09 -0800876func pathForModuleSrcTestModuleFactory() Module {
877 module := &pathForModuleSrcTestModule{}
Colin Cross937664a2019-03-06 10:17:32 -0800878 module.AddProperties(&module.props)
879 InitAndroidModule(module)
880 return module
881}
882
Colin Cross8a497952019-03-05 22:25:09 -0800883func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Crossba71a3f2019-03-18 12:12:48 -0700884 var srcs Paths
885 if p.props.Module_handles_missing_deps {
886 srcs, p.missingDeps = PathsAndMissingDepsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
887 } else {
888 srcs = PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
889 }
Colin Cross8a497952019-03-05 22:25:09 -0800890 p.srcs = srcs.Strings()
Colin Cross937664a2019-03-06 10:17:32 -0800891
Colin Cross8a497952019-03-05 22:25:09 -0800892 for _, src := range srcs {
Colin Cross937664a2019-03-06 10:17:32 -0800893 p.rels = append(p.rels, src.Rel())
894 }
Colin Cross8a497952019-03-05 22:25:09 -0800895
896 if p.props.Src != nil {
897 src := PathForModuleSrc(ctx, *p.props.Src)
898 if src != nil {
899 p.src = src.String()
900 p.rel = src.Rel()
901 }
902 }
903
Colin Crossba71a3f2019-03-18 12:12:48 -0700904 if !p.props.Module_handles_missing_deps {
905 p.missingDeps = ctx.GetMissingDependencies()
906 }
Colin Cross6c4f21f2019-06-06 15:41:36 -0700907
908 ctx.Build(pctx, BuildParams{
909 Rule: Touch,
910 Output: PathForModuleOut(ctx, "output"),
911 })
Colin Cross8a497952019-03-05 22:25:09 -0800912}
913
Colin Cross41955e82019-05-29 14:40:35 -0700914type pathForModuleSrcOutputFileProviderModule struct {
915 ModuleBase
916 props struct {
917 Outs []string
918 Tagged []string
919 }
920
921 outs Paths
922 tagged Paths
923}
924
925func pathForModuleSrcOutputFileProviderModuleFactory() Module {
926 module := &pathForModuleSrcOutputFileProviderModule{}
927 module.AddProperties(&module.props)
928 InitAndroidModule(module)
929 return module
930}
931
932func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
933 for _, out := range p.props.Outs {
934 p.outs = append(p.outs, PathForModuleOut(ctx, out))
935 }
936
937 for _, tagged := range p.props.Tagged {
938 p.tagged = append(p.tagged, PathForModuleOut(ctx, tagged))
939 }
940}
941
942func (p *pathForModuleSrcOutputFileProviderModule) OutputFiles(tag string) (Paths, error) {
943 switch tag {
944 case "":
945 return p.outs, nil
946 case ".tagged":
947 return p.tagged, nil
948 default:
949 return nil, fmt.Errorf("unsupported tag %q", tag)
950 }
951}
952
Colin Cross8a497952019-03-05 22:25:09 -0800953type pathForModuleSrcTestCase struct {
954 name string
955 bp string
956 srcs []string
957 rels []string
958 src string
959 rel string
960}
961
962func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSrcTestCase) {
963 for _, test := range tests {
964 t.Run(test.name, func(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -0800965 ctx := NewTestContext()
966
Colin Cross4b49b762019-11-22 15:25:03 -0800967 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
968 ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
969 ctx.RegisterModuleType("filegroup", FileGroupFactory)
Colin Cross8a497952019-03-05 22:25:09 -0800970
971 fgBp := `
972 filegroup {
973 name: "a",
974 srcs: ["src/a"],
975 }
976 `
977
Colin Cross41955e82019-05-29 14:40:35 -0700978 ofpBp := `
979 output_file_provider {
980 name: "b",
981 outs: ["gen/b"],
982 tagged: ["gen/c"],
983 }
984 `
985
Colin Cross8a497952019-03-05 22:25:09 -0800986 mockFS := map[string][]byte{
987 "fg/Android.bp": []byte(fgBp),
988 "foo/Android.bp": []byte(test.bp),
Colin Cross41955e82019-05-29 14:40:35 -0700989 "ofp/Android.bp": []byte(ofpBp),
Colin Cross8a497952019-03-05 22:25:09 -0800990 "fg/src/a": nil,
991 "foo/src/b": nil,
992 "foo/src/c": nil,
993 "foo/src/d": nil,
994 "foo/src/e/e": nil,
995 "foo/src_special/$": nil,
996 }
997
Colin Cross98be1bb2019-12-13 20:41:13 -0800998 config := TestConfig(buildDir, nil, "", mockFS)
Colin Cross8a497952019-03-05 22:25:09 -0800999
Colin Cross98be1bb2019-12-13 20:41:13 -08001000 ctx.Register(config)
Colin Cross41955e82019-05-29 14:40:35 -07001001 _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp", "ofp/Android.bp"})
Colin Cross8a497952019-03-05 22:25:09 -08001002 FailIfErrored(t, errs)
1003 _, errs = ctx.PrepareBuildActions(config)
1004 FailIfErrored(t, errs)
1005
1006 m := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1007
1008 if g, w := m.srcs, test.srcs; !reflect.DeepEqual(g, w) {
1009 t.Errorf("want srcs %q, got %q", w, g)
1010 }
1011
1012 if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) {
1013 t.Errorf("want rels %q, got %q", w, g)
1014 }
1015
1016 if g, w := m.src, test.src; g != w {
1017 t.Errorf("want src %q, got %q", w, g)
1018 }
1019
1020 if g, w := m.rel, test.rel; g != w {
1021 t.Errorf("want rel %q, got %q", w, g)
1022 }
1023 })
1024 }
Colin Cross937664a2019-03-06 10:17:32 -08001025}
1026
Colin Cross8a497952019-03-05 22:25:09 -08001027func TestPathsForModuleSrc(t *testing.T) {
1028 tests := []pathForModuleSrcTestCase{
Colin Cross937664a2019-03-06 10:17:32 -08001029 {
1030 name: "path",
1031 bp: `
1032 test {
1033 name: "foo",
1034 srcs: ["src/b"],
1035 }`,
1036 srcs: []string{"foo/src/b"},
1037 rels: []string{"src/b"},
1038 },
1039 {
1040 name: "glob",
1041 bp: `
1042 test {
1043 name: "foo",
1044 srcs: [
1045 "src/*",
1046 "src/e/*",
1047 ],
1048 }`,
1049 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1050 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1051 },
1052 {
1053 name: "recursive glob",
1054 bp: `
1055 test {
1056 name: "foo",
1057 srcs: ["src/**/*"],
1058 }`,
1059 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1060 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1061 },
1062 {
1063 name: "filegroup",
1064 bp: `
1065 test {
1066 name: "foo",
1067 srcs: [":a"],
1068 }`,
1069 srcs: []string{"fg/src/a"},
1070 rels: []string{"src/a"},
1071 },
1072 {
Colin Cross41955e82019-05-29 14:40:35 -07001073 name: "output file provider",
1074 bp: `
1075 test {
1076 name: "foo",
1077 srcs: [":b"],
1078 }`,
1079 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"},
1080 rels: []string{"gen/b"},
1081 },
1082 {
1083 name: "output file provider tagged",
1084 bp: `
1085 test {
1086 name: "foo",
1087 srcs: [":b{.tagged}"],
1088 }`,
1089 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/c"},
1090 rels: []string{"gen/c"},
1091 },
1092 {
Colin Cross937664a2019-03-06 10:17:32 -08001093 name: "special characters glob",
1094 bp: `
1095 test {
1096 name: "foo",
1097 srcs: ["src_special/*"],
1098 }`,
1099 srcs: []string{"foo/src_special/$"},
1100 rels: []string{"src_special/$"},
1101 },
1102 }
1103
Colin Cross41955e82019-05-29 14:40:35 -07001104 testPathForModuleSrc(t, buildDir, tests)
1105}
1106
1107func TestPathForModuleSrc(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001108 tests := []pathForModuleSrcTestCase{
1109 {
1110 name: "path",
1111 bp: `
1112 test {
1113 name: "foo",
1114 src: "src/b",
1115 }`,
1116 src: "foo/src/b",
1117 rel: "src/b",
1118 },
1119 {
1120 name: "glob",
1121 bp: `
1122 test {
1123 name: "foo",
1124 src: "src/e/*",
1125 }`,
1126 src: "foo/src/e/e",
1127 rel: "src/e/e",
1128 },
1129 {
1130 name: "filegroup",
1131 bp: `
1132 test {
1133 name: "foo",
1134 src: ":a",
1135 }`,
1136 src: "fg/src/a",
1137 rel: "src/a",
1138 },
1139 {
Colin Cross41955e82019-05-29 14:40:35 -07001140 name: "output file provider",
1141 bp: `
1142 test {
1143 name: "foo",
1144 src: ":b",
1145 }`,
1146 src: buildDir + "/.intermediates/ofp/b/gen/b",
1147 rel: "gen/b",
1148 },
1149 {
1150 name: "output file provider tagged",
1151 bp: `
1152 test {
1153 name: "foo",
1154 src: ":b{.tagged}",
1155 }`,
1156 src: buildDir + "/.intermediates/ofp/b/gen/c",
1157 rel: "gen/c",
1158 },
1159 {
Colin Cross8a497952019-03-05 22:25:09 -08001160 name: "special characters glob",
1161 bp: `
1162 test {
1163 name: "foo",
1164 src: "src_special/*",
1165 }`,
1166 src: "foo/src_special/$",
1167 rel: "src_special/$",
1168 },
1169 }
1170
Colin Cross8a497952019-03-05 22:25:09 -08001171 testPathForModuleSrc(t, buildDir, tests)
1172}
Colin Cross937664a2019-03-06 10:17:32 -08001173
Colin Cross8a497952019-03-05 22:25:09 -08001174func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001175 bp := `
1176 test {
1177 name: "foo",
1178 srcs: [":a"],
1179 exclude_srcs: [":b"],
1180 src: ":c",
1181 }
Colin Crossba71a3f2019-03-18 12:12:48 -07001182
1183 test {
1184 name: "bar",
1185 srcs: [":d"],
1186 exclude_srcs: [":e"],
1187 module_handles_missing_deps: true,
1188 }
Colin Cross8a497952019-03-05 22:25:09 -08001189 `
1190
Colin Cross98be1bb2019-12-13 20:41:13 -08001191 config := TestConfig(buildDir, nil, bp, nil)
1192 config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
Colin Cross8a497952019-03-05 22:25:09 -08001193
Colin Cross98be1bb2019-12-13 20:41:13 -08001194 ctx := NewTestContext()
1195 ctx.SetAllowMissingDependencies(true)
Colin Cross8a497952019-03-05 22:25:09 -08001196
Colin Cross98be1bb2019-12-13 20:41:13 -08001197 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1198
1199 ctx.Register(config)
1200
Colin Cross8a497952019-03-05 22:25:09 -08001201 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
1202 FailIfErrored(t, errs)
1203 _, errs = ctx.PrepareBuildActions(config)
1204 FailIfErrored(t, errs)
1205
1206 foo := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1207
1208 if g, w := foo.missingDeps, []string{"a", "b", "c"}; !reflect.DeepEqual(g, w) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001209 t.Errorf("want foo missing deps %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001210 }
1211
1212 if g, w := foo.srcs, []string{}; !reflect.DeepEqual(g, w) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001213 t.Errorf("want foo srcs %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001214 }
1215
1216 if g, w := foo.src, ""; g != w {
Colin Crossba71a3f2019-03-18 12:12:48 -07001217 t.Errorf("want foo src %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001218 }
1219
Colin Crossba71a3f2019-03-18 12:12:48 -07001220 bar := ctx.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
1221
1222 if g, w := bar.missingDeps, []string{"d", "e"}; !reflect.DeepEqual(g, w) {
1223 t.Errorf("want bar missing deps %q, got %q", w, g)
1224 }
1225
1226 if g, w := bar.srcs, []string{}; !reflect.DeepEqual(g, w) {
1227 t.Errorf("want bar srcs %q, got %q", w, g)
1228 }
Colin Cross937664a2019-03-06 10:17:32 -08001229}
1230
Colin Cross8854a5a2019-02-11 14:14:16 -08001231func ExampleOutputPath_ReplaceExtension() {
1232 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001233 config: TestConfig("out", nil, "", nil),
Colin Cross8854a5a2019-02-11 14:14:16 -08001234 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001235 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross8854a5a2019-02-11 14:14:16 -08001236 p2 := p.ReplaceExtension(ctx, "oat")
1237 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001238 fmt.Println(p.Rel(), p2.Rel())
Colin Cross8854a5a2019-02-11 14:14:16 -08001239
1240 // Output:
1241 // out/system/framework/boot.art out/system/framework/boot.oat
Colin Cross2cdd5df2019-02-25 10:25:24 -08001242 // boot.art boot.oat
Colin Cross8854a5a2019-02-11 14:14:16 -08001243}
Colin Cross40e33732019-02-15 11:08:35 -08001244
1245func ExampleOutputPath_FileInSameDir() {
1246 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001247 config: TestConfig("out", nil, "", nil),
Colin Cross40e33732019-02-15 11:08:35 -08001248 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001249 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross40e33732019-02-15 11:08:35 -08001250 p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
1251 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001252 fmt.Println(p.Rel(), p2.Rel())
Colin Cross40e33732019-02-15 11:08:35 -08001253
1254 // Output:
1255 // out/system/framework/boot.art out/system/framework/oat/arm/boot.vdex
Colin Cross2cdd5df2019-02-25 10:25:24 -08001256 // boot.art oat/arm/boot.vdex
Colin Cross40e33732019-02-15 11:08:35 -08001257}