• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2022 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	"testing"
19
20	"android/soong/android"
21
22	"github.com/google/blueprint/proptools"
23)
24
25func TestR8(t *testing.T) {
26	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
27		android_app {
28			name: "app",
29			srcs: ["foo.java"],
30			libs: ["lib"],
31			static_libs: ["static_lib"],
32			platform_apis: true,
33		}
34
35		android_app {
36			name: "stable_app",
37			srcs: ["foo.java"],
38			sdk_version: "current",
39			min_sdk_version: "31",
40		}
41
42		android_app {
43			name: "core_platform_app",
44			srcs: ["foo.java"],
45			sdk_version: "core_platform",
46			min_sdk_version: "31",
47		}
48
49		java_library {
50			name: "lib",
51			srcs: ["foo.java"],
52		}
53
54		java_library {
55			name: "static_lib",
56			srcs: ["foo.java"],
57		}
58	`)
59
60	app := result.ModuleForTests("app", "android_common")
61	stableApp := result.ModuleForTests("stable_app", "android_common")
62	corePlatformApp := result.ModuleForTests("core_platform_app", "android_common")
63	lib := result.ModuleForTests("lib", "android_common")
64	staticLib := result.ModuleForTests("static_lib", "android_common")
65
66	appJavac := app.Rule("javac")
67	appR8 := app.Rule("r8")
68	stableAppR8 := stableApp.Rule("r8")
69	corePlatformAppR8 := corePlatformApp.Rule("r8")
70	libHeader := lib.Output("turbine-combined/lib.jar").Output
71	staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
72
73	android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath",
74		appJavac.Args["classpath"], libHeader.String())
75	android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath",
76		appJavac.Args["classpath"], staticLibHeader.String())
77
78	android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
79		appR8.Args["r8Flags"], libHeader.String())
80	android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
81		appR8.Args["r8Flags"], staticLibHeader.String())
82	android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
83		appR8.Args["r8Flags"], "-ignorewarnings")
84	android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
85		appR8.Args["r8Flags"], "--android-platform-build")
86	android.AssertStringDoesNotContain(t, "expected no --android-platform-build in stable_app r8 flags",
87		stableAppR8.Args["r8Flags"], "--android-platform-build")
88	android.AssertStringDoesContain(t, "expected --android-platform-build in core_platform_app r8 flags",
89		corePlatformAppR8.Args["r8Flags"], "--android-platform-build")
90}
91
92func TestR8TransitiveDeps(t *testing.T) {
93	bp := `
94		override_android_app {
95			name: "override_app",
96			base: "app",
97		}
98
99		android_app {
100			name: "app",
101			srcs: ["foo.java"],
102			libs: [
103				"lib",
104				"uses_libs_dep_import",
105			],
106			static_libs: [
107				"static_lib",
108				"repeated_dep",
109			],
110			platform_apis: true,
111		}
112
113		java_library {
114			name: "static_lib",
115			srcs: ["foo.java"],
116		}
117
118		java_library {
119			name: "lib",
120			libs: [
121				"transitive_lib",
122				"repeated_dep",
123				"prebuilt_lib",
124			],
125			static_libs: ["transitive_static_lib"],
126			srcs: ["foo.java"],
127		}
128
129		java_library {
130			name: "repeated_dep",
131			srcs: ["foo.java"],
132		}
133
134		java_library {
135			name: "transitive_static_lib",
136			srcs: ["foo.java"],
137		}
138
139		java_library {
140			name: "transitive_lib",
141			srcs: ["foo.java"],
142			libs: ["transitive_lib_2"],
143		}
144
145		java_library {
146			name: "transitive_lib_2",
147			srcs: ["foo.java"],
148		}
149
150		java_import {
151			name: "lib",
152			jars: ["lib.jar"],
153		}
154
155		java_library {
156			name: "uses_lib",
157			srcs: ["foo.java"],
158		}
159
160		java_library {
161			name: "optional_uses_lib",
162			srcs: ["foo.java"],
163		}
164
165		android_library {
166			name: "uses_libs_dep",
167			uses_libs: ["uses_lib"],
168			optional_uses_libs: ["optional_uses_lib"],
169		}
170
171		android_library_import {
172			name: "uses_libs_dep_import",
173			aars: ["aar.aar"],
174			static_libs: ["uses_libs_dep"],
175		}
176	`
177
178	testcases := []struct {
179		name      string
180		unbundled bool
181	}{
182		{
183			name:      "non-unbundled build",
184			unbundled: false,
185		},
186		{
187			name:      "unbundled build",
188			unbundled: true,
189		},
190	}
191
192	for _, tc := range testcases {
193		t.Run(tc.name, func(t *testing.T) {
194			fixturePreparer := PrepareForTestWithJavaDefaultModules
195			if tc.unbundled {
196				fixturePreparer = android.GroupFixturePreparers(
197					fixturePreparer,
198					android.FixtureModifyProductVariables(
199						func(variables android.FixtureProductVariables) {
200							variables.Unbundled_build = proptools.BoolPtr(true)
201						},
202					),
203				)
204			}
205			result := fixturePreparer.RunTestWithBp(t, bp)
206
207			getHeaderJar := func(name string) android.Path {
208				mod := result.ModuleForTests(name, "android_common")
209				return mod.Output("turbine-combined/" + name + ".jar").Output
210			}
211
212			appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
213			overrideAppR8 := result.ModuleForTests("app", "android_common_override_app").Rule("r8")
214			appHeader := getHeaderJar("app")
215			overrideAppHeader := result.ModuleForTests("app", "android_common_override_app").Output("turbine-combined/app.jar").Output
216			libHeader := getHeaderJar("lib")
217			transitiveLibHeader := getHeaderJar("transitive_lib")
218			transitiveLib2Header := getHeaderJar("transitive_lib_2")
219			staticLibHeader := getHeaderJar("static_lib")
220			transitiveStaticLibHeader := getHeaderJar("transitive_static_lib")
221			repeatedDepHeader := getHeaderJar("repeated_dep")
222			usesLibHeader := getHeaderJar("uses_lib")
223			optionalUsesLibHeader := getHeaderJar("optional_uses_lib")
224			prebuiltLibHeader := result.ModuleForTests("prebuilt_lib", "android_common").Output("combined/lib.jar").Output
225
226			for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} {
227				android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath",
228					rule.Args["r8Flags"], appHeader.String())
229				android.AssertStringDoesNotContain(t, "expected no override_app header jar in app r8 classpath",
230					rule.Args["r8Flags"], overrideAppHeader.String())
231				android.AssertStringDoesContain(t, "expected transitive lib header jar in app r8 classpath",
232					rule.Args["r8Flags"], transitiveLibHeader.String())
233				android.AssertStringDoesContain(t, "expected transitive lib ^2 header jar in app r8 classpath",
234					rule.Args["r8Flags"], transitiveLib2Header.String())
235				android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
236					rule.Args["r8Flags"], libHeader.String())
237				android.AssertStringDoesContain(t, "expected uses_lib header jar in app r8 classpath",
238					rule.Args["r8Flags"], usesLibHeader.String())
239				android.AssertStringDoesContain(t, "expected optional_uses_lib header jar in app r8 classpath",
240					rule.Args["r8Flags"], optionalUsesLibHeader.String())
241				android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
242					rule.Args["r8Flags"], staticLibHeader.String())
243				android.AssertStringDoesNotContain(t, "expected no transitive static_lib header jar in app r8 classpath",
244					rule.Args["r8Flags"], transitiveStaticLibHeader.String())
245				// we shouldn't list this dep because it is already included as static_libs in the app
246				android.AssertStringDoesNotContain(t, "expected no repeated_dep header jar in app r8 classpath",
247					rule.Args["r8Flags"], repeatedDepHeader.String())
248				// skip a prebuilt transitive dep if the source is also a transitive dep
249				android.AssertStringDoesNotContain(t, "expected no prebuilt header jar in app r8 classpath",
250					rule.Args["r8Flags"], prebuiltLibHeader.String())
251				android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
252					rule.Args["r8Flags"], "-ignorewarnings")
253				android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
254					rule.Args["r8Flags"], "--android-platform-build")
255			}
256		})
257	}
258}
259
260func TestR8Flags(t *testing.T) {
261	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
262		android_app {
263			name: "app",
264			srcs: ["foo.java"],
265			platform_apis: true,
266			optimize: {
267				shrink: false,
268				optimize: false,
269				obfuscate: false,
270				ignore_warnings: false,
271			},
272		}
273	`)
274
275	app := result.ModuleForTests("app", "android_common")
276	appR8 := app.Rule("r8")
277	android.AssertStringDoesContain(t, "expected -dontshrink in app r8 flags",
278		appR8.Args["r8Flags"], "-dontshrink")
279	android.AssertStringDoesContain(t, "expected -dontoptimize in app r8 flags",
280		appR8.Args["r8Flags"], "-dontoptimize")
281	android.AssertStringDoesContain(t, "expected -dontobfuscate in app r8 flags",
282		appR8.Args["r8Flags"], "-dontobfuscate")
283	android.AssertStringDoesNotContain(t, "expected no -ignorewarnings in app r8 flags",
284		appR8.Args["r8Flags"], "-ignorewarnings")
285	android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
286		appR8.Args["r8Flags"], "--android-platform-build")
287}
288
289func TestD8(t *testing.T) {
290	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
291		java_library {
292			name: "foo",
293			srcs: ["foo.java"],
294			libs: ["lib"],
295			static_libs: ["static_lib"],
296			installable: true,
297		}
298
299		java_library {
300			name: "lib",
301			srcs: ["foo.java"],
302		}
303
304		java_library {
305			name: "static_lib",
306			srcs: ["foo.java"],
307		}
308	`)
309
310	foo := result.ModuleForTests("foo", "android_common")
311	lib := result.ModuleForTests("lib", "android_common")
312	staticLib := result.ModuleForTests("static_lib", "android_common")
313
314	fooJavac := foo.Rule("javac")
315	fooD8 := foo.Rule("d8")
316	libHeader := lib.Output("turbine-combined/lib.jar").Output
317	staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
318
319	android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath",
320		fooJavac.Args["classpath"], libHeader.String())
321	android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath",
322		fooJavac.Args["classpath"], staticLibHeader.String())
323
324	android.AssertStringDoesContain(t, "expected lib header jar in foo d8 classpath",
325		fooD8.Args["d8Flags"], libHeader.String())
326	android.AssertStringDoesNotContain(t, "expected no  static_lib header jar in foo javac classpath",
327		fooD8.Args["d8Flags"], staticLibHeader.String())
328}
329
330func TestProguardFlagsInheritance(t *testing.T) {
331	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
332		android_app {
333			name: "app",
334			static_libs: [
335				"primary_android_lib",
336				"primary_lib",
337			],
338			platform_apis: true,
339		}
340
341		java_library {
342			name: "primary_lib",
343			optimize: {
344				proguard_flags_files: ["primary.flags"],
345			},
346		}
347
348		android_library {
349			name: "primary_android_lib",
350			static_libs: ["secondary_lib"],
351			optimize: {
352				proguard_flags_files: ["primary_android.flags"],
353			},
354		}
355
356		java_library {
357			name: "secondary_lib",
358			static_libs: ["tertiary_lib"],
359			optimize: {
360				proguard_flags_files: ["secondary.flags"],
361			},
362		}
363
364		java_library {
365			name: "tertiary_lib",
366			optimize: {
367				proguard_flags_files: ["tertiary.flags"],
368			},
369		}
370	`)
371
372	app := result.ModuleForTests("app", "android_common")
373	appR8 := app.Rule("r8")
374	android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
375		appR8.Args["r8Flags"], "primary.flags")
376	android.AssertStringDoesContain(t, "expected primary_android_lib's proguard flags from direct dep",
377		appR8.Args["r8Flags"], "primary_android.flags")
378	android.AssertStringDoesContain(t, "expected secondary_lib's proguard flags from inherited dep",
379		appR8.Args["r8Flags"], "secondary.flags")
380	android.AssertStringDoesContain(t, "expected tertiary_lib's proguard flags from inherited dep",
381		appR8.Args["r8Flags"], "tertiary.flags")
382}
383