• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 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 java
16
17import (
18	"fmt"
19	"runtime"
20	"strings"
21	"testing"
22
23	"android/soong/android"
24	"android/soong/cc"
25	"android/soong/dexpreopt"
26)
27
28func init() {
29	RegisterFakeRuntimeApexMutator()
30}
31
32func TestDexpreoptEnabled(t *testing.T) {
33	tests := []struct {
34		name        string
35		bp          string
36		moduleName  string
37		apexVariant bool
38		enabled     bool
39	}{
40		{
41			name: "app",
42			bp: `
43				android_app {
44					name: "foo",
45					srcs: ["a.java"],
46					sdk_version: "current",
47				}`,
48			enabled: true,
49		},
50		{
51			name: "installable java library",
52			bp: `
53				java_library {
54					name: "foo",
55					installable: true,
56					srcs: ["a.java"],
57				}`,
58			enabled: true,
59		},
60		{
61			name: "java binary",
62			bp: `
63				java_binary {
64					name: "foo",
65					srcs: ["a.java"],
66				}`,
67			enabled: true,
68		},
69		{
70			name: "app without sources",
71			bp: `
72				android_app {
73					name: "foo",
74					sdk_version: "current",
75				}`,
76			enabled: false,
77		},
78		{
79			name: "app with libraries",
80			bp: `
81				android_app {
82					name: "foo",
83					static_libs: ["lib"],
84					sdk_version: "current",
85				}
86
87				java_library {
88					name: "lib",
89					srcs: ["a.java"],
90					sdk_version: "current",
91				}`,
92			enabled: true,
93		},
94		{
95			name: "installable java library without sources",
96			bp: `
97				java_library {
98					name: "foo",
99					installable: true,
100				}`,
101			enabled: false,
102		},
103		{
104			name: "static java library",
105			bp: `
106				java_library {
107					name: "foo",
108					srcs: ["a.java"],
109				}`,
110			enabled: false,
111		},
112		{
113			name: "java test",
114			bp: `
115				java_test {
116					name: "foo",
117					srcs: ["a.java"],
118				}`,
119			enabled: false,
120		},
121		{
122			name: "android test",
123			bp: `
124				android_test {
125					name: "foo",
126					srcs: ["a.java"],
127				}`,
128			enabled: false,
129		},
130		{
131			name: "android test helper app",
132			bp: `
133				android_test_helper_app {
134					name: "foo",
135					srcs: ["a.java"],
136				}`,
137			enabled: false,
138		},
139		{
140			name: "compile_dex",
141			bp: `
142				java_library {
143					name: "foo",
144					srcs: ["a.java"],
145					compile_dex: true,
146				}`,
147			enabled: false,
148		},
149		{
150			name: "dex_import",
151			bp: `
152				dex_import {
153					name: "foo",
154					jars: ["a.jar"],
155				}`,
156			enabled: true,
157		},
158		{
159			name: "apex variant",
160			bp: `
161				java_library {
162					name: "foo",
163					installable: true,
164					srcs: ["a.java"],
165					apex_available: ["com.android.apex1"],
166				}`,
167			apexVariant: true,
168			enabled:     false,
169		},
170		{
171			name: "apex variant of apex system server jar",
172			bp: `
173				java_library {
174					name: "service-foo",
175					installable: true,
176					srcs: ["a.java"],
177					apex_available: ["com.android.apex1"],
178				}`,
179			moduleName:  "service-foo",
180			apexVariant: true,
181			enabled:     true,
182		},
183		{
184			name: "apex variant of prebuilt apex system server jar",
185			bp: `
186				java_library {
187					name: "prebuilt_service-foo",
188					installable: true,
189					srcs: ["a.java"],
190					apex_available: ["com.android.apex1"],
191				}`,
192			moduleName:  "prebuilt_service-foo",
193			apexVariant: true,
194			enabled:     true,
195		},
196		{
197			name: "platform variant of apex system server jar",
198			bp: `
199				java_library {
200					name: "service-foo",
201					installable: true,
202					srcs: ["a.java"],
203					apex_available: ["com.android.apex1"],
204				}`,
205			moduleName:  "service-foo",
206			apexVariant: false,
207			enabled:     false,
208		},
209	}
210
211	for _, test := range tests {
212		t.Run(test.name, func(t *testing.T) {
213			preparers := android.GroupFixturePreparers(
214				PrepareForTestWithJavaDefaultModules,
215				PrepareForTestWithFakeApexMutator,
216				dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
217			)
218
219			result := preparers.RunTestWithBp(t, test.bp)
220			ctx := result.TestContext
221
222			moduleName := "foo"
223			if test.moduleName != "" {
224				moduleName = test.moduleName
225			}
226
227			variant := "android_common"
228			if test.apexVariant {
229				variant += "_apex1000"
230			}
231
232			dexpreopt := ctx.ModuleForTests(moduleName, variant).MaybeRule("dexpreopt")
233			enabled := dexpreopt.Rule != nil
234
235			if enabled != test.enabled {
236				t.Fatalf("want dexpreopt %s, got %s", enabledString(test.enabled), enabledString(enabled))
237			}
238		})
239
240	}
241}
242
243func enabledString(enabled bool) string {
244	if enabled {
245		return "enabled"
246	} else {
247		return "disabled"
248	}
249}
250
251func TestDex2oatToolDeps(t *testing.T) {
252	if runtime.GOOS != "linux" {
253		// The host binary paths checked below are build OS dependent.
254		t.Skipf("Unsupported build OS %s", runtime.GOOS)
255	}
256
257	preparers := android.GroupFixturePreparers(
258		cc.PrepareForTestWithCcDefaultModules,
259		PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd,
260		dexpreopt.PrepareForTestByEnablingDexpreopt)
261
262	testDex2oatToolDep := func(sourceEnabled, prebuiltEnabled, prebuiltPreferred bool,
263		expectedDex2oatPath string) {
264		name := fmt.Sprintf("sourceEnabled:%t,prebuiltEnabled:%t,prebuiltPreferred:%t",
265			sourceEnabled, prebuiltEnabled, prebuiltPreferred)
266		t.Run(name, func(t *testing.T) {
267			result := preparers.RunTestWithBp(t, fmt.Sprintf(`
268					cc_binary {
269						name: "dex2oatd",
270						enabled: %t,
271						host_supported: true,
272					}
273					cc_prebuilt_binary {
274						name: "dex2oatd",
275						enabled: %t,
276						prefer: %t,
277						host_supported: true,
278						srcs: ["x86_64/bin/dex2oatd"],
279					}
280					java_library {
281						name: "myjavalib",
282					}
283				`, sourceEnabled, prebuiltEnabled, prebuiltPreferred))
284			pathContext := android.PathContextForTesting(result.Config)
285			dex2oatPath := dexpreopt.GetCachedGlobalSoongConfig(pathContext).Dex2oat
286			android.AssertStringEquals(t, "Testing "+name, expectedDex2oatPath, android.NormalizePathForTesting(dex2oatPath))
287		})
288	}
289
290	sourceDex2oatPath := "host/linux-x86/bin/dex2oatd"
291	prebuiltDex2oatPath := ".intermediates/prebuilt_dex2oatd/linux_glibc_x86_64/dex2oatd"
292
293	testDex2oatToolDep(true, false, false, sourceDex2oatPath)
294	testDex2oatToolDep(true, true, false, sourceDex2oatPath)
295	testDex2oatToolDep(true, true, true, prebuiltDex2oatPath)
296	testDex2oatToolDep(false, true, false, prebuiltDex2oatPath)
297}
298
299func TestDexpreoptBuiltInstalledForApex(t *testing.T) {
300	preparers := android.GroupFixturePreparers(
301		PrepareForTestWithJavaDefaultModules,
302		PrepareForTestWithFakeApexMutator,
303		dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
304	)
305
306	// An APEX system server jar.
307	result := preparers.RunTestWithBp(t, `
308		java_library {
309			name: "service-foo",
310			installable: true,
311			srcs: ["a.java"],
312			apex_available: ["com.android.apex1"],
313		}`)
314	ctx := result.TestContext
315	module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
316	library := module.Module().(*Library)
317
318	installs := library.dexpreopter.DexpreoptBuiltInstalledForApex()
319
320	android.AssertIntEquals(t, "install count", 2, len(installs))
321
322	android.AssertStringEquals(t, "installs[0] FullModuleName",
323		"service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
324		installs[0].FullModuleName())
325
326	android.AssertStringEquals(t, "installs[0] SubModuleName",
327		"-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
328		installs[0].SubModuleName())
329
330	android.AssertStringEquals(t, "installs[1] FullModuleName",
331		"service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
332		installs[1].FullModuleName())
333
334	android.AssertStringEquals(t, "installs[1] SubModuleName",
335		"-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
336		installs[1].SubModuleName())
337
338	// Not an APEX system server jar.
339	result = preparers.RunTestWithBp(t, `
340		java_library {
341			name: "foo",
342			installable: true,
343			srcs: ["a.java"],
344		}`)
345	ctx = result.TestContext
346	module = ctx.ModuleForTests("foo", "android_common")
347	library = module.Module().(*Library)
348
349	installs = library.dexpreopter.DexpreoptBuiltInstalledForApex()
350
351	android.AssertIntEquals(t, "install count", 0, len(installs))
352}
353
354func filterDexpreoptEntriesList(entriesList []android.AndroidMkEntries) []android.AndroidMkEntries {
355	var results []android.AndroidMkEntries
356	for _, entries := range entriesList {
357		if strings.Contains(entries.EntryMap["LOCAL_MODULE"][0], "-dexpreopt-") {
358			results = append(results, entries)
359		}
360	}
361	return results
362}
363
364func verifyEntries(t *testing.T, message string, expectedModule string,
365	expectedPrebuiltModuleFile string, expectedModulePath string, expectedInstalledModuleStem string,
366	entries android.AndroidMkEntries) {
367	android.AssertStringEquals(t, message+" LOCAL_MODULE", expectedModule,
368		entries.EntryMap["LOCAL_MODULE"][0])
369
370	android.AssertStringEquals(t, message+" LOCAL_MODULE_CLASS", "ETC",
371		entries.EntryMap["LOCAL_MODULE_CLASS"][0])
372
373	android.AssertStringDoesContain(t, message+" LOCAL_PREBUILT_MODULE_FILE",
374		entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"][0], expectedPrebuiltModuleFile)
375
376	android.AssertStringDoesContain(t, message+" LOCAL_MODULE_PATH",
377		entries.EntryMap["LOCAL_MODULE_PATH"][0], expectedModulePath)
378
379	android.AssertStringEquals(t, message+" LOCAL_INSTALLED_MODULE_STEM",
380		expectedInstalledModuleStem, entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"][0])
381
382	android.AssertStringEquals(t, message+" LOCAL_NOT_AVAILABLE_FOR_PLATFORM",
383		"false", entries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"][0])
384}
385
386func TestAndroidMkEntriesForApex(t *testing.T) {
387	preparers := android.GroupFixturePreparers(
388		PrepareForTestWithJavaDefaultModules,
389		PrepareForTestWithFakeApexMutator,
390		dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
391	)
392
393	// An APEX system server jar.
394	result := preparers.RunTestWithBp(t, `
395		java_library {
396			name: "service-foo",
397			installable: true,
398			srcs: ["a.java"],
399			apex_available: ["com.android.apex1"],
400		}`)
401	ctx := result.TestContext
402	module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
403
404	entriesList := android.AndroidMkEntriesForTest(t, ctx, module.Module())
405	entriesList = filterDexpreoptEntriesList(entriesList)
406
407	android.AssertIntEquals(t, "entries count", 2, len(entriesList))
408
409	verifyEntries(t,
410		"entriesList[0]",
411		"service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
412		"/dexpreopt/oat/arm64/javalib.odex",
413		"/system/framework/oat/arm64",
414		"apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
415		entriesList[0])
416
417	verifyEntries(t,
418		"entriesList[1]",
419		"service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
420		"/dexpreopt/oat/arm64/javalib.vdex",
421		"/system/framework/oat/arm64",
422		"apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
423		entriesList[1])
424
425	// Not an APEX system server jar.
426	result = preparers.RunTestWithBp(t, `
427		java_library {
428			name: "foo",
429			installable: true,
430			srcs: ["a.java"],
431		}`)
432	ctx = result.TestContext
433	module = ctx.ModuleForTests("foo", "android_common")
434
435	entriesList = android.AndroidMkEntriesForTest(t, ctx, module.Module())
436	entriesList = filterDexpreoptEntriesList(entriesList)
437
438	android.AssertIntEquals(t, "entries count", 0, len(entriesList))
439}
440