blob: 7a32026132fedebe5a47f56657a1c95592c5a21e [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
Dan Willemsen00269f22017-07-06 16:59:48 -0700208}
209
Colin Crossaabf6792017-11-29 00:27:14 -0800210func (m moduleInstallPathContextImpl) Config() Config {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700211 return m.baseModuleContext.config
Dan Willemsen00269f22017-07-06 16:59:48 -0700212}
213
214func (moduleInstallPathContextImpl) AddNinjaFileDeps(deps ...string) {}
215
216func (m moduleInstallPathContextImpl) InstallInData() bool {
217 return m.inData
218}
219
Jaewoong Jung0949f312019-09-11 10:25:18 -0700220func (m moduleInstallPathContextImpl) InstallInTestcases() bool {
221 return m.inTestcases
222}
223
Dan Willemsen00269f22017-07-06 16:59:48 -0700224func (m moduleInstallPathContextImpl) InstallInSanitizerDir() bool {
225 return m.inSanitizerDir
226}
227
Yifan Hong1b3348d2020-01-21 15:53:22 -0800228func (m moduleInstallPathContextImpl) InstallInRamdisk() bool {
229 return m.inRamdisk
230}
231
Jiyong Parkf9332f12018-02-01 00:54:12 +0900232func (m moduleInstallPathContextImpl) InstallInRecovery() bool {
233 return m.inRecovery
234}
235
Colin Cross90ba5f42019-10-02 11:10:58 -0700236func (m moduleInstallPathContextImpl) InstallInRoot() bool {
237 return m.inRoot
238}
239
Colin Cross607d8582019-07-29 16:44:46 -0700240func (m moduleInstallPathContextImpl) InstallBypassMake() bool {
241 return false
242}
243
Colin Cross98be1bb2019-12-13 20:41:13 -0800244func pathTestConfig(buildDir string) Config {
245 return TestConfig(buildDir, nil, "", nil)
246}
247
Dan Willemsen00269f22017-07-06 16:59:48 -0700248func TestPathForModuleInstall(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800249 testConfig := pathTestConfig("")
Dan Willemsen00269f22017-07-06 16:59:48 -0700250
251 hostTarget := Target{Os: Linux}
252 deviceTarget := Target{Os: Android}
253
254 testCases := []struct {
255 name string
256 ctx *moduleInstallPathContextImpl
257 in []string
258 out string
259 }{
260 {
261 name: "host binary",
262 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700263 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800264 os: hostTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700265 target: hostTarget,
266 },
267 },
268 in: []string{"bin", "my_test"},
269 out: "host/linux-x86/bin/my_test",
270 },
271
272 {
273 name: "system binary",
274 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700275 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800276 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700277 target: deviceTarget,
278 },
279 },
280 in: []string{"bin", "my_test"},
281 out: "target/product/test_device/system/bin/my_test",
282 },
283 {
284 name: "vendor binary",
285 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700286 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800287 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700288 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800289 earlyModuleContext: earlyModuleContext{
290 kind: socSpecificModule,
291 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700292 },
293 },
294 in: []string{"bin", "my_test"},
295 out: "target/product/test_device/vendor/bin/my_test",
296 },
Jiyong Park2db76922017-11-08 16:03:48 +0900297 {
298 name: "odm binary",
299 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700300 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800301 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900302 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800303 earlyModuleContext: earlyModuleContext{
304 kind: deviceSpecificModule,
305 },
Jiyong Park2db76922017-11-08 16:03:48 +0900306 },
307 },
308 in: []string{"bin", "my_test"},
309 out: "target/product/test_device/odm/bin/my_test",
310 },
311 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900312 name: "product binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900313 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700314 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800315 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900316 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800317 earlyModuleContext: earlyModuleContext{
318 kind: productSpecificModule,
319 },
Jiyong Park2db76922017-11-08 16:03:48 +0900320 },
321 },
322 in: []string{"bin", "my_test"},
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900323 out: "target/product/test_device/product/bin/my_test",
Jiyong Park2db76922017-11-08 16:03:48 +0900324 },
Dario Frenifd05a742018-05-29 13:28:54 +0100325 {
Justin Yund5f6c822019-06-25 16:47:17 +0900326 name: "system_ext binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100327 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700328 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800329 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100330 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800331 earlyModuleContext: earlyModuleContext{
332 kind: systemExtSpecificModule,
333 },
Dario Frenifd05a742018-05-29 13:28:54 +0100334 },
335 },
336 in: []string{"bin", "my_test"},
Justin Yund5f6c822019-06-25 16:47:17 +0900337 out: "target/product/test_device/system_ext/bin/my_test",
Dario Frenifd05a742018-05-29 13:28:54 +0100338 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700339 {
340 name: "root binary",
341 ctx: &moduleInstallPathContextImpl{
342 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800343 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700344 target: deviceTarget,
345 },
346 inRoot: true,
347 },
348 in: []string{"my_test"},
349 out: "target/product/test_device/root/my_test",
350 },
351 {
352 name: "recovery 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 inRecovery: true,
359 },
360 in: []string{"bin/my_test"},
361 out: "target/product/test_device/recovery/root/system/bin/my_test",
362 },
363 {
364 name: "recovery root 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 inRoot: true,
372 },
373 in: []string{"my_test"},
374 out: "target/product/test_device/recovery/root/my_test",
375 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700376
377 {
378 name: "system native test binary",
379 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700380 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800381 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700382 target: deviceTarget,
383 },
384 inData: true,
385 },
386 in: []string{"nativetest", "my_test"},
387 out: "target/product/test_device/data/nativetest/my_test",
388 },
389 {
390 name: "vendor 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,
Colin Cross1184b642019-12-30 18:43:07 -0800395 earlyModuleContext: earlyModuleContext{
396 kind: socSpecificModule,
397 },
Jiyong Park2db76922017-11-08 16:03:48 +0900398 },
399 inData: true,
400 },
401 in: []string{"nativetest", "my_test"},
402 out: "target/product/test_device/data/nativetest/my_test",
403 },
404 {
405 name: "odm native test binary",
406 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700407 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800408 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900409 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800410 earlyModuleContext: earlyModuleContext{
411 kind: deviceSpecificModule,
412 },
Jiyong Park2db76922017-11-08 16:03:48 +0900413 },
414 inData: true,
415 },
416 in: []string{"nativetest", "my_test"},
417 out: "target/product/test_device/data/nativetest/my_test",
418 },
419 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900420 name: "product native test binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900421 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700422 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800423 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900424 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800425 earlyModuleContext: earlyModuleContext{
426 kind: productSpecificModule,
427 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700428 },
429 inData: true,
430 },
431 in: []string{"nativetest", "my_test"},
432 out: "target/product/test_device/data/nativetest/my_test",
433 },
434
435 {
Justin Yund5f6c822019-06-25 16:47:17 +0900436 name: "system_ext native test binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100437 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700438 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800439 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100440 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800441 earlyModuleContext: earlyModuleContext{
442 kind: systemExtSpecificModule,
443 },
Dario Frenifd05a742018-05-29 13:28:54 +0100444 },
445 inData: true,
446 },
447 in: []string{"nativetest", "my_test"},
448 out: "target/product/test_device/data/nativetest/my_test",
449 },
450
451 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700452 name: "sanitized system binary",
453 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700454 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800455 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700456 target: deviceTarget,
457 },
458 inSanitizerDir: true,
459 },
460 in: []string{"bin", "my_test"},
461 out: "target/product/test_device/data/asan/system/bin/my_test",
462 },
463 {
464 name: "sanitized vendor 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,
Colin Cross1184b642019-12-30 18:43:07 -0800469 earlyModuleContext: earlyModuleContext{
470 kind: socSpecificModule,
471 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700472 },
473 inSanitizerDir: true,
474 },
475 in: []string{"bin", "my_test"},
476 out: "target/product/test_device/data/asan/vendor/bin/my_test",
477 },
Jiyong Park2db76922017-11-08 16:03:48 +0900478 {
479 name: "sanitized odm binary",
480 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700481 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800482 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900483 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800484 earlyModuleContext: earlyModuleContext{
485 kind: deviceSpecificModule,
486 },
Jiyong Park2db76922017-11-08 16:03:48 +0900487 },
488 inSanitizerDir: true,
489 },
490 in: []string{"bin", "my_test"},
491 out: "target/product/test_device/data/asan/odm/bin/my_test",
492 },
493 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900494 name: "sanitized product binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900495 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700496 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800497 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900498 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800499 earlyModuleContext: earlyModuleContext{
500 kind: productSpecificModule,
501 },
Jiyong Park2db76922017-11-08 16:03:48 +0900502 },
503 inSanitizerDir: true,
504 },
505 in: []string{"bin", "my_test"},
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900506 out: "target/product/test_device/data/asan/product/bin/my_test",
Jiyong Park2db76922017-11-08 16:03:48 +0900507 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700508
509 {
Justin Yund5f6c822019-06-25 16:47:17 +0900510 name: "sanitized system_ext binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100511 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700512 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800513 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100514 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800515 earlyModuleContext: earlyModuleContext{
516 kind: systemExtSpecificModule,
517 },
Dario Frenifd05a742018-05-29 13:28:54 +0100518 },
519 inSanitizerDir: true,
520 },
521 in: []string{"bin", "my_test"},
Justin Yund5f6c822019-06-25 16:47:17 +0900522 out: "target/product/test_device/data/asan/system_ext/bin/my_test",
Dario Frenifd05a742018-05-29 13:28:54 +0100523 },
524
525 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700526 name: "sanitized system native test binary",
527 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700528 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800529 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700530 target: deviceTarget,
531 },
532 inData: true,
533 inSanitizerDir: true,
534 },
535 in: []string{"nativetest", "my_test"},
536 out: "target/product/test_device/data/asan/data/nativetest/my_test",
537 },
538 {
539 name: "sanitized vendor native test binary",
540 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700541 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800542 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700543 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800544 earlyModuleContext: earlyModuleContext{
545 kind: socSpecificModule,
546 },
Jiyong Park2db76922017-11-08 16:03:48 +0900547 },
548 inData: true,
549 inSanitizerDir: true,
550 },
551 in: []string{"nativetest", "my_test"},
552 out: "target/product/test_device/data/asan/data/nativetest/my_test",
553 },
554 {
555 name: "sanitized odm native test binary",
556 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700557 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800558 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900559 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800560 earlyModuleContext: earlyModuleContext{
561 kind: deviceSpecificModule,
562 },
Jiyong Park2db76922017-11-08 16:03:48 +0900563 },
564 inData: true,
565 inSanitizerDir: true,
566 },
567 in: []string{"nativetest", "my_test"},
568 out: "target/product/test_device/data/asan/data/nativetest/my_test",
569 },
570 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900571 name: "sanitized product native test binary",
Jiyong Park2db76922017-11-08 16:03:48 +0900572 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700573 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800574 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900575 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800576 earlyModuleContext: earlyModuleContext{
577 kind: productSpecificModule,
578 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700579 },
580 inData: true,
581 inSanitizerDir: true,
582 },
583 in: []string{"nativetest", "my_test"},
584 out: "target/product/test_device/data/asan/data/nativetest/my_test",
585 },
Dario Frenifd05a742018-05-29 13:28:54 +0100586 {
Justin Yund5f6c822019-06-25 16:47:17 +0900587 name: "sanitized system_ext native test binary",
Dario Frenifd05a742018-05-29 13:28:54 +0100588 ctx: &moduleInstallPathContextImpl{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700589 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800590 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100591 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800592 earlyModuleContext: earlyModuleContext{
593 kind: systemExtSpecificModule,
594 },
Dario Frenifd05a742018-05-29 13:28:54 +0100595 },
596 inData: true,
597 inSanitizerDir: true,
598 },
599 in: []string{"nativetest", "my_test"},
600 out: "target/product/test_device/data/asan/data/nativetest/my_test",
601 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700602 }
603
604 for _, tc := range testCases {
605 t.Run(tc.name, func(t *testing.T) {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700606 tc.ctx.baseModuleContext.config = testConfig
Dan Willemsen00269f22017-07-06 16:59:48 -0700607 output := PathForModuleInstall(tc.ctx, tc.in...)
608 if output.basePath.path != tc.out {
609 t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
610 output.basePath.path,
611 tc.out)
612 }
613 })
614 }
615}
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700616
617func TestDirectorySortedPaths(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800618 config := TestConfig("out", nil, "", map[string][]byte{
619 "Android.bp": nil,
620 "a.txt": nil,
621 "a/txt": nil,
622 "a/b/c": nil,
623 "a/b/d": nil,
624 "b": nil,
625 "b/b.txt": nil,
626 "a/a.txt": nil,
Colin Cross07e51612019-03-05 12:46:40 -0800627 })
628
Colin Cross98be1bb2019-12-13 20:41:13 -0800629 ctx := PathContextForTesting(config)
630
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700631 makePaths := func() Paths {
632 return Paths{
Colin Cross07e51612019-03-05 12:46:40 -0800633 PathForSource(ctx, "a.txt"),
634 PathForSource(ctx, "a/txt"),
635 PathForSource(ctx, "a/b/c"),
636 PathForSource(ctx, "a/b/d"),
637 PathForSource(ctx, "b"),
638 PathForSource(ctx, "b/b.txt"),
639 PathForSource(ctx, "a/a.txt"),
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700640 }
641 }
642
643 expected := []string{
644 "a.txt",
645 "a/a.txt",
646 "a/b/c",
647 "a/b/d",
648 "a/txt",
649 "b",
650 "b/b.txt",
651 }
652
653 paths := makePaths()
Colin Crossa140bb02018-04-17 10:52:26 -0700654 reversePaths := ReversePaths(paths)
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700655
656 sortedPaths := PathsToDirectorySortedPaths(paths)
657 reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
658
659 if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
660 t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
661 }
662
663 if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
664 t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
665 }
666
667 expectedA := []string{
668 "a/a.txt",
669 "a/b/c",
670 "a/b/d",
671 "a/txt",
672 }
673
674 inA := sortedPaths.PathsInDirectory("a")
675 if !reflect.DeepEqual(inA.Strings(), expectedA) {
676 t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
677 }
678
679 expectedA_B := []string{
680 "a/b/c",
681 "a/b/d",
682 }
683
684 inA_B := sortedPaths.PathsInDirectory("a/b")
685 if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
686 t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
687 }
688
689 expectedB := []string{
690 "b/b.txt",
691 }
692
693 inB := sortedPaths.PathsInDirectory("b")
694 if !reflect.DeepEqual(inB.Strings(), expectedB) {
695 t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
696 }
697}
Colin Cross43f08db2018-11-12 10:13:39 -0800698
699func TestMaybeRel(t *testing.T) {
700 testCases := []struct {
701 name string
702 base string
703 target string
704 out string
705 isRel bool
706 }{
707 {
708 name: "normal",
709 base: "a/b/c",
710 target: "a/b/c/d",
711 out: "d",
712 isRel: true,
713 },
714 {
715 name: "parent",
716 base: "a/b/c/d",
717 target: "a/b/c",
718 isRel: false,
719 },
720 {
721 name: "not relative",
722 base: "a/b",
723 target: "c/d",
724 isRel: false,
725 },
726 {
727 name: "abs1",
728 base: "/a",
729 target: "a",
730 isRel: false,
731 },
732 {
733 name: "abs2",
734 base: "a",
735 target: "/a",
736 isRel: false,
737 },
738 }
739
740 for _, testCase := range testCases {
741 t.Run(testCase.name, func(t *testing.T) {
742 ctx := &configErrorWrapper{}
743 out, isRel := MaybeRel(ctx, testCase.base, testCase.target)
744 if len(ctx.errors) > 0 {
745 t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v",
746 testCase.base, testCase.target, ctx.errors)
747 }
748 if isRel != testCase.isRel || out != testCase.out {
749 t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v",
750 testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel)
751 }
752 })
753 }
754}
Colin Cross7b3dcc32019-01-24 13:14:39 -0800755
756func TestPathForSource(t *testing.T) {
757 testCases := []struct {
758 name string
759 buildDir string
760 src string
761 err string
762 }{
763 {
764 name: "normal",
765 buildDir: "out",
766 src: "a/b/c",
767 },
768 {
769 name: "abs",
770 buildDir: "out",
771 src: "/a/b/c",
772 err: "is outside directory",
773 },
774 {
775 name: "in out dir",
776 buildDir: "out",
777 src: "out/a/b/c",
778 err: "is in output",
779 },
780 }
781
782 funcs := []struct {
783 name string
784 f func(ctx PathContext, pathComponents ...string) (SourcePath, error)
785 }{
786 {"pathForSource", pathForSource},
787 {"safePathForSource", safePathForSource},
788 }
789
790 for _, f := range funcs {
791 t.Run(f.name, func(t *testing.T) {
792 for _, test := range testCases {
793 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800794 testConfig := pathTestConfig(test.buildDir)
Colin Cross7b3dcc32019-01-24 13:14:39 -0800795 ctx := &configErrorWrapper{config: testConfig}
796 _, err := f.f(ctx, test.src)
797 if len(ctx.errors) > 0 {
798 t.Fatalf("unexpected errors %v", ctx.errors)
799 }
800 if err != nil {
801 if test.err == "" {
802 t.Fatalf("unexpected error %q", err.Error())
803 } else if !strings.Contains(err.Error(), test.err) {
804 t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
805 }
806 } else {
807 if test.err != "" {
808 t.Fatalf("missing error %q", test.err)
809 }
810 }
811 })
812 }
813 })
814 }
815}
Colin Cross8854a5a2019-02-11 14:14:16 -0800816
Colin Cross8a497952019-03-05 22:25:09 -0800817type pathForModuleSrcTestModule struct {
Colin Cross937664a2019-03-06 10:17:32 -0800818 ModuleBase
819 props struct {
820 Srcs []string `android:"path"`
821 Exclude_srcs []string `android:"path"`
Colin Cross8a497952019-03-05 22:25:09 -0800822
823 Src *string `android:"path"`
Colin Crossba71a3f2019-03-18 12:12:48 -0700824
825 Module_handles_missing_deps bool
Colin Cross937664a2019-03-06 10:17:32 -0800826 }
827
Colin Cross8a497952019-03-05 22:25:09 -0800828 src string
829 rel string
830
831 srcs []string
Colin Cross937664a2019-03-06 10:17:32 -0800832 rels []string
Colin Cross8a497952019-03-05 22:25:09 -0800833
834 missingDeps []string
Colin Cross937664a2019-03-06 10:17:32 -0800835}
836
Colin Cross8a497952019-03-05 22:25:09 -0800837func pathForModuleSrcTestModuleFactory() Module {
838 module := &pathForModuleSrcTestModule{}
Colin Cross937664a2019-03-06 10:17:32 -0800839 module.AddProperties(&module.props)
840 InitAndroidModule(module)
841 return module
842}
843
Colin Cross8a497952019-03-05 22:25:09 -0800844func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Crossba71a3f2019-03-18 12:12:48 -0700845 var srcs Paths
846 if p.props.Module_handles_missing_deps {
847 srcs, p.missingDeps = PathsAndMissingDepsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
848 } else {
849 srcs = PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
850 }
Colin Cross8a497952019-03-05 22:25:09 -0800851 p.srcs = srcs.Strings()
Colin Cross937664a2019-03-06 10:17:32 -0800852
Colin Cross8a497952019-03-05 22:25:09 -0800853 for _, src := range srcs {
Colin Cross937664a2019-03-06 10:17:32 -0800854 p.rels = append(p.rels, src.Rel())
855 }
Colin Cross8a497952019-03-05 22:25:09 -0800856
857 if p.props.Src != nil {
858 src := PathForModuleSrc(ctx, *p.props.Src)
859 if src != nil {
860 p.src = src.String()
861 p.rel = src.Rel()
862 }
863 }
864
Colin Crossba71a3f2019-03-18 12:12:48 -0700865 if !p.props.Module_handles_missing_deps {
866 p.missingDeps = ctx.GetMissingDependencies()
867 }
Colin Cross6c4f21f2019-06-06 15:41:36 -0700868
869 ctx.Build(pctx, BuildParams{
870 Rule: Touch,
871 Output: PathForModuleOut(ctx, "output"),
872 })
Colin Cross8a497952019-03-05 22:25:09 -0800873}
874
Colin Cross41955e82019-05-29 14:40:35 -0700875type pathForModuleSrcOutputFileProviderModule struct {
876 ModuleBase
877 props struct {
878 Outs []string
879 Tagged []string
880 }
881
882 outs Paths
883 tagged Paths
884}
885
886func pathForModuleSrcOutputFileProviderModuleFactory() Module {
887 module := &pathForModuleSrcOutputFileProviderModule{}
888 module.AddProperties(&module.props)
889 InitAndroidModule(module)
890 return module
891}
892
893func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
894 for _, out := range p.props.Outs {
895 p.outs = append(p.outs, PathForModuleOut(ctx, out))
896 }
897
898 for _, tagged := range p.props.Tagged {
899 p.tagged = append(p.tagged, PathForModuleOut(ctx, tagged))
900 }
901}
902
903func (p *pathForModuleSrcOutputFileProviderModule) OutputFiles(tag string) (Paths, error) {
904 switch tag {
905 case "":
906 return p.outs, nil
907 case ".tagged":
908 return p.tagged, nil
909 default:
910 return nil, fmt.Errorf("unsupported tag %q", tag)
911 }
912}
913
Colin Cross8a497952019-03-05 22:25:09 -0800914type pathForModuleSrcTestCase struct {
915 name string
916 bp string
917 srcs []string
918 rels []string
919 src string
920 rel string
921}
922
923func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSrcTestCase) {
924 for _, test := range tests {
925 t.Run(test.name, func(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -0800926 ctx := NewTestContext()
927
Colin Cross4b49b762019-11-22 15:25:03 -0800928 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
929 ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
930 ctx.RegisterModuleType("filegroup", FileGroupFactory)
Colin Cross8a497952019-03-05 22:25:09 -0800931
932 fgBp := `
933 filegroup {
934 name: "a",
935 srcs: ["src/a"],
936 }
937 `
938
Colin Cross41955e82019-05-29 14:40:35 -0700939 ofpBp := `
940 output_file_provider {
941 name: "b",
942 outs: ["gen/b"],
943 tagged: ["gen/c"],
944 }
945 `
946
Colin Cross8a497952019-03-05 22:25:09 -0800947 mockFS := map[string][]byte{
948 "fg/Android.bp": []byte(fgBp),
949 "foo/Android.bp": []byte(test.bp),
Colin Cross41955e82019-05-29 14:40:35 -0700950 "ofp/Android.bp": []byte(ofpBp),
Colin Cross8a497952019-03-05 22:25:09 -0800951 "fg/src/a": nil,
952 "foo/src/b": nil,
953 "foo/src/c": nil,
954 "foo/src/d": nil,
955 "foo/src/e/e": nil,
956 "foo/src_special/$": nil,
957 }
958
Colin Cross98be1bb2019-12-13 20:41:13 -0800959 config := TestConfig(buildDir, nil, "", mockFS)
Colin Cross8a497952019-03-05 22:25:09 -0800960
Colin Cross98be1bb2019-12-13 20:41:13 -0800961 ctx.Register(config)
Colin Cross41955e82019-05-29 14:40:35 -0700962 _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp", "ofp/Android.bp"})
Colin Cross8a497952019-03-05 22:25:09 -0800963 FailIfErrored(t, errs)
964 _, errs = ctx.PrepareBuildActions(config)
965 FailIfErrored(t, errs)
966
967 m := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
968
969 if g, w := m.srcs, test.srcs; !reflect.DeepEqual(g, w) {
970 t.Errorf("want srcs %q, got %q", w, g)
971 }
972
973 if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) {
974 t.Errorf("want rels %q, got %q", w, g)
975 }
976
977 if g, w := m.src, test.src; g != w {
978 t.Errorf("want src %q, got %q", w, g)
979 }
980
981 if g, w := m.rel, test.rel; g != w {
982 t.Errorf("want rel %q, got %q", w, g)
983 }
984 })
985 }
Colin Cross937664a2019-03-06 10:17:32 -0800986}
987
Colin Cross8a497952019-03-05 22:25:09 -0800988func TestPathsForModuleSrc(t *testing.T) {
989 tests := []pathForModuleSrcTestCase{
Colin Cross937664a2019-03-06 10:17:32 -0800990 {
991 name: "path",
992 bp: `
993 test {
994 name: "foo",
995 srcs: ["src/b"],
996 }`,
997 srcs: []string{"foo/src/b"},
998 rels: []string{"src/b"},
999 },
1000 {
1001 name: "glob",
1002 bp: `
1003 test {
1004 name: "foo",
1005 srcs: [
1006 "src/*",
1007 "src/e/*",
1008 ],
1009 }`,
1010 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1011 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1012 },
1013 {
1014 name: "recursive glob",
1015 bp: `
1016 test {
1017 name: "foo",
1018 srcs: ["src/**/*"],
1019 }`,
1020 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1021 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1022 },
1023 {
1024 name: "filegroup",
1025 bp: `
1026 test {
1027 name: "foo",
1028 srcs: [":a"],
1029 }`,
1030 srcs: []string{"fg/src/a"},
1031 rels: []string{"src/a"},
1032 },
1033 {
Colin Cross41955e82019-05-29 14:40:35 -07001034 name: "output file provider",
1035 bp: `
1036 test {
1037 name: "foo",
1038 srcs: [":b"],
1039 }`,
1040 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"},
1041 rels: []string{"gen/b"},
1042 },
1043 {
1044 name: "output file provider tagged",
1045 bp: `
1046 test {
1047 name: "foo",
1048 srcs: [":b{.tagged}"],
1049 }`,
1050 srcs: []string{buildDir + "/.intermediates/ofp/b/gen/c"},
1051 rels: []string{"gen/c"},
1052 },
1053 {
Colin Cross937664a2019-03-06 10:17:32 -08001054 name: "special characters glob",
1055 bp: `
1056 test {
1057 name: "foo",
1058 srcs: ["src_special/*"],
1059 }`,
1060 srcs: []string{"foo/src_special/$"},
1061 rels: []string{"src_special/$"},
1062 },
1063 }
1064
Colin Cross41955e82019-05-29 14:40:35 -07001065 testPathForModuleSrc(t, buildDir, tests)
1066}
1067
1068func TestPathForModuleSrc(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001069 tests := []pathForModuleSrcTestCase{
1070 {
1071 name: "path",
1072 bp: `
1073 test {
1074 name: "foo",
1075 src: "src/b",
1076 }`,
1077 src: "foo/src/b",
1078 rel: "src/b",
1079 },
1080 {
1081 name: "glob",
1082 bp: `
1083 test {
1084 name: "foo",
1085 src: "src/e/*",
1086 }`,
1087 src: "foo/src/e/e",
1088 rel: "src/e/e",
1089 },
1090 {
1091 name: "filegroup",
1092 bp: `
1093 test {
1094 name: "foo",
1095 src: ":a",
1096 }`,
1097 src: "fg/src/a",
1098 rel: "src/a",
1099 },
1100 {
Colin Cross41955e82019-05-29 14:40:35 -07001101 name: "output file provider",
1102 bp: `
1103 test {
1104 name: "foo",
1105 src: ":b",
1106 }`,
1107 src: buildDir + "/.intermediates/ofp/b/gen/b",
1108 rel: "gen/b",
1109 },
1110 {
1111 name: "output file provider tagged",
1112 bp: `
1113 test {
1114 name: "foo",
1115 src: ":b{.tagged}",
1116 }`,
1117 src: buildDir + "/.intermediates/ofp/b/gen/c",
1118 rel: "gen/c",
1119 },
1120 {
Colin Cross8a497952019-03-05 22:25:09 -08001121 name: "special characters glob",
1122 bp: `
1123 test {
1124 name: "foo",
1125 src: "src_special/*",
1126 }`,
1127 src: "foo/src_special/$",
1128 rel: "src_special/$",
1129 },
1130 }
1131
Colin Cross8a497952019-03-05 22:25:09 -08001132 testPathForModuleSrc(t, buildDir, tests)
1133}
Colin Cross937664a2019-03-06 10:17:32 -08001134
Colin Cross8a497952019-03-05 22:25:09 -08001135func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001136 bp := `
1137 test {
1138 name: "foo",
1139 srcs: [":a"],
1140 exclude_srcs: [":b"],
1141 src: ":c",
1142 }
Colin Crossba71a3f2019-03-18 12:12:48 -07001143
1144 test {
1145 name: "bar",
1146 srcs: [":d"],
1147 exclude_srcs: [":e"],
1148 module_handles_missing_deps: true,
1149 }
Colin Cross8a497952019-03-05 22:25:09 -08001150 `
1151
Colin Cross98be1bb2019-12-13 20:41:13 -08001152 config := TestConfig(buildDir, nil, bp, nil)
1153 config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
Colin Cross8a497952019-03-05 22:25:09 -08001154
Colin Cross98be1bb2019-12-13 20:41:13 -08001155 ctx := NewTestContext()
1156 ctx.SetAllowMissingDependencies(true)
Colin Cross8a497952019-03-05 22:25:09 -08001157
Colin Cross98be1bb2019-12-13 20:41:13 -08001158 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1159
1160 ctx.Register(config)
1161
Colin Cross8a497952019-03-05 22:25:09 -08001162 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
1163 FailIfErrored(t, errs)
1164 _, errs = ctx.PrepareBuildActions(config)
1165 FailIfErrored(t, errs)
1166
1167 foo := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1168
1169 if g, w := foo.missingDeps, []string{"a", "b", "c"}; !reflect.DeepEqual(g, w) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001170 t.Errorf("want foo missing deps %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001171 }
1172
1173 if g, w := foo.srcs, []string{}; !reflect.DeepEqual(g, w) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001174 t.Errorf("want foo srcs %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001175 }
1176
1177 if g, w := foo.src, ""; g != w {
Colin Crossba71a3f2019-03-18 12:12:48 -07001178 t.Errorf("want foo src %q, got %q", w, g)
Colin Cross8a497952019-03-05 22:25:09 -08001179 }
1180
Colin Crossba71a3f2019-03-18 12:12:48 -07001181 bar := ctx.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
1182
1183 if g, w := bar.missingDeps, []string{"d", "e"}; !reflect.DeepEqual(g, w) {
1184 t.Errorf("want bar missing deps %q, got %q", w, g)
1185 }
1186
1187 if g, w := bar.srcs, []string{}; !reflect.DeepEqual(g, w) {
1188 t.Errorf("want bar srcs %q, got %q", w, g)
1189 }
Colin Cross937664a2019-03-06 10:17:32 -08001190}
1191
Colin Cross8854a5a2019-02-11 14:14:16 -08001192func ExampleOutputPath_ReplaceExtension() {
1193 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001194 config: TestConfig("out", nil, "", nil),
Colin Cross8854a5a2019-02-11 14:14:16 -08001195 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001196 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross8854a5a2019-02-11 14:14:16 -08001197 p2 := p.ReplaceExtension(ctx, "oat")
1198 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001199 fmt.Println(p.Rel(), p2.Rel())
Colin Cross8854a5a2019-02-11 14:14:16 -08001200
1201 // Output:
1202 // out/system/framework/boot.art out/system/framework/boot.oat
Colin Cross2cdd5df2019-02-25 10:25:24 -08001203 // boot.art boot.oat
Colin Cross8854a5a2019-02-11 14:14:16 -08001204}
Colin Cross40e33732019-02-15 11:08:35 -08001205
1206func ExampleOutputPath_FileInSameDir() {
1207 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001208 config: TestConfig("out", nil, "", nil),
Colin Cross40e33732019-02-15 11:08:35 -08001209 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001210 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross40e33732019-02-15 11:08:35 -08001211 p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
1212 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001213 fmt.Println(p.Rel(), p2.Rel())
Colin Cross40e33732019-02-15 11:08:35 -08001214
1215 // Output:
1216 // out/system/framework/boot.art out/system/framework/oat/arm/boot.vdex
Colin Cross2cdd5df2019-02-25 10:25:24 -08001217 // boot.art oat/arm/boot.vdex
Colin Cross40e33732019-02-15 11:08:35 -08001218}