1// Copyright 2020 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18	"testing"
19
20	"github.com/google/blueprint"
21)
22
23// Module to be packaged
24type componentTestModule struct {
25	ModuleBase
26	props struct {
27		Deps []string
28	}
29}
30
31// dep tag used in this test. All dependencies are considered as installable.
32type installDepTag struct {
33	blueprint.BaseDependencyTag
34	InstallAlwaysNeededDependencyTag
35}
36
37func componentTestModuleFactory() Module {
38	m := &componentTestModule{}
39	m.AddProperties(&m.props)
40	InitAndroidArchModule(m, HostAndDeviceSupported, MultilibBoth)
41	return m
42}
43
44func (m *componentTestModule) DepsMutator(ctx BottomUpMutatorContext) {
45	ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
46}
47
48func (m *componentTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
49	builtFile := PathForModuleOut(ctx, m.Name())
50	dir := ctx.Target().Arch.ArchType.Multilib
51	installDir := PathForModuleInstall(ctx, dir)
52	ctx.InstallFile(installDir, m.Name(), builtFile)
53}
54
55// Module that itself is a package
56type packageTestModule struct {
57	ModuleBase
58	PackagingBase
59	properties struct {
60		Install_deps []string `android:`
61	}
62	entries []string
63}
64
65func packageMultiTargetTestModuleFactory() Module {
66	module := &packageTestModule{}
67	InitPackageModule(module)
68	InitAndroidMultiTargetsArchModule(module, DeviceSupported, MultilibCommon)
69	module.AddProperties(&module.properties)
70	return module
71}
72
73func packageTestModuleFactory() Module {
74	module := &packageTestModule{}
75	InitPackageModule(module)
76	InitAndroidArchModule(module, DeviceSupported, MultilibBoth)
77	module.AddProperties(&module.properties)
78	return module
79}
80
81type packagingDepTag struct {
82	blueprint.BaseDependencyTag
83	PackagingItemAlwaysDepTag
84}
85
86func (m *packageTestModule) DepsMutator(ctx BottomUpMutatorContext) {
87	m.AddDeps(ctx, packagingDepTag{})
88	ctx.AddDependency(ctx.Module(), installDepTag{}, m.properties.Install_deps...)
89}
90
91func (m *packageTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
92	zipFile := PathForModuleOut(ctx, "myzip.zip")
93	m.entries = m.CopyDepsToZip(ctx, zipFile)
94}
95
96func runPackagingTest(t *testing.T, multitarget bool, bp string, expected []string) {
97	t.Helper()
98
99	var archVariant string
100	var moduleFactory ModuleFactory
101	if multitarget {
102		archVariant = "android_common"
103		moduleFactory = packageMultiTargetTestModuleFactory
104	} else {
105		archVariant = "android_arm64_armv8-a"
106		moduleFactory = packageTestModuleFactory
107	}
108
109	result := GroupFixturePreparers(
110		PrepareForTestWithArchMutator,
111		FixtureRegisterWithContext(func(ctx RegistrationContext) {
112			ctx.RegisterModuleType("component", componentTestModuleFactory)
113			ctx.RegisterModuleType("package_module", moduleFactory)
114		}),
115		FixtureWithRootAndroidBp(bp),
116	).RunTest(t)
117
118	p := result.Module("package", archVariant).(*packageTestModule)
119	actual := p.entries
120	actual = SortedUniqueStrings(actual)
121	expected = SortedUniqueStrings(expected)
122	AssertDeepEquals(t, "package entries", expected, actual)
123}
124
125func TestPackagingBaseMultiTarget(t *testing.T) {
126	multiTarget := true
127	runPackagingTest(t, multiTarget,
128		`
129		component {
130			name: "foo",
131		}
132
133		package_module {
134			name: "package",
135			deps: ["foo"],
136		}
137		`, []string{"lib64/foo"})
138
139	runPackagingTest(t, multiTarget,
140		`
141		component {
142			name: "foo",
143			deps: ["bar"],
144		}
145
146		component {
147			name: "bar",
148		}
149
150		package_module {
151			name: "package",
152			deps: ["foo"],
153		}
154		`, []string{"lib64/foo", "lib64/bar"})
155
156	runPackagingTest(t, multiTarget,
157		`
158		component {
159			name: "foo",
160			deps: ["bar"],
161		}
162
163		component {
164			name: "bar",
165		}
166
167		package_module {
168			name: "package",
169			deps: ["foo"],
170			compile_multilib: "both",
171		}
172		`, []string{"lib32/foo", "lib32/bar", "lib64/foo", "lib64/bar"})
173
174	runPackagingTest(t, multiTarget,
175		`
176		component {
177			name: "foo",
178		}
179
180		component {
181			name: "bar",
182			compile_multilib: "32",
183		}
184
185		package_module {
186			name: "package",
187			deps: ["foo"],
188			multilib: {
189				lib32: {
190					deps: ["bar"],
191				},
192			},
193			compile_multilib: "both",
194		}
195		`, []string{"lib32/foo", "lib32/bar", "lib64/foo"})
196
197	runPackagingTest(t, multiTarget,
198		`
199		component {
200			name: "foo",
201		}
202
203		component {
204			name: "bar",
205		}
206
207		package_module {
208			name: "package",
209			deps: ["foo"],
210			multilib: {
211				first: {
212					deps: ["bar"],
213				},
214			},
215			compile_multilib: "both",
216		}
217		`, []string{"lib32/foo", "lib64/foo", "lib64/bar"})
218
219	runPackagingTest(t, multiTarget,
220		`
221		component {
222			name: "foo",
223		}
224
225		component {
226			name: "bar",
227		}
228
229		component {
230			name: "baz",
231		}
232
233		package_module {
234			name: "package",
235			deps: ["foo"],
236			arch: {
237				arm64: {
238					deps: ["bar"],
239				},
240				x86_64: {
241					deps: ["baz"],
242				},
243			},
244			compile_multilib: "both",
245		}
246		`, []string{"lib32/foo", "lib64/foo", "lib64/bar"})
247}
248
249func TestPackagingBaseSingleTarget(t *testing.T) {
250	multiTarget := false
251	runPackagingTest(t, multiTarget,
252		`
253		component {
254			name: "foo",
255		}
256
257		package_module {
258			name: "package",
259			deps: ["foo"],
260		}
261		`, []string{"lib64/foo"})
262
263	runPackagingTest(t, multiTarget,
264		`
265		component {
266			name: "foo",
267			deps: ["bar"],
268		}
269
270		component {
271			name: "bar",
272		}
273
274		package_module {
275			name: "package",
276			deps: ["foo"],
277		}
278		`, []string{"lib64/foo", "lib64/bar"})
279
280	runPackagingTest(t, multiTarget,
281		`
282		component {
283			name: "foo",
284		}
285
286		component {
287			name: "bar",
288			compile_multilib: "32",
289		}
290
291		package_module {
292			name: "package",
293			deps: ["foo"],
294			multilib: {
295				lib32: {
296					deps: ["bar"],
297				},
298			},
299		}
300		`, []string{"lib64/foo"})
301
302	runPackagingTest(t, multiTarget,
303		`
304		component {
305			name: "foo",
306		}
307
308		component {
309			name: "bar",
310		}
311
312		package_module {
313			name: "package",
314			deps: ["foo"],
315			multilib: {
316				lib64: {
317					deps: ["bar"],
318				},
319			},
320		}
321		`, []string{"lib64/foo", "lib64/bar"})
322
323	runPackagingTest(t, multiTarget,
324		`
325		component {
326			name: "foo",
327		}
328
329		component {
330			name: "bar",
331		}
332
333		component {
334			name: "baz",
335		}
336
337		package_module {
338			name: "package",
339			deps: ["foo"],
340			arch: {
341				arm64: {
342					deps: ["bar"],
343				},
344				x86_64: {
345					deps: ["baz"],
346				},
347			},
348		}
349		`, []string{"lib64/foo", "lib64/bar"})
350
351	runPackagingTest(t, multiTarget,
352		`
353		component {
354			name: "foo",
355		}
356
357		component {
358			name: "bar",
359		}
360
361		package_module {
362			name: "package",
363			deps: ["foo"],
364			install_deps: ["bar"],
365		}
366		`, []string{"lib64/foo"})
367}
368