xref: /aosp_15_r20/build/soong/android/module_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	"path/filepath"
19*333d2b36SAndroid Build Coastguard Worker	"runtime"
20*333d2b36SAndroid Build Coastguard Worker	"testing"
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
23*333d2b36SAndroid Build Coastguard Worker)
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Workerfunc TestSrcIsModule(t *testing.T) {
26*333d2b36SAndroid Build Coastguard Worker	type args struct {
27*333d2b36SAndroid Build Coastguard Worker		s string
28*333d2b36SAndroid Build Coastguard Worker	}
29*333d2b36SAndroid Build Coastguard Worker	tests := []struct {
30*333d2b36SAndroid Build Coastguard Worker		name       string
31*333d2b36SAndroid Build Coastguard Worker		args       args
32*333d2b36SAndroid Build Coastguard Worker		wantModule string
33*333d2b36SAndroid Build Coastguard Worker	}{
34*333d2b36SAndroid Build Coastguard Worker		{
35*333d2b36SAndroid Build Coastguard Worker			name: "file",
36*333d2b36SAndroid Build Coastguard Worker			args: args{
37*333d2b36SAndroid Build Coastguard Worker				s: "foo",
38*333d2b36SAndroid Build Coastguard Worker			},
39*333d2b36SAndroid Build Coastguard Worker			wantModule: "",
40*333d2b36SAndroid Build Coastguard Worker		},
41*333d2b36SAndroid Build Coastguard Worker		{
42*333d2b36SAndroid Build Coastguard Worker			name: "module",
43*333d2b36SAndroid Build Coastguard Worker			args: args{
44*333d2b36SAndroid Build Coastguard Worker				s: ":foo",
45*333d2b36SAndroid Build Coastguard Worker			},
46*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo",
47*333d2b36SAndroid Build Coastguard Worker		},
48*333d2b36SAndroid Build Coastguard Worker		{
49*333d2b36SAndroid Build Coastguard Worker			name: "tag",
50*333d2b36SAndroid Build Coastguard Worker			args: args{
51*333d2b36SAndroid Build Coastguard Worker				s: ":foo{.bar}",
52*333d2b36SAndroid Build Coastguard Worker			},
53*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo{.bar}",
54*333d2b36SAndroid Build Coastguard Worker		},
55*333d2b36SAndroid Build Coastguard Worker		{
56*333d2b36SAndroid Build Coastguard Worker			name: "extra colon",
57*333d2b36SAndroid Build Coastguard Worker			args: args{
58*333d2b36SAndroid Build Coastguard Worker				s: ":foo:bar",
59*333d2b36SAndroid Build Coastguard Worker			},
60*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo:bar",
61*333d2b36SAndroid Build Coastguard Worker		},
62*333d2b36SAndroid Build Coastguard Worker		{
63*333d2b36SAndroid Build Coastguard Worker			name: "fully qualified",
64*333d2b36SAndroid Build Coastguard Worker			args: args{
65*333d2b36SAndroid Build Coastguard Worker				s: "//foo:bar",
66*333d2b36SAndroid Build Coastguard Worker			},
67*333d2b36SAndroid Build Coastguard Worker			wantModule: "//foo:bar",
68*333d2b36SAndroid Build Coastguard Worker		},
69*333d2b36SAndroid Build Coastguard Worker		{
70*333d2b36SAndroid Build Coastguard Worker			name: "fully qualified with tag",
71*333d2b36SAndroid Build Coastguard Worker			args: args{
72*333d2b36SAndroid Build Coastguard Worker				s: "//foo:bar{.tag}",
73*333d2b36SAndroid Build Coastguard Worker			},
74*333d2b36SAndroid Build Coastguard Worker			wantModule: "//foo:bar{.tag}",
75*333d2b36SAndroid Build Coastguard Worker		},
76*333d2b36SAndroid Build Coastguard Worker		{
77*333d2b36SAndroid Build Coastguard Worker			name: "invalid unqualified name",
78*333d2b36SAndroid Build Coastguard Worker			args: args{
79*333d2b36SAndroid Build Coastguard Worker				s: ":foo/bar",
80*333d2b36SAndroid Build Coastguard Worker			},
81*333d2b36SAndroid Build Coastguard Worker			wantModule: "",
82*333d2b36SAndroid Build Coastguard Worker		},
83*333d2b36SAndroid Build Coastguard Worker	}
84*333d2b36SAndroid Build Coastguard Worker	for _, tt := range tests {
85*333d2b36SAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
86*333d2b36SAndroid Build Coastguard Worker			if gotModule := SrcIsModule(tt.args.s); gotModule != tt.wantModule {
87*333d2b36SAndroid Build Coastguard Worker				t.Errorf("SrcIsModule() = %v, want %v", gotModule, tt.wantModule)
88*333d2b36SAndroid Build Coastguard Worker			}
89*333d2b36SAndroid Build Coastguard Worker		})
90*333d2b36SAndroid Build Coastguard Worker	}
91*333d2b36SAndroid Build Coastguard Worker}
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Workerfunc TestSrcIsModuleWithTag(t *testing.T) {
94*333d2b36SAndroid Build Coastguard Worker	type args struct {
95*333d2b36SAndroid Build Coastguard Worker		s string
96*333d2b36SAndroid Build Coastguard Worker	}
97*333d2b36SAndroid Build Coastguard Worker	tests := []struct {
98*333d2b36SAndroid Build Coastguard Worker		name       string
99*333d2b36SAndroid Build Coastguard Worker		args       args
100*333d2b36SAndroid Build Coastguard Worker		wantModule string
101*333d2b36SAndroid Build Coastguard Worker		wantTag    string
102*333d2b36SAndroid Build Coastguard Worker	}{
103*333d2b36SAndroid Build Coastguard Worker		{
104*333d2b36SAndroid Build Coastguard Worker			name: "file",
105*333d2b36SAndroid Build Coastguard Worker			args: args{
106*333d2b36SAndroid Build Coastguard Worker				s: "foo",
107*333d2b36SAndroid Build Coastguard Worker			},
108*333d2b36SAndroid Build Coastguard Worker			wantModule: "",
109*333d2b36SAndroid Build Coastguard Worker			wantTag:    "",
110*333d2b36SAndroid Build Coastguard Worker		},
111*333d2b36SAndroid Build Coastguard Worker		{
112*333d2b36SAndroid Build Coastguard Worker			name: "module",
113*333d2b36SAndroid Build Coastguard Worker			args: args{
114*333d2b36SAndroid Build Coastguard Worker				s: ":foo",
115*333d2b36SAndroid Build Coastguard Worker			},
116*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo",
117*333d2b36SAndroid Build Coastguard Worker			wantTag:    "",
118*333d2b36SAndroid Build Coastguard Worker		},
119*333d2b36SAndroid Build Coastguard Worker		{
120*333d2b36SAndroid Build Coastguard Worker			name: "tag",
121*333d2b36SAndroid Build Coastguard Worker			args: args{
122*333d2b36SAndroid Build Coastguard Worker				s: ":foo{.bar}",
123*333d2b36SAndroid Build Coastguard Worker			},
124*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo",
125*333d2b36SAndroid Build Coastguard Worker			wantTag:    ".bar",
126*333d2b36SAndroid Build Coastguard Worker		},
127*333d2b36SAndroid Build Coastguard Worker		{
128*333d2b36SAndroid Build Coastguard Worker			name: "empty tag",
129*333d2b36SAndroid Build Coastguard Worker			args: args{
130*333d2b36SAndroid Build Coastguard Worker				s: ":foo{}",
131*333d2b36SAndroid Build Coastguard Worker			},
132*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo",
133*333d2b36SAndroid Build Coastguard Worker			wantTag:    "",
134*333d2b36SAndroid Build Coastguard Worker		},
135*333d2b36SAndroid Build Coastguard Worker		{
136*333d2b36SAndroid Build Coastguard Worker			name: "extra colon",
137*333d2b36SAndroid Build Coastguard Worker			args: args{
138*333d2b36SAndroid Build Coastguard Worker				s: ":foo:bar",
139*333d2b36SAndroid Build Coastguard Worker			},
140*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo:bar",
141*333d2b36SAndroid Build Coastguard Worker		},
142*333d2b36SAndroid Build Coastguard Worker		{
143*333d2b36SAndroid Build Coastguard Worker			name: "invalid tag",
144*333d2b36SAndroid Build Coastguard Worker			args: args{
145*333d2b36SAndroid Build Coastguard Worker				s: ":foo{.bar",
146*333d2b36SAndroid Build Coastguard Worker			},
147*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo{.bar",
148*333d2b36SAndroid Build Coastguard Worker		},
149*333d2b36SAndroid Build Coastguard Worker		{
150*333d2b36SAndroid Build Coastguard Worker			name: "invalid tag 2",
151*333d2b36SAndroid Build Coastguard Worker			args: args{
152*333d2b36SAndroid Build Coastguard Worker				s: ":foo.bar}",
153*333d2b36SAndroid Build Coastguard Worker			},
154*333d2b36SAndroid Build Coastguard Worker			wantModule: "foo.bar}",
155*333d2b36SAndroid Build Coastguard Worker		},
156*333d2b36SAndroid Build Coastguard Worker		{
157*333d2b36SAndroid Build Coastguard Worker			name: "fully qualified",
158*333d2b36SAndroid Build Coastguard Worker			args: args{
159*333d2b36SAndroid Build Coastguard Worker				s: "//foo:bar",
160*333d2b36SAndroid Build Coastguard Worker			},
161*333d2b36SAndroid Build Coastguard Worker			wantModule: "//foo:bar",
162*333d2b36SAndroid Build Coastguard Worker		},
163*333d2b36SAndroid Build Coastguard Worker		{
164*333d2b36SAndroid Build Coastguard Worker			name: "fully qualified with tag",
165*333d2b36SAndroid Build Coastguard Worker			args: args{
166*333d2b36SAndroid Build Coastguard Worker				s: "//foo:bar{.tag}",
167*333d2b36SAndroid Build Coastguard Worker			},
168*333d2b36SAndroid Build Coastguard Worker			wantModule: "//foo:bar",
169*333d2b36SAndroid Build Coastguard Worker			wantTag:    ".tag",
170*333d2b36SAndroid Build Coastguard Worker		},
171*333d2b36SAndroid Build Coastguard Worker		{
172*333d2b36SAndroid Build Coastguard Worker			name: "invalid unqualified name",
173*333d2b36SAndroid Build Coastguard Worker			args: args{
174*333d2b36SAndroid Build Coastguard Worker				s: ":foo/bar",
175*333d2b36SAndroid Build Coastguard Worker			},
176*333d2b36SAndroid Build Coastguard Worker			wantModule: "",
177*333d2b36SAndroid Build Coastguard Worker		},
178*333d2b36SAndroid Build Coastguard Worker		{
179*333d2b36SAndroid Build Coastguard Worker			name: "invalid unqualified name with tag",
180*333d2b36SAndroid Build Coastguard Worker			args: args{
181*333d2b36SAndroid Build Coastguard Worker				s: ":foo/bar{.tag}",
182*333d2b36SAndroid Build Coastguard Worker			},
183*333d2b36SAndroid Build Coastguard Worker			wantModule: "",
184*333d2b36SAndroid Build Coastguard Worker		},
185*333d2b36SAndroid Build Coastguard Worker	}
186*333d2b36SAndroid Build Coastguard Worker	for _, tt := range tests {
187*333d2b36SAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
188*333d2b36SAndroid Build Coastguard Worker			gotModule, gotTag := SrcIsModuleWithTag(tt.args.s)
189*333d2b36SAndroid Build Coastguard Worker			if gotModule != tt.wantModule {
190*333d2b36SAndroid Build Coastguard Worker				t.Errorf("SrcIsModuleWithTag() gotModule = %v, want %v", gotModule, tt.wantModule)
191*333d2b36SAndroid Build Coastguard Worker			}
192*333d2b36SAndroid Build Coastguard Worker			if gotTag != tt.wantTag {
193*333d2b36SAndroid Build Coastguard Worker				t.Errorf("SrcIsModuleWithTag() gotTag = %v, want %v", gotTag, tt.wantTag)
194*333d2b36SAndroid Build Coastguard Worker			}
195*333d2b36SAndroid Build Coastguard Worker		})
196*333d2b36SAndroid Build Coastguard Worker	}
197*333d2b36SAndroid Build Coastguard Worker}
198*333d2b36SAndroid Build Coastguard Worker
199*333d2b36SAndroid Build Coastguard Workertype depsModule struct {
200*333d2b36SAndroid Build Coastguard Worker	ModuleBase
201*333d2b36SAndroid Build Coastguard Worker	props struct {
202*333d2b36SAndroid Build Coastguard Worker		Deps []string
203*333d2b36SAndroid Build Coastguard Worker	}
204*333d2b36SAndroid Build Coastguard Worker}
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Workerfunc (m *depsModule) GenerateAndroidBuildActions(ctx ModuleContext) {
207*333d2b36SAndroid Build Coastguard Worker	outputFile := PathForModuleOut(ctx, ctx.ModuleName())
208*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, BuildParams{
209*333d2b36SAndroid Build Coastguard Worker		Rule:   Touch,
210*333d2b36SAndroid Build Coastguard Worker		Output: outputFile,
211*333d2b36SAndroid Build Coastguard Worker	})
212*333d2b36SAndroid Build Coastguard Worker	installFile := ctx.InstallFile(PathForModuleInstall(ctx), ctx.ModuleName(), outputFile)
213*333d2b36SAndroid Build Coastguard Worker	ctx.InstallSymlink(PathForModuleInstall(ctx, "symlinks"), ctx.ModuleName(), installFile)
214*333d2b36SAndroid Build Coastguard Worker}
215*333d2b36SAndroid Build Coastguard Worker
216*333d2b36SAndroid Build Coastguard Workerfunc (m *depsModule) DepsMutator(ctx BottomUpMutatorContext) {
217*333d2b36SAndroid Build Coastguard Worker	ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
218*333d2b36SAndroid Build Coastguard Worker}
219*333d2b36SAndroid Build Coastguard Worker
220*333d2b36SAndroid Build Coastguard Workerfunc depsModuleFactory() Module {
221*333d2b36SAndroid Build Coastguard Worker	m := &depsModule{}
222*333d2b36SAndroid Build Coastguard Worker	m.AddProperties(&m.props)
223*333d2b36SAndroid Build Coastguard Worker	InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
224*333d2b36SAndroid Build Coastguard Worker	return m
225*333d2b36SAndroid Build Coastguard Worker}
226*333d2b36SAndroid Build Coastguard Worker
227*333d2b36SAndroid Build Coastguard Workervar prepareForModuleTests = FixtureRegisterWithContext(func(ctx RegistrationContext) {
228*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("deps", depsModuleFactory)
229*333d2b36SAndroid Build Coastguard Worker})
230*333d2b36SAndroid Build Coastguard Worker
231*333d2b36SAndroid Build Coastguard Workerfunc TestErrorDependsOnDisabledModule(t *testing.T) {
232*333d2b36SAndroid Build Coastguard Worker	bp := `
233*333d2b36SAndroid Build Coastguard Worker		deps {
234*333d2b36SAndroid Build Coastguard Worker			name: "foo",
235*333d2b36SAndroid Build Coastguard Worker			deps: ["bar"],
236*333d2b36SAndroid Build Coastguard Worker		}
237*333d2b36SAndroid Build Coastguard Worker		deps {
238*333d2b36SAndroid Build Coastguard Worker			name: "bar",
239*333d2b36SAndroid Build Coastguard Worker			enabled: false,
240*333d2b36SAndroid Build Coastguard Worker		}
241*333d2b36SAndroid Build Coastguard Worker	`
242*333d2b36SAndroid Build Coastguard Worker
243*333d2b36SAndroid Build Coastguard Worker	prepareForModuleTests.
244*333d2b36SAndroid Build Coastguard Worker		ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": depends on disabled module "bar"`)).
245*333d2b36SAndroid Build Coastguard Worker		RunTestWithBp(t, bp)
246*333d2b36SAndroid Build Coastguard Worker}
247*333d2b36SAndroid Build Coastguard Worker
248*333d2b36SAndroid Build Coastguard Workerfunc TestDistErrorChecking(t *testing.T) {
249*333d2b36SAndroid Build Coastguard Worker	bp := `
250*333d2b36SAndroid Build Coastguard Worker		deps {
251*333d2b36SAndroid Build Coastguard Worker			name: "foo",
252*333d2b36SAndroid Build Coastguard Worker      dist: {
253*333d2b36SAndroid Build Coastguard Worker        dest: "../invalid-dest",
254*333d2b36SAndroid Build Coastguard Worker        dir: "../invalid-dir",
255*333d2b36SAndroid Build Coastguard Worker        suffix: "invalid/suffix",
256*333d2b36SAndroid Build Coastguard Worker      },
257*333d2b36SAndroid Build Coastguard Worker      dists: [
258*333d2b36SAndroid Build Coastguard Worker        {
259*333d2b36SAndroid Build Coastguard Worker          dest: "../invalid-dest0",
260*333d2b36SAndroid Build Coastguard Worker          dir: "../invalid-dir0",
261*333d2b36SAndroid Build Coastguard Worker          suffix: "invalid/suffix0",
262*333d2b36SAndroid Build Coastguard Worker        },
263*333d2b36SAndroid Build Coastguard Worker        {
264*333d2b36SAndroid Build Coastguard Worker          dest: "../invalid-dest1",
265*333d2b36SAndroid Build Coastguard Worker          dir: "../invalid-dir1",
266*333d2b36SAndroid Build Coastguard Worker          suffix: "invalid/suffix1",
267*333d2b36SAndroid Build Coastguard Worker        },
268*333d2b36SAndroid Build Coastguard Worker      ],
269*333d2b36SAndroid Build Coastguard Worker 		}
270*333d2b36SAndroid Build Coastguard Worker	`
271*333d2b36SAndroid Build Coastguard Worker
272*333d2b36SAndroid Build Coastguard Worker	expectedErrs := []string{
273*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:5:13: module \"foo\": dist.dest: Path is outside directory: ../invalid-dest\\E",
274*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:6:12: module \"foo\": dist.dir: Path is outside directory: ../invalid-dir\\E",
275*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:7:15: module \"foo\": dist.suffix: Suffix may not contain a '/' character.\\E",
276*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:11:15: module \"foo\": dists[0].dest: Path is outside directory: ../invalid-dest0\\E",
277*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:12:14: module \"foo\": dists[0].dir: Path is outside directory: ../invalid-dir0\\E",
278*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:13:17: module \"foo\": dists[0].suffix: Suffix may not contain a '/' character.\\E",
279*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:16:15: module \"foo\": dists[1].dest: Path is outside directory: ../invalid-dest1\\E",
280*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:17:14: module \"foo\": dists[1].dir: Path is outside directory: ../invalid-dir1\\E",
281*333d2b36SAndroid Build Coastguard Worker		"\\QAndroid.bp:18:17: module \"foo\": dists[1].suffix: Suffix may not contain a '/' character.\\E",
282*333d2b36SAndroid Build Coastguard Worker	}
283*333d2b36SAndroid Build Coastguard Worker
284*333d2b36SAndroid Build Coastguard Worker	prepareForModuleTests.
285*333d2b36SAndroid Build Coastguard Worker		ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(expectedErrs)).
286*333d2b36SAndroid Build Coastguard Worker		RunTestWithBp(t, bp)
287*333d2b36SAndroid Build Coastguard Worker}
288*333d2b36SAndroid Build Coastguard Worker
289*333d2b36SAndroid Build Coastguard Workerfunc TestInstall(t *testing.T) {
290*333d2b36SAndroid Build Coastguard Worker	if runtime.GOOS != "linux" {
291*333d2b36SAndroid Build Coastguard Worker		t.Skip("requires linux")
292*333d2b36SAndroid Build Coastguard Worker	}
293*333d2b36SAndroid Build Coastguard Worker	bp := `
294*333d2b36SAndroid Build Coastguard Worker		deps {
295*333d2b36SAndroid Build Coastguard Worker			name: "foo",
296*333d2b36SAndroid Build Coastguard Worker			deps: ["bar"],
297*333d2b36SAndroid Build Coastguard Worker		}
298*333d2b36SAndroid Build Coastguard Worker
299*333d2b36SAndroid Build Coastguard Worker		deps {
300*333d2b36SAndroid Build Coastguard Worker			name: "bar",
301*333d2b36SAndroid Build Coastguard Worker			deps: ["baz", "qux"],
302*333d2b36SAndroid Build Coastguard Worker		}
303*333d2b36SAndroid Build Coastguard Worker
304*333d2b36SAndroid Build Coastguard Worker		deps {
305*333d2b36SAndroid Build Coastguard Worker			name: "baz",
306*333d2b36SAndroid Build Coastguard Worker			deps: ["qux"],
307*333d2b36SAndroid Build Coastguard Worker		}
308*333d2b36SAndroid Build Coastguard Worker
309*333d2b36SAndroid Build Coastguard Worker		deps {
310*333d2b36SAndroid Build Coastguard Worker			name: "qux",
311*333d2b36SAndroid Build Coastguard Worker		}
312*333d2b36SAndroid Build Coastguard Worker	`
313*333d2b36SAndroid Build Coastguard Worker
314*333d2b36SAndroid Build Coastguard Worker	result := GroupFixturePreparers(
315*333d2b36SAndroid Build Coastguard Worker		prepareForModuleTests,
316*333d2b36SAndroid Build Coastguard Worker		PrepareForTestWithArchMutator,
317*333d2b36SAndroid Build Coastguard Worker	).RunTestWithBp(t, bp)
318*333d2b36SAndroid Build Coastguard Worker
319*333d2b36SAndroid Build Coastguard Worker	module := func(name string, host bool) TestingModule {
320*333d2b36SAndroid Build Coastguard Worker		variant := "android_common"
321*333d2b36SAndroid Build Coastguard Worker		if host {
322*333d2b36SAndroid Build Coastguard Worker			variant = result.Config.BuildOSCommonTarget.String()
323*333d2b36SAndroid Build Coastguard Worker		}
324*333d2b36SAndroid Build Coastguard Worker		return result.ModuleForTests(name, variant)
325*333d2b36SAndroid Build Coastguard Worker	}
326*333d2b36SAndroid Build Coastguard Worker
327*333d2b36SAndroid Build Coastguard Worker	outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
328*333d2b36SAndroid Build Coastguard Worker
329*333d2b36SAndroid Build Coastguard Worker	installRule := func(name string) TestingBuildParams {
330*333d2b36SAndroid Build Coastguard Worker		return module(name, false).Output(filepath.Join("out/soong/target/product/test_device/system", name))
331*333d2b36SAndroid Build Coastguard Worker	}
332*333d2b36SAndroid Build Coastguard Worker
333*333d2b36SAndroid Build Coastguard Worker	symlinkRule := func(name string) TestingBuildParams {
334*333d2b36SAndroid Build Coastguard Worker		return module(name, false).Output(filepath.Join("out/soong/target/product/test_device/system/symlinks", name))
335*333d2b36SAndroid Build Coastguard Worker	}
336*333d2b36SAndroid Build Coastguard Worker
337*333d2b36SAndroid Build Coastguard Worker	hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }
338*333d2b36SAndroid Build Coastguard Worker
339*333d2b36SAndroid Build Coastguard Worker	hostInstallRule := func(name string) TestingBuildParams {
340*333d2b36SAndroid Build Coastguard Worker		return module(name, true).Output(filepath.Join("out/soong/host/linux-x86", name))
341*333d2b36SAndroid Build Coastguard Worker	}
342*333d2b36SAndroid Build Coastguard Worker
343*333d2b36SAndroid Build Coastguard Worker	hostSymlinkRule := func(name string) TestingBuildParams {
344*333d2b36SAndroid Build Coastguard Worker		return module(name, true).Output(filepath.Join("out/soong/host/linux-x86/symlinks", name))
345*333d2b36SAndroid Build Coastguard Worker	}
346*333d2b36SAndroid Build Coastguard Worker
347*333d2b36SAndroid Build Coastguard Worker	assertInputs := func(params TestingBuildParams, inputs ...Path) {
348*333d2b36SAndroid Build Coastguard Worker		t.Helper()
349*333d2b36SAndroid Build Coastguard Worker		AssertArrayString(t, "expected inputs", Paths(inputs).Strings(),
350*333d2b36SAndroid Build Coastguard Worker			append(PathsIfNonNil(params.Input), params.Inputs...).Strings())
351*333d2b36SAndroid Build Coastguard Worker	}
352*333d2b36SAndroid Build Coastguard Worker
353*333d2b36SAndroid Build Coastguard Worker	assertImplicits := func(params TestingBuildParams, implicits ...Path) {
354*333d2b36SAndroid Build Coastguard Worker		t.Helper()
355*333d2b36SAndroid Build Coastguard Worker		AssertArrayString(t, "expected implicit dependencies", Paths(implicits).Strings(),
356*333d2b36SAndroid Build Coastguard Worker			append(PathsIfNonNil(params.Implicit), params.Implicits...).Strings())
357*333d2b36SAndroid Build Coastguard Worker	}
358*333d2b36SAndroid Build Coastguard Worker
359*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys := func(params TestingBuildParams, orderonlys ...Path) {
360*333d2b36SAndroid Build Coastguard Worker		t.Helper()
361*333d2b36SAndroid Build Coastguard Worker		AssertArrayString(t, "expected orderonly dependencies", Paths(orderonlys).Strings(),
362*333d2b36SAndroid Build Coastguard Worker			params.OrderOnly.Strings())
363*333d2b36SAndroid Build Coastguard Worker	}
364*333d2b36SAndroid Build Coastguard Worker
365*333d2b36SAndroid Build Coastguard Worker	// Check host install rule dependencies
366*333d2b36SAndroid Build Coastguard Worker	assertInputs(hostInstallRule("foo"), hostOutputRule("foo").Output)
367*333d2b36SAndroid Build Coastguard Worker	assertImplicits(hostInstallRule("foo"),
368*333d2b36SAndroid Build Coastguard Worker		hostInstallRule("bar").Output,
369*333d2b36SAndroid Build Coastguard Worker		hostSymlinkRule("bar").Output,
370*333d2b36SAndroid Build Coastguard Worker		hostInstallRule("baz").Output,
371*333d2b36SAndroid Build Coastguard Worker		hostSymlinkRule("baz").Output,
372*333d2b36SAndroid Build Coastguard Worker		hostInstallRule("qux").Output,
373*333d2b36SAndroid Build Coastguard Worker		hostSymlinkRule("qux").Output,
374*333d2b36SAndroid Build Coastguard Worker	)
375*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys(hostInstallRule("foo"))
376*333d2b36SAndroid Build Coastguard Worker
377*333d2b36SAndroid Build Coastguard Worker	// Check host symlink rule dependencies.  Host symlinks must use a normal dependency, not an
378*333d2b36SAndroid Build Coastguard Worker	// order-only dependency, so that the tool gets updated when the symlink is depended on.
379*333d2b36SAndroid Build Coastguard Worker	assertInputs(hostSymlinkRule("foo"), hostInstallRule("foo").Output)
380*333d2b36SAndroid Build Coastguard Worker	assertImplicits(hostSymlinkRule("foo"))
381*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys(hostSymlinkRule("foo"))
382*333d2b36SAndroid Build Coastguard Worker
383*333d2b36SAndroid Build Coastguard Worker	// Check device install rule dependencies
384*333d2b36SAndroid Build Coastguard Worker	assertInputs(installRule("foo"), outputRule("foo").Output)
385*333d2b36SAndroid Build Coastguard Worker	assertImplicits(installRule("foo"))
386*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys(installRule("foo"),
387*333d2b36SAndroid Build Coastguard Worker		installRule("bar").Output,
388*333d2b36SAndroid Build Coastguard Worker		symlinkRule("bar").Output,
389*333d2b36SAndroid Build Coastguard Worker		installRule("baz").Output,
390*333d2b36SAndroid Build Coastguard Worker		symlinkRule("baz").Output,
391*333d2b36SAndroid Build Coastguard Worker		installRule("qux").Output,
392*333d2b36SAndroid Build Coastguard Worker		symlinkRule("qux").Output,
393*333d2b36SAndroid Build Coastguard Worker	)
394*333d2b36SAndroid Build Coastguard Worker
395*333d2b36SAndroid Build Coastguard Worker	// Check device symlink rule dependencies.  Device symlinks could use an order-only dependency,
396*333d2b36SAndroid Build Coastguard Worker	// but the current implementation uses a normal dependency.
397*333d2b36SAndroid Build Coastguard Worker	assertInputs(symlinkRule("foo"), installRule("foo").Output)
398*333d2b36SAndroid Build Coastguard Worker	assertImplicits(symlinkRule("foo"))
399*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys(symlinkRule("foo"))
400*333d2b36SAndroid Build Coastguard Worker}
401*333d2b36SAndroid Build Coastguard Worker
402*333d2b36SAndroid Build Coastguard Workerfunc TestInstallKatiEnabled(t *testing.T) {
403*333d2b36SAndroid Build Coastguard Worker	if runtime.GOOS != "linux" {
404*333d2b36SAndroid Build Coastguard Worker		t.Skip("requires linux")
405*333d2b36SAndroid Build Coastguard Worker	}
406*333d2b36SAndroid Build Coastguard Worker	bp := `
407*333d2b36SAndroid Build Coastguard Worker		deps {
408*333d2b36SAndroid Build Coastguard Worker			name: "foo",
409*333d2b36SAndroid Build Coastguard Worker			deps: ["bar"],
410*333d2b36SAndroid Build Coastguard Worker		}
411*333d2b36SAndroid Build Coastguard Worker
412*333d2b36SAndroid Build Coastguard Worker		deps {
413*333d2b36SAndroid Build Coastguard Worker			name: "bar",
414*333d2b36SAndroid Build Coastguard Worker			deps: ["baz", "qux"],
415*333d2b36SAndroid Build Coastguard Worker		}
416*333d2b36SAndroid Build Coastguard Worker
417*333d2b36SAndroid Build Coastguard Worker		deps {
418*333d2b36SAndroid Build Coastguard Worker			name: "baz",
419*333d2b36SAndroid Build Coastguard Worker			deps: ["qux"],
420*333d2b36SAndroid Build Coastguard Worker		}
421*333d2b36SAndroid Build Coastguard Worker
422*333d2b36SAndroid Build Coastguard Worker		deps {
423*333d2b36SAndroid Build Coastguard Worker			name: "qux",
424*333d2b36SAndroid Build Coastguard Worker		}
425*333d2b36SAndroid Build Coastguard Worker	`
426*333d2b36SAndroid Build Coastguard Worker
427*333d2b36SAndroid Build Coastguard Worker	result := GroupFixturePreparers(
428*333d2b36SAndroid Build Coastguard Worker		prepareForModuleTests,
429*333d2b36SAndroid Build Coastguard Worker		PrepareForTestWithArchMutator,
430*333d2b36SAndroid Build Coastguard Worker		FixtureModifyConfig(SetKatiEnabledForTests),
431*333d2b36SAndroid Build Coastguard Worker		PrepareForTestWithMakevars,
432*333d2b36SAndroid Build Coastguard Worker	).RunTestWithBp(t, bp)
433*333d2b36SAndroid Build Coastguard Worker
434*333d2b36SAndroid Build Coastguard Worker	rules := result.InstallMakeRulesForTesting(t)
435*333d2b36SAndroid Build Coastguard Worker
436*333d2b36SAndroid Build Coastguard Worker	module := func(name string, host bool) TestingModule {
437*333d2b36SAndroid Build Coastguard Worker		variant := "android_common"
438*333d2b36SAndroid Build Coastguard Worker		if host {
439*333d2b36SAndroid Build Coastguard Worker			variant = result.Config.BuildOSCommonTarget.String()
440*333d2b36SAndroid Build Coastguard Worker		}
441*333d2b36SAndroid Build Coastguard Worker		return result.ModuleForTests(name, variant)
442*333d2b36SAndroid Build Coastguard Worker	}
443*333d2b36SAndroid Build Coastguard Worker
444*333d2b36SAndroid Build Coastguard Worker	outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
445*333d2b36SAndroid Build Coastguard Worker
446*333d2b36SAndroid Build Coastguard Worker	ruleForOutput := func(output string) InstallMakeRule {
447*333d2b36SAndroid Build Coastguard Worker		for _, rule := range rules {
448*333d2b36SAndroid Build Coastguard Worker			if rule.Target == output {
449*333d2b36SAndroid Build Coastguard Worker				return rule
450*333d2b36SAndroid Build Coastguard Worker			}
451*333d2b36SAndroid Build Coastguard Worker		}
452*333d2b36SAndroid Build Coastguard Worker		t.Fatalf("no make install rule for %s", output)
453*333d2b36SAndroid Build Coastguard Worker		return InstallMakeRule{}
454*333d2b36SAndroid Build Coastguard Worker	}
455*333d2b36SAndroid Build Coastguard Worker
456*333d2b36SAndroid Build Coastguard Worker	installRule := func(name string) InstallMakeRule {
457*333d2b36SAndroid Build Coastguard Worker		return ruleForOutput(filepath.Join("out/target/product/test_device/system", name))
458*333d2b36SAndroid Build Coastguard Worker	}
459*333d2b36SAndroid Build Coastguard Worker
460*333d2b36SAndroid Build Coastguard Worker	symlinkRule := func(name string) InstallMakeRule {
461*333d2b36SAndroid Build Coastguard Worker		return ruleForOutput(filepath.Join("out/target/product/test_device/system/symlinks", name))
462*333d2b36SAndroid Build Coastguard Worker	}
463*333d2b36SAndroid Build Coastguard Worker
464*333d2b36SAndroid Build Coastguard Worker	hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }
465*333d2b36SAndroid Build Coastguard Worker
466*333d2b36SAndroid Build Coastguard Worker	hostInstallRule := func(name string) InstallMakeRule {
467*333d2b36SAndroid Build Coastguard Worker		return ruleForOutput(filepath.Join("out/host/linux-x86", name))
468*333d2b36SAndroid Build Coastguard Worker	}
469*333d2b36SAndroid Build Coastguard Worker
470*333d2b36SAndroid Build Coastguard Worker	hostSymlinkRule := func(name string) InstallMakeRule {
471*333d2b36SAndroid Build Coastguard Worker		return ruleForOutput(filepath.Join("out/host/linux-x86/symlinks", name))
472*333d2b36SAndroid Build Coastguard Worker	}
473*333d2b36SAndroid Build Coastguard Worker
474*333d2b36SAndroid Build Coastguard Worker	assertDeps := func(rule InstallMakeRule, deps ...string) {
475*333d2b36SAndroid Build Coastguard Worker		t.Helper()
476*333d2b36SAndroid Build Coastguard Worker		AssertArrayString(t, "expected inputs", deps, rule.Deps)
477*333d2b36SAndroid Build Coastguard Worker	}
478*333d2b36SAndroid Build Coastguard Worker
479*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys := func(rule InstallMakeRule, orderonlys ...string) {
480*333d2b36SAndroid Build Coastguard Worker		t.Helper()
481*333d2b36SAndroid Build Coastguard Worker		AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.OrderOnlyDeps)
482*333d2b36SAndroid Build Coastguard Worker	}
483*333d2b36SAndroid Build Coastguard Worker
484*333d2b36SAndroid Build Coastguard Worker	// Check host install rule dependencies
485*333d2b36SAndroid Build Coastguard Worker	assertDeps(hostInstallRule("foo"),
486*333d2b36SAndroid Build Coastguard Worker		hostOutputRule("foo").Output.String(),
487*333d2b36SAndroid Build Coastguard Worker		hostInstallRule("bar").Target,
488*333d2b36SAndroid Build Coastguard Worker		hostSymlinkRule("bar").Target,
489*333d2b36SAndroid Build Coastguard Worker		hostInstallRule("baz").Target,
490*333d2b36SAndroid Build Coastguard Worker		hostSymlinkRule("baz").Target,
491*333d2b36SAndroid Build Coastguard Worker		hostInstallRule("qux").Target,
492*333d2b36SAndroid Build Coastguard Worker		hostSymlinkRule("qux").Target,
493*333d2b36SAndroid Build Coastguard Worker	)
494*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys(hostInstallRule("foo"))
495*333d2b36SAndroid Build Coastguard Worker
496*333d2b36SAndroid Build Coastguard Worker	// Check host symlink rule dependencies.  Host symlinks must use a normal dependency, not an
497*333d2b36SAndroid Build Coastguard Worker	// order-only dependency, so that the tool gets updated when the symlink is depended on.
498*333d2b36SAndroid Build Coastguard Worker	assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").Target)
499*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys(hostSymlinkRule("foo"))
500*333d2b36SAndroid Build Coastguard Worker
501*333d2b36SAndroid Build Coastguard Worker	// Check device install rule dependencies
502*333d2b36SAndroid Build Coastguard Worker	assertDeps(installRule("foo"), outputRule("foo").Output.String())
503*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys(installRule("foo"),
504*333d2b36SAndroid Build Coastguard Worker		installRule("bar").Target,
505*333d2b36SAndroid Build Coastguard Worker		symlinkRule("bar").Target,
506*333d2b36SAndroid Build Coastguard Worker		installRule("baz").Target,
507*333d2b36SAndroid Build Coastguard Worker		symlinkRule("baz").Target,
508*333d2b36SAndroid Build Coastguard Worker		installRule("qux").Target,
509*333d2b36SAndroid Build Coastguard Worker		symlinkRule("qux").Target,
510*333d2b36SAndroid Build Coastguard Worker	)
511*333d2b36SAndroid Build Coastguard Worker
512*333d2b36SAndroid Build Coastguard Worker	// Check device symlink rule dependencies.  Device symlinks could use an order-only dependency,
513*333d2b36SAndroid Build Coastguard Worker	// but the current implementation uses a normal dependency.
514*333d2b36SAndroid Build Coastguard Worker	assertDeps(symlinkRule("foo"), installRule("foo").Target)
515*333d2b36SAndroid Build Coastguard Worker	assertOrderOnlys(symlinkRule("foo"))
516*333d2b36SAndroid Build Coastguard Worker}
517*333d2b36SAndroid Build Coastguard Worker
518*333d2b36SAndroid Build Coastguard Workertype PropsTestModuleEmbedded struct {
519*333d2b36SAndroid Build Coastguard Worker	Embedded_prop *string
520*333d2b36SAndroid Build Coastguard Worker}
521*333d2b36SAndroid Build Coastguard Worker
522*333d2b36SAndroid Build Coastguard Workertype StructInSlice struct {
523*333d2b36SAndroid Build Coastguard Worker	G string
524*333d2b36SAndroid Build Coastguard Worker	H bool
525*333d2b36SAndroid Build Coastguard Worker	I []string
526*333d2b36SAndroid Build Coastguard Worker}
527*333d2b36SAndroid Build Coastguard Worker
528*333d2b36SAndroid Build Coastguard Workertype propsTestModule struct {
529*333d2b36SAndroid Build Coastguard Worker	ModuleBase
530*333d2b36SAndroid Build Coastguard Worker	DefaultableModuleBase
531*333d2b36SAndroid Build Coastguard Worker	props struct {
532*333d2b36SAndroid Build Coastguard Worker		A string `android:"arch_variant"`
533*333d2b36SAndroid Build Coastguard Worker		B *bool
534*333d2b36SAndroid Build Coastguard Worker		C []string
535*333d2b36SAndroid Build Coastguard Worker	}
536*333d2b36SAndroid Build Coastguard Worker	otherProps struct {
537*333d2b36SAndroid Build Coastguard Worker		PropsTestModuleEmbedded
538*333d2b36SAndroid Build Coastguard Worker
539*333d2b36SAndroid Build Coastguard Worker		D      *int64
540*333d2b36SAndroid Build Coastguard Worker		Nested struct {
541*333d2b36SAndroid Build Coastguard Worker			E *string
542*333d2b36SAndroid Build Coastguard Worker		}
543*333d2b36SAndroid Build Coastguard Worker		F *string `blueprint:"mutated"`
544*333d2b36SAndroid Build Coastguard Worker
545*333d2b36SAndroid Build Coastguard Worker		Slice_of_struct []StructInSlice
546*333d2b36SAndroid Build Coastguard Worker	}
547*333d2b36SAndroid Build Coastguard Worker}
548*333d2b36SAndroid Build Coastguard Worker
549*333d2b36SAndroid Build Coastguard Workerfunc propsTestModuleFactory() Module {
550*333d2b36SAndroid Build Coastguard Worker	module := &propsTestModule{}
551*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.props, &module.otherProps)
552*333d2b36SAndroid Build Coastguard Worker	InitAndroidArchModule(module, HostAndDeviceSupported, MultilibBoth)
553*333d2b36SAndroid Build Coastguard Worker	InitDefaultableModule(module)
554*333d2b36SAndroid Build Coastguard Worker	return module
555*333d2b36SAndroid Build Coastguard Worker}
556*333d2b36SAndroid Build Coastguard Worker
557*333d2b36SAndroid Build Coastguard Workertype propsTestModuleDefaults struct {
558*333d2b36SAndroid Build Coastguard Worker	ModuleBase
559*333d2b36SAndroid Build Coastguard Worker	DefaultsModuleBase
560*333d2b36SAndroid Build Coastguard Worker}
561*333d2b36SAndroid Build Coastguard Worker
562*333d2b36SAndroid Build Coastguard Workerfunc propsTestModuleDefaultsFactory() Module {
563*333d2b36SAndroid Build Coastguard Worker	defaults := &propsTestModuleDefaults{}
564*333d2b36SAndroid Build Coastguard Worker	module := propsTestModule{}
565*333d2b36SAndroid Build Coastguard Worker	defaults.AddProperties(&module.props, &module.otherProps)
566*333d2b36SAndroid Build Coastguard Worker	InitDefaultsModule(defaults)
567*333d2b36SAndroid Build Coastguard Worker	return defaults
568*333d2b36SAndroid Build Coastguard Worker}
569*333d2b36SAndroid Build Coastguard Worker
570*333d2b36SAndroid Build Coastguard Workerfunc (p *propsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
571*333d2b36SAndroid Build Coastguard Worker	str := "abc"
572*333d2b36SAndroid Build Coastguard Worker	p.otherProps.F = &str
573*333d2b36SAndroid Build Coastguard Worker}
574*333d2b36SAndroid Build Coastguard Worker
575*333d2b36SAndroid Build Coastguard Workerfunc TestUsedProperties(t *testing.T) {
576*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
577*333d2b36SAndroid Build Coastguard Worker		desc          string
578*333d2b36SAndroid Build Coastguard Worker		bp            string
579*333d2b36SAndroid Build Coastguard Worker		expectedProps []propInfo
580*333d2b36SAndroid Build Coastguard Worker	}{
581*333d2b36SAndroid Build Coastguard Worker		{
582*333d2b36SAndroid Build Coastguard Worker			desc: "only name",
583*333d2b36SAndroid Build Coastguard Worker			bp: `test {
584*333d2b36SAndroid Build Coastguard Worker			name: "foo",
585*333d2b36SAndroid Build Coastguard Worker		}
586*333d2b36SAndroid Build Coastguard Worker	`,
587*333d2b36SAndroid Build Coastguard Worker			expectedProps: []propInfo{
588*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Name", Type: "string", Value: "foo"},
589*333d2b36SAndroid Build Coastguard Worker			},
590*333d2b36SAndroid Build Coastguard Worker		},
591*333d2b36SAndroid Build Coastguard Worker		{
592*333d2b36SAndroid Build Coastguard Worker			desc: "some props",
593*333d2b36SAndroid Build Coastguard Worker			bp: `test {
594*333d2b36SAndroid Build Coastguard Worker			name: "foo",
595*333d2b36SAndroid Build Coastguard Worker			a: "abc",
596*333d2b36SAndroid Build Coastguard Worker			b: true,
597*333d2b36SAndroid Build Coastguard Worker			d: 123,
598*333d2b36SAndroid Build Coastguard Worker		}
599*333d2b36SAndroid Build Coastguard Worker	`,
600*333d2b36SAndroid Build Coastguard Worker			expectedProps: []propInfo{
601*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "A", Type: "string", Value: "abc"},
602*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "B", Type: "bool", Value: "true"},
603*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "D", Type: "int64", Value: "123"},
604*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Name", Type: "string", Value: "foo"},
605*333d2b36SAndroid Build Coastguard Worker			},
606*333d2b36SAndroid Build Coastguard Worker		},
607*333d2b36SAndroid Build Coastguard Worker		{
608*333d2b36SAndroid Build Coastguard Worker			desc: "unused non-pointer prop",
609*333d2b36SAndroid Build Coastguard Worker			bp: `test {
610*333d2b36SAndroid Build Coastguard Worker			name: "foo",
611*333d2b36SAndroid Build Coastguard Worker			b: true,
612*333d2b36SAndroid Build Coastguard Worker			d: 123,
613*333d2b36SAndroid Build Coastguard Worker		}
614*333d2b36SAndroid Build Coastguard Worker	`,
615*333d2b36SAndroid Build Coastguard Worker			expectedProps: []propInfo{
616*333d2b36SAndroid Build Coastguard Worker				// for non-pointer cannot distinguish between unused and intentionally set to empty
617*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "A", Type: "string", Value: ""},
618*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "B", Type: "bool", Value: "true"},
619*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "D", Type: "int64", Value: "123"},
620*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Name", Type: "string", Value: "foo"},
621*333d2b36SAndroid Build Coastguard Worker			},
622*333d2b36SAndroid Build Coastguard Worker		},
623*333d2b36SAndroid Build Coastguard Worker		{
624*333d2b36SAndroid Build Coastguard Worker			desc: "nested props",
625*333d2b36SAndroid Build Coastguard Worker			bp: `test {
626*333d2b36SAndroid Build Coastguard Worker			name: "foo",
627*333d2b36SAndroid Build Coastguard Worker			nested: {
628*333d2b36SAndroid Build Coastguard Worker				e: "abc",
629*333d2b36SAndroid Build Coastguard Worker			}
630*333d2b36SAndroid Build Coastguard Worker		}
631*333d2b36SAndroid Build Coastguard Worker	`,
632*333d2b36SAndroid Build Coastguard Worker			expectedProps: []propInfo{
633*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Name", Type: "string", Value: "foo"},
634*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Nested.E", Type: "string", Value: "abc"},
635*333d2b36SAndroid Build Coastguard Worker			},
636*333d2b36SAndroid Build Coastguard Worker		},
637*333d2b36SAndroid Build Coastguard Worker		{
638*333d2b36SAndroid Build Coastguard Worker			desc: "arch props",
639*333d2b36SAndroid Build Coastguard Worker			bp: `test {
640*333d2b36SAndroid Build Coastguard Worker			name: "foo",
641*333d2b36SAndroid Build Coastguard Worker			arch: {
642*333d2b36SAndroid Build Coastguard Worker				x86_64: {
643*333d2b36SAndroid Build Coastguard Worker					a: "abc",
644*333d2b36SAndroid Build Coastguard Worker				},
645*333d2b36SAndroid Build Coastguard Worker			}
646*333d2b36SAndroid Build Coastguard Worker		}
647*333d2b36SAndroid Build Coastguard Worker	`,
648*333d2b36SAndroid Build Coastguard Worker			expectedProps: []propInfo{
649*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "abc"},
650*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Name", Type: "string", Value: "foo"},
651*333d2b36SAndroid Build Coastguard Worker			},
652*333d2b36SAndroid Build Coastguard Worker		},
653*333d2b36SAndroid Build Coastguard Worker		{
654*333d2b36SAndroid Build Coastguard Worker			desc: "embedded props",
655*333d2b36SAndroid Build Coastguard Worker			bp: `test {
656*333d2b36SAndroid Build Coastguard Worker			name: "foo",
657*333d2b36SAndroid Build Coastguard Worker			embedded_prop: "a",
658*333d2b36SAndroid Build Coastguard Worker		}
659*333d2b36SAndroid Build Coastguard Worker	`,
660*333d2b36SAndroid Build Coastguard Worker			expectedProps: []propInfo{
661*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Embedded_prop", Type: "string", Value: "a"},
662*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Name", Type: "string", Value: "foo"},
663*333d2b36SAndroid Build Coastguard Worker			},
664*333d2b36SAndroid Build Coastguard Worker		},
665*333d2b36SAndroid Build Coastguard Worker		{
666*333d2b36SAndroid Build Coastguard Worker			desc: "struct slice",
667*333d2b36SAndroid Build Coastguard Worker			bp: `test {
668*333d2b36SAndroid Build Coastguard Worker			name: "foo",
669*333d2b36SAndroid Build Coastguard Worker			slice_of_struct: [
670*333d2b36SAndroid Build Coastguard Worker				{
671*333d2b36SAndroid Build Coastguard Worker					g: "abc",
672*333d2b36SAndroid Build Coastguard Worker					h: false,
673*333d2b36SAndroid Build Coastguard Worker					i: ["baz"],
674*333d2b36SAndroid Build Coastguard Worker				},
675*333d2b36SAndroid Build Coastguard Worker				{
676*333d2b36SAndroid Build Coastguard Worker					g: "def",
677*333d2b36SAndroid Build Coastguard Worker					h: true,
678*333d2b36SAndroid Build Coastguard Worker					i: [],
679*333d2b36SAndroid Build Coastguard Worker				},
680*333d2b36SAndroid Build Coastguard Worker			]
681*333d2b36SAndroid Build Coastguard Worker		}
682*333d2b36SAndroid Build Coastguard Worker	`,
683*333d2b36SAndroid Build Coastguard Worker			expectedProps: []propInfo{
684*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Name", Type: "string", Value: "foo"},
685*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Slice_of_struct", Type: "struct slice", Values: []string{
686*333d2b36SAndroid Build Coastguard Worker					`android.StructInSlice{G: abc, H: false, I: [baz]}`,
687*333d2b36SAndroid Build Coastguard Worker					`android.StructInSlice{G: def, H: true, I: []}`,
688*333d2b36SAndroid Build Coastguard Worker				}},
689*333d2b36SAndroid Build Coastguard Worker			},
690*333d2b36SAndroid Build Coastguard Worker		},
691*333d2b36SAndroid Build Coastguard Worker		{
692*333d2b36SAndroid Build Coastguard Worker			desc: "defaults",
693*333d2b36SAndroid Build Coastguard Worker			bp: `
694*333d2b36SAndroid Build Coastguard Workertest_defaults {
695*333d2b36SAndroid Build Coastguard Worker	name: "foo_defaults",
696*333d2b36SAndroid Build Coastguard Worker	a: "a",
697*333d2b36SAndroid Build Coastguard Worker	b: true,
698*333d2b36SAndroid Build Coastguard Worker	c: ["default_c"],
699*333d2b36SAndroid Build Coastguard Worker	embedded_prop:"a",
700*333d2b36SAndroid Build Coastguard Worker	arch: {
701*333d2b36SAndroid Build Coastguard Worker		x86_64: {
702*333d2b36SAndroid Build Coastguard Worker			a: "x86_64 a",
703*333d2b36SAndroid Build Coastguard Worker		},
704*333d2b36SAndroid Build Coastguard Worker	},
705*333d2b36SAndroid Build Coastguard Worker}
706*333d2b36SAndroid Build Coastguard Workertest {
707*333d2b36SAndroid Build Coastguard Worker	name: "foo",
708*333d2b36SAndroid Build Coastguard Worker	defaults: ["foo_defaults"],
709*333d2b36SAndroid Build Coastguard Worker	c: ["c"],
710*333d2b36SAndroid Build Coastguard Worker	nested: {
711*333d2b36SAndroid Build Coastguard Worker		e: "nested e",
712*333d2b36SAndroid Build Coastguard Worker	},
713*333d2b36SAndroid Build Coastguard Worker	target: {
714*333d2b36SAndroid Build Coastguard Worker		linux: {
715*333d2b36SAndroid Build Coastguard Worker			a: "a",
716*333d2b36SAndroid Build Coastguard Worker		},
717*333d2b36SAndroid Build Coastguard Worker	},
718*333d2b36SAndroid Build Coastguard Worker}
719*333d2b36SAndroid Build Coastguard Worker	`,
720*333d2b36SAndroid Build Coastguard Worker			expectedProps: []propInfo{
721*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "A", Type: "string", Value: "a"},
722*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "x86_64 a"},
723*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "B", Type: "bool", Value: "true"},
724*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "C", Type: "string slice", Values: []string{"default_c", "c"}},
725*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Defaults", Type: "string slice", Values: []string{"foo_defaults"}},
726*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Embedded_prop", Type: "string", Value: "a"},
727*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Name", Type: "string", Value: "foo"},
728*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Nested.E", Type: "string", Value: "nested e"},
729*333d2b36SAndroid Build Coastguard Worker				propInfo{Name: "Target.Linux.A", Type: "string", Value: "a"},
730*333d2b36SAndroid Build Coastguard Worker			},
731*333d2b36SAndroid Build Coastguard Worker		},
732*333d2b36SAndroid Build Coastguard Worker	}
733*333d2b36SAndroid Build Coastguard Worker
734*333d2b36SAndroid Build Coastguard Worker	for _, tc := range testCases {
735*333d2b36SAndroid Build Coastguard Worker		t.Run(tc.desc, func(t *testing.T) {
736*333d2b36SAndroid Build Coastguard Worker			result := GroupFixturePreparers(
737*333d2b36SAndroid Build Coastguard Worker				PrepareForTestWithAllowMissingDependencies,
738*333d2b36SAndroid Build Coastguard Worker				PrepareForTestWithDefaults,
739*333d2b36SAndroid Build Coastguard Worker				FixtureRegisterWithContext(func(ctx RegistrationContext) {
740*333d2b36SAndroid Build Coastguard Worker					ctx.RegisterModuleType("test", propsTestModuleFactory)
741*333d2b36SAndroid Build Coastguard Worker					ctx.RegisterModuleType("test_defaults", propsTestModuleDefaultsFactory)
742*333d2b36SAndroid Build Coastguard Worker				}),
743*333d2b36SAndroid Build Coastguard Worker				FixtureWithRootAndroidBp(tc.bp),
744*333d2b36SAndroid Build Coastguard Worker			).RunTest(t)
745*333d2b36SAndroid Build Coastguard Worker
746*333d2b36SAndroid Build Coastguard Worker			foo := result.ModuleForTests("foo", "").Module().base()
747*333d2b36SAndroid Build Coastguard Worker
748*333d2b36SAndroid Build Coastguard Worker			AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues())
749*333d2b36SAndroid Build Coastguard Worker		})
750*333d2b36SAndroid Build Coastguard Worker	}
751*333d2b36SAndroid Build Coastguard Worker}
752*333d2b36SAndroid Build Coastguard Worker
753*333d2b36SAndroid Build Coastguard Workerfunc TestSortedUniqueNamedPaths(t *testing.T) {
754*333d2b36SAndroid Build Coastguard Worker	type np struct {
755*333d2b36SAndroid Build Coastguard Worker		path, name string
756*333d2b36SAndroid Build Coastguard Worker	}
757*333d2b36SAndroid Build Coastguard Worker	makePaths := func(l []np) NamedPaths {
758*333d2b36SAndroid Build Coastguard Worker		result := make(NamedPaths, 0, len(l))
759*333d2b36SAndroid Build Coastguard Worker		for _, p := range l {
760*333d2b36SAndroid Build Coastguard Worker			result = append(result, NamedPath{PathForTesting(p.path), p.name})
761*333d2b36SAndroid Build Coastguard Worker		}
762*333d2b36SAndroid Build Coastguard Worker		return result
763*333d2b36SAndroid Build Coastguard Worker	}
764*333d2b36SAndroid Build Coastguard Worker
765*333d2b36SAndroid Build Coastguard Worker	tests := []struct {
766*333d2b36SAndroid Build Coastguard Worker		name        string
767*333d2b36SAndroid Build Coastguard Worker		in          []np
768*333d2b36SAndroid Build Coastguard Worker		expectedOut []np
769*333d2b36SAndroid Build Coastguard Worker	}{
770*333d2b36SAndroid Build Coastguard Worker		{
771*333d2b36SAndroid Build Coastguard Worker			name:        "empty",
772*333d2b36SAndroid Build Coastguard Worker			in:          []np{},
773*333d2b36SAndroid Build Coastguard Worker			expectedOut: []np{},
774*333d2b36SAndroid Build Coastguard Worker		},
775*333d2b36SAndroid Build Coastguard Worker		{
776*333d2b36SAndroid Build Coastguard Worker			name: "all_same",
777*333d2b36SAndroid Build Coastguard Worker			in: []np{
778*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "A"},
779*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "A"},
780*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "A"},
781*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "A"},
782*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "A"},
783*333d2b36SAndroid Build Coastguard Worker			},
784*333d2b36SAndroid Build Coastguard Worker			expectedOut: []np{
785*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "A"},
786*333d2b36SAndroid Build Coastguard Worker			},
787*333d2b36SAndroid Build Coastguard Worker		},
788*333d2b36SAndroid Build Coastguard Worker		{
789*333d2b36SAndroid Build Coastguard Worker			name: "same_path_different_names",
790*333d2b36SAndroid Build Coastguard Worker			in: []np{
791*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "C"},
792*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "A"},
793*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "D"},
794*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "B"},
795*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "E"},
796*333d2b36SAndroid Build Coastguard Worker			},
797*333d2b36SAndroid Build Coastguard Worker			expectedOut: []np{
798*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "A"},
799*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "B"},
800*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "C"},
801*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "D"},
802*333d2b36SAndroid Build Coastguard Worker				{"a.txt", "E"},
803*333d2b36SAndroid Build Coastguard Worker			},
804*333d2b36SAndroid Build Coastguard Worker		},
805*333d2b36SAndroid Build Coastguard Worker		{
806*333d2b36SAndroid Build Coastguard Worker			name: "different_paths_same_name",
807*333d2b36SAndroid Build Coastguard Worker			in: []np{
808*333d2b36SAndroid Build Coastguard Worker				{"b/b.txt", "A"},
809*333d2b36SAndroid Build Coastguard Worker				{"a/a.txt", "A"},
810*333d2b36SAndroid Build Coastguard Worker				{"a/txt", "A"},
811*333d2b36SAndroid Build Coastguard Worker				{"b", "A"},
812*333d2b36SAndroid Build Coastguard Worker				{"a/b/d", "A"},
813*333d2b36SAndroid Build Coastguard Worker			},
814*333d2b36SAndroid Build Coastguard Worker			expectedOut: []np{
815*333d2b36SAndroid Build Coastguard Worker				{"a/a.txt", "A"},
816*333d2b36SAndroid Build Coastguard Worker				{"a/b/d", "A"},
817*333d2b36SAndroid Build Coastguard Worker				{"a/txt", "A"},
818*333d2b36SAndroid Build Coastguard Worker				{"b/b.txt", "A"},
819*333d2b36SAndroid Build Coastguard Worker				{"b", "A"},
820*333d2b36SAndroid Build Coastguard Worker			},
821*333d2b36SAndroid Build Coastguard Worker		},
822*333d2b36SAndroid Build Coastguard Worker		{
823*333d2b36SAndroid Build Coastguard Worker			name: "all_different",
824*333d2b36SAndroid Build Coastguard Worker			in: []np{
825*333d2b36SAndroid Build Coastguard Worker				{"b/b.txt", "A"},
826*333d2b36SAndroid Build Coastguard Worker				{"a/a.txt", "B"},
827*333d2b36SAndroid Build Coastguard Worker				{"a/txt", "D"},
828*333d2b36SAndroid Build Coastguard Worker				{"b", "C"},
829*333d2b36SAndroid Build Coastguard Worker				{"a/b/d", "E"},
830*333d2b36SAndroid Build Coastguard Worker			},
831*333d2b36SAndroid Build Coastguard Worker			expectedOut: []np{
832*333d2b36SAndroid Build Coastguard Worker				{"a/a.txt", "B"},
833*333d2b36SAndroid Build Coastguard Worker				{"a/b/d", "E"},
834*333d2b36SAndroid Build Coastguard Worker				{"a/txt", "D"},
835*333d2b36SAndroid Build Coastguard Worker				{"b/b.txt", "A"},
836*333d2b36SAndroid Build Coastguard Worker				{"b", "C"},
837*333d2b36SAndroid Build Coastguard Worker			},
838*333d2b36SAndroid Build Coastguard Worker		},
839*333d2b36SAndroid Build Coastguard Worker		{
840*333d2b36SAndroid Build Coastguard Worker			name: "some_different",
841*333d2b36SAndroid Build Coastguard Worker			in: []np{
842*333d2b36SAndroid Build Coastguard Worker				{"b/b.txt", "A"},
843*333d2b36SAndroid Build Coastguard Worker				{"a/a.txt", "B"},
844*333d2b36SAndroid Build Coastguard Worker				{"a/txt", "D"},
845*333d2b36SAndroid Build Coastguard Worker				{"a/b/d", "E"},
846*333d2b36SAndroid Build Coastguard Worker				{"b", "C"},
847*333d2b36SAndroid Build Coastguard Worker				{"a/a.txt", "B"},
848*333d2b36SAndroid Build Coastguard Worker				{"a/b/d", "E"},
849*333d2b36SAndroid Build Coastguard Worker			},
850*333d2b36SAndroid Build Coastguard Worker			expectedOut: []np{
851*333d2b36SAndroid Build Coastguard Worker				{"a/a.txt", "B"},
852*333d2b36SAndroid Build Coastguard Worker				{"a/b/d", "E"},
853*333d2b36SAndroid Build Coastguard Worker				{"a/txt", "D"},
854*333d2b36SAndroid Build Coastguard Worker				{"b/b.txt", "A"},
855*333d2b36SAndroid Build Coastguard Worker				{"b", "C"},
856*333d2b36SAndroid Build Coastguard Worker			},
857*333d2b36SAndroid Build Coastguard Worker		},
858*333d2b36SAndroid Build Coastguard Worker	}
859*333d2b36SAndroid Build Coastguard Worker	for _, tt := range tests {
860*333d2b36SAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
861*333d2b36SAndroid Build Coastguard Worker			actual := SortedUniqueNamedPaths(makePaths(tt.in))
862*333d2b36SAndroid Build Coastguard Worker			expected := makePaths(tt.expectedOut)
863*333d2b36SAndroid Build Coastguard Worker			t.Logf("actual: %v", actual)
864*333d2b36SAndroid Build Coastguard Worker			t.Logf("expected: %v", expected)
865*333d2b36SAndroid Build Coastguard Worker			AssertDeepEquals(t, "SortedUniqueNamedPaths ", expected, actual)
866*333d2b36SAndroid Build Coastguard Worker		})
867*333d2b36SAndroid Build Coastguard Worker	}
868*333d2b36SAndroid Build Coastguard Worker}
869*333d2b36SAndroid Build Coastguard Worker
870*333d2b36SAndroid Build Coastguard Workerfunc TestSetAndroidMkEntriesWithTestOptions(t *testing.T) {
871*333d2b36SAndroid Build Coastguard Worker	tests := []struct {
872*333d2b36SAndroid Build Coastguard Worker		name        string
873*333d2b36SAndroid Build Coastguard Worker		testOptions CommonTestOptions
874*333d2b36SAndroid Build Coastguard Worker		expected    map[string][]string
875*333d2b36SAndroid Build Coastguard Worker	}{
876*333d2b36SAndroid Build Coastguard Worker		{
877*333d2b36SAndroid Build Coastguard Worker			name:        "empty",
878*333d2b36SAndroid Build Coastguard Worker			testOptions: CommonTestOptions{},
879*333d2b36SAndroid Build Coastguard Worker			expected:    map[string][]string{},
880*333d2b36SAndroid Build Coastguard Worker		},
881*333d2b36SAndroid Build Coastguard Worker		{
882*333d2b36SAndroid Build Coastguard Worker			name: "is unit test",
883*333d2b36SAndroid Build Coastguard Worker			testOptions: CommonTestOptions{
884*333d2b36SAndroid Build Coastguard Worker				Unit_test: boolPtr(true),
885*333d2b36SAndroid Build Coastguard Worker			},
886*333d2b36SAndroid Build Coastguard Worker			expected: map[string][]string{
887*333d2b36SAndroid Build Coastguard Worker				"LOCAL_IS_UNIT_TEST": []string{"true"},
888*333d2b36SAndroid Build Coastguard Worker			},
889*333d2b36SAndroid Build Coastguard Worker		},
890*333d2b36SAndroid Build Coastguard Worker		{
891*333d2b36SAndroid Build Coastguard Worker			name: "is not unit test",
892*333d2b36SAndroid Build Coastguard Worker			testOptions: CommonTestOptions{
893*333d2b36SAndroid Build Coastguard Worker				Unit_test: boolPtr(false),
894*333d2b36SAndroid Build Coastguard Worker			},
895*333d2b36SAndroid Build Coastguard Worker			expected: map[string][]string{},
896*333d2b36SAndroid Build Coastguard Worker		},
897*333d2b36SAndroid Build Coastguard Worker		{
898*333d2b36SAndroid Build Coastguard Worker			name: "empty tag",
899*333d2b36SAndroid Build Coastguard Worker			testOptions: CommonTestOptions{
900*333d2b36SAndroid Build Coastguard Worker				Tags: []string{},
901*333d2b36SAndroid Build Coastguard Worker			},
902*333d2b36SAndroid Build Coastguard Worker			expected: map[string][]string{},
903*333d2b36SAndroid Build Coastguard Worker		},
904*333d2b36SAndroid Build Coastguard Worker		{
905*333d2b36SAndroid Build Coastguard Worker			name: "single tag",
906*333d2b36SAndroid Build Coastguard Worker			testOptions: CommonTestOptions{
907*333d2b36SAndroid Build Coastguard Worker				Tags: []string{"tag1"},
908*333d2b36SAndroid Build Coastguard Worker			},
909*333d2b36SAndroid Build Coastguard Worker			expected: map[string][]string{
910*333d2b36SAndroid Build Coastguard Worker				"LOCAL_TEST_OPTIONS_TAGS": []string{"tag1"},
911*333d2b36SAndroid Build Coastguard Worker			},
912*333d2b36SAndroid Build Coastguard Worker		},
913*333d2b36SAndroid Build Coastguard Worker		{
914*333d2b36SAndroid Build Coastguard Worker			name: "multiple tag",
915*333d2b36SAndroid Build Coastguard Worker			testOptions: CommonTestOptions{
916*333d2b36SAndroid Build Coastguard Worker				Tags: []string{"tag1", "tag2", "tag3"},
917*333d2b36SAndroid Build Coastguard Worker			},
918*333d2b36SAndroid Build Coastguard Worker			expected: map[string][]string{
919*333d2b36SAndroid Build Coastguard Worker				"LOCAL_TEST_OPTIONS_TAGS": []string{"tag1", "tag2", "tag3"},
920*333d2b36SAndroid Build Coastguard Worker			},
921*333d2b36SAndroid Build Coastguard Worker		},
922*333d2b36SAndroid Build Coastguard Worker	}
923*333d2b36SAndroid Build Coastguard Worker	for _, tt := range tests {
924*333d2b36SAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
925*333d2b36SAndroid Build Coastguard Worker			actualEntries := AndroidMkEntries{
926*333d2b36SAndroid Build Coastguard Worker				EntryMap: map[string][]string{},
927*333d2b36SAndroid Build Coastguard Worker			}
928*333d2b36SAndroid Build Coastguard Worker			tt.testOptions.SetAndroidMkEntries(&actualEntries)
929*333d2b36SAndroid Build Coastguard Worker			actual := actualEntries.EntryMap
930*333d2b36SAndroid Build Coastguard Worker			t.Logf("actual: %v", actual)
931*333d2b36SAndroid Build Coastguard Worker			t.Logf("expected: %v", tt.expected)
932*333d2b36SAndroid Build Coastguard Worker			AssertDeepEquals(t, "TestProcessCommonTestOptions ", tt.expected, actual)
933*333d2b36SAndroid Build Coastguard Worker		})
934*333d2b36SAndroid Build Coastguard Worker	}
935*333d2b36SAndroid Build Coastguard Worker}
936*333d2b36SAndroid Build Coastguard Worker
937*333d2b36SAndroid Build Coastguard Workertype sourceProducerTestModule struct {
938*333d2b36SAndroid Build Coastguard Worker	ModuleBase
939*333d2b36SAndroid Build Coastguard Worker	props struct {
940*333d2b36SAndroid Build Coastguard Worker		// A represents the source file
941*333d2b36SAndroid Build Coastguard Worker		A string
942*333d2b36SAndroid Build Coastguard Worker	}
943*333d2b36SAndroid Build Coastguard Worker}
944*333d2b36SAndroid Build Coastguard Worker
945*333d2b36SAndroid Build Coastguard Workerfunc sourceProducerTestModuleFactory() Module {
946*333d2b36SAndroid Build Coastguard Worker	module := &sourceProducerTestModule{}
947*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.props)
948*333d2b36SAndroid Build Coastguard Worker	InitAndroidModule(module)
949*333d2b36SAndroid Build Coastguard Worker	return module
950*333d2b36SAndroid Build Coastguard Worker}
951*333d2b36SAndroid Build Coastguard Worker
952*333d2b36SAndroid Build Coastguard Workerfunc (s sourceProducerTestModule) GenerateAndroidBuildActions(ModuleContext) {}
953*333d2b36SAndroid Build Coastguard Worker
954*333d2b36SAndroid Build Coastguard Workerfunc (s sourceProducerTestModule) Srcs() Paths { return PathsForTesting(s.props.A) }
955*333d2b36SAndroid Build Coastguard Worker
956*333d2b36SAndroid Build Coastguard Workertype outputFilesTestModule struct {
957*333d2b36SAndroid Build Coastguard Worker	ModuleBase
958*333d2b36SAndroid Build Coastguard Worker	props struct {
959*333d2b36SAndroid Build Coastguard Worker		// A represents the tag
960*333d2b36SAndroid Build Coastguard Worker		A string
961*333d2b36SAndroid Build Coastguard Worker		// B represents the output file for tag A
962*333d2b36SAndroid Build Coastguard Worker		B string
963*333d2b36SAndroid Build Coastguard Worker	}
964*333d2b36SAndroid Build Coastguard Worker}
965*333d2b36SAndroid Build Coastguard Worker
966*333d2b36SAndroid Build Coastguard Workerfunc outputFilesTestModuleFactory() Module {
967*333d2b36SAndroid Build Coastguard Worker	module := &outputFilesTestModule{}
968*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.props)
969*333d2b36SAndroid Build Coastguard Worker	InitAndroidModule(module)
970*333d2b36SAndroid Build Coastguard Worker	return module
971*333d2b36SAndroid Build Coastguard Worker}
972*333d2b36SAndroid Build Coastguard Worker
973*333d2b36SAndroid Build Coastguard Workerfunc (o outputFilesTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
974*333d2b36SAndroid Build Coastguard Worker	if o.props.A != "" || o.props.B != "" {
975*333d2b36SAndroid Build Coastguard Worker		ctx.SetOutputFiles(PathsForTesting(o.props.B), o.props.A)
976*333d2b36SAndroid Build Coastguard Worker	}
977*333d2b36SAndroid Build Coastguard Worker	// This is to simulate the case that some module uses an object to set its
978*333d2b36SAndroid Build Coastguard Worker	// OutputFilesProvider, but the object itself is empty.
979*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(Paths{}, "missing")
980*333d2b36SAndroid Build Coastguard Worker}
981*333d2b36SAndroid Build Coastguard Worker
982*333d2b36SAndroid Build Coastguard Workertype pathContextAddMissingDependenciesWrapper struct {
983*333d2b36SAndroid Build Coastguard Worker	PathContext
984*333d2b36SAndroid Build Coastguard Worker	OtherModuleProviderContext
985*333d2b36SAndroid Build Coastguard Worker	missingDeps []string
986*333d2b36SAndroid Build Coastguard Worker}
987*333d2b36SAndroid Build Coastguard Worker
988*333d2b36SAndroid Build Coastguard Workerfunc (p *pathContextAddMissingDependenciesWrapper) AddMissingDependencies(deps []string) {
989*333d2b36SAndroid Build Coastguard Worker	p.missingDeps = append(p.missingDeps, deps...)
990*333d2b36SAndroid Build Coastguard Worker}
991*333d2b36SAndroid Build Coastguard Workerfunc (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module blueprint.Module) string {
992*333d2b36SAndroid Build Coastguard Worker	return module.Name()
993*333d2b36SAndroid Build Coastguard Worker}
994*333d2b36SAndroid Build Coastguard Worker
995*333d2b36SAndroid Build Coastguard Workerfunc (p *pathContextAddMissingDependenciesWrapper) Module() Module { return nil }
996*333d2b36SAndroid Build Coastguard Worker
997*333d2b36SAndroid Build Coastguard Workerfunc (p *pathContextAddMissingDependenciesWrapper) GetOutputFiles() OutputFilesInfo {
998*333d2b36SAndroid Build Coastguard Worker	return OutputFilesInfo{}
999*333d2b36SAndroid Build Coastguard Worker}
1000*333d2b36SAndroid Build Coastguard Worker
1001*333d2b36SAndroid Build Coastguard Workerfunc (p *pathContextAddMissingDependenciesWrapper) EqualModules(m1, m2 Module) bool {
1002*333d2b36SAndroid Build Coastguard Worker	return m1 == m2
1003*333d2b36SAndroid Build Coastguard Worker}
1004*333d2b36SAndroid Build Coastguard Worker
1005*333d2b36SAndroid Build Coastguard Workerfunc TestOutputFileForModule(t *testing.T) {
1006*333d2b36SAndroid Build Coastguard Worker	testcases := []struct {
1007*333d2b36SAndroid Build Coastguard Worker		name        string
1008*333d2b36SAndroid Build Coastguard Worker		bp          string
1009*333d2b36SAndroid Build Coastguard Worker		tag         string
1010*333d2b36SAndroid Build Coastguard Worker		expected    string
1011*333d2b36SAndroid Build Coastguard Worker		missingDeps []string
1012*333d2b36SAndroid Build Coastguard Worker		env         map[string]string
1013*333d2b36SAndroid Build Coastguard Worker		config      func(*config)
1014*333d2b36SAndroid Build Coastguard Worker	}{
1015*333d2b36SAndroid Build Coastguard Worker		{
1016*333d2b36SAndroid Build Coastguard Worker			name: "SourceFileProducer",
1017*333d2b36SAndroid Build Coastguard Worker			bp: `spt_module {
1018*333d2b36SAndroid Build Coastguard Worker					name: "test_module",
1019*333d2b36SAndroid Build Coastguard Worker					a: "spt.txt",
1020*333d2b36SAndroid Build Coastguard Worker				}
1021*333d2b36SAndroid Build Coastguard Worker			`,
1022*333d2b36SAndroid Build Coastguard Worker			tag:      "",
1023*333d2b36SAndroid Build Coastguard Worker			expected: "spt.txt",
1024*333d2b36SAndroid Build Coastguard Worker		},
1025*333d2b36SAndroid Build Coastguard Worker		{
1026*333d2b36SAndroid Build Coastguard Worker			name: "OutputFileProviderEmptyStringTag",
1027*333d2b36SAndroid Build Coastguard Worker			bp: `oft_module {
1028*333d2b36SAndroid Build Coastguard Worker					name: "test_module",
1029*333d2b36SAndroid Build Coastguard Worker					a: "",
1030*333d2b36SAndroid Build Coastguard Worker					b: "empty.txt",
1031*333d2b36SAndroid Build Coastguard Worker				}
1032*333d2b36SAndroid Build Coastguard Worker		`,
1033*333d2b36SAndroid Build Coastguard Worker			tag:      "",
1034*333d2b36SAndroid Build Coastguard Worker			expected: "empty.txt",
1035*333d2b36SAndroid Build Coastguard Worker		},
1036*333d2b36SAndroid Build Coastguard Worker		{
1037*333d2b36SAndroid Build Coastguard Worker			name: "OutputFileProviderTag",
1038*333d2b36SAndroid Build Coastguard Worker			bp: `oft_module {
1039*333d2b36SAndroid Build Coastguard Worker					name: "test_module",
1040*333d2b36SAndroid Build Coastguard Worker					a: "foo",
1041*333d2b36SAndroid Build Coastguard Worker					b: "foo.txt",
1042*333d2b36SAndroid Build Coastguard Worker				}
1043*333d2b36SAndroid Build Coastguard Worker			`,
1044*333d2b36SAndroid Build Coastguard Worker			tag:      "foo",
1045*333d2b36SAndroid Build Coastguard Worker			expected: "foo.txt",
1046*333d2b36SAndroid Build Coastguard Worker		},
1047*333d2b36SAndroid Build Coastguard Worker		{
1048*333d2b36SAndroid Build Coastguard Worker			name: "OutputFileAllowMissingDependencies",
1049*333d2b36SAndroid Build Coastguard Worker			bp: `oft_module {
1050*333d2b36SAndroid Build Coastguard Worker				name: "test_module",
1051*333d2b36SAndroid Build Coastguard Worker			}
1052*333d2b36SAndroid Build Coastguard Worker		`,
1053*333d2b36SAndroid Build Coastguard Worker			tag:         "missing",
1054*333d2b36SAndroid Build Coastguard Worker			expected:    "missing_output_file/test_module",
1055*333d2b36SAndroid Build Coastguard Worker			missingDeps: []string{"test_module"},
1056*333d2b36SAndroid Build Coastguard Worker			config: func(config *config) {
1057*333d2b36SAndroid Build Coastguard Worker				config.TestProductVariables.Allow_missing_dependencies = boolPtr(true)
1058*333d2b36SAndroid Build Coastguard Worker			},
1059*333d2b36SAndroid Build Coastguard Worker		},
1060*333d2b36SAndroid Build Coastguard Worker	}
1061*333d2b36SAndroid Build Coastguard Worker
1062*333d2b36SAndroid Build Coastguard Worker	for _, tt := range testcases {
1063*333d2b36SAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
1064*333d2b36SAndroid Build Coastguard Worker			result := GroupFixturePreparers(
1065*333d2b36SAndroid Build Coastguard Worker				PrepareForTestWithDefaults,
1066*333d2b36SAndroid Build Coastguard Worker				FixtureRegisterWithContext(func(ctx RegistrationContext) {
1067*333d2b36SAndroid Build Coastguard Worker					ctx.RegisterModuleType("spt_module", sourceProducerTestModuleFactory)
1068*333d2b36SAndroid Build Coastguard Worker					ctx.RegisterModuleType("oft_module", outputFilesTestModuleFactory)
1069*333d2b36SAndroid Build Coastguard Worker				}),
1070*333d2b36SAndroid Build Coastguard Worker				FixtureWithRootAndroidBp(tt.bp),
1071*333d2b36SAndroid Build Coastguard Worker			).RunTest(t)
1072*333d2b36SAndroid Build Coastguard Worker
1073*333d2b36SAndroid Build Coastguard Worker			config := TestConfig(buildDir, tt.env, tt.bp, nil)
1074*333d2b36SAndroid Build Coastguard Worker			if tt.config != nil {
1075*333d2b36SAndroid Build Coastguard Worker				tt.config(config.config)
1076*333d2b36SAndroid Build Coastguard Worker			}
1077*333d2b36SAndroid Build Coastguard Worker			ctx := &pathContextAddMissingDependenciesWrapper{
1078*333d2b36SAndroid Build Coastguard Worker				PathContext:                PathContextForTesting(config),
1079*333d2b36SAndroid Build Coastguard Worker				OtherModuleProviderContext: result.TestContext.OtherModuleProviderAdaptor(),
1080*333d2b36SAndroid Build Coastguard Worker			}
1081*333d2b36SAndroid Build Coastguard Worker			got := OutputFileForModule(ctx, result.ModuleForTests("test_module", "").Module(), tt.tag)
1082*333d2b36SAndroid Build Coastguard Worker			AssertPathRelativeToTopEquals(t, "expected output path", tt.expected, got)
1083*333d2b36SAndroid Build Coastguard Worker			AssertArrayString(t, "expected missing deps", tt.missingDeps, ctx.missingDeps)
1084*333d2b36SAndroid Build Coastguard Worker		})
1085*333d2b36SAndroid Build Coastguard Worker	}
1086*333d2b36SAndroid Build Coastguard Worker}
1087*333d2b36SAndroid Build Coastguard Worker
1088*333d2b36SAndroid Build Coastguard Workerfunc TestVintfFragmentModulesChecksPartition(t *testing.T) {
1089*333d2b36SAndroid Build Coastguard Worker	bp := `
1090*333d2b36SAndroid Build Coastguard Worker	vintf_fragment {
1091*333d2b36SAndroid Build Coastguard Worker		name: "vintfModA",
1092*333d2b36SAndroid Build Coastguard Worker		src: "test_vintf_file",
1093*333d2b36SAndroid Build Coastguard Worker		vendor: true,
1094*333d2b36SAndroid Build Coastguard Worker	}
1095*333d2b36SAndroid Build Coastguard Worker	deps {
1096*333d2b36SAndroid Build Coastguard Worker		name: "modA",
1097*333d2b36SAndroid Build Coastguard Worker		vintf_fragment_modules: [
1098*333d2b36SAndroid Build Coastguard Worker			"vintfModA",
1099*333d2b36SAndroid Build Coastguard Worker		]
1100*333d2b36SAndroid Build Coastguard Worker	}
1101*333d2b36SAndroid Build Coastguard Worker	`
1102*333d2b36SAndroid Build Coastguard Worker
1103*333d2b36SAndroid Build Coastguard Worker	testPreparer := GroupFixturePreparers(
1104*333d2b36SAndroid Build Coastguard Worker		PrepareForTestWithAndroidBuildComponents,
1105*333d2b36SAndroid Build Coastguard Worker		prepareForModuleTests,
1106*333d2b36SAndroid Build Coastguard Worker	)
1107*333d2b36SAndroid Build Coastguard Worker
1108*333d2b36SAndroid Build Coastguard Worker	testPreparer.
1109*333d2b36SAndroid Build Coastguard Worker		ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(
1110*333d2b36SAndroid Build Coastguard Worker			"Module .+ and Vintf_fragment .+ are installed to different partitions.")).
1111*333d2b36SAndroid Build Coastguard Worker		RunTestWithBp(t, bp)
1112*333d2b36SAndroid Build Coastguard Worker}
1113