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