xref: /aosp_15_r20/build/soong/android/paths_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2015 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage android
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"errors"
19*333d2b36SAndroid Build Coastguard Worker	"fmt"
20*333d2b36SAndroid Build Coastguard Worker	"reflect"
21*333d2b36SAndroid Build Coastguard Worker	"strconv"
22*333d2b36SAndroid Build Coastguard Worker	"strings"
23*333d2b36SAndroid Build Coastguard Worker	"testing"
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
26*333d2b36SAndroid Build Coastguard Worker)
27*333d2b36SAndroid Build Coastguard Worker
28*333d2b36SAndroid Build Coastguard Workertype strsTestCase struct {
29*333d2b36SAndroid Build Coastguard Worker	in  []string
30*333d2b36SAndroid Build Coastguard Worker	out string
31*333d2b36SAndroid Build Coastguard Worker	err []error
32*333d2b36SAndroid Build Coastguard Worker}
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Workervar commonValidatePathTestCases = []strsTestCase{
35*333d2b36SAndroid Build Coastguard Worker	{
36*333d2b36SAndroid Build Coastguard Worker		in:  []string{""},
37*333d2b36SAndroid Build Coastguard Worker		out: "",
38*333d2b36SAndroid Build Coastguard Worker	},
39*333d2b36SAndroid Build Coastguard Worker	{
40*333d2b36SAndroid Build Coastguard Worker		in:  []string{"", ""},
41*333d2b36SAndroid Build Coastguard Worker		out: "",
42*333d2b36SAndroid Build Coastguard Worker	},
43*333d2b36SAndroid Build Coastguard Worker	{
44*333d2b36SAndroid Build Coastguard Worker		in:  []string{"a", ""},
45*333d2b36SAndroid Build Coastguard Worker		out: "a",
46*333d2b36SAndroid Build Coastguard Worker	},
47*333d2b36SAndroid Build Coastguard Worker	{
48*333d2b36SAndroid Build Coastguard Worker		in:  []string{"", "a"},
49*333d2b36SAndroid Build Coastguard Worker		out: "a",
50*333d2b36SAndroid Build Coastguard Worker	},
51*333d2b36SAndroid Build Coastguard Worker	{
52*333d2b36SAndroid Build Coastguard Worker		in:  []string{"", "a", ""},
53*333d2b36SAndroid Build Coastguard Worker		out: "a",
54*333d2b36SAndroid Build Coastguard Worker	},
55*333d2b36SAndroid Build Coastguard Worker	{
56*333d2b36SAndroid Build Coastguard Worker		in:  []string{"a/b"},
57*333d2b36SAndroid Build Coastguard Worker		out: "a/b",
58*333d2b36SAndroid Build Coastguard Worker	},
59*333d2b36SAndroid Build Coastguard Worker	{
60*333d2b36SAndroid Build Coastguard Worker		in:  []string{"a/b", "c"},
61*333d2b36SAndroid Build Coastguard Worker		out: "a/b/c",
62*333d2b36SAndroid Build Coastguard Worker	},
63*333d2b36SAndroid Build Coastguard Worker	{
64*333d2b36SAndroid Build Coastguard Worker		in:  []string{"a/.."},
65*333d2b36SAndroid Build Coastguard Worker		out: ".",
66*333d2b36SAndroid Build Coastguard Worker	},
67*333d2b36SAndroid Build Coastguard Worker	{
68*333d2b36SAndroid Build Coastguard Worker		in:  []string{"."},
69*333d2b36SAndroid Build Coastguard Worker		out: ".",
70*333d2b36SAndroid Build Coastguard Worker	},
71*333d2b36SAndroid Build Coastguard Worker	{
72*333d2b36SAndroid Build Coastguard Worker		in:  []string{".."},
73*333d2b36SAndroid Build Coastguard Worker		out: "",
74*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path is outside directory: ..")},
75*333d2b36SAndroid Build Coastguard Worker	},
76*333d2b36SAndroid Build Coastguard Worker	{
77*333d2b36SAndroid Build Coastguard Worker		in:  []string{"../a"},
78*333d2b36SAndroid Build Coastguard Worker		out: "",
79*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path is outside directory: ../a")},
80*333d2b36SAndroid Build Coastguard Worker	},
81*333d2b36SAndroid Build Coastguard Worker	{
82*333d2b36SAndroid Build Coastguard Worker		in:  []string{"b/../../a"},
83*333d2b36SAndroid Build Coastguard Worker		out: "",
84*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path is outside directory: ../a")},
85*333d2b36SAndroid Build Coastguard Worker	},
86*333d2b36SAndroid Build Coastguard Worker	{
87*333d2b36SAndroid Build Coastguard Worker		in:  []string{"/a"},
88*333d2b36SAndroid Build Coastguard Worker		out: "",
89*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path is outside directory: /a")},
90*333d2b36SAndroid Build Coastguard Worker	},
91*333d2b36SAndroid Build Coastguard Worker	{
92*333d2b36SAndroid Build Coastguard Worker		in:  []string{"a", "../b"},
93*333d2b36SAndroid Build Coastguard Worker		out: "",
94*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path is outside directory: ../b")},
95*333d2b36SAndroid Build Coastguard Worker	},
96*333d2b36SAndroid Build Coastguard Worker	{
97*333d2b36SAndroid Build Coastguard Worker		in:  []string{"a", "b/../../c"},
98*333d2b36SAndroid Build Coastguard Worker		out: "",
99*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path is outside directory: ../c")},
100*333d2b36SAndroid Build Coastguard Worker	},
101*333d2b36SAndroid Build Coastguard Worker	{
102*333d2b36SAndroid Build Coastguard Worker		in:  []string{"a", "./.."},
103*333d2b36SAndroid Build Coastguard Worker		out: "",
104*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path is outside directory: ..")},
105*333d2b36SAndroid Build Coastguard Worker	},
106*333d2b36SAndroid Build Coastguard Worker}
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Workervar validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
109*333d2b36SAndroid Build Coastguard Worker	{
110*333d2b36SAndroid Build Coastguard Worker		in:  []string{"$host/../$a"},
111*333d2b36SAndroid Build Coastguard Worker		out: "$a",
112*333d2b36SAndroid Build Coastguard Worker	},
113*333d2b36SAndroid Build Coastguard Worker}...)
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Workervar validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
116*333d2b36SAndroid Build Coastguard Worker	{
117*333d2b36SAndroid Build Coastguard Worker		in:  []string{"$host/../$a"},
118*333d2b36SAndroid Build Coastguard Worker		out: "",
119*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path contains invalid character($): $host/../$a")},
120*333d2b36SAndroid Build Coastguard Worker	},
121*333d2b36SAndroid Build Coastguard Worker	{
122*333d2b36SAndroid Build Coastguard Worker		in:  []string{"$host/.."},
123*333d2b36SAndroid Build Coastguard Worker		out: "",
124*333d2b36SAndroid Build Coastguard Worker		err: []error{errors.New("Path contains invalid character($): $host/..")},
125*333d2b36SAndroid Build Coastguard Worker	},
126*333d2b36SAndroid Build Coastguard Worker}...)
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Workerfunc TestValidateSafePath(t *testing.T) {
129*333d2b36SAndroid Build Coastguard Worker	for _, testCase := range validateSafePathTestCases {
130*333d2b36SAndroid Build Coastguard Worker		t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
131*333d2b36SAndroid Build Coastguard Worker			ctx := &configErrorWrapper{}
132*333d2b36SAndroid Build Coastguard Worker			out, err := validateSafePath(testCase.in...)
133*333d2b36SAndroid Build Coastguard Worker			if err != nil {
134*333d2b36SAndroid Build Coastguard Worker				reportPathError(ctx, err)
135*333d2b36SAndroid Build Coastguard Worker			}
136*333d2b36SAndroid Build Coastguard Worker			check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
137*333d2b36SAndroid Build Coastguard Worker		})
138*333d2b36SAndroid Build Coastguard Worker	}
139*333d2b36SAndroid Build Coastguard Worker}
140*333d2b36SAndroid Build Coastguard Worker
141*333d2b36SAndroid Build Coastguard Workerfunc TestValidatePath(t *testing.T) {
142*333d2b36SAndroid Build Coastguard Worker	for _, testCase := range validatePathTestCases {
143*333d2b36SAndroid Build Coastguard Worker		t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
144*333d2b36SAndroid Build Coastguard Worker			ctx := &configErrorWrapper{}
145*333d2b36SAndroid Build Coastguard Worker			out, err := validatePath(testCase.in...)
146*333d2b36SAndroid Build Coastguard Worker			if err != nil {
147*333d2b36SAndroid Build Coastguard Worker				reportPathError(ctx, err)
148*333d2b36SAndroid Build Coastguard Worker			}
149*333d2b36SAndroid Build Coastguard Worker			check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
150*333d2b36SAndroid Build Coastguard Worker		})
151*333d2b36SAndroid Build Coastguard Worker	}
152*333d2b36SAndroid Build Coastguard Worker}
153*333d2b36SAndroid Build Coastguard Worker
154*333d2b36SAndroid Build Coastguard Workerfunc TestOptionalPath(t *testing.T) {
155*333d2b36SAndroid Build Coastguard Worker	var path OptionalPath
156*333d2b36SAndroid Build Coastguard Worker	checkInvalidOptionalPath(t, path, "unknown")
157*333d2b36SAndroid Build Coastguard Worker
158*333d2b36SAndroid Build Coastguard Worker	path = OptionalPathForPath(nil)
159*333d2b36SAndroid Build Coastguard Worker	checkInvalidOptionalPath(t, path, "unknown")
160*333d2b36SAndroid Build Coastguard Worker
161*333d2b36SAndroid Build Coastguard Worker	path = InvalidOptionalPath("foo")
162*333d2b36SAndroid Build Coastguard Worker	checkInvalidOptionalPath(t, path, "foo")
163*333d2b36SAndroid Build Coastguard Worker
164*333d2b36SAndroid Build Coastguard Worker	path = InvalidOptionalPath("")
165*333d2b36SAndroid Build Coastguard Worker	checkInvalidOptionalPath(t, path, "unknown")
166*333d2b36SAndroid Build Coastguard Worker
167*333d2b36SAndroid Build Coastguard Worker	path = OptionalPathForPath(PathForTesting("path"))
168*333d2b36SAndroid Build Coastguard Worker	checkValidOptionalPath(t, path, "path")
169*333d2b36SAndroid Build Coastguard Worker}
170*333d2b36SAndroid Build Coastguard Worker
171*333d2b36SAndroid Build Coastguard Workerfunc checkInvalidOptionalPath(t *testing.T, path OptionalPath, expectedInvalidReason string) {
172*333d2b36SAndroid Build Coastguard Worker	t.Helper()
173*333d2b36SAndroid Build Coastguard Worker	if path.Valid() {
174*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Invalid OptionalPath should not be valid")
175*333d2b36SAndroid Build Coastguard Worker	}
176*333d2b36SAndroid Build Coastguard Worker	if path.InvalidReason() != expectedInvalidReason {
177*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Wrong invalid reason: expected %q, got %q", expectedInvalidReason, path.InvalidReason())
178*333d2b36SAndroid Build Coastguard Worker	}
179*333d2b36SAndroid Build Coastguard Worker	if path.String() != "" {
180*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Invalid OptionalPath String() should return \"\", not %q", path.String())
181*333d2b36SAndroid Build Coastguard Worker	}
182*333d2b36SAndroid Build Coastguard Worker	paths := path.AsPaths()
183*333d2b36SAndroid Build Coastguard Worker	if len(paths) != 0 {
184*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Invalid OptionalPath AsPaths() should return empty Paths, not %q", paths)
185*333d2b36SAndroid Build Coastguard Worker	}
186*333d2b36SAndroid Build Coastguard Worker	defer func() {
187*333d2b36SAndroid Build Coastguard Worker		if r := recover(); r == nil {
188*333d2b36SAndroid Build Coastguard Worker			t.Errorf("Expected a panic when calling Path() on an uninitialized OptionalPath")
189*333d2b36SAndroid Build Coastguard Worker		}
190*333d2b36SAndroid Build Coastguard Worker	}()
191*333d2b36SAndroid Build Coastguard Worker	path.Path()
192*333d2b36SAndroid Build Coastguard Worker}
193*333d2b36SAndroid Build Coastguard Worker
194*333d2b36SAndroid Build Coastguard Workerfunc checkValidOptionalPath(t *testing.T, path OptionalPath, expectedString string) {
195*333d2b36SAndroid Build Coastguard Worker	t.Helper()
196*333d2b36SAndroid Build Coastguard Worker	if !path.Valid() {
197*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Initialized OptionalPath should not be invalid")
198*333d2b36SAndroid Build Coastguard Worker	}
199*333d2b36SAndroid Build Coastguard Worker	if path.InvalidReason() != "" {
200*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Initialized OptionalPath should not have an invalid reason, got: %q", path.InvalidReason())
201*333d2b36SAndroid Build Coastguard Worker	}
202*333d2b36SAndroid Build Coastguard Worker	if path.String() != expectedString {
203*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Initialized OptionalPath String() should return %q, not %q", expectedString, path.String())
204*333d2b36SAndroid Build Coastguard Worker	}
205*333d2b36SAndroid Build Coastguard Worker	paths := path.AsPaths()
206*333d2b36SAndroid Build Coastguard Worker	if len(paths) != 1 {
207*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Initialized OptionalPath AsPaths() should return Paths with length 1, not %q", paths)
208*333d2b36SAndroid Build Coastguard Worker	}
209*333d2b36SAndroid Build Coastguard Worker	path.Path()
210*333d2b36SAndroid Build Coastguard Worker}
211*333d2b36SAndroid Build Coastguard Worker
212*333d2b36SAndroid Build Coastguard Workerfunc check(t *testing.T, testType, testString string,
213*333d2b36SAndroid Build Coastguard Worker	got interface{}, err []error,
214*333d2b36SAndroid Build Coastguard Worker	expected interface{}, expectedErr []error) {
215*333d2b36SAndroid Build Coastguard Worker	t.Helper()
216*333d2b36SAndroid Build Coastguard Worker
217*333d2b36SAndroid Build Coastguard Worker	printedTestCase := false
218*333d2b36SAndroid Build Coastguard Worker	e := func(s string, expected, got interface{}) {
219*333d2b36SAndroid Build Coastguard Worker		t.Helper()
220*333d2b36SAndroid Build Coastguard Worker		if !printedTestCase {
221*333d2b36SAndroid Build Coastguard Worker			t.Errorf("test case %s: %s", testType, testString)
222*333d2b36SAndroid Build Coastguard Worker			printedTestCase = true
223*333d2b36SAndroid Build Coastguard Worker		}
224*333d2b36SAndroid Build Coastguard Worker		t.Errorf("incorrect %s", s)
225*333d2b36SAndroid Build Coastguard Worker		t.Errorf("  expected: %s", p(expected))
226*333d2b36SAndroid Build Coastguard Worker		t.Errorf("       got: %s", p(got))
227*333d2b36SAndroid Build Coastguard Worker	}
228*333d2b36SAndroid Build Coastguard Worker
229*333d2b36SAndroid Build Coastguard Worker	if !reflect.DeepEqual(expectedErr, err) {
230*333d2b36SAndroid Build Coastguard Worker		e("errors:", expectedErr, err)
231*333d2b36SAndroid Build Coastguard Worker	}
232*333d2b36SAndroid Build Coastguard Worker
233*333d2b36SAndroid Build Coastguard Worker	if !reflect.DeepEqual(expected, got) {
234*333d2b36SAndroid Build Coastguard Worker		e("output:", expected, got)
235*333d2b36SAndroid Build Coastguard Worker	}
236*333d2b36SAndroid Build Coastguard Worker}
237*333d2b36SAndroid Build Coastguard Worker
238*333d2b36SAndroid Build Coastguard Workerfunc p(in interface{}) string {
239*333d2b36SAndroid Build Coastguard Worker	if v, ok := in.([]interface{}); ok {
240*333d2b36SAndroid Build Coastguard Worker		s := make([]string, len(v))
241*333d2b36SAndroid Build Coastguard Worker		for i := range v {
242*333d2b36SAndroid Build Coastguard Worker			s[i] = fmt.Sprintf("%#v", v[i])
243*333d2b36SAndroid Build Coastguard Worker		}
244*333d2b36SAndroid Build Coastguard Worker		return "[" + strings.Join(s, ", ") + "]"
245*333d2b36SAndroid Build Coastguard Worker	} else {
246*333d2b36SAndroid Build Coastguard Worker		return fmt.Sprintf("%#v", in)
247*333d2b36SAndroid Build Coastguard Worker	}
248*333d2b36SAndroid Build Coastguard Worker}
249*333d2b36SAndroid Build Coastguard Worker
250*333d2b36SAndroid Build Coastguard Workerfunc pathTestConfig(buildDir string) Config {
251*333d2b36SAndroid Build Coastguard Worker	return TestConfig(buildDir, nil, "", nil)
252*333d2b36SAndroid Build Coastguard Worker}
253*333d2b36SAndroid Build Coastguard Worker
254*333d2b36SAndroid Build Coastguard Workerfunc TestPathForModuleInstall(t *testing.T) {
255*333d2b36SAndroid Build Coastguard Worker	testConfig := pathTestConfig("")
256*333d2b36SAndroid Build Coastguard Worker
257*333d2b36SAndroid Build Coastguard Worker	hostTarget := Target{Os: Linux, Arch: Arch{ArchType: X86}}
258*333d2b36SAndroid Build Coastguard Worker	deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
259*333d2b36SAndroid Build Coastguard Worker
260*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
261*333d2b36SAndroid Build Coastguard Worker		name         string
262*333d2b36SAndroid Build Coastguard Worker		ctx          *testModuleInstallPathContext
263*333d2b36SAndroid Build Coastguard Worker		in           []string
264*333d2b36SAndroid Build Coastguard Worker		out          string
265*333d2b36SAndroid Build Coastguard Worker		partitionDir string
266*333d2b36SAndroid Build Coastguard Worker	}{
267*333d2b36SAndroid Build Coastguard Worker		{
268*333d2b36SAndroid Build Coastguard Worker			name: "host binary",
269*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
270*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
271*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
272*333d2b36SAndroid Build Coastguard Worker						os:     hostTarget.Os,
273*333d2b36SAndroid Build Coastguard Worker						target: hostTarget,
274*333d2b36SAndroid Build Coastguard Worker					},
275*333d2b36SAndroid Build Coastguard Worker				},
276*333d2b36SAndroid Build Coastguard Worker			},
277*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
278*333d2b36SAndroid Build Coastguard Worker			out:          "host/linux-x86/bin/my_test",
279*333d2b36SAndroid Build Coastguard Worker			partitionDir: "host/linux-x86",
280*333d2b36SAndroid Build Coastguard Worker		},
281*333d2b36SAndroid Build Coastguard Worker
282*333d2b36SAndroid Build Coastguard Worker		{
283*333d2b36SAndroid Build Coastguard Worker			name: "system binary",
284*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
285*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
286*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
287*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
288*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
289*333d2b36SAndroid Build Coastguard Worker					},
290*333d2b36SAndroid Build Coastguard Worker				},
291*333d2b36SAndroid Build Coastguard Worker			},
292*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
293*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/system/bin/my_test",
294*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/system",
295*333d2b36SAndroid Build Coastguard Worker		},
296*333d2b36SAndroid Build Coastguard Worker		{
297*333d2b36SAndroid Build Coastguard Worker			name: "vendor binary",
298*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
299*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
300*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
301*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
302*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
303*333d2b36SAndroid Build Coastguard Worker					},
304*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
305*333d2b36SAndroid Build Coastguard Worker						kind: socSpecificModule,
306*333d2b36SAndroid Build Coastguard Worker					},
307*333d2b36SAndroid Build Coastguard Worker				},
308*333d2b36SAndroid Build Coastguard Worker			},
309*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
310*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/vendor/bin/my_test",
311*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/vendor",
312*333d2b36SAndroid Build Coastguard Worker		},
313*333d2b36SAndroid Build Coastguard Worker		{
314*333d2b36SAndroid Build Coastguard Worker			name: "odm binary",
315*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
316*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
317*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
318*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
319*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
320*333d2b36SAndroid Build Coastguard Worker					},
321*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
322*333d2b36SAndroid Build Coastguard Worker						kind: deviceSpecificModule,
323*333d2b36SAndroid Build Coastguard Worker					},
324*333d2b36SAndroid Build Coastguard Worker				},
325*333d2b36SAndroid Build Coastguard Worker			},
326*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
327*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/odm/bin/my_test",
328*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/odm",
329*333d2b36SAndroid Build Coastguard Worker		},
330*333d2b36SAndroid Build Coastguard Worker		{
331*333d2b36SAndroid Build Coastguard Worker			name: "product binary",
332*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
333*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
334*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
335*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
336*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
337*333d2b36SAndroid Build Coastguard Worker					},
338*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
339*333d2b36SAndroid Build Coastguard Worker						kind: productSpecificModule,
340*333d2b36SAndroid Build Coastguard Worker					},
341*333d2b36SAndroid Build Coastguard Worker				},
342*333d2b36SAndroid Build Coastguard Worker			},
343*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
344*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/product/bin/my_test",
345*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/product",
346*333d2b36SAndroid Build Coastguard Worker		},
347*333d2b36SAndroid Build Coastguard Worker		{
348*333d2b36SAndroid Build Coastguard Worker			name: "system_ext binary",
349*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
350*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
351*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
352*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
353*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
354*333d2b36SAndroid Build Coastguard Worker					},
355*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
356*333d2b36SAndroid Build Coastguard Worker						kind: systemExtSpecificModule,
357*333d2b36SAndroid Build Coastguard Worker					},
358*333d2b36SAndroid Build Coastguard Worker				},
359*333d2b36SAndroid Build Coastguard Worker			},
360*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
361*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/system_ext/bin/my_test",
362*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/system_ext",
363*333d2b36SAndroid Build Coastguard Worker		},
364*333d2b36SAndroid Build Coastguard Worker		{
365*333d2b36SAndroid Build Coastguard Worker			name: "root binary",
366*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
367*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
368*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
369*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
370*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
371*333d2b36SAndroid Build Coastguard Worker					},
372*333d2b36SAndroid Build Coastguard Worker				},
373*333d2b36SAndroid Build Coastguard Worker				inRoot: true,
374*333d2b36SAndroid Build Coastguard Worker			},
375*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
376*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/root/my_test",
377*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/root",
378*333d2b36SAndroid Build Coastguard Worker		},
379*333d2b36SAndroid Build Coastguard Worker		{
380*333d2b36SAndroid Build Coastguard Worker			name: "recovery binary",
381*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
382*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
383*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
384*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
385*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
386*333d2b36SAndroid Build Coastguard Worker					},
387*333d2b36SAndroid Build Coastguard Worker				},
388*333d2b36SAndroid Build Coastguard Worker				inRecovery: true,
389*333d2b36SAndroid Build Coastguard Worker			},
390*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin/my_test"},
391*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/recovery/root/system/bin/my_test",
392*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/recovery/root/system",
393*333d2b36SAndroid Build Coastguard Worker		},
394*333d2b36SAndroid Build Coastguard Worker		{
395*333d2b36SAndroid Build Coastguard Worker			name: "recovery root binary",
396*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
397*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
398*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
399*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
400*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
401*333d2b36SAndroid Build Coastguard Worker					},
402*333d2b36SAndroid Build Coastguard Worker				},
403*333d2b36SAndroid Build Coastguard Worker				inRecovery: true,
404*333d2b36SAndroid Build Coastguard Worker				inRoot:     true,
405*333d2b36SAndroid Build Coastguard Worker			},
406*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
407*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/recovery/root/my_test",
408*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/recovery/root",
409*333d2b36SAndroid Build Coastguard Worker		},
410*333d2b36SAndroid Build Coastguard Worker
411*333d2b36SAndroid Build Coastguard Worker		{
412*333d2b36SAndroid Build Coastguard Worker			name: "ramdisk binary",
413*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
414*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
415*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
416*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
417*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
418*333d2b36SAndroid Build Coastguard Worker					},
419*333d2b36SAndroid Build Coastguard Worker				},
420*333d2b36SAndroid Build Coastguard Worker				inRamdisk: true,
421*333d2b36SAndroid Build Coastguard Worker			},
422*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
423*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/ramdisk/system/my_test",
424*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/ramdisk/system",
425*333d2b36SAndroid Build Coastguard Worker		},
426*333d2b36SAndroid Build Coastguard Worker		{
427*333d2b36SAndroid Build Coastguard Worker			name: "ramdisk root binary",
428*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
429*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
430*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
431*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
432*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
433*333d2b36SAndroid Build Coastguard Worker					},
434*333d2b36SAndroid Build Coastguard Worker				},
435*333d2b36SAndroid Build Coastguard Worker				inRamdisk: true,
436*333d2b36SAndroid Build Coastguard Worker				inRoot:    true,
437*333d2b36SAndroid Build Coastguard Worker			},
438*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
439*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/ramdisk/my_test",
440*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/ramdisk",
441*333d2b36SAndroid Build Coastguard Worker		},
442*333d2b36SAndroid Build Coastguard Worker		{
443*333d2b36SAndroid Build Coastguard Worker			name: "vendor_ramdisk binary",
444*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
445*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
446*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
447*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
448*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
449*333d2b36SAndroid Build Coastguard Worker					},
450*333d2b36SAndroid Build Coastguard Worker				},
451*333d2b36SAndroid Build Coastguard Worker				inVendorRamdisk: true,
452*333d2b36SAndroid Build Coastguard Worker			},
453*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
454*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/vendor_ramdisk/system/my_test",
455*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/vendor_ramdisk/system",
456*333d2b36SAndroid Build Coastguard Worker		},
457*333d2b36SAndroid Build Coastguard Worker		{
458*333d2b36SAndroid Build Coastguard Worker			name: "vendor_ramdisk root binary",
459*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
460*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
461*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
462*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
463*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
464*333d2b36SAndroid Build Coastguard Worker					},
465*333d2b36SAndroid Build Coastguard Worker				},
466*333d2b36SAndroid Build Coastguard Worker				inVendorRamdisk: true,
467*333d2b36SAndroid Build Coastguard Worker				inRoot:          true,
468*333d2b36SAndroid Build Coastguard Worker			},
469*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
470*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/vendor_ramdisk/my_test",
471*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/vendor_ramdisk",
472*333d2b36SAndroid Build Coastguard Worker		},
473*333d2b36SAndroid Build Coastguard Worker		{
474*333d2b36SAndroid Build Coastguard Worker			name: "debug_ramdisk binary",
475*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
476*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
477*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
478*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
479*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
480*333d2b36SAndroid Build Coastguard Worker					},
481*333d2b36SAndroid Build Coastguard Worker				},
482*333d2b36SAndroid Build Coastguard Worker				inDebugRamdisk: true,
483*333d2b36SAndroid Build Coastguard Worker			},
484*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
485*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/debug_ramdisk/my_test",
486*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/debug_ramdisk",
487*333d2b36SAndroid Build Coastguard Worker		},
488*333d2b36SAndroid Build Coastguard Worker		{
489*333d2b36SAndroid Build Coastguard Worker			name: "system native test binary",
490*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
491*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
492*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
493*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
494*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
495*333d2b36SAndroid Build Coastguard Worker					},
496*333d2b36SAndroid Build Coastguard Worker				},
497*333d2b36SAndroid Build Coastguard Worker				inData: true,
498*333d2b36SAndroid Build Coastguard Worker			},
499*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
500*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/nativetest/my_test",
501*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data",
502*333d2b36SAndroid Build Coastguard Worker		},
503*333d2b36SAndroid Build Coastguard Worker		{
504*333d2b36SAndroid Build Coastguard Worker			name: "vendor native test binary",
505*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
506*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
507*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
508*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
509*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
510*333d2b36SAndroid Build Coastguard Worker					},
511*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
512*333d2b36SAndroid Build Coastguard Worker						kind: socSpecificModule,
513*333d2b36SAndroid Build Coastguard Worker					},
514*333d2b36SAndroid Build Coastguard Worker				},
515*333d2b36SAndroid Build Coastguard Worker				inData: true,
516*333d2b36SAndroid Build Coastguard Worker			},
517*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
518*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/nativetest/my_test",
519*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data",
520*333d2b36SAndroid Build Coastguard Worker		},
521*333d2b36SAndroid Build Coastguard Worker		{
522*333d2b36SAndroid Build Coastguard Worker			name: "odm native test binary",
523*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
524*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
525*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
526*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
527*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
528*333d2b36SAndroid Build Coastguard Worker					},
529*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
530*333d2b36SAndroid Build Coastguard Worker						kind: deviceSpecificModule,
531*333d2b36SAndroid Build Coastguard Worker					},
532*333d2b36SAndroid Build Coastguard Worker				},
533*333d2b36SAndroid Build Coastguard Worker				inData: true,
534*333d2b36SAndroid Build Coastguard Worker			},
535*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
536*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/nativetest/my_test",
537*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data",
538*333d2b36SAndroid Build Coastguard Worker		},
539*333d2b36SAndroid Build Coastguard Worker		{
540*333d2b36SAndroid Build Coastguard Worker			name: "product native test binary",
541*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
542*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
543*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
544*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
545*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
546*333d2b36SAndroid Build Coastguard Worker					},
547*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
548*333d2b36SAndroid Build Coastguard Worker						kind: productSpecificModule,
549*333d2b36SAndroid Build Coastguard Worker					},
550*333d2b36SAndroid Build Coastguard Worker				},
551*333d2b36SAndroid Build Coastguard Worker				inData: true,
552*333d2b36SAndroid Build Coastguard Worker			},
553*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
554*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/nativetest/my_test",
555*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data",
556*333d2b36SAndroid Build Coastguard Worker		},
557*333d2b36SAndroid Build Coastguard Worker
558*333d2b36SAndroid Build Coastguard Worker		{
559*333d2b36SAndroid Build Coastguard Worker			name: "system_ext native test binary",
560*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
561*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
562*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
563*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
564*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
565*333d2b36SAndroid Build Coastguard Worker					},
566*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
567*333d2b36SAndroid Build Coastguard Worker						kind: systemExtSpecificModule,
568*333d2b36SAndroid Build Coastguard Worker					},
569*333d2b36SAndroid Build Coastguard Worker				},
570*333d2b36SAndroid Build Coastguard Worker				inData: true,
571*333d2b36SAndroid Build Coastguard Worker			},
572*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
573*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/nativetest/my_test",
574*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data",
575*333d2b36SAndroid Build Coastguard Worker		},
576*333d2b36SAndroid Build Coastguard Worker
577*333d2b36SAndroid Build Coastguard Worker		{
578*333d2b36SAndroid Build Coastguard Worker			name: "sanitized system binary",
579*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
580*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
581*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
582*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
583*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
584*333d2b36SAndroid Build Coastguard Worker					},
585*333d2b36SAndroid Build Coastguard Worker				},
586*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
587*333d2b36SAndroid Build Coastguard Worker			},
588*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
589*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/system/bin/my_test",
590*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/system",
591*333d2b36SAndroid Build Coastguard Worker		},
592*333d2b36SAndroid Build Coastguard Worker		{
593*333d2b36SAndroid Build Coastguard Worker			name: "sanitized vendor binary",
594*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
595*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
596*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
597*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
598*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
599*333d2b36SAndroid Build Coastguard Worker					},
600*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
601*333d2b36SAndroid Build Coastguard Worker						kind: socSpecificModule,
602*333d2b36SAndroid Build Coastguard Worker					},
603*333d2b36SAndroid Build Coastguard Worker				},
604*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
605*333d2b36SAndroid Build Coastguard Worker			},
606*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
607*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/vendor/bin/my_test",
608*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/vendor",
609*333d2b36SAndroid Build Coastguard Worker		},
610*333d2b36SAndroid Build Coastguard Worker		{
611*333d2b36SAndroid Build Coastguard Worker			name: "sanitized odm binary",
612*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
613*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
614*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
615*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
616*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
617*333d2b36SAndroid Build Coastguard Worker					},
618*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
619*333d2b36SAndroid Build Coastguard Worker						kind: deviceSpecificModule,
620*333d2b36SAndroid Build Coastguard Worker					},
621*333d2b36SAndroid Build Coastguard Worker				},
622*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
623*333d2b36SAndroid Build Coastguard Worker			},
624*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
625*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/odm/bin/my_test",
626*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/odm",
627*333d2b36SAndroid Build Coastguard Worker		},
628*333d2b36SAndroid Build Coastguard Worker		{
629*333d2b36SAndroid Build Coastguard Worker			name: "sanitized product binary",
630*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
631*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
632*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
633*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
634*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
635*333d2b36SAndroid Build Coastguard Worker					},
636*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
637*333d2b36SAndroid Build Coastguard Worker						kind: productSpecificModule,
638*333d2b36SAndroid Build Coastguard Worker					},
639*333d2b36SAndroid Build Coastguard Worker				},
640*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
641*333d2b36SAndroid Build Coastguard Worker			},
642*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
643*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/product/bin/my_test",
644*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/product",
645*333d2b36SAndroid Build Coastguard Worker		},
646*333d2b36SAndroid Build Coastguard Worker
647*333d2b36SAndroid Build Coastguard Worker		{
648*333d2b36SAndroid Build Coastguard Worker			name: "sanitized system_ext binary",
649*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
650*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
651*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
652*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
653*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
654*333d2b36SAndroid Build Coastguard Worker					},
655*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
656*333d2b36SAndroid Build Coastguard Worker						kind: systemExtSpecificModule,
657*333d2b36SAndroid Build Coastguard Worker					},
658*333d2b36SAndroid Build Coastguard Worker				},
659*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
660*333d2b36SAndroid Build Coastguard Worker			},
661*333d2b36SAndroid Build Coastguard Worker			in:           []string{"bin", "my_test"},
662*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/system_ext/bin/my_test",
663*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/system_ext",
664*333d2b36SAndroid Build Coastguard Worker		},
665*333d2b36SAndroid Build Coastguard Worker
666*333d2b36SAndroid Build Coastguard Worker		{
667*333d2b36SAndroid Build Coastguard Worker			name: "sanitized system native test binary",
668*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
669*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
670*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
671*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
672*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
673*333d2b36SAndroid Build Coastguard Worker					},
674*333d2b36SAndroid Build Coastguard Worker				},
675*333d2b36SAndroid Build Coastguard Worker				inData:         true,
676*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
677*333d2b36SAndroid Build Coastguard Worker			},
678*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
679*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/data/nativetest/my_test",
680*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/data",
681*333d2b36SAndroid Build Coastguard Worker		},
682*333d2b36SAndroid Build Coastguard Worker		{
683*333d2b36SAndroid Build Coastguard Worker			name: "sanitized vendor native test binary",
684*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
685*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
686*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
687*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
688*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
689*333d2b36SAndroid Build Coastguard Worker					},
690*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
691*333d2b36SAndroid Build Coastguard Worker						kind: socSpecificModule,
692*333d2b36SAndroid Build Coastguard Worker					},
693*333d2b36SAndroid Build Coastguard Worker				},
694*333d2b36SAndroid Build Coastguard Worker				inData:         true,
695*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
696*333d2b36SAndroid Build Coastguard Worker			},
697*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
698*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/data/nativetest/my_test",
699*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/data",
700*333d2b36SAndroid Build Coastguard Worker		},
701*333d2b36SAndroid Build Coastguard Worker		{
702*333d2b36SAndroid Build Coastguard Worker			name: "sanitized odm native test binary",
703*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
704*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
705*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
706*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
707*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
708*333d2b36SAndroid Build Coastguard Worker					},
709*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
710*333d2b36SAndroid Build Coastguard Worker						kind: deviceSpecificModule,
711*333d2b36SAndroid Build Coastguard Worker					},
712*333d2b36SAndroid Build Coastguard Worker				},
713*333d2b36SAndroid Build Coastguard Worker				inData:         true,
714*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
715*333d2b36SAndroid Build Coastguard Worker			},
716*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
717*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/data/nativetest/my_test",
718*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/data",
719*333d2b36SAndroid Build Coastguard Worker		},
720*333d2b36SAndroid Build Coastguard Worker		{
721*333d2b36SAndroid Build Coastguard Worker			name: "sanitized product native test binary",
722*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
723*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
724*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
725*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
726*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
727*333d2b36SAndroid Build Coastguard Worker					},
728*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
729*333d2b36SAndroid Build Coastguard Worker						kind: productSpecificModule,
730*333d2b36SAndroid Build Coastguard Worker					},
731*333d2b36SAndroid Build Coastguard Worker				},
732*333d2b36SAndroid Build Coastguard Worker				inData:         true,
733*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
734*333d2b36SAndroid Build Coastguard Worker			},
735*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
736*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/data/nativetest/my_test",
737*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/data",
738*333d2b36SAndroid Build Coastguard Worker		},
739*333d2b36SAndroid Build Coastguard Worker		{
740*333d2b36SAndroid Build Coastguard Worker			name: "sanitized system_ext native test binary",
741*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
742*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
743*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
744*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
745*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
746*333d2b36SAndroid Build Coastguard Worker					},
747*333d2b36SAndroid Build Coastguard Worker					earlyModuleContext: earlyModuleContext{
748*333d2b36SAndroid Build Coastguard Worker						kind: systemExtSpecificModule,
749*333d2b36SAndroid Build Coastguard Worker					},
750*333d2b36SAndroid Build Coastguard Worker				},
751*333d2b36SAndroid Build Coastguard Worker				inData:         true,
752*333d2b36SAndroid Build Coastguard Worker				inSanitizerDir: true,
753*333d2b36SAndroid Build Coastguard Worker			},
754*333d2b36SAndroid Build Coastguard Worker			in:           []string{"nativetest", "my_test"},
755*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/data/asan/data/nativetest/my_test",
756*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/data/asan/data",
757*333d2b36SAndroid Build Coastguard Worker		}, {
758*333d2b36SAndroid Build Coastguard Worker			name: "device testcases",
759*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
760*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
761*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
762*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
763*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
764*333d2b36SAndroid Build Coastguard Worker					},
765*333d2b36SAndroid Build Coastguard Worker				},
766*333d2b36SAndroid Build Coastguard Worker				inTestcases: true,
767*333d2b36SAndroid Build Coastguard Worker			},
768*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test", "my_test_bin"},
769*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/testcases/my_test/my_test_bin",
770*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/testcases",
771*333d2b36SAndroid Build Coastguard Worker		}, {
772*333d2b36SAndroid Build Coastguard Worker			name: "host testcases",
773*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
774*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
775*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
776*333d2b36SAndroid Build Coastguard Worker						os:     hostTarget.Os,
777*333d2b36SAndroid Build Coastguard Worker						target: hostTarget,
778*333d2b36SAndroid Build Coastguard Worker					},
779*333d2b36SAndroid Build Coastguard Worker				},
780*333d2b36SAndroid Build Coastguard Worker				inTestcases: true,
781*333d2b36SAndroid Build Coastguard Worker			},
782*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test", "my_test_bin"},
783*333d2b36SAndroid Build Coastguard Worker			out:          "host/linux-x86/testcases/my_test/my_test_bin",
784*333d2b36SAndroid Build Coastguard Worker			partitionDir: "host/linux-x86/testcases",
785*333d2b36SAndroid Build Coastguard Worker		}, {
786*333d2b36SAndroid Build Coastguard Worker			name: "forced host testcases",
787*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
788*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
789*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
790*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
791*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
792*333d2b36SAndroid Build Coastguard Worker					},
793*333d2b36SAndroid Build Coastguard Worker				},
794*333d2b36SAndroid Build Coastguard Worker				inTestcases: true,
795*333d2b36SAndroid Build Coastguard Worker				forceOS:     &Linux,
796*333d2b36SAndroid Build Coastguard Worker				forceArch:   &X86,
797*333d2b36SAndroid Build Coastguard Worker			},
798*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test", "my_test_bin"},
799*333d2b36SAndroid Build Coastguard Worker			out:          "host/linux-x86/testcases/my_test/my_test_bin",
800*333d2b36SAndroid Build Coastguard Worker			partitionDir: "host/linux-x86/testcases",
801*333d2b36SAndroid Build Coastguard Worker		},
802*333d2b36SAndroid Build Coastguard Worker	}
803*333d2b36SAndroid Build Coastguard Worker
804*333d2b36SAndroid Build Coastguard Worker	for _, tc := range testCases {
805*333d2b36SAndroid Build Coastguard Worker		t.Run(tc.name, func(t *testing.T) {
806*333d2b36SAndroid Build Coastguard Worker			tc.ctx.baseModuleContext.config = testConfig
807*333d2b36SAndroid Build Coastguard Worker			output := PathForModuleInstall(tc.ctx, tc.in...)
808*333d2b36SAndroid Build Coastguard Worker			if output.basePath.path != tc.out {
809*333d2b36SAndroid Build Coastguard Worker				t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
810*333d2b36SAndroid Build Coastguard Worker					output.basePath.path,
811*333d2b36SAndroid Build Coastguard Worker					tc.out)
812*333d2b36SAndroid Build Coastguard Worker			}
813*333d2b36SAndroid Build Coastguard Worker			if output.partitionDir != tc.partitionDir {
814*333d2b36SAndroid Build Coastguard Worker				t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n",
815*333d2b36SAndroid Build Coastguard Worker					output.partitionDir, tc.partitionDir)
816*333d2b36SAndroid Build Coastguard Worker			}
817*333d2b36SAndroid Build Coastguard Worker		})
818*333d2b36SAndroid Build Coastguard Worker	}
819*333d2b36SAndroid Build Coastguard Worker}
820*333d2b36SAndroid Build Coastguard Worker
821*333d2b36SAndroid Build Coastguard Workerfunc TestPathForModuleInstallRecoveryAsBoot(t *testing.T) {
822*333d2b36SAndroid Build Coastguard Worker	testConfig := pathTestConfig("")
823*333d2b36SAndroid Build Coastguard Worker	testConfig.TestProductVariables.BoardUsesRecoveryAsBoot = proptools.BoolPtr(true)
824*333d2b36SAndroid Build Coastguard Worker	testConfig.TestProductVariables.BoardMoveRecoveryResourcesToVendorBoot = proptools.BoolPtr(true)
825*333d2b36SAndroid Build Coastguard Worker	deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
826*333d2b36SAndroid Build Coastguard Worker
827*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
828*333d2b36SAndroid Build Coastguard Worker		name         string
829*333d2b36SAndroid Build Coastguard Worker		ctx          *testModuleInstallPathContext
830*333d2b36SAndroid Build Coastguard Worker		in           []string
831*333d2b36SAndroid Build Coastguard Worker		out          string
832*333d2b36SAndroid Build Coastguard Worker		partitionDir string
833*333d2b36SAndroid Build Coastguard Worker	}{
834*333d2b36SAndroid Build Coastguard Worker		{
835*333d2b36SAndroid Build Coastguard Worker			name: "ramdisk binary",
836*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
837*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
838*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
839*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
840*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
841*333d2b36SAndroid Build Coastguard Worker					},
842*333d2b36SAndroid Build Coastguard Worker				},
843*333d2b36SAndroid Build Coastguard Worker				inRamdisk: true,
844*333d2b36SAndroid Build Coastguard Worker				inRoot:    true,
845*333d2b36SAndroid Build Coastguard Worker			},
846*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
847*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/recovery/root/first_stage_ramdisk/my_test",
848*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/recovery/root/first_stage_ramdisk",
849*333d2b36SAndroid Build Coastguard Worker		},
850*333d2b36SAndroid Build Coastguard Worker
851*333d2b36SAndroid Build Coastguard Worker		{
852*333d2b36SAndroid Build Coastguard Worker			name: "vendor_ramdisk binary",
853*333d2b36SAndroid Build Coastguard Worker			ctx: &testModuleInstallPathContext{
854*333d2b36SAndroid Build Coastguard Worker				baseModuleContext: baseModuleContext{
855*333d2b36SAndroid Build Coastguard Worker					archModuleContext: archModuleContext{
856*333d2b36SAndroid Build Coastguard Worker						os:     deviceTarget.Os,
857*333d2b36SAndroid Build Coastguard Worker						target: deviceTarget,
858*333d2b36SAndroid Build Coastguard Worker					},
859*333d2b36SAndroid Build Coastguard Worker				},
860*333d2b36SAndroid Build Coastguard Worker				inVendorRamdisk: true,
861*333d2b36SAndroid Build Coastguard Worker				inRoot:          true,
862*333d2b36SAndroid Build Coastguard Worker			},
863*333d2b36SAndroid Build Coastguard Worker			in:           []string{"my_test"},
864*333d2b36SAndroid Build Coastguard Worker			out:          "target/product/test_device/vendor_ramdisk/first_stage_ramdisk/my_test",
865*333d2b36SAndroid Build Coastguard Worker			partitionDir: "target/product/test_device/vendor_ramdisk/first_stage_ramdisk",
866*333d2b36SAndroid Build Coastguard Worker		},
867*333d2b36SAndroid Build Coastguard Worker	}
868*333d2b36SAndroid Build Coastguard Worker
869*333d2b36SAndroid Build Coastguard Worker	for _, tc := range testCases {
870*333d2b36SAndroid Build Coastguard Worker		t.Run(tc.name, func(t *testing.T) {
871*333d2b36SAndroid Build Coastguard Worker			tc.ctx.baseModuleContext.config = testConfig
872*333d2b36SAndroid Build Coastguard Worker			output := PathForModuleInstall(tc.ctx, tc.in...)
873*333d2b36SAndroid Build Coastguard Worker			if output.basePath.path != tc.out {
874*333d2b36SAndroid Build Coastguard Worker				t.Errorf("unexpected path:\n got: %q\nwant: %q\n",
875*333d2b36SAndroid Build Coastguard Worker					output.basePath.path,
876*333d2b36SAndroid Build Coastguard Worker					tc.out)
877*333d2b36SAndroid Build Coastguard Worker			}
878*333d2b36SAndroid Build Coastguard Worker			if output.partitionDir != tc.partitionDir {
879*333d2b36SAndroid Build Coastguard Worker				t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n",
880*333d2b36SAndroid Build Coastguard Worker					output.partitionDir, tc.partitionDir)
881*333d2b36SAndroid Build Coastguard Worker			}
882*333d2b36SAndroid Build Coastguard Worker		})
883*333d2b36SAndroid Build Coastguard Worker	}
884*333d2b36SAndroid Build Coastguard Worker}
885*333d2b36SAndroid Build Coastguard Worker
886*333d2b36SAndroid Build Coastguard Workerfunc TestBaseDirForInstallPath(t *testing.T) {
887*333d2b36SAndroid Build Coastguard Worker	testConfig := pathTestConfig("")
888*333d2b36SAndroid Build Coastguard Worker	deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
889*333d2b36SAndroid Build Coastguard Worker
890*333d2b36SAndroid Build Coastguard Worker	ctx := &testModuleInstallPathContext{
891*333d2b36SAndroid Build Coastguard Worker		baseModuleContext: baseModuleContext{
892*333d2b36SAndroid Build Coastguard Worker			archModuleContext: archModuleContext{
893*333d2b36SAndroid Build Coastguard Worker				os:     deviceTarget.Os,
894*333d2b36SAndroid Build Coastguard Worker				target: deviceTarget,
895*333d2b36SAndroid Build Coastguard Worker			},
896*333d2b36SAndroid Build Coastguard Worker		},
897*333d2b36SAndroid Build Coastguard Worker	}
898*333d2b36SAndroid Build Coastguard Worker	ctx.baseModuleContext.config = testConfig
899*333d2b36SAndroid Build Coastguard Worker
900*333d2b36SAndroid Build Coastguard Worker	actual := PathForModuleInstall(ctx, "foo", "bar")
901*333d2b36SAndroid Build Coastguard Worker	expectedBaseDir := "target/product/test_device/system"
902*333d2b36SAndroid Build Coastguard Worker	if actual.partitionDir != expectedBaseDir {
903*333d2b36SAndroid Build Coastguard Worker		t.Errorf("unexpected partitionDir:\n got: %q\nwant: %q\n", actual.partitionDir, expectedBaseDir)
904*333d2b36SAndroid Build Coastguard Worker	}
905*333d2b36SAndroid Build Coastguard Worker	expectedRelPath := "foo/bar"
906*333d2b36SAndroid Build Coastguard Worker	if actual.Rel() != expectedRelPath {
907*333d2b36SAndroid Build Coastguard Worker		t.Errorf("unexpected Rel():\n got: %q\nwant: %q\n", actual.Rel(), expectedRelPath)
908*333d2b36SAndroid Build Coastguard Worker	}
909*333d2b36SAndroid Build Coastguard Worker
910*333d2b36SAndroid Build Coastguard Worker	actualAfterJoin := actual.Join(ctx, "baz")
911*333d2b36SAndroid Build Coastguard Worker	// partitionDir is preserved even after joining
912*333d2b36SAndroid Build Coastguard Worker	if actualAfterJoin.partitionDir != expectedBaseDir {
913*333d2b36SAndroid Build Coastguard Worker		t.Errorf("unexpected partitionDir after joining:\n got: %q\nwant: %q\n", actualAfterJoin.partitionDir, expectedBaseDir)
914*333d2b36SAndroid Build Coastguard Worker	}
915*333d2b36SAndroid Build Coastguard Worker	// Rel() is updated though
916*333d2b36SAndroid Build Coastguard Worker	expectedRelAfterJoin := "baz"
917*333d2b36SAndroid Build Coastguard Worker	if actualAfterJoin.Rel() != expectedRelAfterJoin {
918*333d2b36SAndroid Build Coastguard Worker		t.Errorf("unexpected Rel() after joining:\n got: %q\nwant: %q\n", actualAfterJoin.Rel(), expectedRelAfterJoin)
919*333d2b36SAndroid Build Coastguard Worker	}
920*333d2b36SAndroid Build Coastguard Worker}
921*333d2b36SAndroid Build Coastguard Worker
922*333d2b36SAndroid Build Coastguard Workerfunc TestDirectorySortedPaths(t *testing.T) {
923*333d2b36SAndroid Build Coastguard Worker	config := TestConfig("out", nil, "", map[string][]byte{
924*333d2b36SAndroid Build Coastguard Worker		"Android.bp": nil,
925*333d2b36SAndroid Build Coastguard Worker		"a.txt":      nil,
926*333d2b36SAndroid Build Coastguard Worker		"a/txt":      nil,
927*333d2b36SAndroid Build Coastguard Worker		"a/b/c":      nil,
928*333d2b36SAndroid Build Coastguard Worker		"a/b/d":      nil,
929*333d2b36SAndroid Build Coastguard Worker		"b":          nil,
930*333d2b36SAndroid Build Coastguard Worker		"b/b.txt":    nil,
931*333d2b36SAndroid Build Coastguard Worker		"a/a.txt":    nil,
932*333d2b36SAndroid Build Coastguard Worker	})
933*333d2b36SAndroid Build Coastguard Worker
934*333d2b36SAndroid Build Coastguard Worker	ctx := PathContextForTesting(config)
935*333d2b36SAndroid Build Coastguard Worker
936*333d2b36SAndroid Build Coastguard Worker	makePaths := func() Paths {
937*333d2b36SAndroid Build Coastguard Worker		return Paths{
938*333d2b36SAndroid Build Coastguard Worker			PathForSource(ctx, "a.txt"),
939*333d2b36SAndroid Build Coastguard Worker			PathForSource(ctx, "a/txt"),
940*333d2b36SAndroid Build Coastguard Worker			PathForSource(ctx, "a/b/c"),
941*333d2b36SAndroid Build Coastguard Worker			PathForSource(ctx, "a/b/d"),
942*333d2b36SAndroid Build Coastguard Worker			PathForSource(ctx, "b"),
943*333d2b36SAndroid Build Coastguard Worker			PathForSource(ctx, "b/b.txt"),
944*333d2b36SAndroid Build Coastguard Worker			PathForSource(ctx, "a/a.txt"),
945*333d2b36SAndroid Build Coastguard Worker		}
946*333d2b36SAndroid Build Coastguard Worker	}
947*333d2b36SAndroid Build Coastguard Worker
948*333d2b36SAndroid Build Coastguard Worker	expected := []string{
949*333d2b36SAndroid Build Coastguard Worker		"a.txt",
950*333d2b36SAndroid Build Coastguard Worker		"a/a.txt",
951*333d2b36SAndroid Build Coastguard Worker		"a/b/c",
952*333d2b36SAndroid Build Coastguard Worker		"a/b/d",
953*333d2b36SAndroid Build Coastguard Worker		"a/txt",
954*333d2b36SAndroid Build Coastguard Worker		"b",
955*333d2b36SAndroid Build Coastguard Worker		"b/b.txt",
956*333d2b36SAndroid Build Coastguard Worker	}
957*333d2b36SAndroid Build Coastguard Worker
958*333d2b36SAndroid Build Coastguard Worker	paths := makePaths()
959*333d2b36SAndroid Build Coastguard Worker	reversePaths := ReversePaths(paths)
960*333d2b36SAndroid Build Coastguard Worker
961*333d2b36SAndroid Build Coastguard Worker	sortedPaths := PathsToDirectorySortedPaths(paths)
962*333d2b36SAndroid Build Coastguard Worker	reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
963*333d2b36SAndroid Build Coastguard Worker
964*333d2b36SAndroid Build Coastguard Worker	if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
965*333d2b36SAndroid Build Coastguard Worker		t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
966*333d2b36SAndroid Build Coastguard Worker	}
967*333d2b36SAndroid Build Coastguard Worker
968*333d2b36SAndroid Build Coastguard Worker	if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
969*333d2b36SAndroid Build Coastguard Worker		t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
970*333d2b36SAndroid Build Coastguard Worker	}
971*333d2b36SAndroid Build Coastguard Worker
972*333d2b36SAndroid Build Coastguard Worker	expectedA := []string{
973*333d2b36SAndroid Build Coastguard Worker		"a/a.txt",
974*333d2b36SAndroid Build Coastguard Worker		"a/b/c",
975*333d2b36SAndroid Build Coastguard Worker		"a/b/d",
976*333d2b36SAndroid Build Coastguard Worker		"a/txt",
977*333d2b36SAndroid Build Coastguard Worker	}
978*333d2b36SAndroid Build Coastguard Worker
979*333d2b36SAndroid Build Coastguard Worker	inA := sortedPaths.PathsInDirectory("a")
980*333d2b36SAndroid Build Coastguard Worker	if !reflect.DeepEqual(inA.Strings(), expectedA) {
981*333d2b36SAndroid Build Coastguard Worker		t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
982*333d2b36SAndroid Build Coastguard Worker	}
983*333d2b36SAndroid Build Coastguard Worker
984*333d2b36SAndroid Build Coastguard Worker	expectedA_B := []string{
985*333d2b36SAndroid Build Coastguard Worker		"a/b/c",
986*333d2b36SAndroid Build Coastguard Worker		"a/b/d",
987*333d2b36SAndroid Build Coastguard Worker	}
988*333d2b36SAndroid Build Coastguard Worker
989*333d2b36SAndroid Build Coastguard Worker	inA_B := sortedPaths.PathsInDirectory("a/b")
990*333d2b36SAndroid Build Coastguard Worker	if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
991*333d2b36SAndroid Build Coastguard Worker		t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
992*333d2b36SAndroid Build Coastguard Worker	}
993*333d2b36SAndroid Build Coastguard Worker
994*333d2b36SAndroid Build Coastguard Worker	expectedB := []string{
995*333d2b36SAndroid Build Coastguard Worker		"b/b.txt",
996*333d2b36SAndroid Build Coastguard Worker	}
997*333d2b36SAndroid Build Coastguard Worker
998*333d2b36SAndroid Build Coastguard Worker	inB := sortedPaths.PathsInDirectory("b")
999*333d2b36SAndroid Build Coastguard Worker	if !reflect.DeepEqual(inB.Strings(), expectedB) {
1000*333d2b36SAndroid Build Coastguard Worker		t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
1001*333d2b36SAndroid Build Coastguard Worker	}
1002*333d2b36SAndroid Build Coastguard Worker}
1003*333d2b36SAndroid Build Coastguard Worker
1004*333d2b36SAndroid Build Coastguard Workerfunc TestMaybeRel(t *testing.T) {
1005*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
1006*333d2b36SAndroid Build Coastguard Worker		name   string
1007*333d2b36SAndroid Build Coastguard Worker		base   string
1008*333d2b36SAndroid Build Coastguard Worker		target string
1009*333d2b36SAndroid Build Coastguard Worker		out    string
1010*333d2b36SAndroid Build Coastguard Worker		isRel  bool
1011*333d2b36SAndroid Build Coastguard Worker	}{
1012*333d2b36SAndroid Build Coastguard Worker		{
1013*333d2b36SAndroid Build Coastguard Worker			name:   "normal",
1014*333d2b36SAndroid Build Coastguard Worker			base:   "a/b/c",
1015*333d2b36SAndroid Build Coastguard Worker			target: "a/b/c/d",
1016*333d2b36SAndroid Build Coastguard Worker			out:    "d",
1017*333d2b36SAndroid Build Coastguard Worker			isRel:  true,
1018*333d2b36SAndroid Build Coastguard Worker		},
1019*333d2b36SAndroid Build Coastguard Worker		{
1020*333d2b36SAndroid Build Coastguard Worker			name:   "parent",
1021*333d2b36SAndroid Build Coastguard Worker			base:   "a/b/c/d",
1022*333d2b36SAndroid Build Coastguard Worker			target: "a/b/c",
1023*333d2b36SAndroid Build Coastguard Worker			isRel:  false,
1024*333d2b36SAndroid Build Coastguard Worker		},
1025*333d2b36SAndroid Build Coastguard Worker		{
1026*333d2b36SAndroid Build Coastguard Worker			name:   "not relative",
1027*333d2b36SAndroid Build Coastguard Worker			base:   "a/b",
1028*333d2b36SAndroid Build Coastguard Worker			target: "c/d",
1029*333d2b36SAndroid Build Coastguard Worker			isRel:  false,
1030*333d2b36SAndroid Build Coastguard Worker		},
1031*333d2b36SAndroid Build Coastguard Worker		{
1032*333d2b36SAndroid Build Coastguard Worker			name:   "abs1",
1033*333d2b36SAndroid Build Coastguard Worker			base:   "/a",
1034*333d2b36SAndroid Build Coastguard Worker			target: "a",
1035*333d2b36SAndroid Build Coastguard Worker			isRel:  false,
1036*333d2b36SAndroid Build Coastguard Worker		},
1037*333d2b36SAndroid Build Coastguard Worker		{
1038*333d2b36SAndroid Build Coastguard Worker			name:   "abs2",
1039*333d2b36SAndroid Build Coastguard Worker			base:   "a",
1040*333d2b36SAndroid Build Coastguard Worker			target: "/a",
1041*333d2b36SAndroid Build Coastguard Worker			isRel:  false,
1042*333d2b36SAndroid Build Coastguard Worker		},
1043*333d2b36SAndroid Build Coastguard Worker	}
1044*333d2b36SAndroid Build Coastguard Worker
1045*333d2b36SAndroid Build Coastguard Worker	for _, testCase := range testCases {
1046*333d2b36SAndroid Build Coastguard Worker		t.Run(testCase.name, func(t *testing.T) {
1047*333d2b36SAndroid Build Coastguard Worker			ctx := &configErrorWrapper{}
1048*333d2b36SAndroid Build Coastguard Worker			out, isRel := MaybeRel(ctx, testCase.base, testCase.target)
1049*333d2b36SAndroid Build Coastguard Worker			if len(ctx.errors) > 0 {
1050*333d2b36SAndroid Build Coastguard Worker				t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v",
1051*333d2b36SAndroid Build Coastguard Worker					testCase.base, testCase.target, ctx.errors)
1052*333d2b36SAndroid Build Coastguard Worker			}
1053*333d2b36SAndroid Build Coastguard Worker			if isRel != testCase.isRel || out != testCase.out {
1054*333d2b36SAndroid Build Coastguard Worker				t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v",
1055*333d2b36SAndroid Build Coastguard Worker					testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel)
1056*333d2b36SAndroid Build Coastguard Worker			}
1057*333d2b36SAndroid Build Coastguard Worker		})
1058*333d2b36SAndroid Build Coastguard Worker	}
1059*333d2b36SAndroid Build Coastguard Worker}
1060*333d2b36SAndroid Build Coastguard Worker
1061*333d2b36SAndroid Build Coastguard Workerfunc TestPathForSource(t *testing.T) {
1062*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
1063*333d2b36SAndroid Build Coastguard Worker		name     string
1064*333d2b36SAndroid Build Coastguard Worker		buildDir string
1065*333d2b36SAndroid Build Coastguard Worker		src      string
1066*333d2b36SAndroid Build Coastguard Worker		err      string
1067*333d2b36SAndroid Build Coastguard Worker	}{
1068*333d2b36SAndroid Build Coastguard Worker		{
1069*333d2b36SAndroid Build Coastguard Worker			name:     "normal",
1070*333d2b36SAndroid Build Coastguard Worker			buildDir: "out",
1071*333d2b36SAndroid Build Coastguard Worker			src:      "a/b/c",
1072*333d2b36SAndroid Build Coastguard Worker		},
1073*333d2b36SAndroid Build Coastguard Worker		{
1074*333d2b36SAndroid Build Coastguard Worker			name:     "abs",
1075*333d2b36SAndroid Build Coastguard Worker			buildDir: "out",
1076*333d2b36SAndroid Build Coastguard Worker			src:      "/a/b/c",
1077*333d2b36SAndroid Build Coastguard Worker			err:      "is outside directory",
1078*333d2b36SAndroid Build Coastguard Worker		},
1079*333d2b36SAndroid Build Coastguard Worker		{
1080*333d2b36SAndroid Build Coastguard Worker			name:     "in out dir",
1081*333d2b36SAndroid Build Coastguard Worker			buildDir: "out",
1082*333d2b36SAndroid Build Coastguard Worker			src:      "out/soong/a/b/c",
1083*333d2b36SAndroid Build Coastguard Worker			err:      "is in output",
1084*333d2b36SAndroid Build Coastguard Worker		},
1085*333d2b36SAndroid Build Coastguard Worker	}
1086*333d2b36SAndroid Build Coastguard Worker
1087*333d2b36SAndroid Build Coastguard Worker	funcs := []struct {
1088*333d2b36SAndroid Build Coastguard Worker		name string
1089*333d2b36SAndroid Build Coastguard Worker		f    func(ctx PathContext, pathComponents ...string) (SourcePath, error)
1090*333d2b36SAndroid Build Coastguard Worker	}{
1091*333d2b36SAndroid Build Coastguard Worker		{"pathForSource", pathForSource},
1092*333d2b36SAndroid Build Coastguard Worker		{"safePathForSource", safePathForSource},
1093*333d2b36SAndroid Build Coastguard Worker	}
1094*333d2b36SAndroid Build Coastguard Worker
1095*333d2b36SAndroid Build Coastguard Worker	for _, f := range funcs {
1096*333d2b36SAndroid Build Coastguard Worker		t.Run(f.name, func(t *testing.T) {
1097*333d2b36SAndroid Build Coastguard Worker			for _, test := range testCases {
1098*333d2b36SAndroid Build Coastguard Worker				t.Run(test.name, func(t *testing.T) {
1099*333d2b36SAndroid Build Coastguard Worker					testConfig := pathTestConfig(test.buildDir)
1100*333d2b36SAndroid Build Coastguard Worker					ctx := &configErrorWrapper{config: testConfig}
1101*333d2b36SAndroid Build Coastguard Worker					_, err := f.f(ctx, test.src)
1102*333d2b36SAndroid Build Coastguard Worker					if len(ctx.errors) > 0 {
1103*333d2b36SAndroid Build Coastguard Worker						t.Fatalf("unexpected errors %v", ctx.errors)
1104*333d2b36SAndroid Build Coastguard Worker					}
1105*333d2b36SAndroid Build Coastguard Worker					if err != nil {
1106*333d2b36SAndroid Build Coastguard Worker						if test.err == "" {
1107*333d2b36SAndroid Build Coastguard Worker							t.Fatalf("unexpected error %q", err.Error())
1108*333d2b36SAndroid Build Coastguard Worker						} else if !strings.Contains(err.Error(), test.err) {
1109*333d2b36SAndroid Build Coastguard Worker							t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
1110*333d2b36SAndroid Build Coastguard Worker						}
1111*333d2b36SAndroid Build Coastguard Worker					} else {
1112*333d2b36SAndroid Build Coastguard Worker						if test.err != "" {
1113*333d2b36SAndroid Build Coastguard Worker							t.Fatalf("missing error %q", test.err)
1114*333d2b36SAndroid Build Coastguard Worker						}
1115*333d2b36SAndroid Build Coastguard Worker					}
1116*333d2b36SAndroid Build Coastguard Worker				})
1117*333d2b36SAndroid Build Coastguard Worker			}
1118*333d2b36SAndroid Build Coastguard Worker		})
1119*333d2b36SAndroid Build Coastguard Worker	}
1120*333d2b36SAndroid Build Coastguard Worker}
1121*333d2b36SAndroid Build Coastguard Worker
1122*333d2b36SAndroid Build Coastguard Workertype pathForModuleSrcTestModule struct {
1123*333d2b36SAndroid Build Coastguard Worker	ModuleBase
1124*333d2b36SAndroid Build Coastguard Worker	props struct {
1125*333d2b36SAndroid Build Coastguard Worker		Srcs         []string `android:"path"`
1126*333d2b36SAndroid Build Coastguard Worker		Exclude_srcs []string `android:"path"`
1127*333d2b36SAndroid Build Coastguard Worker
1128*333d2b36SAndroid Build Coastguard Worker		Src *string `android:"path"`
1129*333d2b36SAndroid Build Coastguard Worker
1130*333d2b36SAndroid Build Coastguard Worker		Module_handles_missing_deps bool
1131*333d2b36SAndroid Build Coastguard Worker	}
1132*333d2b36SAndroid Build Coastguard Worker
1133*333d2b36SAndroid Build Coastguard Worker	src string
1134*333d2b36SAndroid Build Coastguard Worker	rel string
1135*333d2b36SAndroid Build Coastguard Worker
1136*333d2b36SAndroid Build Coastguard Worker	srcs []string
1137*333d2b36SAndroid Build Coastguard Worker	rels []string
1138*333d2b36SAndroid Build Coastguard Worker
1139*333d2b36SAndroid Build Coastguard Worker	missingDeps []string
1140*333d2b36SAndroid Build Coastguard Worker}
1141*333d2b36SAndroid Build Coastguard Worker
1142*333d2b36SAndroid Build Coastguard Workerfunc pathForModuleSrcTestModuleFactory() Module {
1143*333d2b36SAndroid Build Coastguard Worker	module := &pathForModuleSrcTestModule{}
1144*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.props)
1145*333d2b36SAndroid Build Coastguard Worker	InitAndroidModule(module)
1146*333d2b36SAndroid Build Coastguard Worker	return module
1147*333d2b36SAndroid Build Coastguard Worker}
1148*333d2b36SAndroid Build Coastguard Worker
1149*333d2b36SAndroid Build Coastguard Workerfunc (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
1150*333d2b36SAndroid Build Coastguard Worker	var srcs Paths
1151*333d2b36SAndroid Build Coastguard Worker	if p.props.Module_handles_missing_deps {
1152*333d2b36SAndroid Build Coastguard Worker		srcs, p.missingDeps = PathsAndMissingDepsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
1153*333d2b36SAndroid Build Coastguard Worker	} else {
1154*333d2b36SAndroid Build Coastguard Worker		srcs = PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
1155*333d2b36SAndroid Build Coastguard Worker	}
1156*333d2b36SAndroid Build Coastguard Worker	p.srcs = srcs.Strings()
1157*333d2b36SAndroid Build Coastguard Worker
1158*333d2b36SAndroid Build Coastguard Worker	for _, src := range srcs {
1159*333d2b36SAndroid Build Coastguard Worker		p.rels = append(p.rels, src.Rel())
1160*333d2b36SAndroid Build Coastguard Worker	}
1161*333d2b36SAndroid Build Coastguard Worker
1162*333d2b36SAndroid Build Coastguard Worker	if p.props.Src != nil {
1163*333d2b36SAndroid Build Coastguard Worker		src := PathForModuleSrc(ctx, *p.props.Src)
1164*333d2b36SAndroid Build Coastguard Worker		if src != nil {
1165*333d2b36SAndroid Build Coastguard Worker			p.src = src.String()
1166*333d2b36SAndroid Build Coastguard Worker			p.rel = src.Rel()
1167*333d2b36SAndroid Build Coastguard Worker		}
1168*333d2b36SAndroid Build Coastguard Worker	}
1169*333d2b36SAndroid Build Coastguard Worker
1170*333d2b36SAndroid Build Coastguard Worker	if !p.props.Module_handles_missing_deps {
1171*333d2b36SAndroid Build Coastguard Worker		p.missingDeps = ctx.GetMissingDependencies()
1172*333d2b36SAndroid Build Coastguard Worker	}
1173*333d2b36SAndroid Build Coastguard Worker
1174*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, BuildParams{
1175*333d2b36SAndroid Build Coastguard Worker		Rule:   Touch,
1176*333d2b36SAndroid Build Coastguard Worker		Output: PathForModuleOut(ctx, "output"),
1177*333d2b36SAndroid Build Coastguard Worker	})
1178*333d2b36SAndroid Build Coastguard Worker}
1179*333d2b36SAndroid Build Coastguard Worker
1180*333d2b36SAndroid Build Coastguard Workertype pathForModuleSrcOutputFileProviderModule struct {
1181*333d2b36SAndroid Build Coastguard Worker	ModuleBase
1182*333d2b36SAndroid Build Coastguard Worker	props struct {
1183*333d2b36SAndroid Build Coastguard Worker		Outs   []string
1184*333d2b36SAndroid Build Coastguard Worker		Tagged []string
1185*333d2b36SAndroid Build Coastguard Worker	}
1186*333d2b36SAndroid Build Coastguard Worker}
1187*333d2b36SAndroid Build Coastguard Worker
1188*333d2b36SAndroid Build Coastguard Workerfunc pathForModuleSrcOutputFileProviderModuleFactory() Module {
1189*333d2b36SAndroid Build Coastguard Worker	module := &pathForModuleSrcOutputFileProviderModule{}
1190*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.props)
1191*333d2b36SAndroid Build Coastguard Worker	InitAndroidModule(module)
1192*333d2b36SAndroid Build Coastguard Worker	return module
1193*333d2b36SAndroid Build Coastguard Worker}
1194*333d2b36SAndroid Build Coastguard Worker
1195*333d2b36SAndroid Build Coastguard Workerfunc (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
1196*333d2b36SAndroid Build Coastguard Worker	var outs, taggedOuts Paths
1197*333d2b36SAndroid Build Coastguard Worker	for _, out := range p.props.Outs {
1198*333d2b36SAndroid Build Coastguard Worker		outs = append(outs, PathForModuleOut(ctx, out))
1199*333d2b36SAndroid Build Coastguard Worker	}
1200*333d2b36SAndroid Build Coastguard Worker
1201*333d2b36SAndroid Build Coastguard Worker	for _, tagged := range p.props.Tagged {
1202*333d2b36SAndroid Build Coastguard Worker		taggedOuts = append(taggedOuts, PathForModuleOut(ctx, tagged))
1203*333d2b36SAndroid Build Coastguard Worker	}
1204*333d2b36SAndroid Build Coastguard Worker
1205*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(outs, "")
1206*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(taggedOuts, ".tagged")
1207*333d2b36SAndroid Build Coastguard Worker}
1208*333d2b36SAndroid Build Coastguard Worker
1209*333d2b36SAndroid Build Coastguard Workertype pathForModuleSrcTestCase struct {
1210*333d2b36SAndroid Build Coastguard Worker	name string
1211*333d2b36SAndroid Build Coastguard Worker	bp   string
1212*333d2b36SAndroid Build Coastguard Worker	srcs []string
1213*333d2b36SAndroid Build Coastguard Worker	rels []string
1214*333d2b36SAndroid Build Coastguard Worker	src  string
1215*333d2b36SAndroid Build Coastguard Worker	rel  string
1216*333d2b36SAndroid Build Coastguard Worker
1217*333d2b36SAndroid Build Coastguard Worker	// Make test specific preparations to the test fixture.
1218*333d2b36SAndroid Build Coastguard Worker	preparer FixturePreparer
1219*333d2b36SAndroid Build Coastguard Worker
1220*333d2b36SAndroid Build Coastguard Worker	// A test specific error handler.
1221*333d2b36SAndroid Build Coastguard Worker	errorHandler FixtureErrorHandler
1222*333d2b36SAndroid Build Coastguard Worker}
1223*333d2b36SAndroid Build Coastguard Worker
1224*333d2b36SAndroid Build Coastguard Workerfunc testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) {
1225*333d2b36SAndroid Build Coastguard Worker	for _, test := range tests {
1226*333d2b36SAndroid Build Coastguard Worker		t.Run(test.name, func(t *testing.T) {
1227*333d2b36SAndroid Build Coastguard Worker			fgBp := `
1228*333d2b36SAndroid Build Coastguard Worker				filegroup {
1229*333d2b36SAndroid Build Coastguard Worker					name: "a",
1230*333d2b36SAndroid Build Coastguard Worker					srcs: ["src/a"],
1231*333d2b36SAndroid Build Coastguard Worker				}
1232*333d2b36SAndroid Build Coastguard Worker			`
1233*333d2b36SAndroid Build Coastguard Worker
1234*333d2b36SAndroid Build Coastguard Worker			ofpBp := `
1235*333d2b36SAndroid Build Coastguard Worker				output_file_provider {
1236*333d2b36SAndroid Build Coastguard Worker					name: "b",
1237*333d2b36SAndroid Build Coastguard Worker					outs: ["gen/b"],
1238*333d2b36SAndroid Build Coastguard Worker					tagged: ["gen/c"],
1239*333d2b36SAndroid Build Coastguard Worker				}
1240*333d2b36SAndroid Build Coastguard Worker			`
1241*333d2b36SAndroid Build Coastguard Worker
1242*333d2b36SAndroid Build Coastguard Worker			mockFS := MockFS{
1243*333d2b36SAndroid Build Coastguard Worker				"fg/Android.bp":     []byte(fgBp),
1244*333d2b36SAndroid Build Coastguard Worker				"foo/Android.bp":    []byte(test.bp),
1245*333d2b36SAndroid Build Coastguard Worker				"ofp/Android.bp":    []byte(ofpBp),
1246*333d2b36SAndroid Build Coastguard Worker				"fg/src/a":          nil,
1247*333d2b36SAndroid Build Coastguard Worker				"foo/src/b":         nil,
1248*333d2b36SAndroid Build Coastguard Worker				"foo/src/c":         nil,
1249*333d2b36SAndroid Build Coastguard Worker				"foo/src/d":         nil,
1250*333d2b36SAndroid Build Coastguard Worker				"foo/src/e/e":       nil,
1251*333d2b36SAndroid Build Coastguard Worker				"foo/src_special/$": nil,
1252*333d2b36SAndroid Build Coastguard Worker			}
1253*333d2b36SAndroid Build Coastguard Worker
1254*333d2b36SAndroid Build Coastguard Worker			errorHandler := test.errorHandler
1255*333d2b36SAndroid Build Coastguard Worker			if errorHandler == nil {
1256*333d2b36SAndroid Build Coastguard Worker				errorHandler = FixtureExpectsNoErrors
1257*333d2b36SAndroid Build Coastguard Worker			}
1258*333d2b36SAndroid Build Coastguard Worker
1259*333d2b36SAndroid Build Coastguard Worker			result := GroupFixturePreparers(
1260*333d2b36SAndroid Build Coastguard Worker				FixtureRegisterWithContext(func(ctx RegistrationContext) {
1261*333d2b36SAndroid Build Coastguard Worker					ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1262*333d2b36SAndroid Build Coastguard Worker					ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
1263*333d2b36SAndroid Build Coastguard Worker				}),
1264*333d2b36SAndroid Build Coastguard Worker				PrepareForTestWithFilegroup,
1265*333d2b36SAndroid Build Coastguard Worker				PrepareForTestWithNamespace,
1266*333d2b36SAndroid Build Coastguard Worker				mockFS.AddToFixture(),
1267*333d2b36SAndroid Build Coastguard Worker				OptionalFixturePreparer(test.preparer),
1268*333d2b36SAndroid Build Coastguard Worker			).
1269*333d2b36SAndroid Build Coastguard Worker				ExtendWithErrorHandler(errorHandler).
1270*333d2b36SAndroid Build Coastguard Worker				RunTest(t)
1271*333d2b36SAndroid Build Coastguard Worker
1272*333d2b36SAndroid Build Coastguard Worker			m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1273*333d2b36SAndroid Build Coastguard Worker
1274*333d2b36SAndroid Build Coastguard Worker			AssertStringPathsRelativeToTopEquals(t, "srcs", result.Config, test.srcs, m.srcs)
1275*333d2b36SAndroid Build Coastguard Worker			AssertStringPathsRelativeToTopEquals(t, "rels", result.Config, test.rels, m.rels)
1276*333d2b36SAndroid Build Coastguard Worker			AssertStringPathRelativeToTopEquals(t, "src", result.Config, test.src, m.src)
1277*333d2b36SAndroid Build Coastguard Worker			AssertStringPathRelativeToTopEquals(t, "rel", result.Config, test.rel, m.rel)
1278*333d2b36SAndroid Build Coastguard Worker		})
1279*333d2b36SAndroid Build Coastguard Worker	}
1280*333d2b36SAndroid Build Coastguard Worker}
1281*333d2b36SAndroid Build Coastguard Worker
1282*333d2b36SAndroid Build Coastguard Workerfunc TestPathsForModuleSrc(t *testing.T) {
1283*333d2b36SAndroid Build Coastguard Worker	tests := []pathForModuleSrcTestCase{
1284*333d2b36SAndroid Build Coastguard Worker		{
1285*333d2b36SAndroid Build Coastguard Worker			name: "path",
1286*333d2b36SAndroid Build Coastguard Worker			bp: `
1287*333d2b36SAndroid Build Coastguard Worker			test {
1288*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1289*333d2b36SAndroid Build Coastguard Worker				srcs: ["src/b"],
1290*333d2b36SAndroid Build Coastguard Worker			}`,
1291*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"foo/src/b"},
1292*333d2b36SAndroid Build Coastguard Worker			rels: []string{"src/b"},
1293*333d2b36SAndroid Build Coastguard Worker		},
1294*333d2b36SAndroid Build Coastguard Worker		{
1295*333d2b36SAndroid Build Coastguard Worker			name: "glob",
1296*333d2b36SAndroid Build Coastguard Worker			bp: `
1297*333d2b36SAndroid Build Coastguard Worker			test {
1298*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1299*333d2b36SAndroid Build Coastguard Worker				srcs: [
1300*333d2b36SAndroid Build Coastguard Worker					"src/*",
1301*333d2b36SAndroid Build Coastguard Worker					"src/e/*",
1302*333d2b36SAndroid Build Coastguard Worker				],
1303*333d2b36SAndroid Build Coastguard Worker			}`,
1304*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1305*333d2b36SAndroid Build Coastguard Worker			rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1306*333d2b36SAndroid Build Coastguard Worker		},
1307*333d2b36SAndroid Build Coastguard Worker		{
1308*333d2b36SAndroid Build Coastguard Worker			name: "recursive glob",
1309*333d2b36SAndroid Build Coastguard Worker			bp: `
1310*333d2b36SAndroid Build Coastguard Worker			test {
1311*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1312*333d2b36SAndroid Build Coastguard Worker				srcs: ["src/**/*"],
1313*333d2b36SAndroid Build Coastguard Worker			}`,
1314*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"foo/src/b", "foo/src/c", "foo/src/d", "foo/src/e/e"},
1315*333d2b36SAndroid Build Coastguard Worker			rels: []string{"src/b", "src/c", "src/d", "src/e/e"},
1316*333d2b36SAndroid Build Coastguard Worker		},
1317*333d2b36SAndroid Build Coastguard Worker		{
1318*333d2b36SAndroid Build Coastguard Worker			name: "filegroup",
1319*333d2b36SAndroid Build Coastguard Worker			bp: `
1320*333d2b36SAndroid Build Coastguard Worker			test {
1321*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1322*333d2b36SAndroid Build Coastguard Worker				srcs: [":a"],
1323*333d2b36SAndroid Build Coastguard Worker			}`,
1324*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"fg/src/a"},
1325*333d2b36SAndroid Build Coastguard Worker			rels: []string{"src/a"},
1326*333d2b36SAndroid Build Coastguard Worker		},
1327*333d2b36SAndroid Build Coastguard Worker		{
1328*333d2b36SAndroid Build Coastguard Worker			name: "output file provider",
1329*333d2b36SAndroid Build Coastguard Worker			bp: `
1330*333d2b36SAndroid Build Coastguard Worker			test {
1331*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1332*333d2b36SAndroid Build Coastguard Worker				srcs: [":b"],
1333*333d2b36SAndroid Build Coastguard Worker			}`,
1334*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"},
1335*333d2b36SAndroid Build Coastguard Worker			rels: []string{"gen/b"},
1336*333d2b36SAndroid Build Coastguard Worker		},
1337*333d2b36SAndroid Build Coastguard Worker		{
1338*333d2b36SAndroid Build Coastguard Worker			name: "output file provider tagged",
1339*333d2b36SAndroid Build Coastguard Worker			bp: `
1340*333d2b36SAndroid Build Coastguard Worker			test {
1341*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1342*333d2b36SAndroid Build Coastguard Worker				srcs: [":b{.tagged}"],
1343*333d2b36SAndroid Build Coastguard Worker			}`,
1344*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"out/soong/.intermediates/ofp/b/gen/c"},
1345*333d2b36SAndroid Build Coastguard Worker			rels: []string{"gen/c"},
1346*333d2b36SAndroid Build Coastguard Worker		},
1347*333d2b36SAndroid Build Coastguard Worker		{
1348*333d2b36SAndroid Build Coastguard Worker			name: "output file provider with exclude",
1349*333d2b36SAndroid Build Coastguard Worker			bp: `
1350*333d2b36SAndroid Build Coastguard Worker			test {
1351*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1352*333d2b36SAndroid Build Coastguard Worker				srcs: [":b", ":c"],
1353*333d2b36SAndroid Build Coastguard Worker				exclude_srcs: [":c"]
1354*333d2b36SAndroid Build Coastguard Worker			}
1355*333d2b36SAndroid Build Coastguard Worker			output_file_provider {
1356*333d2b36SAndroid Build Coastguard Worker				name: "c",
1357*333d2b36SAndroid Build Coastguard Worker				outs: ["gen/c"],
1358*333d2b36SAndroid Build Coastguard Worker			}`,
1359*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"},
1360*333d2b36SAndroid Build Coastguard Worker			rels: []string{"gen/b"},
1361*333d2b36SAndroid Build Coastguard Worker		},
1362*333d2b36SAndroid Build Coastguard Worker		{
1363*333d2b36SAndroid Build Coastguard Worker			name: "special characters glob",
1364*333d2b36SAndroid Build Coastguard Worker			bp: `
1365*333d2b36SAndroid Build Coastguard Worker			test {
1366*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1367*333d2b36SAndroid Build Coastguard Worker				srcs: ["src_special/*"],
1368*333d2b36SAndroid Build Coastguard Worker			}`,
1369*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"foo/src_special/$"},
1370*333d2b36SAndroid Build Coastguard Worker			rels: []string{"src_special/$"},
1371*333d2b36SAndroid Build Coastguard Worker		},
1372*333d2b36SAndroid Build Coastguard Worker	}
1373*333d2b36SAndroid Build Coastguard Worker
1374*333d2b36SAndroid Build Coastguard Worker	testPathForModuleSrc(t, tests)
1375*333d2b36SAndroid Build Coastguard Worker}
1376*333d2b36SAndroid Build Coastguard Worker
1377*333d2b36SAndroid Build Coastguard Workerfunc TestPathForModuleSrc(t *testing.T) {
1378*333d2b36SAndroid Build Coastguard Worker	tests := []pathForModuleSrcTestCase{
1379*333d2b36SAndroid Build Coastguard Worker		{
1380*333d2b36SAndroid Build Coastguard Worker			name: "path",
1381*333d2b36SAndroid Build Coastguard Worker			bp: `
1382*333d2b36SAndroid Build Coastguard Worker			test {
1383*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1384*333d2b36SAndroid Build Coastguard Worker				src: "src/b",
1385*333d2b36SAndroid Build Coastguard Worker			}`,
1386*333d2b36SAndroid Build Coastguard Worker			src: "foo/src/b",
1387*333d2b36SAndroid Build Coastguard Worker			rel: "src/b",
1388*333d2b36SAndroid Build Coastguard Worker		},
1389*333d2b36SAndroid Build Coastguard Worker		{
1390*333d2b36SAndroid Build Coastguard Worker			name: "glob",
1391*333d2b36SAndroid Build Coastguard Worker			bp: `
1392*333d2b36SAndroid Build Coastguard Worker			test {
1393*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1394*333d2b36SAndroid Build Coastguard Worker				src: "src/e/*",
1395*333d2b36SAndroid Build Coastguard Worker			}`,
1396*333d2b36SAndroid Build Coastguard Worker			src: "foo/src/e/e",
1397*333d2b36SAndroid Build Coastguard Worker			rel: "src/e/e",
1398*333d2b36SAndroid Build Coastguard Worker		},
1399*333d2b36SAndroid Build Coastguard Worker		{
1400*333d2b36SAndroid Build Coastguard Worker			name: "filegroup",
1401*333d2b36SAndroid Build Coastguard Worker			bp: `
1402*333d2b36SAndroid Build Coastguard Worker			test {
1403*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1404*333d2b36SAndroid Build Coastguard Worker				src: ":a",
1405*333d2b36SAndroid Build Coastguard Worker			}`,
1406*333d2b36SAndroid Build Coastguard Worker			src: "fg/src/a",
1407*333d2b36SAndroid Build Coastguard Worker			rel: "src/a",
1408*333d2b36SAndroid Build Coastguard Worker		},
1409*333d2b36SAndroid Build Coastguard Worker		{
1410*333d2b36SAndroid Build Coastguard Worker			name: "output file provider",
1411*333d2b36SAndroid Build Coastguard Worker			bp: `
1412*333d2b36SAndroid Build Coastguard Worker			test {
1413*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1414*333d2b36SAndroid Build Coastguard Worker				src: ":b",
1415*333d2b36SAndroid Build Coastguard Worker			}`,
1416*333d2b36SAndroid Build Coastguard Worker			src: "out/soong/.intermediates/ofp/b/gen/b",
1417*333d2b36SAndroid Build Coastguard Worker			rel: "gen/b",
1418*333d2b36SAndroid Build Coastguard Worker		},
1419*333d2b36SAndroid Build Coastguard Worker		{
1420*333d2b36SAndroid Build Coastguard Worker			name: "output file provider tagged",
1421*333d2b36SAndroid Build Coastguard Worker			bp: `
1422*333d2b36SAndroid Build Coastguard Worker			test {
1423*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1424*333d2b36SAndroid Build Coastguard Worker				src: ":b{.tagged}",
1425*333d2b36SAndroid Build Coastguard Worker			}`,
1426*333d2b36SAndroid Build Coastguard Worker			src: "out/soong/.intermediates/ofp/b/gen/c",
1427*333d2b36SAndroid Build Coastguard Worker			rel: "gen/c",
1428*333d2b36SAndroid Build Coastguard Worker		},
1429*333d2b36SAndroid Build Coastguard Worker		{
1430*333d2b36SAndroid Build Coastguard Worker			name: "special characters glob",
1431*333d2b36SAndroid Build Coastguard Worker			bp: `
1432*333d2b36SAndroid Build Coastguard Worker			test {
1433*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1434*333d2b36SAndroid Build Coastguard Worker				src: "src_special/*",
1435*333d2b36SAndroid Build Coastguard Worker			}`,
1436*333d2b36SAndroid Build Coastguard Worker			src: "foo/src_special/$",
1437*333d2b36SAndroid Build Coastguard Worker			rel: "src_special/$",
1438*333d2b36SAndroid Build Coastguard Worker		},
1439*333d2b36SAndroid Build Coastguard Worker		{
1440*333d2b36SAndroid Build Coastguard Worker			// This test makes sure that an unqualified module name cannot contain characters that make
1441*333d2b36SAndroid Build Coastguard Worker			// it appear as a qualified module name.
1442*333d2b36SAndroid Build Coastguard Worker			name: "output file provider, invalid fully qualified name",
1443*333d2b36SAndroid Build Coastguard Worker			bp: `
1444*333d2b36SAndroid Build Coastguard Worker			test {
1445*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1446*333d2b36SAndroid Build Coastguard Worker				src: "://other:b",
1447*333d2b36SAndroid Build Coastguard Worker				srcs: ["://other:c"],
1448*333d2b36SAndroid Build Coastguard Worker			}`,
1449*333d2b36SAndroid Build Coastguard Worker			preparer: FixtureAddTextFile("other/Android.bp", `
1450*333d2b36SAndroid Build Coastguard Worker				soong_namespace {}
1451*333d2b36SAndroid Build Coastguard Worker
1452*333d2b36SAndroid Build Coastguard Worker				output_file_provider {
1453*333d2b36SAndroid Build Coastguard Worker					name: "b",
1454*333d2b36SAndroid Build Coastguard Worker					outs: ["gen/b"],
1455*333d2b36SAndroid Build Coastguard Worker				}
1456*333d2b36SAndroid Build Coastguard Worker
1457*333d2b36SAndroid Build Coastguard Worker				output_file_provider {
1458*333d2b36SAndroid Build Coastguard Worker					name: "c",
1459*333d2b36SAndroid Build Coastguard Worker					outs: ["gen/c"],
1460*333d2b36SAndroid Build Coastguard Worker				}
1461*333d2b36SAndroid Build Coastguard Worker			`),
1462*333d2b36SAndroid Build Coastguard Worker			src:  "foo/:/other:b",
1463*333d2b36SAndroid Build Coastguard Worker			rel:  ":/other:b",
1464*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"foo/:/other:c"},
1465*333d2b36SAndroid Build Coastguard Worker			rels: []string{":/other:c"},
1466*333d2b36SAndroid Build Coastguard Worker		},
1467*333d2b36SAndroid Build Coastguard Worker		{
1468*333d2b36SAndroid Build Coastguard Worker			name: "output file provider, missing fully qualified name",
1469*333d2b36SAndroid Build Coastguard Worker			bp: `
1470*333d2b36SAndroid Build Coastguard Worker			test {
1471*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1472*333d2b36SAndroid Build Coastguard Worker				src: "//other:b",
1473*333d2b36SAndroid Build Coastguard Worker				srcs: ["//other:c"],
1474*333d2b36SAndroid Build Coastguard Worker			}`,
1475*333d2b36SAndroid Build Coastguard Worker			errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{
1476*333d2b36SAndroid Build Coastguard Worker				`"foo" depends on undefined module "//other:b"`,
1477*333d2b36SAndroid Build Coastguard Worker				`"foo" depends on undefined module "//other:c"`,
1478*333d2b36SAndroid Build Coastguard Worker			}),
1479*333d2b36SAndroid Build Coastguard Worker		},
1480*333d2b36SAndroid Build Coastguard Worker		{
1481*333d2b36SAndroid Build Coastguard Worker			name: "output file provider, fully qualified name",
1482*333d2b36SAndroid Build Coastguard Worker			bp: `
1483*333d2b36SAndroid Build Coastguard Worker			test {
1484*333d2b36SAndroid Build Coastguard Worker				name: "foo",
1485*333d2b36SAndroid Build Coastguard Worker				src: "//other:b",
1486*333d2b36SAndroid Build Coastguard Worker				srcs: ["//other:c"],
1487*333d2b36SAndroid Build Coastguard Worker			}`,
1488*333d2b36SAndroid Build Coastguard Worker			src:  "out/soong/.intermediates/other/b/gen/b",
1489*333d2b36SAndroid Build Coastguard Worker			rel:  "gen/b",
1490*333d2b36SAndroid Build Coastguard Worker			srcs: []string{"out/soong/.intermediates/other/c/gen/c"},
1491*333d2b36SAndroid Build Coastguard Worker			rels: []string{"gen/c"},
1492*333d2b36SAndroid Build Coastguard Worker			preparer: FixtureAddTextFile("other/Android.bp", `
1493*333d2b36SAndroid Build Coastguard Worker				soong_namespace {}
1494*333d2b36SAndroid Build Coastguard Worker
1495*333d2b36SAndroid Build Coastguard Worker				output_file_provider {
1496*333d2b36SAndroid Build Coastguard Worker					name: "b",
1497*333d2b36SAndroid Build Coastguard Worker					outs: ["gen/b"],
1498*333d2b36SAndroid Build Coastguard Worker				}
1499*333d2b36SAndroid Build Coastguard Worker
1500*333d2b36SAndroid Build Coastguard Worker				output_file_provider {
1501*333d2b36SAndroid Build Coastguard Worker					name: "c",
1502*333d2b36SAndroid Build Coastguard Worker					outs: ["gen/c"],
1503*333d2b36SAndroid Build Coastguard Worker				}
1504*333d2b36SAndroid Build Coastguard Worker			`),
1505*333d2b36SAndroid Build Coastguard Worker		},
1506*333d2b36SAndroid Build Coastguard Worker	}
1507*333d2b36SAndroid Build Coastguard Worker
1508*333d2b36SAndroid Build Coastguard Worker	testPathForModuleSrc(t, tests)
1509*333d2b36SAndroid Build Coastguard Worker}
1510*333d2b36SAndroid Build Coastguard Worker
1511*333d2b36SAndroid Build Coastguard Workerfunc TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
1512*333d2b36SAndroid Build Coastguard Worker	bp := `
1513*333d2b36SAndroid Build Coastguard Worker		test {
1514*333d2b36SAndroid Build Coastguard Worker			name: "foo",
1515*333d2b36SAndroid Build Coastguard Worker			srcs: [":a"],
1516*333d2b36SAndroid Build Coastguard Worker			exclude_srcs: [":b"],
1517*333d2b36SAndroid Build Coastguard Worker			src: ":c",
1518*333d2b36SAndroid Build Coastguard Worker		}
1519*333d2b36SAndroid Build Coastguard Worker
1520*333d2b36SAndroid Build Coastguard Worker		test {
1521*333d2b36SAndroid Build Coastguard Worker			name: "bar",
1522*333d2b36SAndroid Build Coastguard Worker			srcs: [":d"],
1523*333d2b36SAndroid Build Coastguard Worker			exclude_srcs: [":e"],
1524*333d2b36SAndroid Build Coastguard Worker			module_handles_missing_deps: true,
1525*333d2b36SAndroid Build Coastguard Worker		}
1526*333d2b36SAndroid Build Coastguard Worker	`
1527*333d2b36SAndroid Build Coastguard Worker
1528*333d2b36SAndroid Build Coastguard Worker	result := GroupFixturePreparers(
1529*333d2b36SAndroid Build Coastguard Worker		PrepareForTestWithAllowMissingDependencies,
1530*333d2b36SAndroid Build Coastguard Worker		FixtureRegisterWithContext(func(ctx RegistrationContext) {
1531*333d2b36SAndroid Build Coastguard Worker			ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
1532*333d2b36SAndroid Build Coastguard Worker		}),
1533*333d2b36SAndroid Build Coastguard Worker		FixtureWithRootAndroidBp(bp),
1534*333d2b36SAndroid Build Coastguard Worker	).RunTest(t)
1535*333d2b36SAndroid Build Coastguard Worker
1536*333d2b36SAndroid Build Coastguard Worker	foo := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
1537*333d2b36SAndroid Build Coastguard Worker
1538*333d2b36SAndroid Build Coastguard Worker	AssertArrayString(t, "foo missing deps", []string{"a", "b", "c"}, foo.missingDeps)
1539*333d2b36SAndroid Build Coastguard Worker	AssertArrayString(t, "foo srcs", []string{}, foo.srcs)
1540*333d2b36SAndroid Build Coastguard Worker	AssertStringEquals(t, "foo src", "", foo.src)
1541*333d2b36SAndroid Build Coastguard Worker
1542*333d2b36SAndroid Build Coastguard Worker	bar := result.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
1543*333d2b36SAndroid Build Coastguard Worker
1544*333d2b36SAndroid Build Coastguard Worker	AssertArrayString(t, "bar missing deps", []string{"d", "e"}, bar.missingDeps)
1545*333d2b36SAndroid Build Coastguard Worker	AssertArrayString(t, "bar srcs", []string{}, bar.srcs)
1546*333d2b36SAndroid Build Coastguard Worker}
1547*333d2b36SAndroid Build Coastguard Worker
1548*333d2b36SAndroid Build Coastguard Workerfunc TestPathRelativeToTop(t *testing.T) {
1549*333d2b36SAndroid Build Coastguard Worker	testConfig := pathTestConfig("/tmp/build/top")
1550*333d2b36SAndroid Build Coastguard Worker	deviceTarget := Target{Os: Android, Arch: Arch{ArchType: Arm64}}
1551*333d2b36SAndroid Build Coastguard Worker
1552*333d2b36SAndroid Build Coastguard Worker	ctx := &testModuleInstallPathContext{
1553*333d2b36SAndroid Build Coastguard Worker		baseModuleContext: baseModuleContext{
1554*333d2b36SAndroid Build Coastguard Worker			archModuleContext: archModuleContext{
1555*333d2b36SAndroid Build Coastguard Worker				os:     deviceTarget.Os,
1556*333d2b36SAndroid Build Coastguard Worker				target: deviceTarget,
1557*333d2b36SAndroid Build Coastguard Worker			},
1558*333d2b36SAndroid Build Coastguard Worker		},
1559*333d2b36SAndroid Build Coastguard Worker	}
1560*333d2b36SAndroid Build Coastguard Worker	ctx.baseModuleContext.config = testConfig
1561*333d2b36SAndroid Build Coastguard Worker
1562*333d2b36SAndroid Build Coastguard Worker	t.Run("install for soong", func(t *testing.T) {
1563*333d2b36SAndroid Build Coastguard Worker		p := PathForModuleInstall(ctx, "install/path")
1564*333d2b36SAndroid Build Coastguard Worker		AssertPathRelativeToTopEquals(t, "install path for soong", "out/soong/target/product/test_device/system/install/path", p)
1565*333d2b36SAndroid Build Coastguard Worker	})
1566*333d2b36SAndroid Build Coastguard Worker	t.Run("install for make", func(t *testing.T) {
1567*333d2b36SAndroid Build Coastguard Worker		p := PathForModuleInstall(ctx, "install/path")
1568*333d2b36SAndroid Build Coastguard Worker		p.makePath = true
1569*333d2b36SAndroid Build Coastguard Worker		AssertPathRelativeToTopEquals(t, "install path for make", "out/target/product/test_device/system/install/path", p)
1570*333d2b36SAndroid Build Coastguard Worker	})
1571*333d2b36SAndroid Build Coastguard Worker	t.Run("output", func(t *testing.T) {
1572*333d2b36SAndroid Build Coastguard Worker		p := PathForOutput(ctx, "output/path")
1573*333d2b36SAndroid Build Coastguard Worker		AssertPathRelativeToTopEquals(t, "output path", "out/soong/output/path", p)
1574*333d2b36SAndroid Build Coastguard Worker	})
1575*333d2b36SAndroid Build Coastguard Worker	t.Run("source", func(t *testing.T) {
1576*333d2b36SAndroid Build Coastguard Worker		p := PathForSource(ctx, "source/path")
1577*333d2b36SAndroid Build Coastguard Worker		AssertPathRelativeToTopEquals(t, "source path", "source/path", p)
1578*333d2b36SAndroid Build Coastguard Worker	})
1579*333d2b36SAndroid Build Coastguard Worker	t.Run("mixture", func(t *testing.T) {
1580*333d2b36SAndroid Build Coastguard Worker		paths := Paths{
1581*333d2b36SAndroid Build Coastguard Worker			PathForModuleInstall(ctx, "install/path"),
1582*333d2b36SAndroid Build Coastguard Worker			PathForOutput(ctx, "output/path"),
1583*333d2b36SAndroid Build Coastguard Worker			PathForSource(ctx, "source/path"),
1584*333d2b36SAndroid Build Coastguard Worker		}
1585*333d2b36SAndroid Build Coastguard Worker
1586*333d2b36SAndroid Build Coastguard Worker		expected := []string{
1587*333d2b36SAndroid Build Coastguard Worker			"out/soong/target/product/test_device/system/install/path",
1588*333d2b36SAndroid Build Coastguard Worker			"out/soong/output/path",
1589*333d2b36SAndroid Build Coastguard Worker			"source/path",
1590*333d2b36SAndroid Build Coastguard Worker		}
1591*333d2b36SAndroid Build Coastguard Worker		AssertPathsRelativeToTopEquals(t, "mixture", expected, paths)
1592*333d2b36SAndroid Build Coastguard Worker	})
1593*333d2b36SAndroid Build Coastguard Worker}
1594*333d2b36SAndroid Build Coastguard Worker
1595*333d2b36SAndroid Build Coastguard Workerfunc TestDirectoryPathIsIncompatibleWithPath(t *testing.T) {
1596*333d2b36SAndroid Build Coastguard Worker	d := (DirectoryPath)(&directoryPath{})
1597*333d2b36SAndroid Build Coastguard Worker	_, ok := d.(Path)
1598*333d2b36SAndroid Build Coastguard Worker	AssertBoolEquals(t, "directoryPath shouldn't implement Path", ok, false)
1599*333d2b36SAndroid Build Coastguard Worker}
1600*333d2b36SAndroid Build Coastguard Worker
1601*333d2b36SAndroid Build Coastguard Workerfunc ExampleOutputPath_ReplaceExtension() {
1602*333d2b36SAndroid Build Coastguard Worker	ctx := &configErrorWrapper{
1603*333d2b36SAndroid Build Coastguard Worker		config: TestConfig("out", nil, "", nil),
1604*333d2b36SAndroid Build Coastguard Worker	}
1605*333d2b36SAndroid Build Coastguard Worker	p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
1606*333d2b36SAndroid Build Coastguard Worker	p2 := p.ReplaceExtension(ctx, "oat")
1607*333d2b36SAndroid Build Coastguard Worker	fmt.Println(p, p2)
1608*333d2b36SAndroid Build Coastguard Worker	fmt.Println(p.Rel(), p2.Rel())
1609*333d2b36SAndroid Build Coastguard Worker
1610*333d2b36SAndroid Build Coastguard Worker	// Output:
1611*333d2b36SAndroid Build Coastguard Worker	// out/soong/system/framework/boot.art out/soong/system/framework/boot.oat
1612*333d2b36SAndroid Build Coastguard Worker	// boot.art boot.oat
1613*333d2b36SAndroid Build Coastguard Worker}
1614*333d2b36SAndroid Build Coastguard Worker
1615*333d2b36SAndroid Build Coastguard Workerfunc ExampleOutputPath_InSameDir() {
1616*333d2b36SAndroid Build Coastguard Worker	ctx := &configErrorWrapper{
1617*333d2b36SAndroid Build Coastguard Worker		config: TestConfig("out", nil, "", nil),
1618*333d2b36SAndroid Build Coastguard Worker	}
1619*333d2b36SAndroid Build Coastguard Worker	p := PathForOutput(ctx, "system/framework").Join(ctx, "boot.art")
1620*333d2b36SAndroid Build Coastguard Worker	p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
1621*333d2b36SAndroid Build Coastguard Worker	fmt.Println(p, p2)
1622*333d2b36SAndroid Build Coastguard Worker	fmt.Println(p.Rel(), p2.Rel())
1623*333d2b36SAndroid Build Coastguard Worker
1624*333d2b36SAndroid Build Coastguard Worker	// Output:
1625*333d2b36SAndroid Build Coastguard Worker	// out/soong/system/framework/boot.art out/soong/system/framework/oat/arm/boot.vdex
1626*333d2b36SAndroid Build Coastguard Worker	// boot.art oat/arm/boot.vdex
1627*333d2b36SAndroid Build Coastguard Worker}
1628*333d2b36SAndroid Build Coastguard Worker
1629*333d2b36SAndroid Build Coastguard Workerfunc BenchmarkFirstUniquePaths(b *testing.B) {
1630*333d2b36SAndroid Build Coastguard Worker	implementations := []struct {
1631*333d2b36SAndroid Build Coastguard Worker		name string
1632*333d2b36SAndroid Build Coastguard Worker		f    func(Paths) Paths
1633*333d2b36SAndroid Build Coastguard Worker	}{
1634*333d2b36SAndroid Build Coastguard Worker		{
1635*333d2b36SAndroid Build Coastguard Worker			name: "list",
1636*333d2b36SAndroid Build Coastguard Worker			f:    firstUniquePathsList,
1637*333d2b36SAndroid Build Coastguard Worker		},
1638*333d2b36SAndroid Build Coastguard Worker		{
1639*333d2b36SAndroid Build Coastguard Worker			name: "map",
1640*333d2b36SAndroid Build Coastguard Worker			f:    firstUniquePathsMap,
1641*333d2b36SAndroid Build Coastguard Worker		},
1642*333d2b36SAndroid Build Coastguard Worker	}
1643*333d2b36SAndroid Build Coastguard Worker	const maxSize = 1024
1644*333d2b36SAndroid Build Coastguard Worker	uniquePaths := make(Paths, maxSize)
1645*333d2b36SAndroid Build Coastguard Worker	for i := range uniquePaths {
1646*333d2b36SAndroid Build Coastguard Worker		uniquePaths[i] = PathForTesting(strconv.Itoa(i))
1647*333d2b36SAndroid Build Coastguard Worker	}
1648*333d2b36SAndroid Build Coastguard Worker	samePath := make(Paths, maxSize)
1649*333d2b36SAndroid Build Coastguard Worker	for i := range samePath {
1650*333d2b36SAndroid Build Coastguard Worker		samePath[i] = uniquePaths[0]
1651*333d2b36SAndroid Build Coastguard Worker	}
1652*333d2b36SAndroid Build Coastguard Worker
1653*333d2b36SAndroid Build Coastguard Worker	f := func(b *testing.B, imp func(Paths) Paths, paths Paths) {
1654*333d2b36SAndroid Build Coastguard Worker		for i := 0; i < b.N; i++ {
1655*333d2b36SAndroid Build Coastguard Worker			b.ReportAllocs()
1656*333d2b36SAndroid Build Coastguard Worker			paths = append(Paths(nil), paths...)
1657*333d2b36SAndroid Build Coastguard Worker			imp(paths)
1658*333d2b36SAndroid Build Coastguard Worker		}
1659*333d2b36SAndroid Build Coastguard Worker	}
1660*333d2b36SAndroid Build Coastguard Worker
1661*333d2b36SAndroid Build Coastguard Worker	for n := 1; n <= maxSize; n <<= 1 {
1662*333d2b36SAndroid Build Coastguard Worker		b.Run(strconv.Itoa(n), func(b *testing.B) {
1663*333d2b36SAndroid Build Coastguard Worker			for _, implementation := range implementations {
1664*333d2b36SAndroid Build Coastguard Worker				b.Run(implementation.name, func(b *testing.B) {
1665*333d2b36SAndroid Build Coastguard Worker					b.Run("same", func(b *testing.B) {
1666*333d2b36SAndroid Build Coastguard Worker						f(b, implementation.f, samePath[:n])
1667*333d2b36SAndroid Build Coastguard Worker					})
1668*333d2b36SAndroid Build Coastguard Worker					b.Run("unique", func(b *testing.B) {
1669*333d2b36SAndroid Build Coastguard Worker						f(b, implementation.f, uniquePaths[:n])
1670*333d2b36SAndroid Build Coastguard Worker					})
1671*333d2b36SAndroid Build Coastguard Worker				})
1672*333d2b36SAndroid Build Coastguard Worker			}
1673*333d2b36SAndroid Build Coastguard Worker		})
1674*333d2b36SAndroid Build Coastguard Worker	}
1675*333d2b36SAndroid Build Coastguard Worker}
1676