blob: 5e618f914a1d77575e64e9bf96ae819c3a3deacb [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 }
Colin Cross41955e82019-05-29 14:40:35 -07001186}
1187
1188func pathForModuleSrcOutputFileProviderModuleFactory() Module {
1189 module := &pathForModuleSrcOutputFileProviderModule{}
1190 module.AddProperties(&module.props)
1191 InitAndroidModule(module)
1192 return module
1193}
1194
1195func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
mrziwang01715ca2024-07-01 11:50:18 -07001196 var outs, taggedOuts Paths
Colin Cross41955e82019-05-29 14:40:35 -07001197 for _, out := range p.props.Outs {
mrziwang01715ca2024-07-01 11:50:18 -07001198 outs = append(outs, PathForModuleOut(ctx, out))
Colin Cross41955e82019-05-29 14:40:35 -07001199 }
1200
1201 for _, tagged := range p.props.Tagged {
mrziwang01715ca2024-07-01 11:50:18 -07001202 taggedOuts = append(taggedOuts, PathForModuleOut(ctx, tagged))
Colin Cross41955e82019-05-29 14:40:35 -07001203 }
Colin Cross41955e82019-05-29 14:40:35 -07001204
mrziwang01715ca2024-07-01 11:50:18 -07001205 ctx.SetOutputFiles(outs, "")
1206 ctx.SetOutputFiles(taggedOuts, ".tagged")
Colin Cross41955e82019-05-29 14:40:35 -07001207}
1208
Colin Cross8a497952019-03-05 22:25:09 -08001209type pathForModuleSrcTestCase struct {
1210 name string
1211 bp string
1212 srcs []string
1213 rels []string
1214 src string
1215 rel string
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001216
1217 // Make test specific preparations to the test fixture.
1218 preparer FixturePreparer
1219
1220 // A test specific error handler.
1221 errorHandler FixtureErrorHandler
Colin Cross8a497952019-03-05 22:25:09 -08001222}
1223
Paul Duffin54054682021-03-16 21:11:42 +00001224func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) {
Colin Cross8a497952019-03-05 22:25:09 -08001225 for _, test := range tests {
1226 t.Run(test.name, func(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001227 fgBp := `
1228 filegroup {
1229 name: "a",
1230 srcs: ["src/a"],
1231 }
1232 `
1233
Colin Cross41955e82019-05-29 14:40:35 -07001234 ofpBp := `
1235 output_file_provider {
1236 name: "b",
1237 outs: ["gen/b"],
1238 tagged: ["gen/c"],
1239 }
1240 `
1241
Paul Duffin54054682021-03-16 21:11:42 +00001242 mockFS := MockFS{
Colin Cross8a497952019-03-05 22:25:09 -08001243 "fg/Android.bp": []byte(fgBp),
1244 "foo/Android.bp": []byte(test.bp),
Colin Cross41955e82019-05-29 14:40:35 -07001245 "ofp/Android.bp": []byte(ofpBp),
Colin Cross8a497952019-03-05 22:25:09 -08001246 "fg/src/a": nil,
1247 "foo/src/b": nil,
1248 "foo/src/c": nil,
1249 "foo/src/d": nil,
1250 "foo/src/e/e": nil,
1251 "foo/src_special/$": nil,
1252 }
1253
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001254 errorHandler := test.errorHandler
1255 if errorHandler == nil {
1256 errorHandler = FixtureExpectsNoErrors
1257 }
1258
Paul Duffin30ac3e72021-03-20 00:36:14 +00001259 result := GroupFixturePreparers(
Paul Duffin54054682021-03-16 21:11:42 +00001260 FixtureRegisterWithContext(func(ctx RegistrationContext) {
1261 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1262 ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
Paul Duffin54054682021-03-16 21:11:42 +00001263 }),
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001264 PrepareForTestWithFilegroup,
1265 PrepareForTestWithNamespace,
Paul Duffin54054682021-03-16 21:11:42 +00001266 mockFS.AddToFixture(),
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001267 OptionalFixturePreparer(test.preparer),
1268 ).
1269 ExtendWithErrorHandler(errorHandler).
1270 RunTest(t)
Colin Cross8a497952019-03-05 22:25:09 -08001271
Paul Duffin54054682021-03-16 21:11:42 +00001272 m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
Colin Crossae8600b2020-10-29 17:09:13 -07001273
Paul Duffin54054682021-03-16 21:11:42 +00001274 AssertStringPathsRelativeToTopEquals(t, "srcs", result.Config, test.srcs, m.srcs)
1275 AssertStringPathsRelativeToTopEquals(t, "rels", result.Config, test.rels, m.rels)
1276 AssertStringPathRelativeToTopEquals(t, "src", result.Config, test.src, m.src)
1277 AssertStringPathRelativeToTopEquals(t, "rel", result.Config, test.rel, m.rel)
Colin Cross8a497952019-03-05 22:25:09 -08001278 })
1279 }
Colin Cross937664a2019-03-06 10:17:32 -08001280}
1281
Colin Cross8a497952019-03-05 22:25:09 -08001282func TestPathsForModuleSrc(t *testing.T) {
1283 tests := []pathForModuleSrcTestCase{
Colin Cross937664a2019-03-06 10:17:32 -08001284 {
1285 name: "path",
1286 bp: `
1287 test {
1288 name: "foo",
1289 srcs: ["src/b"],
1290 }`,
1291 srcs: []string{"foo/src/b"},
1292 rels: []string{"src/b"},
1293 },
1294 {
1295 name: "glob",
1296 bp: `
1297 test {
1298 name: "foo",
1299 srcs: [
1300 "src/*",
1301 "src/e/*",
1302 ],
1303 }`,
1304 srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1305 rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1306 },
1307 {
1308 name: "recursive glob",
1309 bp: `
1310 test {
1311 name: "foo",
1312 srcs: ["src/**/*"],
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: "filegroup",
1319 bp: `
1320 test {
1321 name: "foo",
1322 srcs: [":a"],
1323 }`,
1324 srcs: []string{"fg/src/a"},
1325 rels: []string{"src/a"},
1326 },
1327 {
Colin Cross41955e82019-05-29 14:40:35 -07001328 name: "output file provider",
1329 bp: `
1330 test {
1331 name: "foo",
1332 srcs: [":b"],
1333 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001334 srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"},
Colin Cross41955e82019-05-29 14:40:35 -07001335 rels: []string{"gen/b"},
1336 },
1337 {
1338 name: "output file provider tagged",
1339 bp: `
1340 test {
1341 name: "foo",
1342 srcs: [":b{.tagged}"],
1343 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001344 srcs: []string{"out/soong/.intermediates/ofp/b/gen/c"},
Colin Cross41955e82019-05-29 14:40:35 -07001345 rels: []string{"gen/c"},
1346 },
1347 {
Jooyung Han7607dd32020-07-05 10:23:14 +09001348 name: "output file provider with exclude",
1349 bp: `
1350 test {
1351 name: "foo",
1352 srcs: [":b", ":c"],
1353 exclude_srcs: [":c"]
1354 }
1355 output_file_provider {
1356 name: "c",
1357 outs: ["gen/c"],
1358 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001359 srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"},
Jooyung Han7607dd32020-07-05 10:23:14 +09001360 rels: []string{"gen/b"},
1361 },
1362 {
Colin Cross937664a2019-03-06 10:17:32 -08001363 name: "special characters glob",
1364 bp: `
1365 test {
1366 name: "foo",
1367 srcs: ["src_special/*"],
1368 }`,
1369 srcs: []string{"foo/src_special/$"},
1370 rels: []string{"src_special/$"},
1371 },
1372 }
1373
Paul Duffin54054682021-03-16 21:11:42 +00001374 testPathForModuleSrc(t, tests)
Colin Cross41955e82019-05-29 14:40:35 -07001375}
1376
1377func TestPathForModuleSrc(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001378 tests := []pathForModuleSrcTestCase{
1379 {
1380 name: "path",
1381 bp: `
1382 test {
1383 name: "foo",
1384 src: "src/b",
1385 }`,
1386 src: "foo/src/b",
1387 rel: "src/b",
1388 },
1389 {
1390 name: "glob",
1391 bp: `
1392 test {
1393 name: "foo",
1394 src: "src/e/*",
1395 }`,
1396 src: "foo/src/e/e",
1397 rel: "src/e/e",
1398 },
1399 {
1400 name: "filegroup",
1401 bp: `
1402 test {
1403 name: "foo",
1404 src: ":a",
1405 }`,
1406 src: "fg/src/a",
1407 rel: "src/a",
1408 },
1409 {
Colin Cross41955e82019-05-29 14:40:35 -07001410 name: "output file provider",
1411 bp: `
1412 test {
1413 name: "foo",
1414 src: ":b",
1415 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001416 src: "out/soong/.intermediates/ofp/b/gen/b",
Colin Cross41955e82019-05-29 14:40:35 -07001417 rel: "gen/b",
1418 },
1419 {
1420 name: "output file provider tagged",
1421 bp: `
1422 test {
1423 name: "foo",
1424 src: ":b{.tagged}",
1425 }`,
Paul Duffin54054682021-03-16 21:11:42 +00001426 src: "out/soong/.intermediates/ofp/b/gen/c",
Colin Cross41955e82019-05-29 14:40:35 -07001427 rel: "gen/c",
1428 },
1429 {
Colin Cross8a497952019-03-05 22:25:09 -08001430 name: "special characters glob",
1431 bp: `
1432 test {
1433 name: "foo",
1434 src: "src_special/*",
1435 }`,
1436 src: "foo/src_special/$",
1437 rel: "src_special/$",
1438 },
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001439 {
1440 // This test makes sure that an unqualified module name cannot contain characters that make
1441 // it appear as a qualified module name.
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001442 name: "output file provider, invalid fully qualified name",
1443 bp: `
1444 test {
1445 name: "foo",
1446 src: "://other:b",
1447 srcs: ["://other:c"],
1448 }`,
1449 preparer: FixtureAddTextFile("other/Android.bp", `
1450 soong_namespace {}
1451
1452 output_file_provider {
1453 name: "b",
1454 outs: ["gen/b"],
1455 }
1456
1457 output_file_provider {
1458 name: "c",
1459 outs: ["gen/c"],
1460 }
1461 `),
Paul Duffine6ba0722021-07-12 20:12:12 +01001462 src: "foo/:/other:b",
1463 rel: ":/other:b",
1464 srcs: []string{"foo/:/other:c"},
1465 rels: []string{":/other:c"},
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001466 },
1467 {
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001468 name: "output file provider, missing fully qualified name",
1469 bp: `
1470 test {
1471 name: "foo",
1472 src: "//other:b",
1473 srcs: ["//other:c"],
1474 }`,
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001475 errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{
Paul Duffine6ba0722021-07-12 20:12:12 +01001476 `"foo" depends on undefined module "//other:b"`,
1477 `"foo" depends on undefined module "//other:c"`,
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001478 }),
1479 },
1480 {
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001481 name: "output file provider, fully qualified name",
1482 bp: `
1483 test {
1484 name: "foo",
1485 src: "//other:b",
1486 srcs: ["//other:c"],
1487 }`,
Paul Duffin40131a32021-07-09 17:10:35 +01001488 src: "out/soong/.intermediates/other/b/gen/b",
1489 rel: "gen/b",
1490 srcs: []string{"out/soong/.intermediates/other/c/gen/c"},
1491 rels: []string{"gen/c"},
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001492 preparer: FixtureAddTextFile("other/Android.bp", `
1493 soong_namespace {}
1494
1495 output_file_provider {
1496 name: "b",
1497 outs: ["gen/b"],
1498 }
1499
1500 output_file_provider {
1501 name: "c",
1502 outs: ["gen/c"],
1503 }
1504 `),
Paul Duffinec0bd8c2021-07-09 16:56:15 +01001505 },
Colin Cross8a497952019-03-05 22:25:09 -08001506 }
1507
Paul Duffin54054682021-03-16 21:11:42 +00001508 testPathForModuleSrc(t, tests)
Colin Cross8a497952019-03-05 22:25:09 -08001509}
Colin Cross937664a2019-03-06 10:17:32 -08001510
Colin Cross8a497952019-03-05 22:25:09 -08001511func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
Colin Cross8a497952019-03-05 22:25:09 -08001512 bp := `
1513 test {
1514 name: "foo",
1515 srcs: [":a"],
1516 exclude_srcs: [":b"],
1517 src: ":c",
1518 }
Colin Crossba71a3f2019-03-18 12:12:48 -07001519
1520 test {
1521 name: "bar",
1522 srcs: [":d"],
1523 exclude_srcs: [":e"],
1524 module_handles_missing_deps: true,
1525 }
Colin Cross8a497952019-03-05 22:25:09 -08001526 `
1527
Paul Duffin30ac3e72021-03-20 00:36:14 +00001528 result := GroupFixturePreparers(
Paul Duffin54054682021-03-16 21:11:42 +00001529 PrepareForTestWithAllowMissingDependencies,
1530 FixtureRegisterWithContext(func(ctx RegistrationContext) {
1531 ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1532 }),
1533 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +00001534 ).RunTest(t)
Colin Cross8a497952019-03-05 22:25:09 -08001535
Paul Duffin54054682021-03-16 21:11:42 +00001536 foo := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
Colin Cross8a497952019-03-05 22:25:09 -08001537
Paul Duffin54054682021-03-16 21:11:42 +00001538 AssertArrayString(t, "foo missing deps", []string{"a", "b", "c"}, foo.missingDeps)
1539 AssertArrayString(t, "foo srcs", []string{}, foo.srcs)
1540 AssertStringEquals(t, "foo src", "", foo.src)
Colin Cross98be1bb2019-12-13 20:41:13 -08001541
Paul Duffin54054682021-03-16 21:11:42 +00001542 bar := result.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
Colin Cross98be1bb2019-12-13 20:41:13 -08001543
Paul Duffin54054682021-03-16 21:11:42 +00001544 AssertArrayString(t, "bar missing deps", []string{"d", "e"}, bar.missingDeps)
1545 AssertArrayString(t, "bar srcs", []string{}, bar.srcs)
Colin Cross937664a2019-03-06 10:17:32 -08001546}
1547
Paul Duffin567465d2021-03-16 01:21:34 +00001548func TestPathRelativeToTop(t *testing.T) {
1549 testConfig := pathTestConfig("/tmp/build/top")
1550 deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
1551
1552 ctx := &testModuleInstallPathContext{
1553 baseModuleContext: baseModuleContext{
Colin Cross1d3d9f12024-01-18 14:30:22 -08001554 archModuleContext: archModuleContext{
1555 os: deviceTarget.Os,
1556 target: deviceTarget,
1557 },
Paul Duffin567465d2021-03-16 01:21:34 +00001558 },
1559 }
1560 ctx.baseModuleContext.config = testConfig
1561
1562 t.Run("install for soong", func(t *testing.T) {
1563 p := PathForModuleInstall(ctx, "install/path")
1564 AssertPathRelativeToTopEquals(t, "install path for soong", "out/soong/target/product/test_device/system/install/path", p)
1565 })
1566 t.Run("install for make", func(t *testing.T) {
Colin Crossc68db4b2021-11-11 18:59:15 -08001567 p := PathForModuleInstall(ctx, "install/path")
1568 p.makePath = true
Paul Duffin567465d2021-03-16 01:21:34 +00001569 AssertPathRelativeToTopEquals(t, "install path for make", "out/target/product/test_device/system/install/path", p)
1570 })
1571 t.Run("output", func(t *testing.T) {
1572 p := PathForOutput(ctx, "output/path")
1573 AssertPathRelativeToTopEquals(t, "output path", "out/soong/output/path", p)
1574 })
1575 t.Run("source", func(t *testing.T) {
1576 p := PathForSource(ctx, "source/path")
1577 AssertPathRelativeToTopEquals(t, "source path", "source/path", p)
1578 })
1579 t.Run("mixture", func(t *testing.T) {
1580 paths := Paths{
1581 PathForModuleInstall(ctx, "install/path"),
Paul Duffin567465d2021-03-16 01:21:34 +00001582 PathForOutput(ctx, "output/path"),
1583 PathForSource(ctx, "source/path"),
1584 }
1585
1586 expected := []string{
1587 "out/soong/target/product/test_device/system/install/path",
Paul Duffin567465d2021-03-16 01:21:34 +00001588 "out/soong/output/path",
1589 "source/path",
1590 }
1591 AssertPathsRelativeToTopEquals(t, "mixture", expected, paths)
1592 })
1593}
1594
Inseob Kim93036a52024-10-25 17:02:21 +09001595func TestDirectoryPathIsIncompatibleWithPath(t *testing.T) {
1596 d := (DirectoryPath)(&directoryPath{})
1597 _, ok := d.(Path)
1598 AssertBoolEquals(t, "directoryPath shouldn't implement Path", ok, false)
1599}
1600
Colin Cross8854a5a2019-02-11 14:14:16 -08001601func ExampleOutputPath_ReplaceExtension() {
1602 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001603 config: TestConfig("out", nil, "", nil),
Colin Cross8854a5a2019-02-11 14:14:16 -08001604 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001605 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross8854a5a2019-02-11 14:14:16 -08001606 p2 := p.ReplaceExtension(ctx, "oat")
1607 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001608 fmt.Println(p.Rel(), p2.Rel())
Colin Cross8854a5a2019-02-11 14:14:16 -08001609
1610 // Output:
Colin Cross7b6a55f2021-11-09 12:34:39 -08001611 // out/soong/system/framework/boot.art out/soong/system/framework/boot.oat
Colin Cross2cdd5df2019-02-25 10:25:24 -08001612 // boot.art boot.oat
Colin Cross8854a5a2019-02-11 14:14:16 -08001613}
Colin Cross40e33732019-02-15 11:08:35 -08001614
Colin Cross41b46762020-10-09 19:26:32 -07001615func ExampleOutputPath_InSameDir() {
Colin Cross40e33732019-02-15 11:08:35 -08001616 ctx := &configErrorWrapper{
Colin Cross98be1bb2019-12-13 20:41:13 -08001617 config: TestConfig("out", nil, "", nil),
Colin Cross40e33732019-02-15 11:08:35 -08001618 }
Colin Cross2cdd5df2019-02-25 10:25:24 -08001619 p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
Colin Cross40e33732019-02-15 11:08:35 -08001620 p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
1621 fmt.Println(p, p2)
Colin Cross2cdd5df2019-02-25 10:25:24 -08001622 fmt.Println(p.Rel(), p2.Rel())
Colin Cross40e33732019-02-15 11:08:35 -08001623
1624 // Output:
Colin Cross7b6a55f2021-11-09 12:34:39 -08001625 // out/soong/system/framework/boot.art out/soong/system/framework/oat/arm/boot.vdex
Colin Cross2cdd5df2019-02-25 10:25:24 -08001626 // boot.art oat/arm/boot.vdex
Colin Cross40e33732019-02-15 11:08:35 -08001627}
Colin Cross27027c72020-02-28 15:34:17 -08001628
1629func BenchmarkFirstUniquePaths(b *testing.B) {
1630 implementations := []struct {
1631 name string
1632 f func(Paths) Paths
1633 }{
1634 {
1635 name: "list",
1636 f: firstUniquePathsList,
1637 },
1638 {
1639 name: "map",
1640 f: firstUniquePathsMap,
1641 },
1642 }
1643 const maxSize = 1024
1644 uniquePaths := make(Paths, maxSize)
1645 for i := range uniquePaths {
1646 uniquePaths[i] = PathForTesting(strconv.Itoa(i))
1647 }
1648 samePath := make(Paths, maxSize)
1649 for i := range samePath {
1650 samePath[i] = uniquePaths[0]
1651 }
1652
1653 f := func(b *testing.B, imp func(Paths) Paths, paths Paths) {
1654 for i := 0; i < b.N; i++ {
1655 b.ReportAllocs()
1656 paths = append(Paths(nil), paths...)
1657 imp(paths)
1658 }
1659 }
1660
1661 for n := 1; n <= maxSize; n <<= 1 {
1662 b.Run(strconv.Itoa(n), func(b *testing.B) {
1663 for _, implementation := range implementations {
1664 b.Run(implementation.name, func(b *testing.B) {
1665 b.Run("same", func(b *testing.B) {
1666 f(b, implementation.f, samePath[:n])
1667 })
1668 b.Run("unique", func(b *testing.B) {
1669 f(b, implementation.f, uniquePaths[:n])
1670 })
1671 })
1672 }
1673 })
1674 }
1675}