blob: 93b9b9a1669fc3d3793fe7cd9759d52b22458780 [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 {
Colin Crossbf9ed3f2023-10-24 14:17:03 -070040 in: []string{"", ""},
41 out: "",
42 },
43 {
44 in: []string{"a", ""},
45 out: "a",
46 },
47 {
48 in: []string{"", "a"},
49 out: "a",
50 },
51 {
52 in: []string{"", "a", ""},
53 out: "a",
54 },
55 {
Dan Willemsen34cc69e2015-09-23 15:26:20 -070056 in: []string{"a/b"},
57 out: "a/b",
58 },
59 {
60 in: []string{"a/b", "c"},
61 out: "a/b/c",
62 },
63 {
64 in: []string{"a/.."},
65 out: ".",
66 },
67 {
68 in: []string{"."},
69 out: ".",
70 },
71 {
72 in: []string{".."},
73 out: "",
74 err: []error{errors.New("Path is outside directory: ..")},
75 },
76 {
77 in: []string{"../a"},
78 out: "",
79 err: []error{errors.New("Path is outside directory: ../a")},
80 },
81 {
82 in: []string{"b/../../a"},
83 out: "",
84 err: []error{errors.New("Path is outside directory: ../a")},
85 },
86 {
87 in: []string{"/a"},
88 out: "",
89 err: []error{errors.New("Path is outside directory: /a")},
90 },
Dan Willemsen80a7c2a2015-12-21 14:57:11 -080091 {
92 in: []string{"a", "../b"},
93 out: "",
94 err: []error{errors.New("Path is outside directory: ../b")},
95 },
96 {
97 in: []string{"a", "b/../../c"},
98 out: "",
99 err: []error{errors.New("Path is outside directory: ../c")},
100 },
101 {
102 in: []string{"a", "./.."},
103 out: "",
104 err: []error{errors.New("Path is outside directory: ..")},
105 },
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700106}
107
108var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
109 {
110 in: []string{"$host/../$a"},
111 out: "$a",
112 },
113}...)
114
115var validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
116 {
117 in: []string{"$host/../$a"},
118 out: "",
119 err: []error{errors.New("Path contains invalid character($): $host/../$a")},
120 },
121 {
122 in: []string{"$host/.."},
123 out: "",
124 err: []error{errors.New("Path contains invalid character($): $host/..")},
125 },
126}...)
127
128func TestValidateSafePath(t *testing.T) {
129 for _, testCase := range validateSafePathTestCases {
Colin Crossdc75ae72018-02-22 13:48:13 -0800130 t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
131 ctx := &configErrorWrapper{}
Colin Cross1ccfcc32018-02-22 13:54:26 -0800132 out, err := validateSafePath(testCase.in...)
133 if err != nil {
134 reportPathError(ctx, err)
135 }
Colin Crossdc75ae72018-02-22 13:48:13 -0800136 check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
137 })
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700138 }
139}
140
141func TestValidatePath(t *testing.T) {
142 for _, testCase := range validatePathTestCases {
Colin Crossdc75ae72018-02-22 13:48:13 -0800143 t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
144 ctx := &configErrorWrapper{}
Colin Cross1ccfcc32018-02-22 13:54:26 -0800145 out, err := validatePath(testCase.in...)
146 if err != nil {
147 reportPathError(ctx, err)
148 }
Colin Crossdc75ae72018-02-22 13:48:13 -0800149 check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
150 })
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700151 }
152}
153
154func TestOptionalPath(t *testing.T) {
155 var path OptionalPath
Martin Stjernholmc32dd1c2021-09-15 02:39:00 +0100156 checkInvalidOptionalPath(t, path, "unknown")
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700157
158 path = OptionalPathForPath(nil)
Martin Stjernholmc32dd1c2021-09-15 02:39:00 +0100159 checkInvalidOptionalPath(t, path, "unknown")
160
161 path = InvalidOptionalPath("foo")
162 checkInvalidOptionalPath(t, path, "foo")
163
164 path = InvalidOptionalPath("")
165 checkInvalidOptionalPath(t, path, "unknown")
Paul Duffinef081852021-05-13 11:11:15 +0100166
167 path = OptionalPathForPath(PathForTesting("path"))
168 checkValidOptionalPath(t, path, "path")
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700169}
170
Martin Stjernholmc32dd1c2021-09-15 02:39:00 +0100171func checkInvalidOptionalPath(t *testing.T, path OptionalPath, expectedInvalidReason string) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800172 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700173 if path.Valid() {
Martin Stjernholmc32dd1c2021-09-15 02:39:00 +0100174 t.Errorf("Invalid OptionalPath should not be valid")
175 }
176 if path.InvalidReason() != expectedInvalidReason {
177 t.Errorf("Wrong invalid reason: expected %q, got %q", expectedInvalidReason, path.InvalidReason())
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700178 }
179 if path.String() != "" {
Martin Stjernholmc32dd1c2021-09-15 02:39:00 +0100180 t.Errorf("Invalid OptionalPath String() should return \"\", not %q", path.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700181 }
Paul Duffinef081852021-05-13 11:11:15 +0100182 paths := path.AsPaths()
183 if len(paths) != 0 {
Martin Stjernholmc32dd1c2021-09-15 02:39:00 +0100184 t.Errorf("Invalid OptionalPath AsPaths() should return empty Paths, not %q", paths)
Paul Duffinef081852021-05-13 11:11:15 +0100185 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700186 defer func() {
187 if r := recover(); r == nil {
188 t.Errorf("Expected a panic when calling Path() on an uninitialized OptionalPath")
189 }
190 }()
191 path.Path()
192}
193
Paul Duffinef081852021-05-13 11:11:15 +0100194func checkValidOptionalPath(t *testing.T, path OptionalPath, expectedString string) {
195 t.Helper()
196 if !path.Valid() {
197 t.Errorf("Initialized OptionalPath should not be invalid")
198 }
Martin Stjernholmc32dd1c2021-09-15 02:39:00 +0100199 if path.InvalidReason() != "" {
200 t.Errorf("Initialized OptionalPath should not have an invalid reason, got: %q", path.InvalidReason())
201 }
Paul Duffinef081852021-05-13 11:11:15 +0100202 if path.String() != expectedString {
203 t.Errorf("Initialized OptionalPath String() should return %q, not %q", expectedString, path.String())
204 }
205 paths := path.AsPaths()
206 if len(paths) != 1 {
207 t.Errorf("Initialized OptionalPath AsPaths() should return Paths with length 1, not %q", paths)
208 }
209 path.Path()
210}
211
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700212func check(t *testing.T, testType, testString string,
213 got interface{}, err []error,
214 expected interface{}, expectedErr []error) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800215 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700216
217 printedTestCase := false
218 e := func(s string, expected, got interface{}) {
Colin Crossdc75ae72018-02-22 13:48:13 -0800219 t.Helper()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700220 if !printedTestCase {
221 t.Errorf("test case %s: %s", testType, testString)
222 printedTestCase = true
223 }
224 t.Errorf("incorrect %s", s)
225 t.Errorf(" expected: %s", p(expected))
226 t.Errorf(" got: %s", p(got))
227 }
228
229 if !reflect.DeepEqual(expectedErr, err) {
230 e("errors:", expectedErr, err)
231 }
232
233 if !reflect.DeepEqual(expected, got) {
234 e("output:", expected, got)
235 }
236}
237
238func p(in interface{}) string {
239 if v, ok := in.([]interface{}); ok {
240 s := make([]string, len(v))
241 for i := range v {
242 s[i] = fmt.Sprintf("%#v", v[i])
243 }
244 return "[" + strings.Join(s, ", ") + "]"
245 } else {
246 return fmt.Sprintf("%#v", in)
247 }
248}
Dan Willemsen00269f22017-07-06 16:59:48 -0700249
Colin Cross98be1bb2019-12-13 20:41:13 -0800250func pathTestConfig(buildDir string) Config {
251 return TestConfig(buildDir, nil, "", nil)
252}
253
Dan Willemsen00269f22017-07-06 16:59:48 -0700254func TestPathForModuleInstall(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800255 testConfig := pathTestConfig("")
Dan Willemsen00269f22017-07-06 16:59:48 -0700256
Jiyong Park87788b52020-09-01 12:37:45 +0900257 hostTarget := Target{Os: Linux, Arch: Arch{ArchType: X86}}
258 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
Dan Willemsen00269f22017-07-06 16:59:48 -0700259
260 testCases := []struct {
Jiyong Park957bcd92020-10-20 18:23:33 +0900261 name string
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100262 ctx *testModuleInstallPathContext
Jiyong Park957bcd92020-10-20 18:23:33 +0900263 in []string
264 out string
265 partitionDir string
Dan Willemsen00269f22017-07-06 16:59:48 -0700266 }{
267 {
268 name: "host binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100269 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700270 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800271 archModuleContext: archModuleContext{
272 os: hostTarget.Os,
273 target: hostTarget,
274 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700275 },
276 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900277 in: []string{"bin", "my_test"},
278 out: "host/linux-x86/bin/my_test",
279 partitionDir: "host/linux-x86",
Dan Willemsen00269f22017-07-06 16:59:48 -0700280 },
281
282 {
283 name: "system binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100284 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700285 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800286 archModuleContext: archModuleContext{
287 os: deviceTarget.Os,
288 target: deviceTarget,
289 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700290 },
291 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900292 in: []string{"bin", "my_test"},
293 out: "target/product/test_device/system/bin/my_test",
294 partitionDir: "target/product/test_device/system",
Dan Willemsen00269f22017-07-06 16:59:48 -0700295 },
296 {
297 name: "vendor binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100298 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700299 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800300 archModuleContext: archModuleContext{
301 os: deviceTarget.Os,
302 target: deviceTarget,
303 },
Colin Cross1184b642019-12-30 18:43:07 -0800304 earlyModuleContext: earlyModuleContext{
305 kind: socSpecificModule,
306 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700307 },
308 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900309 in: []string{"bin", "my_test"},
310 out: "target/product/test_device/vendor/bin/my_test",
311 partitionDir: "target/product/test_device/vendor",
Dan Willemsen00269f22017-07-06 16:59:48 -0700312 },
Jiyong Park2db76922017-11-08 16:03:48 +0900313 {
314 name: "odm binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100315 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700316 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800317 archModuleContext: archModuleContext{
318 os: deviceTarget.Os,
319 target: deviceTarget,
320 },
Colin Cross1184b642019-12-30 18:43:07 -0800321 earlyModuleContext: earlyModuleContext{
322 kind: deviceSpecificModule,
323 },
Jiyong Park2db76922017-11-08 16:03:48 +0900324 },
325 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900326 in: []string{"bin", "my_test"},
327 out: "target/product/test_device/odm/bin/my_test",
328 partitionDir: "target/product/test_device/odm",
Jiyong Park2db76922017-11-08 16:03:48 +0900329 },
330 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900331 name: "product binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100332 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700333 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800334 archModuleContext: archModuleContext{
335 os: deviceTarget.Os,
336 target: deviceTarget,
337 },
Colin Cross1184b642019-12-30 18:43:07 -0800338 earlyModuleContext: earlyModuleContext{
339 kind: productSpecificModule,
340 },
Jiyong Park2db76922017-11-08 16:03:48 +0900341 },
342 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900343 in: []string{"bin", "my_test"},
344 out: "target/product/test_device/product/bin/my_test",
345 partitionDir: "target/product/test_device/product",
Jiyong Park2db76922017-11-08 16:03:48 +0900346 },
Dario Frenifd05a742018-05-29 13:28:54 +0100347 {
Justin Yund5f6c822019-06-25 16:47:17 +0900348 name: "system_ext binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100349 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700350 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800351 archModuleContext: archModuleContext{
352 os: deviceTarget.Os,
353 target: deviceTarget,
354 },
Colin Cross1184b642019-12-30 18:43:07 -0800355 earlyModuleContext: earlyModuleContext{
356 kind: systemExtSpecificModule,
357 },
Dario Frenifd05a742018-05-29 13:28:54 +0100358 },
359 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900360 in: []string{"bin", "my_test"},
361 out: "target/product/test_device/system_ext/bin/my_test",
362 partitionDir: "target/product/test_device/system_ext",
Dario Frenifd05a742018-05-29 13:28:54 +0100363 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700364 {
365 name: "root binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100366 ctx: &testModuleInstallPathContext{
Colin Cross90ba5f42019-10-02 11:10:58 -0700367 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800368 archModuleContext: archModuleContext{
369 os: deviceTarget.Os,
370 target: deviceTarget,
371 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700372 },
373 inRoot: true,
374 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900375 in: []string{"my_test"},
376 out: "target/product/test_device/root/my_test",
377 partitionDir: "target/product/test_device/root",
Colin Cross90ba5f42019-10-02 11:10:58 -0700378 },
379 {
380 name: "recovery binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100381 ctx: &testModuleInstallPathContext{
Colin Cross90ba5f42019-10-02 11:10:58 -0700382 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800383 archModuleContext: archModuleContext{
384 os: deviceTarget.Os,
385 target: deviceTarget,
386 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700387 },
388 inRecovery: true,
389 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900390 in: []string{"bin/my_test"},
391 out: "target/product/test_device/recovery/root/system/bin/my_test",
392 partitionDir: "target/product/test_device/recovery/root/system",
Colin Cross90ba5f42019-10-02 11:10:58 -0700393 },
394 {
395 name: "recovery root binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100396 ctx: &testModuleInstallPathContext{
Colin Cross90ba5f42019-10-02 11:10:58 -0700397 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800398 archModuleContext: archModuleContext{
399 os: deviceTarget.Os,
400 target: deviceTarget,
401 },
Colin Cross90ba5f42019-10-02 11:10:58 -0700402 },
403 inRecovery: true,
404 inRoot: true,
405 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900406 in: []string{"my_test"},
407 out: "target/product/test_device/recovery/root/my_test",
408 partitionDir: "target/product/test_device/recovery/root",
Colin Cross90ba5f42019-10-02 11:10:58 -0700409 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700410
411 {
Inseob Kimd9580b82021-04-13 21:13:49 +0900412 name: "ramdisk binary",
413 ctx: &testModuleInstallPathContext{
414 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800415 archModuleContext: archModuleContext{
416 os: deviceTarget.Os,
417 target: deviceTarget,
418 },
Inseob Kimd9580b82021-04-13 21:13:49 +0900419 },
420 inRamdisk: true,
421 },
422 in: []string{"my_test"},
423 out: "target/product/test_device/ramdisk/system/my_test",
424 partitionDir: "target/product/test_device/ramdisk/system",
425 },
426 {
427 name: "ramdisk root binary",
428 ctx: &testModuleInstallPathContext{
429 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800430 archModuleContext: archModuleContext{
431 os: deviceTarget.Os,
432 target: deviceTarget,
433 },
Inseob Kimd9580b82021-04-13 21:13:49 +0900434 },
435 inRamdisk: true,
436 inRoot: true,
437 },
438 in: []string{"my_test"},
439 out: "target/product/test_device/ramdisk/my_test",
440 partitionDir: "target/product/test_device/ramdisk",
441 },
442 {
443 name: "vendor_ramdisk binary",
444 ctx: &testModuleInstallPathContext{
445 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800446 archModuleContext: archModuleContext{
447 os: deviceTarget.Os,
448 target: deviceTarget,
449 },
Inseob Kimd9580b82021-04-13 21:13:49 +0900450 },
451 inVendorRamdisk: true,
452 },
453 in: []string{"my_test"},
454 out: "target/product/test_device/vendor_ramdisk/system/my_test",
455 partitionDir: "target/product/test_device/vendor_ramdisk/system",
456 },
457 {
458 name: "vendor_ramdisk root binary",
459 ctx: &testModuleInstallPathContext{
460 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800461 archModuleContext: archModuleContext{
462 os: deviceTarget.Os,
463 target: deviceTarget,
464 },
Inseob Kimd9580b82021-04-13 21:13:49 +0900465 },
466 inVendorRamdisk: true,
467 inRoot: true,
468 },
469 in: []string{"my_test"},
470 out: "target/product/test_device/vendor_ramdisk/my_test",
471 partitionDir: "target/product/test_device/vendor_ramdisk",
472 },
473 {
Inseob Kim08758f02021-04-08 21:13:22 +0900474 name: "debug_ramdisk binary",
475 ctx: &testModuleInstallPathContext{
476 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800477 archModuleContext: archModuleContext{
478 os: deviceTarget.Os,
479 target: deviceTarget,
480 },
Inseob Kim08758f02021-04-08 21:13:22 +0900481 },
482 inDebugRamdisk: true,
483 },
484 in: []string{"my_test"},
485 out: "target/product/test_device/debug_ramdisk/my_test",
486 partitionDir: "target/product/test_device/debug_ramdisk",
487 },
488 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700489 name: "system native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100490 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700491 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800492 archModuleContext: archModuleContext{
493 os: deviceTarget.Os,
494 target: deviceTarget,
495 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700496 },
497 inData: true,
498 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900499 in: []string{"nativetest", "my_test"},
500 out: "target/product/test_device/data/nativetest/my_test",
501 partitionDir: "target/product/test_device/data",
Dan Willemsen00269f22017-07-06 16:59:48 -0700502 },
503 {
504 name: "vendor native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100505 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700506 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800507 archModuleContext: archModuleContext{
508 os: deviceTarget.Os,
509 target: deviceTarget,
510 },
Colin Cross1184b642019-12-30 18:43:07 -0800511 earlyModuleContext: earlyModuleContext{
512 kind: socSpecificModule,
513 },
Jiyong Park2db76922017-11-08 16:03:48 +0900514 },
515 inData: true,
516 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900517 in: []string{"nativetest", "my_test"},
518 out: "target/product/test_device/data/nativetest/my_test",
519 partitionDir: "target/product/test_device/data",
Jiyong Park2db76922017-11-08 16:03:48 +0900520 },
521 {
522 name: "odm native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100523 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700524 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800525 archModuleContext: archModuleContext{
526 os: deviceTarget.Os,
527 target: deviceTarget,
528 },
Colin Cross1184b642019-12-30 18:43:07 -0800529 earlyModuleContext: earlyModuleContext{
530 kind: deviceSpecificModule,
531 },
Jiyong Park2db76922017-11-08 16:03:48 +0900532 },
533 inData: true,
534 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900535 in: []string{"nativetest", "my_test"},
536 out: "target/product/test_device/data/nativetest/my_test",
537 partitionDir: "target/product/test_device/data",
Jiyong Park2db76922017-11-08 16:03:48 +0900538 },
539 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900540 name: "product native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100541 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700542 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800543 archModuleContext: archModuleContext{
544 os: deviceTarget.Os,
545 target: deviceTarget,
546 },
Colin Cross1184b642019-12-30 18:43:07 -0800547 earlyModuleContext: earlyModuleContext{
548 kind: productSpecificModule,
549 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700550 },
551 inData: true,
552 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900553 in: []string{"nativetest", "my_test"},
554 out: "target/product/test_device/data/nativetest/my_test",
555 partitionDir: "target/product/test_device/data",
Dan Willemsen00269f22017-07-06 16:59:48 -0700556 },
557
558 {
Justin Yund5f6c822019-06-25 16:47:17 +0900559 name: "system_ext native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100560 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700561 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800562 archModuleContext: archModuleContext{
563 os: deviceTarget.Os,
564 target: deviceTarget,
565 },
Colin Cross1184b642019-12-30 18:43:07 -0800566 earlyModuleContext: earlyModuleContext{
567 kind: systemExtSpecificModule,
568 },
Dario Frenifd05a742018-05-29 13:28:54 +0100569 },
570 inData: true,
571 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900572 in: []string{"nativetest", "my_test"},
573 out: "target/product/test_device/data/nativetest/my_test",
574 partitionDir: "target/product/test_device/data",
Dario Frenifd05a742018-05-29 13:28:54 +0100575 },
576
577 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700578 name: "sanitized system binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100579 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700580 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800581 archModuleContext: archModuleContext{
582 os: deviceTarget.Os,
583 target: deviceTarget,
584 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700585 },
586 inSanitizerDir: true,
587 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900588 in: []string{"bin", "my_test"},
589 out: "target/product/test_device/data/asan/system/bin/my_test",
590 partitionDir: "target/product/test_device/data/asan/system",
Dan Willemsen00269f22017-07-06 16:59:48 -0700591 },
592 {
593 name: "sanitized vendor binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100594 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700595 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800596 archModuleContext: archModuleContext{
597 os: deviceTarget.Os,
598 target: deviceTarget,
599 },
Colin Cross1184b642019-12-30 18:43:07 -0800600 earlyModuleContext: earlyModuleContext{
601 kind: socSpecificModule,
602 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700603 },
604 inSanitizerDir: true,
605 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900606 in: []string{"bin", "my_test"},
607 out: "target/product/test_device/data/asan/vendor/bin/my_test",
608 partitionDir: "target/product/test_device/data/asan/vendor",
Dan Willemsen00269f22017-07-06 16:59:48 -0700609 },
Jiyong Park2db76922017-11-08 16:03:48 +0900610 {
611 name: "sanitized odm binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100612 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700613 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800614 archModuleContext: archModuleContext{
615 os: deviceTarget.Os,
616 target: deviceTarget,
617 },
Colin Cross1184b642019-12-30 18:43:07 -0800618 earlyModuleContext: earlyModuleContext{
619 kind: deviceSpecificModule,
620 },
Jiyong Park2db76922017-11-08 16:03:48 +0900621 },
622 inSanitizerDir: true,
623 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900624 in: []string{"bin", "my_test"},
625 out: "target/product/test_device/data/asan/odm/bin/my_test",
626 partitionDir: "target/product/test_device/data/asan/odm",
Jiyong Park2db76922017-11-08 16:03:48 +0900627 },
628 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900629 name: "sanitized product binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100630 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700631 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800632 archModuleContext: archModuleContext{
633 os: deviceTarget.Os,
634 target: deviceTarget,
635 },
Colin Cross1184b642019-12-30 18:43:07 -0800636 earlyModuleContext: earlyModuleContext{
637 kind: productSpecificModule,
638 },
Jiyong Park2db76922017-11-08 16:03:48 +0900639 },
640 inSanitizerDir: true,
641 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900642 in: []string{"bin", "my_test"},
643 out: "target/product/test_device/data/asan/product/bin/my_test",
644 partitionDir: "target/product/test_device/data/asan/product",
Jiyong Park2db76922017-11-08 16:03:48 +0900645 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700646
647 {
Justin Yund5f6c822019-06-25 16:47:17 +0900648 name: "sanitized system_ext binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100649 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700650 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800651 archModuleContext: archModuleContext{
652 os: deviceTarget.Os,
653 target: deviceTarget,
654 },
Colin Cross1184b642019-12-30 18:43:07 -0800655 earlyModuleContext: earlyModuleContext{
656 kind: systemExtSpecificModule,
657 },
Dario Frenifd05a742018-05-29 13:28:54 +0100658 },
659 inSanitizerDir: true,
660 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900661 in: []string{"bin", "my_test"},
662 out: "target/product/test_device/data/asan/system_ext/bin/my_test",
663 partitionDir: "target/product/test_device/data/asan/system_ext",
Dario Frenifd05a742018-05-29 13:28:54 +0100664 },
665
666 {
Dan Willemsen00269f22017-07-06 16:59:48 -0700667 name: "sanitized system native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100668 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700669 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800670 archModuleContext: archModuleContext{
671 os: deviceTarget.Os,
672 target: deviceTarget,
673 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700674 },
675 inData: true,
676 inSanitizerDir: true,
677 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900678 in: []string{"nativetest", "my_test"},
679 out: "target/product/test_device/data/asan/data/nativetest/my_test",
680 partitionDir: "target/product/test_device/data/asan/data",
Dan Willemsen00269f22017-07-06 16:59:48 -0700681 },
682 {
683 name: "sanitized vendor native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100684 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700685 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800686 archModuleContext: archModuleContext{
687 os: deviceTarget.Os,
688 target: deviceTarget,
689 },
Colin Cross1184b642019-12-30 18:43:07 -0800690 earlyModuleContext: earlyModuleContext{
691 kind: socSpecificModule,
692 },
Jiyong Park2db76922017-11-08 16:03:48 +0900693 },
694 inData: true,
695 inSanitizerDir: true,
696 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900697 in: []string{"nativetest", "my_test"},
698 out: "target/product/test_device/data/asan/data/nativetest/my_test",
699 partitionDir: "target/product/test_device/data/asan/data",
Jiyong Park2db76922017-11-08 16:03:48 +0900700 },
701 {
702 name: "sanitized odm native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100703 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700704 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800705 archModuleContext: archModuleContext{
706 os: deviceTarget.Os,
707 target: deviceTarget,
708 },
Colin Cross1184b642019-12-30 18:43:07 -0800709 earlyModuleContext: earlyModuleContext{
710 kind: deviceSpecificModule,
711 },
Jiyong Park2db76922017-11-08 16:03:48 +0900712 },
713 inData: true,
714 inSanitizerDir: true,
715 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900716 in: []string{"nativetest", "my_test"},
717 out: "target/product/test_device/data/asan/data/nativetest/my_test",
718 partitionDir: "target/product/test_device/data/asan/data",
Jiyong Park2db76922017-11-08 16:03:48 +0900719 },
720 {
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900721 name: "sanitized product native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100722 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700723 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800724 archModuleContext: archModuleContext{
725 os: deviceTarget.Os,
726 target: deviceTarget,
727 },
Colin Cross1184b642019-12-30 18:43:07 -0800728 earlyModuleContext: earlyModuleContext{
729 kind: productSpecificModule,
730 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700731 },
732 inData: true,
733 inSanitizerDir: true,
734 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900735 in: []string{"nativetest", "my_test"},
736 out: "target/product/test_device/data/asan/data/nativetest/my_test",
737 partitionDir: "target/product/test_device/data/asan/data",
Dan Willemsen00269f22017-07-06 16:59:48 -0700738 },
Dario Frenifd05a742018-05-29 13:28:54 +0100739 {
Justin Yund5f6c822019-06-25 16:47:17 +0900740 name: "sanitized system_ext native test binary",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100741 ctx: &testModuleInstallPathContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700742 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800743 archModuleContext: archModuleContext{
744 os: deviceTarget.Os,
745 target: deviceTarget,
746 },
Colin Cross1184b642019-12-30 18:43:07 -0800747 earlyModuleContext: earlyModuleContext{
748 kind: systemExtSpecificModule,
749 },
Dario Frenifd05a742018-05-29 13:28:54 +0100750 },
751 inData: true,
752 inSanitizerDir: true,
753 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900754 in: []string{"nativetest", "my_test"},
755 out: "target/product/test_device/data/asan/data/nativetest/my_test",
756 partitionDir: "target/product/test_device/data/asan/data",
Colin Cross6e359402020-02-10 15:29:54 -0800757 }, {
758 name: "device testcases",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100759 ctx: &testModuleInstallPathContext{
Colin Cross6e359402020-02-10 15:29:54 -0800760 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800761 archModuleContext: archModuleContext{
762 os: deviceTarget.Os,
763 target: deviceTarget,
764 },
Colin Cross6e359402020-02-10 15:29:54 -0800765 },
766 inTestcases: true,
767 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900768 in: []string{"my_test", "my_test_bin"},
769 out: "target/product/test_device/testcases/my_test/my_test_bin",
770 partitionDir: "target/product/test_device/testcases",
Colin Cross6e359402020-02-10 15:29:54 -0800771 }, {
772 name: "host testcases",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100773 ctx: &testModuleInstallPathContext{
Colin Cross6e359402020-02-10 15:29:54 -0800774 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800775 archModuleContext: archModuleContext{
776 os: hostTarget.Os,
777 target: hostTarget,
778 },
Colin Cross6e359402020-02-10 15:29:54 -0800779 },
780 inTestcases: true,
781 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900782 in: []string{"my_test", "my_test_bin"},
783 out: "host/linux-x86/testcases/my_test/my_test_bin",
784 partitionDir: "host/linux-x86/testcases",
Colin Cross6e359402020-02-10 15:29:54 -0800785 }, {
786 name: "forced host testcases",
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100787 ctx: &testModuleInstallPathContext{
Colin Cross6e359402020-02-10 15:29:54 -0800788 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800789 archModuleContext: archModuleContext{
790 os: deviceTarget.Os,
791 target: deviceTarget,
792 },
Colin Cross6e359402020-02-10 15:29:54 -0800793 },
794 inTestcases: true,
795 forceOS: &Linux,
Jiyong Park87788b52020-09-01 12:37:45 +0900796 forceArch: &X86,
Colin Cross6e359402020-02-10 15:29:54 -0800797 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900798 in: []string{"my_test", "my_test_bin"},
799 out: "host/linux-x86/testcases/my_test/my_test_bin",
800 partitionDir: "host/linux-x86/testcases",
Dario Frenifd05a742018-05-29 13:28:54 +0100801 },
Dan Willemsen00269f22017-07-06 16:59:48 -0700802 }
803
804 for _, tc := range testCases {
805 t.Run(tc.name, func(t *testing.T) {
Colin Cross0ea8ba82019-06-06 14:33:29 -0700806 tc.ctx.baseModuleContext.config = testConfig
Dan Willemsen00269f22017-07-06 16:59:48 -0700807 output := PathForModuleInstall(tc.ctx, tc.in...)
808 if output.basePath.path != tc.out {
809 t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
810 output.basePath.path,
811 tc.out)
812 }
Jiyong Park957bcd92020-10-20 18:23:33 +0900813 if output.partitionDir != tc.partitionDir {
814 t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n",
815 output.partitionDir, tc.partitionDir)
816 }
Dan Willemsen00269f22017-07-06 16:59:48 -0700817 })
818 }
819}
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700820
Inseob Kimd9580b82021-04-13 21:13:49 +0900821func TestPathForModuleInstallRecoveryAsBoot(t *testing.T) {
822 testConfig := pathTestConfig("")
823 testConfig.TestProductVariables.BoardUsesRecoveryAsBoot = proptools.BoolPtr(true)
824 testConfig.TestProductVariables.BoardMoveRecoveryResourcesToVendorBoot = proptools.BoolPtr(true)
825 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
826
827 testCases := []struct {
828 name string
829 ctx *testModuleInstallPathContext
830 in []string
831 out string
832 partitionDir string
833 }{
834 {
835 name: "ramdisk binary",
836 ctx: &testModuleInstallPathContext{
837 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800838 archModuleContext: archModuleContext{
839 os: deviceTarget.Os,
840 target: deviceTarget,
841 },
Inseob Kimd9580b82021-04-13 21:13:49 +0900842 },
843 inRamdisk: true,
844 inRoot: true,
845 },
846 in: []string{"my_test"},
847 out: "target/product/test_device/recovery/root/first_stage_ramdisk/my_test",
848 partitionDir: "target/product/test_device/recovery/root/first_stage_ramdisk",
849 },
850
851 {
852 name: "vendor_ramdisk binary",
853 ctx: &testModuleInstallPathContext{
854 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800855 archModuleContext: archModuleContext{
856 os: deviceTarget.Os,
857 target: deviceTarget,
858 },
Inseob Kimd9580b82021-04-13 21:13:49 +0900859 },
860 inVendorRamdisk: true,
861 inRoot: true,
862 },
863 in: []string{"my_test"},
864 out: "target/product/test_device/vendor_ramdisk/first_stage_ramdisk/my_test",
865 partitionDir: "target/product/test_device/vendor_ramdisk/first_stage_ramdisk",
866 },
867 }
868
869 for _, tc := range testCases {
870 t.Run(tc.name, func(t *testing.T) {
871 tc.ctx.baseModuleContext.config = testConfig
872 output := PathForModuleInstall(tc.ctx, tc.in...)
873 if output.basePath.path != tc.out {
874 t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
875 output.basePath.path,
876 tc.out)
877 }
878 if output.partitionDir != tc.partitionDir {
879 t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n",
880 output.partitionDir, tc.partitionDir)
881 }
882 })
883 }
884}
885
Jiyong Park957bcd92020-10-20 18:23:33 +0900886func TestBaseDirForInstallPath(t *testing.T) {
887 testConfig := pathTestConfig("")
888 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
889
Ulya Trafimovichccc8c852020-10-14 11:29:07 +0100890 ctx := &testModuleInstallPathContext{
Jiyong Park957bcd92020-10-20 18:23:33 +0900891 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -0800892 archModuleContext: archModuleContext{
893 os: deviceTarget.Os,
894 target: deviceTarget,
895 },
Jiyong Park957bcd92020-10-20 18:23:33 +0900896 },
897 }
898 ctx.baseModuleContext.config = testConfig
899
900 actual := PathForModuleInstall(ctx, "foo", "bar")
901 expectedBaseDir := "target/product/test_device/system"
902 if actual.partitionDir != expectedBaseDir {
903 t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n", actual.partitionDir, expectedBaseDir)
904 }
905 expectedRelPath := "foo/bar"
906 if actual.Rel() != expectedRelPath {
907 t.Errorf("unexpected Rel():\n got: %q\nwant: %q\n", actual.Rel(), expectedRelPath)
908 }
909
910 actualAfterJoin := actual.Join(ctx, "baz")
911 // partitionDir is preserved even after joining
912 if actualAfterJoin.partitionDir != expectedBaseDir {
913 t.Errorf("unexpected partitionDir after joining:\n got: %q\nwant: %q\n", actualAfterJoin.partitionDir, expectedBaseDir)
914 }
915 // Rel() is updated though
916 expectedRelAfterJoin := "baz"
917 if actualAfterJoin.Rel() != expectedRelAfterJoin {
918 t.Errorf("unexpected Rel() after joining:\n got: %q\nwant: %q\n", actualAfterJoin.Rel(), expectedRelAfterJoin)
919 }
920}
921
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700922func TestDirectorySortedPaths(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800923 config := TestConfig("out", nil, "", map[string][]byte{
924 "Android.bp": nil,
925 "a.txt": nil,
926 "a/txt": nil,
927 "a/b/c": nil,
928 "a/b/d": nil,
929 "b": nil,
930 "b/b.txt": nil,
931 "a/a.txt": nil,
Colin Cross07e51612019-03-05 12:46:40 -0800932 })
933
Colin Cross98be1bb2019-12-13 20:41:13 -0800934 ctx := PathContextForTesting(config)
935
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700936 makePaths := func() Paths {
937 return Paths{
Colin Cross07e51612019-03-05 12:46:40 -0800938 PathForSource(ctx, "a.txt"),
939 PathForSource(ctx, "a/txt"),
940 PathForSource(ctx, "a/b/c"),
941 PathForSource(ctx, "a/b/d"),
942 PathForSource(ctx, "b"),
943 PathForSource(ctx, "b/b.txt"),
944 PathForSource(ctx, "a/a.txt"),
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700945 }
946 }
947
948 expected := []string{
949 "a.txt",
950 "a/a.txt",
951 "a/b/c",
952 "a/b/d",
953 "a/txt",
954 "b",
955 "b/b.txt",
956 }
957
958 paths := makePaths()
Colin Crossa140bb02018-04-17 10:52:26 -0700959 reversePaths := ReversePaths(paths)
Colin Cross5e6cfbe2017-11-03 15:20:35 -0700960
961 sortedPaths := PathsToDirectorySortedPaths(paths)
962 reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
963
964 if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
965 t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
966 }
967
968 if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
969 t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
970 }
971
972 expectedA := []string{
973 "a/a.txt",
974 "a/b/c",
975 "a/b/d",
976 "a/txt",
977 }
978
979 inA := sortedPaths.PathsInDirectory("a")
980 if !reflect.DeepEqual(inA.Strings(), expectedA) {
981 t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
982 }
983
984 expectedA_B := []string{
985 "a/b/c",
986 "a/b/d",
987 }
988
989 inA_B := sortedPaths.PathsInDirectory("a/b")
990 if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
991 t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
992 }
993
994 expectedB := []string{
995 "b/b.txt",
996 }
997
998 inB := sortedPaths.PathsInDirectory("b")
999 if !reflect.DeepEqual(inB.Strings(), expectedB) {
1000 t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
1001 }
1002}
Colin Cross43f08db2018-11-12 10:13:39 -08001003
1004func TestMaybeRel(t *testing.T) {
1005 testCases := []struct {
1006 name string
1007 base string
1008 target string
1009 out string
1010 isRel bool
1011 }{
1012 {
1013 name: "normal",
1014 base: "a/b/c",
1015 target: "a/b/c/d",
1016 out: "d",
1017 isRel: true,
1018 },
1019 {
1020 name: "parent",
1021 base: "a/b/c/d",
1022 target: "a/b/c",
1023 isRel: false,
1024 },
1025 {
1026 name: "not relative",
1027 base: "a/b",
1028 target: "c/d",
1029 isRel: false,
1030 },
1031 {
1032 name: "abs1",
1033 base: "/a",
1034 target: "a",
1035 isRel: false,
1036 },
1037 {
1038 name: "abs2",
1039 base: "a",
1040 target: "/a",
1041 isRel: false,
1042 },
1043 }
1044
1045 for _, testCase := range testCases {
1046 t.Run(testCase.name, func(t *testing.T) {
1047 ctx := &configErrorWrapper{}
1048 out, isRel := MaybeRel(ctx, testCase.base, testCase.target)
1049 if len(ctx.errors) > 0 {
1050 t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v",
1051 testCase.base, testCase.target, ctx.errors)
1052 }
1053 if isRel != testCase.isRel || out != testCase.out {
1054 t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v",
1055 testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel)
1056 }
1057 })
1058 }
1059}
Colin Cross7b3dcc32019-01-24 13:14:39 -08001060
1061func TestPathForSource(t *testing.T) {
1062 testCases := []struct {
1063 name string
1064 buildDir string
1065 src string
1066 err string
1067 }{
1068 {
1069 name: "normal",
1070 buildDir: "out",
1071 src: "a/b/c",
1072 },
1073 {
1074 name: "abs",
1075 buildDir: "out",
1076 src: "/a/b/c",
1077 err: "is outside directory",
1078 },
1079 {
1080 name: "in out dir",
1081 buildDir: "out",
Colin Cross7b6a55f2021-11-09 12:34:39 -08001082 src: "out/soong/a/b/c",
Colin Cross7b3dcc32019-01-24 13:14:39 -08001083 err: "is in output",
1084 },
1085 }
1086
1087 funcs := []struct {
1088 name string
1089 f func(ctx PathContext, pathComponents ...string) (SourcePath, error)
1090 }{
1091 {"pathForSource", pathForSource},
1092 {"safePathForSource", safePathForSource},
1093 }
1094
1095 for _, f := range funcs {
1096 t.Run(f.name, func(t *testing.T) {
1097 for _, test := range testCases {
1098 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001099 testConfig := pathTestConfig(test.buildDir)
Colin Cross7b3dcc32019-01-24 13:14:39 -08001100 ctx := &configErrorWrapper{config: testConfig}
1101 _, err := f.f(ctx, test.src)
1102 if len(ctx.errors) > 0 {
1103 t.Fatalf("unexpected errors %v", ctx.errors)
1104 }
1105 if err != nil {
1106 if test.err == "" {
1107 t.Fatalf("unexpected error %q", err.Error())
1108 } else if !strings.Contains(err.Error(), test.err) {
1109 t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
1110 }
1111 } else {
1112 if test.err != "" {
1113 t.Fatalf("missing error %q", test.err)
1114 }
1115 }
1116 })
1117 }
1118 })
1119 }
1120}
Colin Cross8854a5a2019-02-11 14:14:16 -08001121
Colin Cross8a497952019-03-05 22:25:09 -08001122type pathForModuleSrcTestModule struct {
Colin Cross937664a2019-03-06 10:17:32 -08001123 ModuleBase
1124 props struct {
1125 Srcs []string `android:"path"`
1126 Exclude_srcs []string `android:"path"`
Colin Cross8a497952019-03-05 22:25:09 -08001127
1128 Src *string `android:"path"`
Colin Crossba71a3f2019-03-18 12:12:48 -07001129
1130 Module_handles_missing_deps bool
Colin Cross937664a2019-03-06 10:17:32 -08001131 }
1132
Colin Cross8a497952019-03-05 22:25:09 -08001133 src string
1134 rel string
1135
1136 srcs []string
Colin Cross937664a2019-03-06 10:17:32 -08001137 rels []string
Colin Cross8a497952019-03-05 22:25:09 -08001138
1139 missingDeps []string
Colin Cross937664a2019-03-06 10:17:32 -08001140}
1141
Colin Cross8a497952019-03-05 22:25:09 -08001142func pathForModuleSrcTestModuleFactory() Module {
1143 module := &pathForModuleSrcTestModule{}
Colin Cross937664a2019-03-06 10:17:32 -08001144 module.AddProperties(&module.props)
1145 InitAndroidModule(module)
1146 return module
1147}
1148
Colin Cross8a497952019-03-05 22:25:09 -08001149func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Crossba71a3f2019-03-18 12:12:48 -07001150 var srcs Paths
1151 if p.props.Module_handles_missing_deps {
1152 srcs, p.missingDeps = PathsAndMissingDepsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
1153 } else {
1154 srcs = PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
1155 }
Colin Cross8a497952019-03-05 22:25:09 -08001156 p.srcs = srcs.Strings()
Colin Cross937664a2019-03-06 10:17:32 -08001157
Colin Cross8a497952019-03-05 22:25:09 -08001158 for _, src := range srcs {
Colin Cross937664a2019-03-06 10:17:32 -08001159 p.rels = append(p.rels, src.Rel())
1160 }
Colin Cross8a497952019-03-05 22:25:09 -08001161
1162 if p.props.Src != nil {
1163 src := PathForModuleSrc(ctx, *p.props.Src)
1164 if src != nil {
1165 p.src = src.String()
1166 p.rel = src.Rel()
1167 }
1168 }
1169
Colin Crossba71a3f2019-03-18 12:12:48 -07001170 if !p.props.Module_handles_missing_deps {
1171 p.missingDeps = ctx.GetMissingDependencies()
1172 }
Colin Cross6c4f21f2019-06-06 15:41:36 -07001173
1174 ctx.Build(pctx, BuildParams{
1175 Rule: Touch,
1176 Output: PathForModuleOut(ctx, "output"),
1177 })
Colin Cross8a497952019-03-05 22:25:09 -08001178}
1179
Colin Cross41955e82019-05-29 14:40:35 -07001180type pathForModuleSrcOutputFileProviderModule struct {
1181 ModuleBase
1182 props struct {
1183 Outs []string
1184 Tagged []string
1185 }
Zi Wang9b215962024-06-27 21:51:33 +00001186
1187 outs Paths
1188 tagged Paths
Colin Cross41955e82019-05-29 14:40:35 -07001189}
1190
1191func pathForModuleSrcOutputFileProviderModuleFactory() Module {
1192 module := &pathForModuleSrcOutputFileProviderModule{}
1193 module.AddProperties(&module.props)
1194 InitAndroidModule(module)
1195 return module
1196}
1197
1198func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
1199 for _, out := range p.props.Outs {
Zi Wang9b215962024-06-27 21:51:33 +00001200 p.outs = append(p.outs, PathForModuleOut(ctx, out))
Colin Cross41955e82019-05-29 14:40:35 -07001201 }
1202
1203 for _, tagged := range p.props.Tagged {
Zi Wang9b215962024-06-27 21:51:33 +00001204 p.tagged = append(p.tagged, PathForModuleOut(ctx, tagged))
Colin Cross41955e82019-05-29 14:40:35 -07001205 }
Zi Wang9b215962024-06-27 21:51:33 +00001206}
Colin Cross41955e82019-05-29 14:40:35 -07001207
Zi Wang9b215962024-06-27 21:51:33 +00001208func (p *pathForModuleSrcOutputFileProviderModule) OutputFiles(tag string) (Paths, error) {
1209 switch tag {
1210 case "":
1211 return p.outs, nil
1212 case ".tagged":
1213 return p.tagged, nil
1214 default:
1215 return nil, fmt.Errorf("unsupported tag %q", tag)
1216 }
Colin Cross41955e82019-05-29 14:40:35 -07001217}
1218
Colin Cross8a497952019-03-05 22:25:09 -08001219type pathForModuleSrcTestCase struct {
1220 name string
1221 bp string
1222 srcs []string
1223 rels []string
1224 src string
1225 rel string
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001226
1227 // Make test specific preparations to the test fixture.
1228 preparer FixturePreparer
1229
1230 // A test specific error handler.
1231 errorHandler FixtureErrorHandler
Colin Cross8a497952019-03-05 22:25:09 -08001232}
1233
Paul Duffin54054682021-03-16 21:11:42 +00001234func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) {
Colin Cross8a497952019-03-05 22:25:09 -08001235 for _, test := range tests {
1236 t.Run(test.name, func(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001237 fgBp := `
1238 filegroup {
1239 name: "a",
1240 srcs: ["src/a"],
1241 }
1242 `
1243
Colin Cross41955e82019-05-29 14:40:35 -07001244 ofpBp := `
1245 output_file_provider {
1246 name: "b",
1247 outs: ["gen/b"],
1248 tagged: ["gen/c"],
1249 }
1250 `
1251
Paul Duffin54054682021-03-16 21:11:42 +00001252 mockFS := MockFS{
Colin Cross8a497952019-03-05 22:25:09 -08001253 "fg/Android.bp": []byte(fgBp),
1254 "foo/Android.bp": []byte(test.bp),
Colin Cross41955e82019-05-29 14:40:35 -07001255 "ofp/Android.bp": []byte(ofpBp),
Colin Cross8a497952019-03-05 22:25:09 -08001256 "fg/src/a": nil,
1257 "foo/src/b": nil,
1258 "foo/src/c": nil,
1259 "foo/src/d": nil,
1260 "foo/src/e/e": nil,
1261 "foo/src_special/$": nil,
1262 }
1263
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001264 errorHandler := test.errorHandler
1265 if errorHandler == nil {
1266 errorHandler = FixtureExpectsNoErrors
1267 }
1268
Paul Duffin30ac3e72021-03-20 00:36:14 +00001269 result := GroupFixturePreparers(
Paul Duffin54054682021-03-16 21:11:42 +00001270 FixtureRegisterWithContext(func(ctx RegistrationContext) {
1271 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1272 ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
Paul Duffin54054682021-03-16 21:11:42 +00001273 }),
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001274 PrepareForTestWithFilegroup,
1275 PrepareForTestWithNamespace,
Paul Duffin54054682021-03-16 21:11:42 +00001276 mockFS.AddToFixture(),
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001277 OptionalFixturePreparer(test.preparer),
1278 ).
1279 ExtendWithErrorHandler(errorHandler).
1280 RunTest(t)
Colin Cross8a497952019-03-05 22:25:09 -08001281
Paul Duffin54054682021-03-16 21:11:42 +00001282 m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
Colin Crossae8600b2020-10-29 17:09:13 -07001283
Paul Duffin54054682021-03-16 21:11:42 +00001284 AssertStringPathsRelativeToTopEquals(t, "srcs", result.Config, test.srcs, m.srcs)
1285 AssertStringPathsRelativeToTopEquals(t, "rels", result.Config, test.rels, m.rels)
1286 AssertStringPathRelativeToTopEquals(t, "src", result.Config, test.src, m.src)
1287 AssertStringPathRelativeToTopEquals(t, "rel", result.Config, test.rel, m.rel)
Colin Cross8a497952019-03-05 22:25:09 -08001288 })
1289 }
Colin Cross937664a2019-03-06 10:17:32 -08001290}
1291
Colin Cross8a497952019-03-05 22:25:09 -08001292func TestPathsForModuleSrc(t *testing.T) {
1293 tests := []pathForModuleSrcTestCase{
Colin Cross937664a2019-03-06 10:17:32 -08001294 {
1295 name: "path",
1296 bp: `
1297 test {
1298 name: "foo",
1299 srcs: ["src/b"],
1300 }`,
1301 srcs: []string{"foo/src/b"},
1302 rels: []string{"src/b"},
1303 },
1304 {
1305 name: "glob",
1306 bp: `
1307 test {
1308 name: "foo",
1309 srcs: [
1310 "src/*",
1311 "src/e/*",
1312 ],
1313 }`,
1314 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1315 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1316 },
1317 {
1318 name: "recursive glob",
1319 bp: `
1320 test {
1321 name: "foo",
1322 srcs: ["src/**/*"],
1323 }`,
1324 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1325 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1326 },
1327 {
1328 name: "filegroup",
1329 bp: `
1330 test {
1331 name: "foo",
1332 srcs: [":a"],
1333 }`,
1334 srcs: []string{"fg/src/a"},
1335 rels: []string{"src/a"},
1336 },
1337 {
Colin Cross41955e82019-05-29 14:40:35 -07001338 name: "output file provider",
1339 bp: `
1340 test {
1341 name: "foo",
1342 srcs: [":b"],
1343 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001344 srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"},
Colin Cross41955e82019-05-29 14:40:35 -07001345 rels: []string{"gen/b"},
1346 },
1347 {
1348 name: "output file provider tagged",
1349 bp: `
1350 test {
1351 name: "foo",
1352 srcs: [":b{.tagged}"],
1353 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001354 srcs: []string{"out/soong/.intermediates/ofp/b/gen/c"},
Colin Cross41955e82019-05-29 14:40:35 -07001355 rels: []string{"gen/c"},
1356 },
1357 {
Jooyung Han7607dd32020-07-05 10:23:14 +09001358 name: "output file provider with exclude",
1359 bp: `
1360 test {
1361 name: "foo",
1362 srcs: [":b", ":c"],
1363 exclude_srcs: [":c"]
1364 }
1365 output_file_provider {
1366 name: "c",
1367 outs: ["gen/c"],
1368 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001369 srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"},
Jooyung Han7607dd32020-07-05 10:23:14 +09001370 rels: []string{"gen/b"},
1371 },
1372 {
Colin Cross937664a2019-03-06 10:17:32 -08001373 name: "special characters glob",
1374 bp: `
1375 test {
1376 name: "foo",
1377 srcs: ["src_special/*"],
1378 }`,
1379 srcs: []string{"foo/src_special/$"},
1380 rels: []string{"src_special/$"},
1381 },
1382 }
1383
Paul Duffin54054682021-03-16 21:11:42 +00001384 testPathForModuleSrc(t, tests)
Colin Cross41955e82019-05-29 14:40:35 -07001385}
1386
1387func TestPathForModuleSrc(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001388 tests := []pathForModuleSrcTestCase{
1389 {
1390 name: "path",
1391 bp: `
1392 test {
1393 name: "foo",
1394 src: "src/b",
1395 }`,
1396 src: "foo/src/b",
1397 rel: "src/b",
1398 },
1399 {
1400 name: "glob",
1401 bp: `
1402 test {
1403 name: "foo",
1404 src: "src/e/*",
1405 }`,
1406 src: "foo/src/e/e",
1407 rel: "src/e/e",
1408 },
1409 {
1410 name: "filegroup",
1411 bp: `
1412 test {
1413 name: "foo",
1414 src: ":a",
1415 }`,
1416 src: "fg/src/a",
1417 rel: "src/a",
1418 },
1419 {
Colin Cross41955e82019-05-29 14:40:35 -07001420 name: "output file provider",
1421 bp: `
1422 test {
1423 name: "foo",
1424 src: ":b",
1425 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001426 src: "out/soong/.intermediates/ofp/b/gen/b",
Colin Cross41955e82019-05-29 14:40:35 -07001427 rel: "gen/b",
1428 },
1429 {
1430 name: "output file provider tagged",
1431 bp: `
1432 test {
1433 name: "foo",
1434 src: ":b{.tagged}",
1435 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001436 src: "out/soong/.intermediates/ofp/b/gen/c",
Colin Cross41955e82019-05-29 14:40:35 -07001437 rel: "gen/c",
1438 },
1439 {
Colin Cross8a497952019-03-05 22:25:09 -08001440 name: "special characters glob",
1441 bp: `
1442 test {
1443 name: "foo",
1444 src: "src_special/*",
1445 }`,
1446 src: "foo/src_special/$",
1447 rel: "src_special/$",
1448 },
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001449 {
1450 // This test makes sure that an unqualified module name cannot contain characters that make
1451 // it appear as a qualified module name.
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001452 name: "output file provider, invalid fully qualified name",
1453 bp: `
1454 test {
1455 name: "foo",
1456 src: "://other:b",
1457 srcs: ["://other:c"],
1458 }`,
1459 preparer: FixtureAddTextFile("other/Android.bp", `
1460 soong_namespace {}
1461
1462 output_file_provider {
1463 name: "b",
1464 outs: ["gen/b"],
1465 }
1466
1467 output_file_provider {
1468 name: "c",
1469 outs: ["gen/c"],
1470 }
1471 `),
Paul Duffine6ba0722021-07-12 20:12:12 +01001472 src: "foo/:/other:b",
1473 rel: ":/other:b",
1474 srcs: []string{"foo/:/other:c"},
1475 rels: []string{":/other:c"},
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001476 },
1477 {
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001478 name: "output file provider, missing fully qualified name",
1479 bp: `
1480 test {
1481 name: "foo",
1482 src: "//other:b",
1483 srcs: ["//other:c"],
1484 }`,
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001485 errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{
Paul Duffine6ba0722021-07-12 20:12:12 +01001486 `"foo" depends on undefined module "//other:b"`,
1487 `"foo" depends on undefined module "//other:c"`,
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001488 }),
1489 },
1490 {
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001491 name: "output file provider, fully qualified name",
1492 bp: `
1493 test {
1494 name: "foo",
1495 src: "//other:b",
1496 srcs: ["//other:c"],
1497 }`,
Paul Duffin40131a32021-07-09 17:10:35 +01001498 src: "out/soong/.intermediates/other/b/gen/b",
1499 rel: "gen/b",
1500 srcs: []string{"out/soong/.intermediates/other/c/gen/c"},
1501 rels: []string{"gen/c"},
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001502 preparer: FixtureAddTextFile("other/Android.bp", `
1503 soong_namespace {}
1504
1505 output_file_provider {
1506 name: "b",
1507 outs: ["gen/b"],
1508 }
1509
1510 output_file_provider {
1511 name: "c",
1512 outs: ["gen/c"],
1513 }
1514 `),
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001515 },
Colin Cross8a497952019-03-05 22:25:09 -08001516 }
1517
Paul Duffin54054682021-03-16 21:11:42 +00001518 testPathForModuleSrc(t, tests)
Colin Cross8a497952019-03-05 22:25:09 -08001519}
Colin Cross937664a2019-03-06 10:17:32 -08001520
Colin Cross8a497952019-03-05 22:25:09 -08001521func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001522 bp := `
1523 test {
1524 name: "foo",
1525 srcs: [":a"],
1526 exclude_srcs: [":b"],
1527 src: ":c",
1528 }
Colin Crossba71a3f2019-03-18 12:12:48 -07001529
1530 test {
1531 name: "bar",
1532 srcs: [":d"],
1533 exclude_srcs: [":e"],
1534 module_handles_missing_deps: true,
1535 }
Colin Cross8a497952019-03-05 22:25:09 -08001536 `
1537
Paul Duffin30ac3e72021-03-20 00:36:14 +00001538 result := GroupFixturePreparers(
Paul Duffin54054682021-03-16 21:11:42 +00001539 PrepareForTestWithAllowMissingDependencies,
1540 FixtureRegisterWithContext(func(ctx RegistrationContext) {
1541 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1542 }),
1543 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +00001544 ).RunTest(t)
Colin Cross8a497952019-03-05 22:25:09 -08001545
Paul Duffin54054682021-03-16 21:11:42 +00001546 foo := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
Colin Cross8a497952019-03-05 22:25:09 -08001547
Paul Duffin54054682021-03-16 21:11:42 +00001548 AssertArrayString(t, "foo missing deps", []string{"a", "b", "c"}, foo.missingDeps)
1549 AssertArrayString(t, "foo srcs", []string{}, foo.srcs)
1550 AssertStringEquals(t, "foo src", "", foo.src)
Colin Cross98be1bb2019-12-13 20:41:13 -08001551
Paul Duffin54054682021-03-16 21:11:42 +00001552 bar := result.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
Colin Cross98be1bb2019-12-13 20:41:13 -08001553
Paul Duffin54054682021-03-16 21:11:42 +00001554 AssertArrayString(t, "bar missing deps", []string{"d", "e"}, bar.missingDeps)
1555 AssertArrayString(t, "bar srcs", []string{}, bar.srcs)
Colin Cross937664a2019-03-06 10:17:32 -08001556}
1557
Paul Duffin567465d2021-03-16 01:21:34 +00001558func TestPathRelativeToTop(t *testing.T) {
1559 testConfig := pathTestConfig("/tmp/build/top")
1560 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
1561
1562 ctx := &testModuleInstallPathContext{
1563 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -08001564 archModuleContext: archModuleContext{
1565 os: deviceTarget.Os,
1566 target: deviceTarget,
1567 },
Paul Duffin567465d2021-03-16 01:21:34 +00001568 },
1569 }
1570 ctx.baseModuleContext.config = testConfig
1571
1572 t.Run("install for soong", func(t *testing.T) {
1573 p := PathForModuleInstall(ctx, "install/path")
1574 AssertPathRelativeToTopEquals(t, "install path for soong", "out/soong/target/product/test_device/system/install/path", p)
1575 })
1576 t.Run("install for make", func(t *testing.T) {
Colin Crossc68db4b2021-11-11 18:59:15 -08001577 p := PathForModuleInstall(ctx, "install/path")
1578 p.makePath = true
Paul Duffin567465d2021-03-16 01:21:34 +00001579 AssertPathRelativeToTopEquals(t, "install path for make", "out/target/product/test_device/system/install/path", p)
1580 })
1581 t.Run("output", func(t *testing.T) {
1582 p := PathForOutput(ctx, "output/path")
1583 AssertPathRelativeToTopEquals(t, "output path", "out/soong/output/path", p)
1584 })
1585 t.Run("source", func(t *testing.T) {
1586 p := PathForSource(ctx, "source/path")
1587 AssertPathRelativeToTopEquals(t, "source path", "source/path", p)
1588 })
1589 t.Run("mixture", func(t *testing.T) {
1590 paths := Paths{
1591 PathForModuleInstall(ctx, "install/path"),
Paul Duffin567465d2021-03-16 01:21:34 +00001592 PathForOutput(ctx, "output/path"),
1593 PathForSource(ctx, "source/path"),
1594 }
1595
1596 expected := []string{
1597 "out/soong/target/product/test_device/system/install/path",
Paul Duffin567465d2021-03-16 01:21:34 +00001598 "out/soong/output/path",
1599 "source/path",
1600 }
1601 AssertPathsRelativeToTopEquals(t, "mixture", expected, paths)
1602 })
1603}
1604
Colin Cross8854a5a2019-02-11 14:14:16 -08001605func ExampleOutputPath_ReplaceExtension() {
1606 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001607 config: TestConfig("out", nil, "", nil),
Colin Cross8854a5a2019-02-11 14:14:16 -08001608 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001609 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross8854a5a2019-02-11 14:14:16 -08001610 p2 := p.ReplaceExtension(ctx, "oat")
1611 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001612 fmt.Println(p.Rel(), p2.Rel())
Colin Cross8854a5a2019-02-11 14:14:16 -08001613
1614 // Output:
Colin Cross7b6a55f2021-11-09 12:34:39 -08001615 // out/soong/system/framework/boot.art out/soong/system/framework/boot.oat
Colin Cross2cdd5df2019-02-25 10:25:24 -08001616 // boot.art boot.oat
Colin Cross8854a5a2019-02-11 14:14:16 -08001617}
Colin Cross40e33732019-02-15 11:08:35 -08001618
Colin Cross41b46762020-10-09 19:26:32 -07001619func ExampleOutputPath_InSameDir() {
Colin Cross40e33732019-02-15 11:08:35 -08001620 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001621 config: TestConfig("out", nil, "", nil),
Colin Cross40e33732019-02-15 11:08:35 -08001622 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001623 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross40e33732019-02-15 11:08:35 -08001624 p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
1625 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001626 fmt.Println(p.Rel(), p2.Rel())
Colin Cross40e33732019-02-15 11:08:35 -08001627
1628 // Output:
Colin Cross7b6a55f2021-11-09 12:34:39 -08001629 // out/soong/system/framework/boot.art out/soong/system/framework/oat/arm/boot.vdex
Colin Cross2cdd5df2019-02-25 10:25:24 -08001630 // boot.art oat/arm/boot.vdex
Colin Cross40e33732019-02-15 11:08:35 -08001631}
Colin Cross27027c72020-02-28 15:34:17 -08001632
1633func BenchmarkFirstUniquePaths(b *testing.B) {
1634 implementations := []struct {
1635 name string
1636 f func(Paths) Paths
1637 }{
1638 {
1639 name: "list",
1640 f: firstUniquePathsList,
1641 },
1642 {
1643 name: "map",
1644 f: firstUniquePathsMap,
1645 },
1646 }
1647 const maxSize = 1024
1648 uniquePaths := make(Paths, maxSize)
1649 for i := range uniquePaths {
1650 uniquePaths[i] = PathForTesting(strconv.Itoa(i))
1651 }
1652 samePath := make(Paths, maxSize)
1653 for i := range samePath {
1654 samePath[i] = uniquePaths[0]
1655 }
1656
1657 f := func(b *testing.B, imp func(Paths) Paths, paths Paths) {
1658 for i := 0; i < b.N; i++ {
1659 b.ReportAllocs()
1660 paths = append(Paths(nil), paths...)
1661 imp(paths)
1662 }
1663 }
1664
1665 for n := 1; n <= maxSize; n <<= 1 {
1666 b.Run(strconv.Itoa(n), func(b *testing.B) {
1667 for _, implementation := range implementations {
1668 b.Run(implementation.name, func(b *testing.B) {
1669 b.Run("same", func(b *testing.B) {
1670 f(b, implementation.f, samePath[:n])
1671 })
1672 b.Run("unique", func(b *testing.B) {
1673 f(b, implementation.f, uniquePaths[:n])
1674 })
1675 })
1676 }
1677 })
1678 }
1679}