blob: cb9138b98aed1ddd0e5e8cb1c1f3ef3ef56d8772 [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"
Inseob Kimd9580b82021-04-13 21:13:49 +090024
25 "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
Colin Cross98be1bb2019-12-13 20:41:13 -0800200func pathTestConfig(buildDir string) Config {
201 return TestConfig(buildDir, nil, "", nil)
202}
203
Dan Willemsen00269f22017-07-06 16:59:48 -0700204func TestPathForModuleInstall(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800205 testConfig := pathTestConfig("")
Dan Willemsen00269f22017-07-06 16:59:48 -0700206
Jiyong Park87788b52020-09-01 12:37:45 +0900207 hostTarget := Target{Os: Linux, Arch: Arch{ArchType: X86}}
208 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
Dan Willemsen00269f22017-07-06 16:59:48 -0700209
210 testCases := []struct {
Jiyong Park957bcd92020-10-20 18:23:33 +0900211 name string
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100212 ctx *testModuleInstallPathContext
Jiyong Park957bcd92020-10-20 18:23:33 +0900213 in []string
214 out string
215 partitionDir string
Dan Willemsen00269f22017-07-06 16:59:48 -0700216 }{
217 {
218 name: "host binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100219 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700220 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800221 os: hostTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700222 target: hostTarget,
223 },
224 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900225 in: []string{"bin", "my_test"},
226 out: "host/linux-x86/bin/my_test",
227 partitionDir: "host/linux-x86",
Dan Willemsen00269f22017-07-06 16:59:48 -0700228 },
229
230 {
231 name: "system binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100232 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700233 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800234 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700235 target: deviceTarget,
236 },
237 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900238 in: []string{"bin", "my_test"},
239 out: "target/product/test_device/system/bin/my_test",
240 partitionDir: "target/product/test_device/system",
Dan Willemsen00269f22017-07-06 16:59:48 -0700241 },
242 {
243 name: "vendor binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100244 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700245 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800246 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700247 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800248 earlyModuleContext: earlyModuleContext{
249 kind: socSpecificModule,
250 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700251 },
252 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900253 in: []string{"bin", "my_test"},
254 out: "target/product/test_device/vendor/bin/my_test",
255 partitionDir: "target/product/test_device/vendor",
Dan Willemsen00269f22017-07-06 16:59:48 -0700256 },
Jiyong Park2db76922017-11-08 16:03:48 +0900257 {
258 name: "odm binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100259 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700260 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800261 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900262 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800263 earlyModuleContext: earlyModuleContext{
264 kind: deviceSpecificModule,
265 },
Jiyong Park2db76922017-11-08 16:03:48 +0900266 },
267 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900268 in: []string{"bin", "my_test"},
269 out: "target/product/test_device/odm/bin/my_test",
270 partitionDir: "target/product/test_device/odm",
Jiyong Park2db76922017-11-08 16:03:48 +0900271 },
272 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900273 name: "product binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100274 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700275 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800276 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900277 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800278 earlyModuleContext: earlyModuleContext{
279 kind: productSpecificModule,
280 },
Jiyong Park2db76922017-11-08 16:03:48 +0900281 },
282 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900283 in: []string{"bin", "my_test"},
284 out: "target/product/test_device/product/bin/my_test",
285 partitionDir: "target/product/test_device/product",
Jiyong Park2db76922017-11-08 16:03:48 +0900286 },
Dario Frenifd05a742018-05-29 13:28:54 +0100287 {
Justin Yund5f6c822019-06-25 16:47:17 +0900288 name: "system_ext binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100289 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700290 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800291 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100292 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800293 earlyModuleContext: earlyModuleContext{
294 kind: systemExtSpecificModule,
295 },
Dario Frenifd05a742018-05-29 13:28:54 +0100296 },
297 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900298 in: []string{"bin", "my_test"},
299 out: "target/product/test_device/system_ext/bin/my_test",
300 partitionDir: "target/product/test_device/system_ext",
Dario Frenifd05a742018-05-29 13:28:54 +0100301 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700302 {
303 name: "root binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100304 ctx: &testModuleInstallPathContext{
Colin Cross90ba5f42019-10-02 11:10:58 -0700305 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800306 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700307 target: deviceTarget,
308 },
309 inRoot: true,
310 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900311 in: []string{"my_test"},
312 out: "target/product/test_device/root/my_test",
313 partitionDir: "target/product/test_device/root",
Colin Cross90ba5f42019-10-02 11:10:58 -0700314 },
315 {
316 name: "recovery binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100317 ctx: &testModuleInstallPathContext{
Colin Cross90ba5f42019-10-02 11:10:58 -0700318 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800319 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700320 target: deviceTarget,
321 },
322 inRecovery: true,
323 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900324 in: []string{"bin/my_test"},
325 out: "target/product/test_device/recovery/root/system/bin/my_test",
326 partitionDir: "target/product/test_device/recovery/root/system",
Colin Cross90ba5f42019-10-02 11:10:58 -0700327 },
328 {
329 name: "recovery root binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100330 ctx: &testModuleInstallPathContext{
Colin Cross90ba5f42019-10-02 11:10:58 -0700331 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800332 os: deviceTarget.Os,
Colin Cross90ba5f42019-10-02 11:10:58 -0700333 target: deviceTarget,
334 },
335 inRecovery: true,
336 inRoot: true,
337 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900338 in: []string{"my_test"},
339 out: "target/product/test_device/recovery/root/my_test",
340 partitionDir: "target/product/test_device/recovery/root",
Colin Cross90ba5f42019-10-02 11:10:58 -0700341 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700342
343 {
Inseob Kimd9580b82021-04-13 21:13:49 +0900344 name: "ramdisk binary",
345 ctx: &testModuleInstallPathContext{
346 baseModuleContext: baseModuleContext{
347 os: deviceTarget.Os,
348 target: deviceTarget,
349 },
350 inRamdisk: true,
351 },
352 in: []string{"my_test"},
353 out: "target/product/test_device/ramdisk/system/my_test",
354 partitionDir: "target/product/test_device/ramdisk/system",
355 },
356 {
357 name: "ramdisk root binary",
358 ctx: &testModuleInstallPathContext{
359 baseModuleContext: baseModuleContext{
360 os: deviceTarget.Os,
361 target: deviceTarget,
362 },
363 inRamdisk: true,
364 inRoot: true,
365 },
366 in: []string{"my_test"},
367 out: "target/product/test_device/ramdisk/my_test",
368 partitionDir: "target/product/test_device/ramdisk",
369 },
370 {
371 name: "vendor_ramdisk binary",
372 ctx: &testModuleInstallPathContext{
373 baseModuleContext: baseModuleContext{
374 os: deviceTarget.Os,
375 target: deviceTarget,
376 },
377 inVendorRamdisk: true,
378 },
379 in: []string{"my_test"},
380 out: "target/product/test_device/vendor_ramdisk/system/my_test",
381 partitionDir: "target/product/test_device/vendor_ramdisk/system",
382 },
383 {
384 name: "vendor_ramdisk root binary",
385 ctx: &testModuleInstallPathContext{
386 baseModuleContext: baseModuleContext{
387 os: deviceTarget.Os,
388 target: deviceTarget,
389 },
390 inVendorRamdisk: true,
391 inRoot: true,
392 },
393 in: []string{"my_test"},
394 out: "target/product/test_device/vendor_ramdisk/my_test",
395 partitionDir: "target/product/test_device/vendor_ramdisk",
396 },
397 {
Inseob Kimf84e9c02021-04-08 21:13:22 +0900398 name: "debug_ramdisk binary",
399 ctx: &testModuleInstallPathContext{
400 baseModuleContext: baseModuleContext{
401 os: deviceTarget.Os,
402 target: deviceTarget,
403 },
404 inDebugRamdisk: true,
405 },
406 in: []string{"my_test"},
407 out: "target/product/test_device/debug_ramdisk/my_test",
408 partitionDir: "target/product/test_device/debug_ramdisk",
409 },
410 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700411 name: "system native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100412 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700413 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800414 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700415 target: deviceTarget,
416 },
417 inData: true,
418 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900419 in: []string{"nativetest", "my_test"},
420 out: "target/product/test_device/data/nativetest/my_test",
421 partitionDir: "target/product/test_device/data",
Dan Willemsen00269f22017-07-06 16:59:48 -0700422 },
423 {
424 name: "vendor native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100425 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700426 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800427 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700428 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800429 earlyModuleContext: earlyModuleContext{
430 kind: socSpecificModule,
431 },
Jiyong Park2db76922017-11-08 16:03:48 +0900432 },
433 inData: true,
434 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900435 in: []string{"nativetest", "my_test"},
436 out: "target/product/test_device/data/nativetest/my_test",
437 partitionDir: "target/product/test_device/data",
Jiyong Park2db76922017-11-08 16:03:48 +0900438 },
439 {
440 name: "odm native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100441 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700442 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800443 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900444 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800445 earlyModuleContext: earlyModuleContext{
446 kind: deviceSpecificModule,
447 },
Jiyong Park2db76922017-11-08 16:03:48 +0900448 },
449 inData: true,
450 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900451 in: []string{"nativetest", "my_test"},
452 out: "target/product/test_device/data/nativetest/my_test",
453 partitionDir: "target/product/test_device/data",
Jiyong Park2db76922017-11-08 16:03:48 +0900454 },
455 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900456 name: "product native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100457 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700458 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800459 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900460 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800461 earlyModuleContext: earlyModuleContext{
462 kind: productSpecificModule,
463 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700464 },
465 inData: true,
466 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900467 in: []string{"nativetest", "my_test"},
468 out: "target/product/test_device/data/nativetest/my_test",
469 partitionDir: "target/product/test_device/data",
Dan Willemsen00269f22017-07-06 16:59:48 -0700470 },
471
472 {
Justin Yund5f6c822019-06-25 16:47:17 +0900473 name: "system_ext native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100474 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700475 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800476 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100477 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800478 earlyModuleContext: earlyModuleContext{
479 kind: systemExtSpecificModule,
480 },
Dario Frenifd05a742018-05-29 13:28:54 +0100481 },
482 inData: true,
483 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900484 in: []string{"nativetest", "my_test"},
485 out: "target/product/test_device/data/nativetest/my_test",
486 partitionDir: "target/product/test_device/data",
Dario Frenifd05a742018-05-29 13:28:54 +0100487 },
488
489 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700490 name: "sanitized system binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100491 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700492 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800493 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700494 target: deviceTarget,
495 },
496 inSanitizerDir: true,
497 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900498 in: []string{"bin", "my_test"},
499 out: "target/product/test_device/data/asan/system/bin/my_test",
500 partitionDir: "target/product/test_device/data/asan/system",
Dan Willemsen00269f22017-07-06 16:59:48 -0700501 },
502 {
503 name: "sanitized vendor binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100504 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700505 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800506 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700507 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800508 earlyModuleContext: earlyModuleContext{
509 kind: socSpecificModule,
510 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700511 },
512 inSanitizerDir: true,
513 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900514 in: []string{"bin", "my_test"},
515 out: "target/product/test_device/data/asan/vendor/bin/my_test",
516 partitionDir: "target/product/test_device/data/asan/vendor",
Dan Willemsen00269f22017-07-06 16:59:48 -0700517 },
Jiyong Park2db76922017-11-08 16:03:48 +0900518 {
519 name: "sanitized odm binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100520 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700521 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800522 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900523 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800524 earlyModuleContext: earlyModuleContext{
525 kind: deviceSpecificModule,
526 },
Jiyong Park2db76922017-11-08 16:03:48 +0900527 },
528 inSanitizerDir: true,
529 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900530 in: []string{"bin", "my_test"},
531 out: "target/product/test_device/data/asan/odm/bin/my_test",
532 partitionDir: "target/product/test_device/data/asan/odm",
Jiyong Park2db76922017-11-08 16:03:48 +0900533 },
534 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900535 name: "sanitized product binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100536 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700537 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800538 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900539 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800540 earlyModuleContext: earlyModuleContext{
541 kind: productSpecificModule,
542 },
Jiyong Park2db76922017-11-08 16:03:48 +0900543 },
544 inSanitizerDir: true,
545 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900546 in: []string{"bin", "my_test"},
547 out: "target/product/test_device/data/asan/product/bin/my_test",
548 partitionDir: "target/product/test_device/data/asan/product",
Jiyong Park2db76922017-11-08 16:03:48 +0900549 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700550
551 {
Justin Yund5f6c822019-06-25 16:47:17 +0900552 name: "sanitized system_ext binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100553 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700554 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800555 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100556 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800557 earlyModuleContext: earlyModuleContext{
558 kind: systemExtSpecificModule,
559 },
Dario Frenifd05a742018-05-29 13:28:54 +0100560 },
561 inSanitizerDir: true,
562 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900563 in: []string{"bin", "my_test"},
564 out: "target/product/test_device/data/asan/system_ext/bin/my_test",
565 partitionDir: "target/product/test_device/data/asan/system_ext",
Dario Frenifd05a742018-05-29 13:28:54 +0100566 },
567
568 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700569 name: "sanitized system native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100570 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700571 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800572 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700573 target: deviceTarget,
574 },
575 inData: true,
576 inSanitizerDir: true,
577 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900578 in: []string{"nativetest", "my_test"},
579 out: "target/product/test_device/data/asan/data/nativetest/my_test",
580 partitionDir: "target/product/test_device/data/asan/data",
Dan Willemsen00269f22017-07-06 16:59:48 -0700581 },
582 {
583 name: "sanitized vendor native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100584 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700585 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800586 os: deviceTarget.Os,
Dan Willemsen00269f22017-07-06 16:59:48 -0700587 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800588 earlyModuleContext: earlyModuleContext{
589 kind: socSpecificModule,
590 },
Jiyong Park2db76922017-11-08 16:03:48 +0900591 },
592 inData: true,
593 inSanitizerDir: true,
594 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900595 in: []string{"nativetest", "my_test"},
596 out: "target/product/test_device/data/asan/data/nativetest/my_test",
597 partitionDir: "target/product/test_device/data/asan/data",
Jiyong Park2db76922017-11-08 16:03:48 +0900598 },
599 {
600 name: "sanitized odm native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100601 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700602 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800603 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900604 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800605 earlyModuleContext: earlyModuleContext{
606 kind: deviceSpecificModule,
607 },
Jiyong Park2db76922017-11-08 16:03:48 +0900608 },
609 inData: true,
610 inSanitizerDir: true,
611 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900612 in: []string{"nativetest", "my_test"},
613 out: "target/product/test_device/data/asan/data/nativetest/my_test",
614 partitionDir: "target/product/test_device/data/asan/data",
Jiyong Park2db76922017-11-08 16:03:48 +0900615 },
616 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900617 name: "sanitized product native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100618 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700619 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800620 os: deviceTarget.Os,
Jiyong Park2db76922017-11-08 16:03:48 +0900621 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800622 earlyModuleContext: earlyModuleContext{
623 kind: productSpecificModule,
624 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700625 },
626 inData: true,
627 inSanitizerDir: true,
628 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900629 in: []string{"nativetest", "my_test"},
630 out: "target/product/test_device/data/asan/data/nativetest/my_test",
631 partitionDir: "target/product/test_device/data/asan/data",
Dan Willemsen00269f22017-07-06 16:59:48 -0700632 },
Dario Frenifd05a742018-05-29 13:28:54 +0100633 {
Justin Yund5f6c822019-06-25 16:47:17 +0900634 name: "sanitized system_ext native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100635 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700636 baseModuleContext: baseModuleContext{
Colin Crossfb0c16e2019-11-20 17:12:35 -0800637 os: deviceTarget.Os,
Dario Frenifd05a742018-05-29 13:28:54 +0100638 target: deviceTarget,
Colin Cross1184b642019-12-30 18:43:07 -0800639 earlyModuleContext: earlyModuleContext{
640 kind: systemExtSpecificModule,
641 },
Dario Frenifd05a742018-05-29 13:28:54 +0100642 },
643 inData: true,
644 inSanitizerDir: true,
645 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900646 in: []string{"nativetest", "my_test"},
647 out: "target/product/test_device/data/asan/data/nativetest/my_test",
648 partitionDir: "target/product/test_device/data/asan/data",
Colin Cross6e359402020-02-10 15:29:54 -0800649 }, {
650 name: "device testcases",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100651 ctx: &testModuleInstallPathContext{
Colin Cross6e359402020-02-10 15:29:54 -0800652 baseModuleContext: baseModuleContext{
653 os: deviceTarget.Os,
654 target: deviceTarget,
655 },
656 inTestcases: true,
657 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900658 in: []string{"my_test", "my_test_bin"},
659 out: "target/product/test_device/testcases/my_test/my_test_bin",
660 partitionDir: "target/product/test_device/testcases",
Colin Cross6e359402020-02-10 15:29:54 -0800661 }, {
662 name: "host testcases",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100663 ctx: &testModuleInstallPathContext{
Colin Cross6e359402020-02-10 15:29:54 -0800664 baseModuleContext: baseModuleContext{
665 os: hostTarget.Os,
666 target: hostTarget,
667 },
668 inTestcases: true,
669 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900670 in: []string{"my_test", "my_test_bin"},
671 out: "host/linux-x86/testcases/my_test/my_test_bin",
672 partitionDir: "host/linux-x86/testcases",
Colin Cross6e359402020-02-10 15:29:54 -0800673 }, {
674 name: "forced host testcases",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100675 ctx: &testModuleInstallPathContext{
Colin Cross6e359402020-02-10 15:29:54 -0800676 baseModuleContext: baseModuleContext{
677 os: deviceTarget.Os,
678 target: deviceTarget,
679 },
680 inTestcases: true,
681 forceOS: &Linux,
Jiyong Park87788b52020-09-01 12:37:45 +0900682 forceArch: &X86,
Colin Cross6e359402020-02-10 15:29:54 -0800683 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900684 in: []string{"my_test", "my_test_bin"},
685 out: "host/linux-x86/testcases/my_test/my_test_bin",
686 partitionDir: "host/linux-x86/testcases",
Dario Frenifd05a742018-05-29 13:28:54 +0100687 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700688 }
689
690 for _, tc := range testCases {
691 t.Run(tc.name, func(t *testing.T) {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700692 tc.ctx.baseModuleContext.config = testConfig
Dan Willemsen00269f22017-07-06 16:59:48 -0700693 output := PathForModuleInstall(tc.ctx, tc.in...)
694 if output.basePath.path != tc.out {
695 t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
696 output.basePath.path,
697 tc.out)
698 }
Jiyong Park957bcd92020-10-20 18:23:33 +0900699 if output.partitionDir != tc.partitionDir {
700 t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n",
701 output.partitionDir, tc.partitionDir)
702 }
Dan Willemsen00269f22017-07-06 16:59:48 -0700703 })
704 }
705}
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700706
Inseob Kimd9580b82021-04-13 21:13:49 +0900707func TestPathForModuleInstallRecoveryAsBoot(t *testing.T) {
708 testConfig := pathTestConfig("")
709 testConfig.TestProductVariables.BoardUsesRecoveryAsBoot = proptools.BoolPtr(true)
710 testConfig.TestProductVariables.BoardMoveRecoveryResourcesToVendorBoot = proptools.BoolPtr(true)
711 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
712
713 testCases := []struct {
714 name string
715 ctx *testModuleInstallPathContext
716 in []string
717 out string
718 partitionDir string
719 }{
720 {
721 name: "ramdisk binary",
722 ctx: &testModuleInstallPathContext{
723 baseModuleContext: baseModuleContext{
724 os: deviceTarget.Os,
725 target: deviceTarget,
726 },
727 inRamdisk: true,
728 inRoot: true,
729 },
730 in: []string{"my_test"},
731 out: "target/product/test_device/recovery/root/first_stage_ramdisk/my_test",
732 partitionDir: "target/product/test_device/recovery/root/first_stage_ramdisk",
733 },
734
735 {
736 name: "vendor_ramdisk binary",
737 ctx: &testModuleInstallPathContext{
738 baseModuleContext: baseModuleContext{
739 os: deviceTarget.Os,
740 target: deviceTarget,
741 },
742 inVendorRamdisk: true,
743 inRoot: true,
744 },
745 in: []string{"my_test"},
746 out: "target/product/test_device/vendor_ramdisk/first_stage_ramdisk/my_test",
747 partitionDir: "target/product/test_device/vendor_ramdisk/first_stage_ramdisk",
748 },
Inseob Kimf84e9c02021-04-08 21:13:22 +0900749 {
750 name: "debug_ramdisk binary",
751 ctx: &testModuleInstallPathContext{
752 baseModuleContext: baseModuleContext{
753 os: deviceTarget.Os,
754 target: deviceTarget,
755 },
756 inDebugRamdisk: true,
757 },
758 in: []string{"my_test"},
759 out: "target/product/test_device/debug_ramdisk/first_stage_ramdisk/my_test",
760 partitionDir: "target/product/test_device/debug_ramdisk/first_stage_ramdisk",
761 },
Inseob Kimd9580b82021-04-13 21:13:49 +0900762 }
763
764 for _, tc := range testCases {
765 t.Run(tc.name, func(t *testing.T) {
766 tc.ctx.baseModuleContext.config = testConfig
767 output := PathForModuleInstall(tc.ctx, tc.in...)
768 if output.basePath.path != tc.out {
769 t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
770 output.basePath.path,
771 tc.out)
772 }
773 if output.partitionDir != tc.partitionDir {
774 t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n",
775 output.partitionDir, tc.partitionDir)
776 }
777 })
778 }
779}
780
Jiyong Park957bcd92020-10-20 18:23:33 +0900781func TestBaseDirForInstallPath(t *testing.T) {
782 testConfig := pathTestConfig("")
783 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
784
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100785 ctx := &testModuleInstallPathContext{
Jiyong Park957bcd92020-10-20 18:23:33 +0900786 baseModuleContext: baseModuleContext{
787 os: deviceTarget.Os,
788 target: deviceTarget,
789 },
790 }
791 ctx.baseModuleContext.config = testConfig
792
793 actual := PathForModuleInstall(ctx, "foo", "bar")
794 expectedBaseDir := "target/product/test_device/system"
795 if actual.partitionDir != expectedBaseDir {
796 t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n", actual.partitionDir, expectedBaseDir)
797 }
798 expectedRelPath := "foo/bar"
799 if actual.Rel() != expectedRelPath {
800 t.Errorf("unexpected Rel():\n got: %q\nwant: %q\n", actual.Rel(), expectedRelPath)
801 }
802
803 actualAfterJoin := actual.Join(ctx, "baz")
804 // partitionDir is preserved even after joining
805 if actualAfterJoin.partitionDir != expectedBaseDir {
806 t.Errorf("unexpected partitionDir after joining:\n got: %q\nwant: %q\n", actualAfterJoin.partitionDir, expectedBaseDir)
807 }
808 // Rel() is updated though
809 expectedRelAfterJoin := "baz"
810 if actualAfterJoin.Rel() != expectedRelAfterJoin {
811 t.Errorf("unexpected Rel() after joining:\n got: %q\nwant: %q\n", actualAfterJoin.Rel(), expectedRelAfterJoin)
812 }
813}
814
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700815func TestDirectorySortedPaths(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800816 config := TestConfig("out", nil, "", map[string][]byte{
817 "Android.bp": nil,
818 "a.txt": nil,
819 "a/txt": nil,
820 "a/b/c": nil,
821 "a/b/d": nil,
822 "b": nil,
823 "b/b.txt": nil,
824 "a/a.txt": nil,
Colin Cross07e51612019-03-05 12:46:40 -0800825 })
826
Colin Cross98be1bb2019-12-13 20:41:13 -0800827 ctx := PathContextForTesting(config)
828
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700829 makePaths := func() Paths {
830 return Paths{
Colin Cross07e51612019-03-05 12:46:40 -0800831 PathForSource(ctx, "a.txt"),
832 PathForSource(ctx, "a/txt"),
833 PathForSource(ctx, "a/b/c"),
834 PathForSource(ctx, "a/b/d"),
835 PathForSource(ctx, "b"),
836 PathForSource(ctx, "b/b.txt"),
837 PathForSource(ctx, "a/a.txt"),
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700838 }
839 }
840
841 expected := []string{
842 "a.txt",
843 "a/a.txt",
844 "a/b/c",
845 "a/b/d",
846 "a/txt",
847 "b",
848 "b/b.txt",
849 }
850
851 paths := makePaths()
Colin Crossa140bb02018-04-17 10:52:26 -0700852 reversePaths := ReversePaths(paths)
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700853
854 sortedPaths := PathsToDirectorySortedPaths(paths)
855 reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
856
857 if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
858 t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
859 }
860
861 if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
862 t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
863 }
864
865 expectedA := []string{
866 "a/a.txt",
867 "a/b/c",
868 "a/b/d",
869 "a/txt",
870 }
871
872 inA := sortedPaths.PathsInDirectory("a")
873 if !reflect.DeepEqual(inA.Strings(), expectedA) {
874 t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
875 }
876
877 expectedA_B := []string{
878 "a/b/c",
879 "a/b/d",
880 }
881
882 inA_B := sortedPaths.PathsInDirectory("a/b")
883 if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
884 t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
885 }
886
887 expectedB := []string{
888 "b/b.txt",
889 }
890
891 inB := sortedPaths.PathsInDirectory("b")
892 if !reflect.DeepEqual(inB.Strings(), expectedB) {
893 t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
894 }
895}
Colin Cross43f08db2018-11-12 10:13:39 -0800896
897func TestMaybeRel(t *testing.T) {
898 testCases := []struct {
899 name string
900 base string
901 target string
902 out string
903 isRel bool
904 }{
905 {
906 name: "normal",
907 base: "a/b/c",
908 target: "a/b/c/d",
909 out: "d",
910 isRel: true,
911 },
912 {
913 name: "parent",
914 base: "a/b/c/d",
915 target: "a/b/c",
916 isRel: false,
917 },
918 {
919 name: "not relative",
920 base: "a/b",
921 target: "c/d",
922 isRel: false,
923 },
924 {
925 name: "abs1",
926 base: "/a",
927 target: "a",
928 isRel: false,
929 },
930 {
931 name: "abs2",
932 base: "a",
933 target: "/a",
934 isRel: false,
935 },
936 }
937
938 for _, testCase := range testCases {
939 t.Run(testCase.name, func(t *testing.T) {
940 ctx := &configErrorWrapper{}
941 out, isRel := MaybeRel(ctx, testCase.base, testCase.target)
942 if len(ctx.errors) > 0 {
943 t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v",
944 testCase.base, testCase.target, ctx.errors)
945 }
946 if isRel != testCase.isRel || out != testCase.out {
947 t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v",
948 testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel)
949 }
950 })
951 }
952}
Colin Cross7b3dcc32019-01-24 13:14:39 -0800953
954func TestPathForSource(t *testing.T) {
955 testCases := []struct {
956 name string
957 buildDir string
958 src string
959 err string
960 }{
961 {
962 name: "normal",
963 buildDir: "out",
964 src: "a/b/c",
965 },
966 {
967 name: "abs",
968 buildDir: "out",
969 src: "/a/b/c",
970 err: "is outside directory",
971 },
972 {
973 name: "in out dir",
974 buildDir: "out",
975 src: "out/a/b/c",
976 err: "is in output",
977 },
978 }
979
980 funcs := []struct {
981 name string
982 f func(ctx PathContext, pathComponents ...string) (SourcePath, error)
983 }{
984 {"pathForSource", pathForSource},
985 {"safePathForSource", safePathForSource},
986 }
987
988 for _, f := range funcs {
989 t.Run(f.name, func(t *testing.T) {
990 for _, test := range testCases {
991 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800992 testConfig := pathTestConfig(test.buildDir)
Colin Cross7b3dcc32019-01-24 13:14:39 -0800993 ctx := &configErrorWrapper{config: testConfig}
994 _, err := f.f(ctx, test.src)
995 if len(ctx.errors) > 0 {
996 t.Fatalf("unexpected errors %v", ctx.errors)
997 }
998 if err != nil {
999 if test.err == "" {
1000 t.Fatalf("unexpected error %q", err.Error())
1001 } else if !strings.Contains(err.Error(), test.err) {
1002 t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
1003 }
1004 } else {
1005 if test.err != "" {
1006 t.Fatalf("missing error %q", test.err)
1007 }
1008 }
1009 })
1010 }
1011 })
1012 }
1013}
Colin Cross8854a5a2019-02-11 14:14:16 -08001014
Colin Cross8a497952019-03-05 22:25:09 -08001015type pathForModuleSrcTestModule struct {
Colin Cross937664a2019-03-06 10:17:32 -08001016 ModuleBase
1017 props struct {
1018 Srcs []string `android:"path"`
1019 Exclude_srcs []string `android:"path"`
Colin Cross8a497952019-03-05 22:25:09 -08001020
1021 Src *string `android:"path"`
Colin Crossba71a3f2019-03-18 12:12:48 -07001022
1023 Module_handles_missing_deps bool
Colin Cross937664a2019-03-06 10:17:32 -08001024 }
1025
Colin Cross8a497952019-03-05 22:25:09 -08001026 src string
1027 rel string
1028
1029 srcs []string
Colin Cross937664a2019-03-06 10:17:32 -08001030 rels []string
Colin Cross8a497952019-03-05 22:25:09 -08001031
1032 missingDeps []string
Colin Cross937664a2019-03-06 10:17:32 -08001033}
1034
Colin Cross8a497952019-03-05 22:25:09 -08001035func pathForModuleSrcTestModuleFactory() Module {
1036 module := &pathForModuleSrcTestModule{}
Colin Cross937664a2019-03-06 10:17:32 -08001037 module.AddProperties(&module.props)
1038 InitAndroidModule(module)
1039 return module
1040}
1041
Colin Cross8a497952019-03-05 22:25:09 -08001042func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001043 var srcs Paths
1044 if p.props.Module_handles_missing_deps {
1045 srcs, p.missingDeps = PathsAndMissingDepsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
1046 } else {
1047 srcs = PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
1048 }
Colin Cross8a497952019-03-05 22:25:09 -08001049 p.srcs = srcs.Strings()
Colin Cross937664a2019-03-06 10:17:32 -08001050
Colin Cross8a497952019-03-05 22:25:09 -08001051 for _, src := range srcs {
Colin Cross937664a2019-03-06 10:17:32 -08001052 p.rels = append(p.rels, src.Rel())
1053 }
Colin Cross8a497952019-03-05 22:25:09 -08001054
1055 if p.props.Src != nil {
1056 src := PathForModuleSrc(ctx, *p.props.Src)
1057 if src != nil {
1058 p.src = src.String()
1059 p.rel = src.Rel()
1060 }
1061 }
1062
Colin Crossba71a3f2019-03-18 12:12:48 -07001063 if !p.props.Module_handles_missing_deps {
1064 p.missingDeps = ctx.GetMissingDependencies()
1065 }
Colin Cross6c4f21f2019-06-06 15:41:36 -07001066
1067 ctx.Build(pctx, BuildParams{
1068 Rule: Touch,
1069 Output: PathForModuleOut(ctx, "output"),
1070 })
Colin Cross8a497952019-03-05 22:25:09 -08001071}
1072
Colin Cross41955e82019-05-29 14:40:35 -07001073type pathForModuleSrcOutputFileProviderModule struct {
1074 ModuleBase
1075 props struct {
1076 Outs []string
1077 Tagged []string
1078 }
1079
1080 outs Paths
1081 tagged Paths
1082}
1083
1084func pathForModuleSrcOutputFileProviderModuleFactory() Module {
1085 module := &pathForModuleSrcOutputFileProviderModule{}
1086 module.AddProperties(&module.props)
1087 InitAndroidModule(module)
1088 return module
1089}
1090
1091func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
1092 for _, out := range p.props.Outs {
1093 p.outs = append(p.outs, PathForModuleOut(ctx, out))
1094 }
1095
1096 for _, tagged := range p.props.Tagged {
1097 p.tagged = append(p.tagged, PathForModuleOut(ctx, tagged))
1098 }
1099}
1100
1101func (p *pathForModuleSrcOutputFileProviderModule) OutputFiles(tag string) (Paths, error) {
1102 switch tag {
1103 case "":
1104 return p.outs, nil
1105 case ".tagged":
1106 return p.tagged, nil
1107 default:
1108 return nil, fmt.Errorf("unsupported tag %q", tag)
1109 }
1110}
1111
Colin Cross8a497952019-03-05 22:25:09 -08001112type pathForModuleSrcTestCase struct {
1113 name string
1114 bp string
1115 srcs []string
1116 rels []string
1117 src string
1118 rel string
1119}
1120
Paul Duffin54054682021-03-16 21:11:42 +00001121func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) {
Colin Cross8a497952019-03-05 22:25:09 -08001122 for _, test := range tests {
1123 t.Run(test.name, func(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001124 fgBp := `
1125 filegroup {
1126 name: "a",
1127 srcs: ["src/a"],
1128 }
1129 `
1130
Colin Cross41955e82019-05-29 14:40:35 -07001131 ofpBp := `
1132 output_file_provider {
1133 name: "b",
1134 outs: ["gen/b"],
1135 tagged: ["gen/c"],
1136 }
1137 `
1138
Paul Duffin54054682021-03-16 21:11:42 +00001139 mockFS := MockFS{
Colin Cross8a497952019-03-05 22:25:09 -08001140 "fg/Android.bp": []byte(fgBp),
1141 "foo/Android.bp": []byte(test.bp),
Colin Cross41955e82019-05-29 14:40:35 -07001142 "ofp/Android.bp": []byte(ofpBp),
Colin Cross8a497952019-03-05 22:25:09 -08001143 "fg/src/a": nil,
1144 "foo/src/b": nil,
1145 "foo/src/c": nil,
1146 "foo/src/d": nil,
1147 "foo/src/e/e": nil,
1148 "foo/src_special/$": nil,
1149 }
1150
Paul Duffin30ac3e72021-03-20 00:36:14 +00001151 result := GroupFixturePreparers(
Paul Duffin54054682021-03-16 21:11:42 +00001152 FixtureRegisterWithContext(func(ctx RegistrationContext) {
1153 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1154 ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
1155 ctx.RegisterModuleType("filegroup", FileGroupFactory)
1156 }),
1157 mockFS.AddToFixture(),
Paul Duffin30ac3e72021-03-20 00:36:14 +00001158 ).RunTest(t)
Colin Cross8a497952019-03-05 22:25:09 -08001159
Paul Duffin54054682021-03-16 21:11:42 +00001160 m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
Colin Crossae8600b2020-10-29 17:09:13 -07001161
Paul Duffin54054682021-03-16 21:11:42 +00001162 AssertStringPathsRelativeToTopEquals(t, "srcs", result.Config, test.srcs, m.srcs)
1163 AssertStringPathsRelativeToTopEquals(t, "rels", result.Config, test.rels, m.rels)
1164 AssertStringPathRelativeToTopEquals(t, "src", result.Config, test.src, m.src)
1165 AssertStringPathRelativeToTopEquals(t, "rel", result.Config, test.rel, m.rel)
Colin Cross8a497952019-03-05 22:25:09 -08001166 })
1167 }
Colin Cross937664a2019-03-06 10:17:32 -08001168}
1169
Colin Cross8a497952019-03-05 22:25:09 -08001170func TestPathsForModuleSrc(t *testing.T) {
1171 tests := []pathForModuleSrcTestCase{
Colin Cross937664a2019-03-06 10:17:32 -08001172 {
1173 name: "path",
1174 bp: `
1175 test {
1176 name: "foo",
1177 srcs: ["src/b"],
1178 }`,
1179 srcs: []string{"foo/src/b"},
1180 rels: []string{"src/b"},
1181 },
1182 {
1183 name: "glob",
1184 bp: `
1185 test {
1186 name: "foo",
1187 srcs: [
1188 "src/*",
1189 "src/e/*",
1190 ],
1191 }`,
1192 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1193 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1194 },
1195 {
1196 name: "recursive glob",
1197 bp: `
1198 test {
1199 name: "foo",
1200 srcs: ["src/**/*"],
1201 }`,
1202 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1203 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1204 },
1205 {
1206 name: "filegroup",
1207 bp: `
1208 test {
1209 name: "foo",
1210 srcs: [":a"],
1211 }`,
1212 srcs: []string{"fg/src/a"},
1213 rels: []string{"src/a"},
1214 },
1215 {
Colin Cross41955e82019-05-29 14:40:35 -07001216 name: "output file provider",
1217 bp: `
1218 test {
1219 name: "foo",
1220 srcs: [":b"],
1221 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001222 srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"},
Colin Cross41955e82019-05-29 14:40:35 -07001223 rels: []string{"gen/b"},
1224 },
1225 {
1226 name: "output file provider tagged",
1227 bp: `
1228 test {
1229 name: "foo",
1230 srcs: [":b{.tagged}"],
1231 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001232 srcs: []string{"out/soong/.intermediates/ofp/b/gen/c"},
Colin Cross41955e82019-05-29 14:40:35 -07001233 rels: []string{"gen/c"},
1234 },
1235 {
Jooyung Han7607dd32020-07-05 10:23:14 +09001236 name: "output file provider with exclude",
1237 bp: `
1238 test {
1239 name: "foo",
1240 srcs: [":b", ":c"],
1241 exclude_srcs: [":c"]
1242 }
1243 output_file_provider {
1244 name: "c",
1245 outs: ["gen/c"],
1246 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001247 srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"},
Jooyung Han7607dd32020-07-05 10:23:14 +09001248 rels: []string{"gen/b"},
1249 },
1250 {
Colin Cross937664a2019-03-06 10:17:32 -08001251 name: "special characters glob",
1252 bp: `
1253 test {
1254 name: "foo",
1255 srcs: ["src_special/*"],
1256 }`,
1257 srcs: []string{"foo/src_special/$"},
1258 rels: []string{"src_special/$"},
1259 },
1260 }
1261
Paul Duffin54054682021-03-16 21:11:42 +00001262 testPathForModuleSrc(t, tests)
Colin Cross41955e82019-05-29 14:40:35 -07001263}
1264
1265func TestPathForModuleSrc(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001266 tests := []pathForModuleSrcTestCase{
1267 {
1268 name: "path",
1269 bp: `
1270 test {
1271 name: "foo",
1272 src: "src/b",
1273 }`,
1274 src: "foo/src/b",
1275 rel: "src/b",
1276 },
1277 {
1278 name: "glob",
1279 bp: `
1280 test {
1281 name: "foo",
1282 src: "src/e/*",
1283 }`,
1284 src: "foo/src/e/e",
1285 rel: "src/e/e",
1286 },
1287 {
1288 name: "filegroup",
1289 bp: `
1290 test {
1291 name: "foo",
1292 src: ":a",
1293 }`,
1294 src: "fg/src/a",
1295 rel: "src/a",
1296 },
1297 {
Colin Cross41955e82019-05-29 14:40:35 -07001298 name: "output file provider",
1299 bp: `
1300 test {
1301 name: "foo",
1302 src: ":b",
1303 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001304 src: "out/soong/.intermediates/ofp/b/gen/b",
Colin Cross41955e82019-05-29 14:40:35 -07001305 rel: "gen/b",
1306 },
1307 {
1308 name: "output file provider tagged",
1309 bp: `
1310 test {
1311 name: "foo",
1312 src: ":b{.tagged}",
1313 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001314 src: "out/soong/.intermediates/ofp/b/gen/c",
Colin Cross41955e82019-05-29 14:40:35 -07001315 rel: "gen/c",
1316 },
1317 {
Colin Cross8a497952019-03-05 22:25:09 -08001318 name: "special characters glob",
1319 bp: `
1320 test {
1321 name: "foo",
1322 src: "src_special/*",
1323 }`,
1324 src: "foo/src_special/$",
1325 rel: "src_special/$",
1326 },
1327 }
1328
Paul Duffin54054682021-03-16 21:11:42 +00001329 testPathForModuleSrc(t, tests)
Colin Cross8a497952019-03-05 22:25:09 -08001330}
Colin Cross937664a2019-03-06 10:17:32 -08001331
Colin Cross8a497952019-03-05 22:25:09 -08001332func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001333 bp := `
1334 test {
1335 name: "foo",
1336 srcs: [":a"],
1337 exclude_srcs: [":b"],
1338 src: ":c",
1339 }
Colin Crossba71a3f2019-03-18 12:12:48 -07001340
1341 test {
1342 name: "bar",
1343 srcs: [":d"],
1344 exclude_srcs: [":e"],
1345 module_handles_missing_deps: true,
1346 }
Colin Cross8a497952019-03-05 22:25:09 -08001347 `
1348
Paul Duffin30ac3e72021-03-20 00:36:14 +00001349 result := GroupFixturePreparers(
Paul Duffin54054682021-03-16 21:11:42 +00001350 PrepareForTestWithAllowMissingDependencies,
1351 FixtureRegisterWithContext(func(ctx RegistrationContext) {
1352 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1353 }),
1354 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +00001355 ).RunTest(t)
Colin Cross8a497952019-03-05 22:25:09 -08001356
Paul Duffin54054682021-03-16 21:11:42 +00001357 foo := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
Colin Cross8a497952019-03-05 22:25:09 -08001358
Paul Duffin54054682021-03-16 21:11:42 +00001359 AssertArrayString(t, "foo missing deps", []string{"a", "b", "c"}, foo.missingDeps)
1360 AssertArrayString(t, "foo srcs", []string{}, foo.srcs)
1361 AssertStringEquals(t, "foo src", "", foo.src)
Colin Cross98be1bb2019-12-13 20:41:13 -08001362
Paul Duffin54054682021-03-16 21:11:42 +00001363 bar := result.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
Colin Cross98be1bb2019-12-13 20:41:13 -08001364
Paul Duffin54054682021-03-16 21:11:42 +00001365 AssertArrayString(t, "bar missing deps", []string{"d", "e"}, bar.missingDeps)
1366 AssertArrayString(t, "bar srcs", []string{}, bar.srcs)
Colin Cross937664a2019-03-06 10:17:32 -08001367}
1368
Paul Duffin567465d2021-03-16 01:21:34 +00001369func TestPathRelativeToTop(t *testing.T) {
1370 testConfig := pathTestConfig("/tmp/build/top")
1371 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
1372
1373 ctx := &testModuleInstallPathContext{
1374 baseModuleContext: baseModuleContext{
1375 os: deviceTarget.Os,
1376 target: deviceTarget,
1377 },
1378 }
1379 ctx.baseModuleContext.config = testConfig
1380
1381 t.Run("install for soong", func(t *testing.T) {
1382 p := PathForModuleInstall(ctx, "install/path")
1383 AssertPathRelativeToTopEquals(t, "install path for soong", "out/soong/target/product/test_device/system/install/path", p)
1384 })
1385 t.Run("install for make", func(t *testing.T) {
1386 p := PathForModuleInstall(ctx, "install/path").ToMakePath()
1387 AssertPathRelativeToTopEquals(t, "install path for make", "out/target/product/test_device/system/install/path", p)
1388 })
1389 t.Run("output", func(t *testing.T) {
1390 p := PathForOutput(ctx, "output/path")
1391 AssertPathRelativeToTopEquals(t, "output path", "out/soong/output/path", p)
1392 })
1393 t.Run("source", func(t *testing.T) {
1394 p := PathForSource(ctx, "source/path")
1395 AssertPathRelativeToTopEquals(t, "source path", "source/path", p)
1396 })
1397 t.Run("mixture", func(t *testing.T) {
1398 paths := Paths{
1399 PathForModuleInstall(ctx, "install/path"),
1400 PathForModuleInstall(ctx, "install/path").ToMakePath(),
1401 PathForOutput(ctx, "output/path"),
1402 PathForSource(ctx, "source/path"),
1403 }
1404
1405 expected := []string{
1406 "out/soong/target/product/test_device/system/install/path",
1407 "out/target/product/test_device/system/install/path",
1408 "out/soong/output/path",
1409 "source/path",
1410 }
1411 AssertPathsRelativeToTopEquals(t, "mixture", expected, paths)
1412 })
1413}
1414
Colin Cross8854a5a2019-02-11 14:14:16 -08001415func ExampleOutputPath_ReplaceExtension() {
1416 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001417 config: TestConfig("out", nil, "", nil),
Colin Cross8854a5a2019-02-11 14:14:16 -08001418 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001419 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross8854a5a2019-02-11 14:14:16 -08001420 p2 := p.ReplaceExtension(ctx, "oat")
1421 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001422 fmt.Println(p.Rel(), p2.Rel())
Colin Cross8854a5a2019-02-11 14:14:16 -08001423
1424 // Output:
1425 // out/system/framework/boot.art out/system/framework/boot.oat
Colin Cross2cdd5df2019-02-25 10:25:24 -08001426 // boot.art boot.oat
Colin Cross8854a5a2019-02-11 14:14:16 -08001427}
Colin Cross40e33732019-02-15 11:08:35 -08001428
Colin Cross41b46762020-10-09 19:26:32 -07001429func ExampleOutputPath_InSameDir() {
Colin Cross40e33732019-02-15 11:08:35 -08001430 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001431 config: TestConfig("out", nil, "", nil),
Colin Cross40e33732019-02-15 11:08:35 -08001432 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001433 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross40e33732019-02-15 11:08:35 -08001434 p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
1435 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001436 fmt.Println(p.Rel(), p2.Rel())
Colin Cross40e33732019-02-15 11:08:35 -08001437
1438 // Output:
1439 // out/system/framework/boot.art out/system/framework/oat/arm/boot.vdex
Colin Cross2cdd5df2019-02-25 10:25:24 -08001440 // boot.art oat/arm/boot.vdex
Colin Cross40e33732019-02-15 11:08:35 -08001441}
Colin Cross27027c72020-02-28 15:34:17 -08001442
1443func BenchmarkFirstUniquePaths(b *testing.B) {
1444 implementations := []struct {
1445 name string
1446 f func(Paths) Paths
1447 }{
1448 {
1449 name: "list",
1450 f: firstUniquePathsList,
1451 },
1452 {
1453 name: "map",
1454 f: firstUniquePathsMap,
1455 },
1456 }
1457 const maxSize = 1024
1458 uniquePaths := make(Paths, maxSize)
1459 for i := range uniquePaths {
1460 uniquePaths[i] = PathForTesting(strconv.Itoa(i))
1461 }
1462 samePath := make(Paths, maxSize)
1463 for i := range samePath {
1464 samePath[i] = uniquePaths[0]
1465 }
1466
1467 f := func(b *testing.B, imp func(Paths) Paths, paths Paths) {
1468 for i := 0; i < b.N; i++ {
1469 b.ReportAllocs()
1470 paths = append(Paths(nil), paths...)
1471 imp(paths)
1472 }
1473 }
1474
1475 for n := 1; n <= maxSize; n <<= 1 {
1476 b.Run(strconv.Itoa(n), func(b *testing.B) {
1477 for _, implementation := range implementations {
1478 b.Run(implementation.name, func(b *testing.B) {
1479 b.Run("same", func(b *testing.B) {
1480 f(b, implementation.f, samePath[:n])
1481 })
1482 b.Run("unique", func(b *testing.B) {
1483 f(b, implementation.f, uniquePaths[:n])
1484 })
1485 })
1486 }
1487 })
1488 }
1489}