blob: f261066df68fb88f5c165bd2ea6f8a8049b7fcdf [file] [log] [blame]
Colin Cross9bb9bfb2022-03-17 11:12:32 -07001// 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 (
Sam Delmerico95d70942023-08-02 18:00:35 -040018 "fmt"
Colin Cross9bb9bfb2022-03-17 11:12:32 -070019 "testing"
20
21 "android/soong/android"
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050022
23 "github.com/google/blueprint/proptools"
Colin Cross9bb9bfb2022-03-17 11:12:32 -070024)
25
26func TestR8(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080027 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +000028 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Colin Cross9bb9bfb2022-03-17 11:12:32 -070029 android_app {
30 name: "app",
31 srcs: ["foo.java"],
32 libs: ["lib"],
33 static_libs: ["static_lib"],
34 platform_apis: true,
35 }
36
Jared Duke40d731a2022-09-20 15:32:14 -070037 android_app {
38 name: "stable_app",
39 srcs: ["foo.java"],
40 sdk_version: "current",
41 min_sdk_version: "31",
42 }
43
44 android_app {
45 name: "core_platform_app",
46 srcs: ["foo.java"],
47 sdk_version: "core_platform",
Spandan Dasc404cc72023-02-23 18:05:05 +000048 min_sdk_version: "31",
Jared Duke40d731a2022-09-20 15:32:14 -070049 }
50
Colin Cross9bb9bfb2022-03-17 11:12:32 -070051 java_library {
52 name: "lib",
53 srcs: ["foo.java"],
54 }
55
56 java_library {
57 name: "static_lib",
58 srcs: ["foo.java"],
59 }
60 `)
61
62 app := result.ModuleForTests("app", "android_common")
Jared Duke40d731a2022-09-20 15:32:14 -070063 stableApp := result.ModuleForTests("stable_app", "android_common")
64 corePlatformApp := result.ModuleForTests("core_platform_app", "android_common")
Colin Cross9bb9bfb2022-03-17 11:12:32 -070065 lib := result.ModuleForTests("lib", "android_common")
66 staticLib := result.ModuleForTests("static_lib", "android_common")
67
68 appJavac := app.Rule("javac")
69 appR8 := app.Rule("r8")
Jared Duke40d731a2022-09-20 15:32:14 -070070 stableAppR8 := stableApp.Rule("r8")
71 corePlatformAppR8 := corePlatformApp.Rule("r8")
Colin Cross9bb9bfb2022-03-17 11:12:32 -070072 libHeader := lib.Output("turbine-combined/lib.jar").Output
73 staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
74
75 android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath",
76 appJavac.Args["classpath"], libHeader.String())
77 android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath",
78 appJavac.Args["classpath"], staticLibHeader.String())
79
80 android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
81 appR8.Args["r8Flags"], libHeader.String())
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050082 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
Colin Cross9bb9bfb2022-03-17 11:12:32 -070083 appR8.Args["r8Flags"], staticLibHeader.String())
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +090084 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
85 appR8.Args["r8Flags"], "-ignorewarnings")
Jared Duke40d731a2022-09-20 15:32:14 -070086 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
87 appR8.Args["r8Flags"], "--android-platform-build")
88 android.AssertStringDoesNotContain(t, "expected no --android-platform-build in stable_app r8 flags",
89 stableAppR8.Args["r8Flags"], "--android-platform-build")
90 android.AssertStringDoesContain(t, "expected --android-platform-build in core_platform_app r8 flags",
91 corePlatformAppR8.Args["r8Flags"], "--android-platform-build")
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +090092}
93
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050094func TestR8TransitiveDeps(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080095 t.Parallel()
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050096 bp := `
97 override_android_app {
98 name: "override_app",
99 base: "app",
100 }
101
102 android_app {
103 name: "app",
104 srcs: ["foo.java"],
105 libs: [
106 "lib",
107 "uses_libs_dep_import",
108 ],
109 static_libs: [
110 "static_lib",
111 "repeated_dep",
112 ],
113 platform_apis: true,
114 }
115
116 java_library {
117 name: "static_lib",
118 srcs: ["foo.java"],
119 }
120
121 java_library {
122 name: "lib",
123 libs: [
124 "transitive_lib",
125 "repeated_dep",
126 "prebuilt_lib",
127 ],
128 static_libs: ["transitive_static_lib"],
129 srcs: ["foo.java"],
130 }
131
132 java_library {
133 name: "repeated_dep",
134 srcs: ["foo.java"],
135 }
136
137 java_library {
138 name: "transitive_static_lib",
139 srcs: ["foo.java"],
140 }
141
142 java_library {
143 name: "transitive_lib",
144 srcs: ["foo.java"],
145 libs: ["transitive_lib_2"],
146 }
147
148 java_library {
149 name: "transitive_lib_2",
150 srcs: ["foo.java"],
151 }
152
153 java_import {
154 name: "lib",
155 jars: ["lib.jar"],
156 }
157
158 java_library {
159 name: "uses_lib",
160 srcs: ["foo.java"],
161 }
162
163 java_library {
164 name: "optional_uses_lib",
165 srcs: ["foo.java"],
166 }
167
168 android_library {
169 name: "uses_libs_dep",
170 uses_libs: ["uses_lib"],
171 optional_uses_libs: ["optional_uses_lib"],
172 }
173
174 android_library_import {
175 name: "uses_libs_dep_import",
176 aars: ["aar.aar"],
177 static_libs: ["uses_libs_dep"],
178 }
179 `
180
181 testcases := []struct {
182 name string
183 unbundled bool
184 }{
185 {
186 name: "non-unbundled build",
187 unbundled: false,
188 },
189 {
190 name: "unbundled build",
191 unbundled: true,
192 },
193 }
194
195 for _, tc := range testcases {
196 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800197 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000198 fixturePreparer := PrepareForTestWithJavaDefaultModules
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500199 if tc.unbundled {
200 fixturePreparer = android.GroupFixturePreparers(
201 fixturePreparer,
202 android.FixtureModifyProductVariables(
203 func(variables android.FixtureProductVariables) {
204 variables.Unbundled_build = proptools.BoolPtr(true)
205 },
206 ),
207 )
208 }
209 result := fixturePreparer.RunTestWithBp(t, bp)
210
211 getHeaderJar := func(name string) android.Path {
212 mod := result.ModuleForTests(name, "android_common")
213 return mod.Output("turbine-combined/" + name + ".jar").Output
214 }
215
216 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
217 overrideAppR8 := result.ModuleForTests("app", "android_common_override_app").Rule("r8")
218 appHeader := getHeaderJar("app")
219 overrideAppHeader := result.ModuleForTests("app", "android_common_override_app").Output("turbine-combined/app.jar").Output
220 libHeader := getHeaderJar("lib")
221 transitiveLibHeader := getHeaderJar("transitive_lib")
222 transitiveLib2Header := getHeaderJar("transitive_lib_2")
223 staticLibHeader := getHeaderJar("static_lib")
224 transitiveStaticLibHeader := getHeaderJar("transitive_static_lib")
225 repeatedDepHeader := getHeaderJar("repeated_dep")
226 usesLibHeader := getHeaderJar("uses_lib")
227 optionalUsesLibHeader := getHeaderJar("optional_uses_lib")
228 prebuiltLibHeader := result.ModuleForTests("prebuilt_lib", "android_common").Output("combined/lib.jar").Output
229
230 for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} {
231 android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath",
232 rule.Args["r8Flags"], appHeader.String())
233 android.AssertStringDoesNotContain(t, "expected no override_app header jar in app r8 classpath",
234 rule.Args["r8Flags"], overrideAppHeader.String())
235 android.AssertStringDoesContain(t, "expected transitive lib header jar in app r8 classpath",
236 rule.Args["r8Flags"], transitiveLibHeader.String())
237 android.AssertStringDoesContain(t, "expected transitive lib ^2 header jar in app r8 classpath",
238 rule.Args["r8Flags"], transitiveLib2Header.String())
239 android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
240 rule.Args["r8Flags"], libHeader.String())
241 android.AssertStringDoesContain(t, "expected uses_lib header jar in app r8 classpath",
242 rule.Args["r8Flags"], usesLibHeader.String())
243 android.AssertStringDoesContain(t, "expected optional_uses_lib header jar in app r8 classpath",
244 rule.Args["r8Flags"], optionalUsesLibHeader.String())
245 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
246 rule.Args["r8Flags"], staticLibHeader.String())
247 android.AssertStringDoesNotContain(t, "expected no transitive static_lib header jar in app r8 classpath",
248 rule.Args["r8Flags"], transitiveStaticLibHeader.String())
249 // we shouldn't list this dep because it is already included as static_libs in the app
250 android.AssertStringDoesNotContain(t, "expected no repeated_dep header jar in app r8 classpath",
251 rule.Args["r8Flags"], repeatedDepHeader.String())
252 // skip a prebuilt transitive dep if the source is also a transitive dep
253 android.AssertStringDoesNotContain(t, "expected no prebuilt header jar in app r8 classpath",
254 rule.Args["r8Flags"], prebuiltLibHeader.String())
255 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
256 rule.Args["r8Flags"], "-ignorewarnings")
257 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
258 rule.Args["r8Flags"], "--android-platform-build")
259 }
260 })
261 }
262}
263
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900264func TestR8Flags(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800265 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000266 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900267 android_app {
268 name: "app",
269 srcs: ["foo.java"],
270 platform_apis: true,
271 optimize: {
272 shrink: false,
273 optimize: false,
274 obfuscate: false,
275 ignore_warnings: false,
276 },
277 }
278 `)
279
280 app := result.ModuleForTests("app", "android_common")
281 appR8 := app.Rule("r8")
282 android.AssertStringDoesContain(t, "expected -dontshrink in app r8 flags",
283 appR8.Args["r8Flags"], "-dontshrink")
284 android.AssertStringDoesContain(t, "expected -dontoptimize in app r8 flags",
285 appR8.Args["r8Flags"], "-dontoptimize")
286 android.AssertStringDoesContain(t, "expected -dontobfuscate in app r8 flags",
287 appR8.Args["r8Flags"], "-dontobfuscate")
288 android.AssertStringDoesNotContain(t, "expected no -ignorewarnings in app r8 flags",
289 appR8.Args["r8Flags"], "-ignorewarnings")
Jared Duke40d731a2022-09-20 15:32:14 -0700290 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
291 appR8.Args["r8Flags"], "--android-platform-build")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700292}
293
294func TestD8(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800295 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000296 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700297 java_library {
298 name: "foo",
299 srcs: ["foo.java"],
300 libs: ["lib"],
301 static_libs: ["static_lib"],
302 installable: true,
303 }
304
305 java_library {
306 name: "lib",
307 srcs: ["foo.java"],
308 }
309
310 java_library {
311 name: "static_lib",
312 srcs: ["foo.java"],
313 }
314 `)
315
316 foo := result.ModuleForTests("foo", "android_common")
317 lib := result.ModuleForTests("lib", "android_common")
318 staticLib := result.ModuleForTests("static_lib", "android_common")
319
320 fooJavac := foo.Rule("javac")
321 fooD8 := foo.Rule("d8")
322 libHeader := lib.Output("turbine-combined/lib.jar").Output
323 staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
324
325 android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath",
326 fooJavac.Args["classpath"], libHeader.String())
327 android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath",
328 fooJavac.Args["classpath"], staticLibHeader.String())
329
330 android.AssertStringDoesContain(t, "expected lib header jar in foo d8 classpath",
331 fooD8.Args["d8Flags"], libHeader.String())
332 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in foo javac classpath",
333 fooD8.Args["d8Flags"], staticLibHeader.String())
334}
Jared Duke5979b302022-12-19 21:08:39 +0000335
Sam Delmerico95d70942023-08-02 18:00:35 -0400336func TestProguardFlagsInheritanceStatic(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800337 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000338 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Jared Duke5979b302022-12-19 21:08:39 +0000339 android_app {
340 name: "app",
341 static_libs: [
342 "primary_android_lib",
343 "primary_lib",
344 ],
345 platform_apis: true,
346 }
347
348 java_library {
349 name: "primary_lib",
350 optimize: {
351 proguard_flags_files: ["primary.flags"],
352 },
353 }
354
355 android_library {
356 name: "primary_android_lib",
357 static_libs: ["secondary_lib"],
358 optimize: {
359 proguard_flags_files: ["primary_android.flags"],
360 },
361 }
362
363 java_library {
364 name: "secondary_lib",
365 static_libs: ["tertiary_lib"],
366 optimize: {
367 proguard_flags_files: ["secondary.flags"],
368 },
369 }
370
371 java_library {
372 name: "tertiary_lib",
373 optimize: {
374 proguard_flags_files: ["tertiary.flags"],
375 },
376 }
377 `)
378
379 app := result.ModuleForTests("app", "android_common")
380 appR8 := app.Rule("r8")
381 android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
382 appR8.Args["r8Flags"], "primary.flags")
383 android.AssertStringDoesContain(t, "expected primary_android_lib's proguard flags from direct dep",
384 appR8.Args["r8Flags"], "primary_android.flags")
385 android.AssertStringDoesContain(t, "expected secondary_lib's proguard flags from inherited dep",
386 appR8.Args["r8Flags"], "secondary.flags")
387 android.AssertStringDoesContain(t, "expected tertiary_lib's proguard flags from inherited dep",
388 appR8.Args["r8Flags"], "tertiary.flags")
389}
Sam Delmerico95d70942023-08-02 18:00:35 -0400390
391func TestProguardFlagsInheritance(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800392 t.Parallel()
Sam Delmerico95d70942023-08-02 18:00:35 -0400393 directDepFlagsFileName := "direct_dep.flags"
394 transitiveDepFlagsFileName := "transitive_dep.flags"
Sam Delmerico95d70942023-08-02 18:00:35 -0400395
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000396 topLevelModules := []struct {
397 name string
398 definition string
399 }{
400 {
401 name: "android_app",
402 definition: `
403 android_app {
404 name: "app",
405 static_libs: ["androidlib"], // this must be static_libs to initate dexing
406 platform_apis: true,
407 }
408 `,
409 },
410 {
411 name: "android_library",
412 definition: `
413 android_library {
414 name: "app",
415 static_libs: ["androidlib"], // this must be static_libs to initate dexing
416 installable: true,
417 optimize: {
418 enabled: true,
419 shrink: true,
420 },
421 }
422 `,
423 },
424 {
425 name: "java_library",
426 definition: `
427 java_library {
428 name: "app",
429 static_libs: ["androidlib"], // this must be static_libs to initate dexing
430 srcs: ["Foo.java"],
431 installable: true,
432 optimize: {
433 enabled: true,
434 shrink: true,
435 },
436 }
437 `,
438 },
439 }
440
441 bp := `
Sam Delmerico95d70942023-08-02 18:00:35 -0400442 android_library {
443 name: "androidlib",
444 static_libs: ["app_dep"],
445 }
446
447 java_library {
448 name: "app_dep",
449 %s: ["dep"],
450 }
451
452 java_library {
453 name: "dep",
454 %s: ["transitive_dep"],
455 optimize: {
456 proguard_flags_files: ["direct_dep.flags"],
457 export_proguard_flags_files: %v,
458 },
459 }
460
461 java_library {
462 name: "transitive_dep",
463 optimize: {
464 proguard_flags_files: ["transitive_dep.flags"],
465 export_proguard_flags_files: %v,
466 },
467 }
468 `
469
470 testcases := []struct {
471 name string
472 depType string
473 depExportsFlagsFiles bool
474 transitiveDepType string
475 transitiveDepExportsFlagsFiles bool
476 expectedFlagsFiles []string
477 }{
478 {
479 name: "libs_export_libs_export",
480 depType: "libs",
481 depExportsFlagsFiles: true,
482 transitiveDepType: "libs",
483 transitiveDepExportsFlagsFiles: true,
484 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
485 },
486 {
487 name: "static_export_libs_export",
488 depType: "static_libs",
489 depExportsFlagsFiles: true,
490 transitiveDepType: "libs",
491 transitiveDepExportsFlagsFiles: true,
492 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
493 },
494 {
495 name: "libs_no-export_static_export",
496 depType: "libs",
497 depExportsFlagsFiles: false,
498 transitiveDepType: "static_libs",
499 transitiveDepExportsFlagsFiles: true,
500 expectedFlagsFiles: []string{transitiveDepFlagsFileName},
501 },
502 {
503 name: "static_no-export_static_export",
504 depType: "static_libs",
505 depExportsFlagsFiles: false,
506 transitiveDepType: "static_libs",
507 transitiveDepExportsFlagsFiles: true,
508 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
509 },
510 {
511 name: "libs_export_libs_no-export",
512 depType: "libs",
513 depExportsFlagsFiles: true,
514 transitiveDepType: "libs",
515 transitiveDepExportsFlagsFiles: false,
516 expectedFlagsFiles: []string{directDepFlagsFileName},
517 },
518 {
519 name: "static_export_libs_no-export",
520 depType: "static_libs",
521 depExportsFlagsFiles: true,
522 transitiveDepType: "libs",
523 transitiveDepExportsFlagsFiles: false,
524 expectedFlagsFiles: []string{directDepFlagsFileName},
525 },
526 {
527 name: "libs_no-export_static_no-export",
528 depType: "libs",
529 depExportsFlagsFiles: false,
530 transitiveDepType: "static_libs",
531 transitiveDepExportsFlagsFiles: false,
532 expectedFlagsFiles: []string{},
533 },
534 {
535 name: "static_no-export_static_no-export",
536 depType: "static_libs",
537 depExportsFlagsFiles: false,
538 transitiveDepType: "static_libs",
539 transitiveDepExportsFlagsFiles: false,
540 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
541 },
542 {
543 name: "libs_no-export_libs_export",
544 depType: "libs",
545 depExportsFlagsFiles: false,
546 transitiveDepType: "libs",
547 transitiveDepExportsFlagsFiles: true,
548 expectedFlagsFiles: []string{transitiveDepFlagsFileName},
549 },
550 {
551 name: "static_no-export_libs_export",
552 depType: "static_libs",
553 depExportsFlagsFiles: false,
554 transitiveDepType: "libs",
555 transitiveDepExportsFlagsFiles: true,
556 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
557 },
558 {
559 name: "libs_export_static_export",
560 depType: "libs",
561 depExportsFlagsFiles: true,
562 transitiveDepType: "static_libs",
563 transitiveDepExportsFlagsFiles: true,
564 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
565 },
566 {
567 name: "static_export_static_export",
568 depType: "static_libs",
569 depExportsFlagsFiles: true,
570 transitiveDepType: "static_libs",
571 transitiveDepExportsFlagsFiles: true,
572 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
573 },
574 {
575 name: "libs_no-export_libs_no-export",
576 depType: "libs",
577 depExportsFlagsFiles: false,
578 transitiveDepType: "libs",
579 transitiveDepExportsFlagsFiles: false,
580 expectedFlagsFiles: []string{},
581 },
582 {
583 name: "static_no-export_libs_no-export",
584 depType: "static_libs",
585 depExportsFlagsFiles: false,
586 transitiveDepType: "libs",
587 transitiveDepExportsFlagsFiles: false,
588 expectedFlagsFiles: []string{directDepFlagsFileName},
589 },
590 {
591 name: "libs_export_static_no-export",
592 depType: "libs",
593 depExportsFlagsFiles: true,
594 transitiveDepType: "static_libs",
595 transitiveDepExportsFlagsFiles: false,
596 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
597 },
598 {
599 name: "static_export_static_no-export",
600 depType: "static_libs",
601 depExportsFlagsFiles: true,
602 transitiveDepType: "static_libs",
603 transitiveDepExportsFlagsFiles: false,
604 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
605 },
606 }
607
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000608 for _, topLevelModuleDef := range topLevelModules {
609 for _, tc := range testcases {
610 t.Run(topLevelModuleDef.name+"-"+tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800611 t.Parallel()
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000612 result := android.GroupFixturePreparers(
613 PrepareForTestWithJavaDefaultModules,
614 android.FixtureMergeMockFs(android.MockFS{
615 directDepFlagsFileName: nil,
616 transitiveDepFlagsFileName: nil,
617 }),
618 ).RunTestWithBp(t,
619 topLevelModuleDef.definition+
620 fmt.Sprintf(
621 bp,
622 tc.depType,
623 tc.transitiveDepType,
624 tc.depExportsFlagsFiles,
625 tc.transitiveDepExportsFlagsFiles,
626 ),
627 )
628 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
Sam Delmerico95d70942023-08-02 18:00:35 -0400629
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000630 shouldHaveDepFlags := android.InList(directDepFlagsFileName, tc.expectedFlagsFiles)
631 if shouldHaveDepFlags {
632 android.AssertStringDoesContain(t, "expected deps's proguard flags",
633 appR8.Args["r8Flags"], directDepFlagsFileName)
634 } else {
635 android.AssertStringDoesNotContain(t, "app did not expect deps's proguard flags",
636 appR8.Args["r8Flags"], directDepFlagsFileName)
637 }
Sam Delmerico95d70942023-08-02 18:00:35 -0400638
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000639 shouldHaveTransitiveDepFlags := android.InList(transitiveDepFlagsFileName, tc.expectedFlagsFiles)
640 if shouldHaveTransitiveDepFlags {
641 android.AssertStringDoesContain(t, "expected transitive deps's proguard flags",
642 appR8.Args["r8Flags"], transitiveDepFlagsFileName)
643 } else {
644 android.AssertStringDoesNotContain(t, "app did not expect transitive deps's proguard flags",
645 appR8.Args["r8Flags"], transitiveDepFlagsFileName)
646 }
647 })
648 }
Sam Delmerico95d70942023-08-02 18:00:35 -0400649 }
650}
651
652func TestProguardFlagsInheritanceAppImport(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800653 t.Parallel()
Sam Delmerico95d70942023-08-02 18:00:35 -0400654 bp := `
655 android_app {
656 name: "app",
657 static_libs: ["aarimport"], // this must be static_libs to initate dexing
658 platform_apis: true,
659 }
660
Sam Delmerico95d70942023-08-02 18:00:35 -0400661 android_library_import {
662 name: "aarimport",
663 aars: ["import.aar"],
664 }
665 `
666 result := android.GroupFixturePreparers(
667 PrepareForTestWithJavaDefaultModules,
668 ).RunTestWithBp(t, bp)
669
670 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
671 android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
672 appR8.Args["r8Flags"], "proguard.txt")
673}
Spandan Das3dbda182024-05-20 22:23:10 +0000674
675func TestR8FlagsArtProfile(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800676 t.Parallel()
Spandan Das3dbda182024-05-20 22:23:10 +0000677 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
678 android_app {
679 name: "app",
680 srcs: ["foo.java"],
681 platform_apis: true,
682 dex_preopt: {
683 profile_guided: true,
684 profile: "profile.txt.prof",
685 enable_profile_rewriting: true,
686 },
687 }
688 `)
689
690 app := result.ModuleForTests("app", "android_common")
691 appR8 := app.Rule("r8")
692 android.AssertStringDoesContain(t, "expected --art-profile in app r8 flags",
693 appR8.Args["r8Flags"], "--art-profile")
694
695 appDexpreopt := app.Rule("dexpreopt")
696 android.AssertStringDoesContain(t,
697 "expected --art-profile output to be used to create .prof binary",
698 appDexpreopt.RuleParams.Command,
699 "--create-profile-from=out/soong/.intermediates/app/android_common/profile.prof.txt --output-profile-type=app",
700 )
701}
Spandan Das15a67112024-05-30 00:07:40 +0000702
703// This test checks that users explicitly set `enable_profile_rewriting` to true when the following are true
704// 1. optimize or obfuscate is enabled AND
705// 2. dex_preopt.profile_guided is enabled
706//
707// The rewritten profile should be used since the dex signatures in the checked-in profile will not match the optimized binary.
708func TestEnableProfileRewritingIsRequiredForOptimizedApps(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800709 t.Parallel()
Spandan Das15a67112024-05-30 00:07:40 +0000710 testJavaError(t,
711 "Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on",
712 `
713android_app {
714 name: "app",
715 srcs: ["foo.java"],
716 platform_apis: true,
717 dex_preopt: {
718 profile_guided: true,
719 profile: "profile.txt.prof",
720 // enable_profile_rewriting is not set, this is an error
721 },
722 optimize: {
723 optimize: true,
724 }
725}`)
726}
Jared Duked32e85f2024-09-25 23:54:30 +0000727
728func TestDebugReleaseFlags(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800729 t.Parallel()
Jared Duked32e85f2024-09-25 23:54:30 +0000730 bp := `
731 android_app {
732 name: "app",
733 srcs: ["foo.java"],
734 platform_apis: true,
735 dxflags: ["%s"]
736 }
737 `
738
739 testcases := []struct {
740 name string
741 envVar string
742 isEng bool
743 dxFlags string
744 expectedFlags string
745 }{
746 {
747 name: "app_no_optimize_dx",
748 envVar: "NO_OPTIMIZE_DX",
749 expectedFlags: "--debug",
750 },
751 {
752 name: "app_release_no_optimize_dx",
753 envVar: "NO_OPTIMIZE_DX",
754 dxFlags: "--release",
755 // Global env vars override explicit dxflags.
756 expectedFlags: "--debug",
757 },
758 {
759 name: "app_generate_dex_debug",
760 envVar: "GENERATE_DEX_DEBUG",
761 expectedFlags: "--debug",
762 },
763 {
764 name: "app_release_generate_dex_debug",
765 envVar: "GENERATE_DEX_DEBUG",
766 dxFlags: "--release",
767 // Global env vars override explicit dxflags.
768 expectedFlags: "--debug",
769 },
770 {
771 name: "app_eng",
772 isEng: true,
773 expectedFlags: "--debug",
774 },
775 {
776 name: "app_release_eng",
777 isEng: true,
778 dxFlags: "--release",
779 // Eng mode does *not* override explicit dxflags.
780 expectedFlags: "--release",
781 },
782 }
783
784 for _, tc := range testcases {
785 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800786 t.Parallel()
Jared Duked32e85f2024-09-25 23:54:30 +0000787 fixturePreparer := PrepareForTestWithJavaDefaultModules
788 fixturePreparer = android.GroupFixturePreparers(
789 fixturePreparer,
790 android.FixtureModifyProductVariables(
791 func(variables android.FixtureProductVariables) {
792 variables.Eng = proptools.BoolPtr(tc.isEng)
793 },
794 ),
795 )
796 if tc.envVar != "" {
797 fixturePreparer = android.GroupFixturePreparers(
798 fixturePreparer,
799 android.FixtureMergeEnv(map[string]string{
800 tc.envVar: "true",
801 }),
802 )
803 }
804 result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, tc.dxFlags))
805
806 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
807 android.AssertStringDoesContain(t, "expected flag in R8 flags",
808 appR8.Args["r8Flags"], tc.expectedFlags)
809
810 var unexpectedFlags string
811 if tc.expectedFlags == "--debug" {
812 unexpectedFlags = "--release"
813 } else if tc.expectedFlags == "--release" {
814 unexpectedFlags = "--debug"
815 }
816 if unexpectedFlags != "" {
817 android.AssertStringDoesNotContain(t, "unexpected flag in R8 flags",
818 appR8.Args["r8Flags"], unexpectedFlags)
819 }
820 })
821 }
822}