1// Copyright 2021 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 "path/filepath" 20 "regexp" 21 "strings" 22 "testing" 23 24 "android/soong/android" 25 26 "github.com/google/blueprint/proptools" 27) 28 29func TestJavaSdkLibrary(t *testing.T) { 30 result := android.GroupFixturePreparers( 31 prepareForJavaTest, 32 PrepareForTestWithJavaSdkLibraryFiles, 33 FixtureWithPrebuiltApis(map[string][]string{ 34 "28": {"foo"}, 35 "29": {"foo"}, 36 "30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"}, 37 }), 38 android.FixtureModifyConfig(func(config android.Config) { 39 config.SetApiLibraries([]string{"foo"}) 40 }), 41 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 42 variables.BuildFlags = map[string]string{ 43 "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true", 44 } 45 }), 46 ).RunTestWithBp(t, ` 47 droiddoc_exported_dir { 48 name: "droiddoc-templates-sdk", 49 path: ".", 50 } 51 java_sdk_library { 52 name: "foo", 53 srcs: ["a.java", "b.java"], 54 api_packages: ["foo"], 55 } 56 java_sdk_library { 57 name: "bar", 58 srcs: ["a.java", "b.java"], 59 api_packages: ["bar"], 60 exclude_kotlinc_generated_files: true, 61 } 62 java_library { 63 name: "baz", 64 srcs: ["c.java"], 65 libs: ["foo", "bar.stubs"], 66 sdk_version: "system_current", 67 } 68 java_sdk_library { 69 name: "barney", 70 srcs: ["c.java"], 71 api_only: true, 72 } 73 java_sdk_library { 74 name: "betty", 75 srcs: ["c.java"], 76 shared_library: false, 77 } 78 java_sdk_library_import { 79 name: "quuz", 80 public: { 81 jars: ["c.jar"], 82 current_api: "api/current.txt", 83 removed_api: "api/removed.txt", 84 }, 85 } 86 java_sdk_library_import { 87 name: "fred", 88 public: { 89 jars: ["b.jar"], 90 }, 91 } 92 java_sdk_library_import { 93 name: "wilma", 94 public: { 95 jars: ["b.jar"], 96 }, 97 shared_library: false, 98 } 99 java_library { 100 name: "qux", 101 srcs: ["c.java"], 102 libs: ["baz", "fred", "quuz.stubs", "wilma", "barney", "betty"], 103 sdk_version: "system_current", 104 } 105 java_library { 106 name: "baz-test", 107 srcs: ["c.java"], 108 libs: ["foo"], 109 sdk_version: "test_current", 110 } 111 java_library { 112 name: "baz-29", 113 srcs: ["c.java"], 114 libs: ["foo"], 115 sdk_version: "system_29", 116 } 117 java_library { 118 name: "baz-module-30", 119 srcs: ["c.java"], 120 libs: ["foo"], 121 sdk_version: "module_30", 122 } 123 `) 124 125 // check the existence of the internal modules 126 foo := result.ModuleForTests("foo", "android_common") 127 result.ModuleForTests(apiScopePublic.stubsLibraryModuleName("foo"), "android_common") 128 result.ModuleForTests(apiScopeSystem.stubsLibraryModuleName("foo"), "android_common") 129 result.ModuleForTests(apiScopeTest.stubsLibraryModuleName("foo"), "android_common") 130 result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo"), "android_common") 131 result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common") 132 result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common") 133 result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "") 134 result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common") 135 result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common") 136 result.ModuleForTests("foo.api.public.28", "") 137 result.ModuleForTests("foo.api.system.28", "") 138 result.ModuleForTests("foo.api.test.28", "") 139 140 exportedComponentsInfo, _ := android.SingletonModuleProvider(result, foo.Module(), android.ExportedComponentsInfoProvider) 141 expectedFooExportedComponents := []string{ 142 "foo-removed.api.combined.public.latest", 143 "foo-removed.api.combined.system.latest", 144 "foo.api.combined.public.latest", 145 "foo.api.combined.system.latest", 146 "foo.stubs", 147 "foo.stubs.exportable", 148 "foo.stubs.exportable.system", 149 "foo.stubs.exportable.test", 150 "foo.stubs.source", 151 "foo.stubs.source.system", 152 "foo.stubs.source.test", 153 "foo.stubs.system", 154 "foo.stubs.test", 155 } 156 android.AssertArrayString(t, "foo exported components", expectedFooExportedComponents, exportedComponentsInfo.Components) 157 158 bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac") 159 // tests if baz is actually linked to the stubs lib 160 android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.jar") 161 // ... and not to the impl lib 162 android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.jar") 163 // test if baz is not linked to the system variant of foo 164 android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.jar") 165 166 bazTestJavac := result.ModuleForTests("baz-test", "android_common").Rule("javac") 167 // tests if baz-test is actually linked to the test stubs lib 168 android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.jar") 169 170 baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac") 171 // tests if baz-29 is actually linked to the system 29 stubs lib 172 android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/29/system/foo.jar") 173 174 bazModule30Javac := result.ModuleForTests("baz-module-30", "android_common").Rule("javac") 175 // tests if "baz-module-30" is actually linked to the module 30 stubs lib 176 android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/30/module-lib/foo.jar") 177 178 // test if baz has exported SDK lib names foo and bar to qux 179 qux := result.ModuleForTests("qux", "android_common") 180 if quxLib, ok := qux.Module().(*Library); ok { 181 requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs() 182 android.AssertDeepEquals(t, "qux exports (required)", []string{"fred", "quuz", "foo", "bar"}, requiredSdkLibs) 183 android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs) 184 } 185 186 // test if quuz have created the api_contribution module 187 result.ModuleForTests(apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "") 188 189 fooImplDexJar := result.ModuleForTests("foo.impl", "android_common").Rule("d8") 190 // tests if kotlinc generated files are NOT excluded from output of foo.impl. 191 android.AssertStringDoesNotContain(t, "foo.impl dex", fooImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module") 192 193 barImplDexJar := result.ModuleForTests("bar.impl", "android_common").Rule("d8") 194 // tests if kotlinc generated files are excluded from output of bar.impl. 195 android.AssertStringDoesContain(t, "bar.impl dex", barImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module") 196} 197 198func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) { 199 result := android.GroupFixturePreparers( 200 prepareForJavaTest, 201 PrepareForTestWithJavaSdkLibraryFiles, 202 FixtureWithPrebuiltApis(map[string][]string{ 203 "28": {"foo"}, 204 "29": {"foo"}, 205 "30": {"foo", "fooUpdatable", "fooUpdatableErr"}, 206 }), 207 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 208 variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V", "W", "X"} 209 }), 210 ).RunTestWithBp(t, 211 ` 212 java_sdk_library { 213 name: "fooUpdatable", 214 srcs: ["a.java", "b.java"], 215 api_packages: ["foo"], 216 on_bootclasspath_since: "U", 217 on_bootclasspath_before: "V", 218 min_device_sdk: "W", 219 max_device_sdk: "X", 220 min_sdk_version: "S", 221 } 222 java_sdk_library { 223 name: "foo", 224 srcs: ["a.java", "b.java"], 225 api_packages: ["foo"], 226 } 227`) 228 229 // test that updatability attributes are passed on correctly 230 fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Output("fooUpdatable.xml") 231 fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable) 232 android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-since="U"`) 233 android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-before="V"`) 234 android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `min-device-sdk="W"`) 235 android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `max-device-sdk="X"`) 236 237 // double check that updatability attributes are not written if they don't exist in the bp file 238 // the permissions file for the foo library defined above 239 fooPermissions := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml") 240 fooPermissionsContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooPermissions) 241 android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-since`) 242 android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-before`) 243 android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `min-device-sdk`) 244 android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `max-device-sdk`) 245} 246 247func TestJavaSdkLibrary_UpdatableLibrary_Validation_ValidVersion(t *testing.T) { 248 android.GroupFixturePreparers( 249 prepareForJavaTest, 250 PrepareForTestWithJavaSdkLibraryFiles, 251 FixtureWithPrebuiltApis(map[string][]string{ 252 "30": {"fooUpdatable", "fooUpdatableErr"}, 253 }), 254 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern( 255 []string{ 256 `on_bootclasspath_since: "aaa" could not be parsed as an integer and is not a recognized codename`, 257 `on_bootclasspath_before: "bbc" could not be parsed as an integer and is not a recognized codename`, 258 `min_device_sdk: "ccc" could not be parsed as an integer and is not a recognized codename`, 259 `max_device_sdk: "current" is not an allowed value for this attribute`, 260 })).RunTestWithBp(t, 261 ` 262 java_sdk_library { 263 name: "fooUpdatableErr", 264 srcs: ["a.java", "b.java"], 265 api_packages: ["foo"], 266 on_bootclasspath_since: "aaa", 267 on_bootclasspath_before: "bbc", 268 min_device_sdk: "ccc", 269 max_device_sdk: "current", 270 } 271`) 272} 273 274func TestJavaSdkLibrary_UpdatableLibrary_Validation_AtLeastTAttributes(t *testing.T) { 275 android.GroupFixturePreparers( 276 prepareForJavaTest, 277 PrepareForTestWithJavaSdkLibraryFiles, 278 FixtureWithPrebuiltApis(map[string][]string{ 279 "28": {"foo"}, 280 }), 281 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern( 282 []string{ 283 "on_bootclasspath_since: Attribute value needs to be at least T", 284 "on_bootclasspath_before: Attribute value needs to be at least T", 285 "min_device_sdk: Attribute value needs to be at least T", 286 "max_device_sdk: Attribute value needs to be at least T", 287 }, 288 )).RunTestWithBp(t, 289 ` 290 java_sdk_library { 291 name: "foo", 292 srcs: ["a.java", "b.java"], 293 api_packages: ["foo"], 294 on_bootclasspath_since: "S", 295 on_bootclasspath_before: "S", 296 min_device_sdk: "S", 297 max_device_sdk: "S", 298 min_sdk_version: "S", 299 } 300`) 301} 302 303func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdk(t *testing.T) { 304 android.GroupFixturePreparers( 305 prepareForJavaTest, 306 PrepareForTestWithJavaSdkLibraryFiles, 307 FixtureWithPrebuiltApis(map[string][]string{ 308 "28": {"foo"}, 309 }), 310 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 311 variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V"} 312 }), 313 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern( 314 []string{ 315 "min_device_sdk can't be greater than max_device_sdk", 316 }, 317 )).RunTestWithBp(t, 318 ` 319 java_sdk_library { 320 name: "foo", 321 srcs: ["a.java", "b.java"], 322 api_packages: ["foo"], 323 min_device_sdk: "V", 324 max_device_sdk: "U", 325 min_sdk_version: "S", 326 } 327`) 328} 329 330func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdkAndModuleMinSdk(t *testing.T) { 331 android.GroupFixturePreparers( 332 prepareForJavaTest, 333 PrepareForTestWithJavaSdkLibraryFiles, 334 FixtureWithPrebuiltApis(map[string][]string{ 335 "28": {"foo"}, 336 }), 337 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 338 variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V"} 339 }), 340 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern( 341 []string{ 342 regexp.QuoteMeta("min_device_sdk: Can't be less than module's min sdk (V)"), 343 regexp.QuoteMeta("max_device_sdk: Can't be less than module's min sdk (V)"), 344 }, 345 )).RunTestWithBp(t, 346 ` 347 java_sdk_library { 348 name: "foo", 349 srcs: ["a.java", "b.java"], 350 api_packages: ["foo"], 351 min_device_sdk: "U", 352 max_device_sdk: "U", 353 min_sdk_version: "V", 354 } 355`) 356} 357 358func TestJavaSdkLibrary_UpdatableLibrary_usesNewTag(t *testing.T) { 359 result := android.GroupFixturePreparers( 360 prepareForJavaTest, 361 PrepareForTestWithJavaSdkLibraryFiles, 362 FixtureWithPrebuiltApis(map[string][]string{ 363 "30": {"foo"}, 364 }), 365 ).RunTestWithBp(t, 366 ` 367 java_sdk_library { 368 name: "foo", 369 srcs: ["a.java", "b.java"], 370 min_device_sdk: "Tiramisu", 371 min_sdk_version: "S", 372 } 373`) 374 // test that updatability attributes are passed on correctly 375 fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml") 376 fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable) 377 android.AssertStringDoesContain(t, "foo.xml contents", fooUpdatableContents, `<apex-library`) 378 android.AssertStringDoesNotContain(t, "foo.xml contents", fooUpdatableContents, `<library`) 379} 380 381func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) { 382 result := android.GroupFixturePreparers( 383 prepareForJavaTest, 384 PrepareForTestWithJavaSdkLibraryFiles, 385 FixtureWithLastReleaseApis("sdklib"), 386 ).RunTestWithBp(t, ` 387 java_sdk_library { 388 name: "sdklib", 389 srcs: ["a.java"], 390 libs: ["lib"], 391 static_libs: ["static-lib"], 392 impl_only_libs: ["impl-only-lib"], 393 stub_only_libs: ["stub-only-lib"], 394 stub_only_static_libs: ["stub-only-static-lib"], 395 } 396 java_defaults { 397 name: "defaults", 398 srcs: ["a.java"], 399 sdk_version: "current", 400 } 401 java_library { name: "lib", defaults: ["defaults"] } 402 java_library { name: "static-lib", defaults: ["defaults"] } 403 java_library { name: "impl-only-lib", defaults: ["defaults"] } 404 java_library { name: "stub-only-lib", defaults: ["defaults"] } 405 java_library { name: "stub-only-static-lib", defaults: ["defaults"] } 406 `) 407 var expectations = []struct { 408 lib string 409 on_impl_classpath bool 410 on_stub_classpath bool 411 in_impl_combined bool 412 in_stub_combined bool 413 }{ 414 {lib: "lib", on_impl_classpath: true}, 415 {lib: "static-lib", in_impl_combined: true}, 416 {lib: "impl-only-lib", on_impl_classpath: true}, 417 {lib: "stub-only-lib", on_stub_classpath: true}, 418 {lib: "stub-only-static-lib", in_stub_combined: true}, 419 } 420 verify := func(sdklib, dep string, cp, combined bool) { 421 sdklibCp := result.ModuleForTests(sdklib, "android_common").Rule("javac").Args["classpath"] 422 expected := cp || combined // Every combined jar is also on the classpath. 423 android.AssertStringContainsEquals(t, "bad classpath for "+sdklib, sdklibCp, "/"+dep+".jar", expected) 424 425 combineJarInputs := result.ModuleForTests(sdklib, "android_common").Rule("combineJar").Inputs.Strings() 426 depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine-combined", dep+".jar") 427 android.AssertStringListContainsEquals(t, "bad combined inputs for "+sdklib, combineJarInputs, depPath, combined) 428 } 429 for _, expectation := range expectations { 430 verify("sdklib.impl", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined) 431 432 stubName := apiScopePublic.sourceStubLibraryModuleName("sdklib") 433 verify(stubName, expectation.lib, expectation.on_stub_classpath, expectation.in_stub_combined) 434 } 435} 436 437func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) { 438 result := android.GroupFixturePreparers( 439 prepareForJavaTest, 440 PrepareForTestWithJavaSdkLibraryFiles, 441 FixtureWithLastReleaseApis("foo"), 442 ).RunTestWithBp(t, ` 443 java_sdk_library { 444 name: "foo", 445 srcs: ["a.java"], 446 api_only: true, 447 public: { 448 enabled: true, 449 }, 450 } 451 452 java_library { 453 name: "bar", 454 srcs: ["b.java"], 455 libs: ["foo"], 456 } 457 `) 458 459 // The bar library should depend on the stubs jar. 460 barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac") 461 if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 462 t.Errorf("expected %q, found %#q", expected, actual) 463 } 464} 465 466func TestJavaSdkLibrary_AccessOutputFiles(t *testing.T) { 467 android.GroupFixturePreparers( 468 prepareForJavaTest, 469 PrepareForTestWithJavaSdkLibraryFiles, 470 FixtureWithLastReleaseApis("foo"), 471 ).RunTestWithBp(t, ` 472 java_sdk_library { 473 name: "foo", 474 srcs: ["a.java"], 475 api_packages: ["foo"], 476 annotations_enabled: true, 477 public: { 478 enabled: true, 479 }, 480 } 481 java_library { 482 name: "bar", 483 srcs: ["b.java", ":foo{.public.stubs.source}"], 484 java_resources: [":foo{.public.annotations.zip}"], 485 } 486 `) 487} 488 489func TestJavaSdkLibrary_AccessOutputFiles_NoAnnotations(t *testing.T) { 490 android.GroupFixturePreparers( 491 prepareForJavaTest, 492 PrepareForTestWithJavaSdkLibraryFiles, 493 FixtureWithLastReleaseApis("foo"), 494 ). 495 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": failed to get output file from module "foo" at tag ".public.annotations.zip": annotations.zip not available for api scope public`)). 496 RunTestWithBp(t, ` 497 java_sdk_library { 498 name: "foo", 499 srcs: ["a.java"], 500 api_packages: ["foo"], 501 public: { 502 enabled: true, 503 }, 504 } 505 506 java_library { 507 name: "bar", 508 srcs: ["b.java", ":foo{.public.stubs.source}"], 509 java_resources: [":foo{.public.annotations.zip}"], 510 } 511 `) 512} 513 514func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) { 515 android.GroupFixturePreparers( 516 prepareForJavaTest, 517 PrepareForTestWithJavaSdkLibraryFiles, 518 FixtureWithLastReleaseApis("foo"), 519 ). 520 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"foo" does not provide api scope system`)). 521 RunTestWithBp(t, ` 522 java_sdk_library { 523 name: "foo", 524 srcs: ["a.java"], 525 api_packages: ["foo"], 526 public: { 527 enabled: true, 528 }, 529 } 530 531 java_library { 532 name: "bar", 533 srcs: ["b.java", ":foo{.system.stubs.source}"], 534 } 535 `) 536} 537 538func TestJavaSdkLibrary_Deps(t *testing.T) { 539 result := android.GroupFixturePreparers( 540 prepareForJavaTest, 541 PrepareForTestWithJavaSdkLibraryFiles, 542 FixtureWithLastReleaseApis("sdklib"), 543 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 544 variables.BuildFlags = map[string]string{ 545 "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true", 546 } 547 }), 548 ).RunTestWithBp(t, ` 549 java_sdk_library { 550 name: "sdklib", 551 srcs: ["a.java"], 552 sdk_version: "none", 553 system_modules: "none", 554 public: { 555 enabled: true, 556 }, 557 } 558 `) 559 560 CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ 561 `dex2oatd`, 562 `sdklib-removed.api.combined.public.latest`, 563 `sdklib.api.combined.public.latest`, 564 `sdklib.impl`, 565 `sdklib.stubs`, 566 `sdklib.stubs.exportable`, 567 `sdklib.stubs.source`, 568 `sdklib.xml`, 569 }) 570} 571 572func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) { 573 prepareForJavaTest.RunTestWithBp(t, ` 574 java_sdk_library_import { 575 name: "foo", 576 public: { 577 jars: ["a.jar"], 578 stub_srcs: ["a.java"], 579 current_api: "api/current.txt", 580 removed_api: "api/removed.txt", 581 annotations: "x/annotations.zip", 582 }, 583 } 584 585 java_library { 586 name: "bar", 587 srcs: [":foo{.public.stubs.source}"], 588 java_resources: [ 589 ":foo{.public.api.txt}", 590 ":foo{.public.removed-api.txt}", 591 ":foo{.public.annotations.zip}", 592 ], 593 } 594 `) 595} 596 597func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) { 598 bp := ` 599 java_sdk_library_import { 600 name: "foo", 601 public: { 602 jars: ["a.jar"], 603 }, 604 } 605 ` 606 607 t.Run("stubs.source", func(t *testing.T) { 608 prepareForJavaTest. 609 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`stubs.source not available for api scope public`)). 610 RunTestWithBp(t, bp+` 611 java_library { 612 name: "bar", 613 srcs: [":foo{.public.stubs.source}"], 614 java_resources: [ 615 ":foo{.public.api.txt}", 616 ":foo{.public.removed-api.txt}", 617 ], 618 } 619 `) 620 }) 621 622 t.Run("api.txt", func(t *testing.T) { 623 prepareForJavaTest. 624 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`api.txt not available for api scope public`)). 625 RunTestWithBp(t, bp+` 626 java_library { 627 name: "bar", 628 srcs: ["a.java"], 629 java_resources: [ 630 ":foo{.public.api.txt}", 631 ], 632 } 633 `) 634 }) 635 636 t.Run("removed-api.txt", func(t *testing.T) { 637 prepareForJavaTest. 638 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`removed-api.txt not available for api scope public`)). 639 RunTestWithBp(t, bp+` 640 java_library { 641 name: "bar", 642 srcs: ["a.java"], 643 java_resources: [ 644 ":foo{.public.removed-api.txt}", 645 ], 646 } 647 `) 648 }) 649} 650 651func TestJavaSdkLibrary_InvalidScopes(t *testing.T) { 652 prepareForJavaTest. 653 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": enabled api scope "system" depends on disabled scope "public"`)). 654 RunTestWithBp(t, ` 655 java_sdk_library { 656 name: "foo", 657 srcs: ["a.java", "b.java"], 658 api_packages: ["foo"], 659 // Explicitly disable public to test the check that ensures the set of enabled 660 // scopes is consistent. 661 public: { 662 enabled: false, 663 }, 664 system: { 665 enabled: true, 666 }, 667 } 668 `) 669} 670 671func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) { 672 android.GroupFixturePreparers( 673 prepareForJavaTest, 674 PrepareForTestWithJavaSdkLibraryFiles, 675 FixtureWithLastReleaseApis("foo"), 676 ).RunTestWithBp(t, ` 677 java_sdk_library { 678 name: "foo", 679 srcs: ["a.java", "b.java"], 680 api_packages: ["foo"], 681 system: { 682 enabled: true, 683 sdk_version: "module_current", 684 }, 685 } 686 `) 687} 688 689func TestJavaSdkLibrary_ModuleLib(t *testing.T) { 690 android.GroupFixturePreparers( 691 prepareForJavaTest, 692 PrepareForTestWithJavaSdkLibraryFiles, 693 FixtureWithLastReleaseApis("foo"), 694 ).RunTestWithBp(t, ` 695 java_sdk_library { 696 name: "foo", 697 srcs: ["a.java", "b.java"], 698 api_packages: ["foo"], 699 system: { 700 enabled: true, 701 }, 702 module_lib: { 703 enabled: true, 704 }, 705 } 706 `) 707} 708 709func TestJavaSdkLibrary_SystemServer(t *testing.T) { 710 android.GroupFixturePreparers( 711 prepareForJavaTest, 712 PrepareForTestWithJavaSdkLibraryFiles, 713 FixtureWithLastReleaseApis("foo"), 714 ).RunTestWithBp(t, ` 715 java_sdk_library { 716 name: "foo", 717 srcs: ["a.java", "b.java"], 718 api_packages: ["foo"], 719 system: { 720 enabled: true, 721 }, 722 system_server: { 723 enabled: true, 724 }, 725 } 726 `) 727} 728 729func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) { 730 result := android.GroupFixturePreparers( 731 prepareForJavaTest, 732 PrepareForTestWithJavaSdkLibraryFiles, 733 FixtureWithLastReleaseApis("foo-public", "foo-system", "foo-module-lib", "foo-system-server"), 734 ).RunTestWithBp(t, ` 735 java_sdk_library { 736 name: "foo-public", 737 srcs: ["a.java"], 738 api_packages: ["foo"], 739 public: { 740 enabled: true, 741 }, 742 } 743 744 java_sdk_library { 745 name: "foo-system", 746 srcs: ["a.java"], 747 api_packages: ["foo"], 748 system: { 749 enabled: true, 750 }, 751 } 752 753 java_sdk_library { 754 name: "foo-module-lib", 755 srcs: ["a.java"], 756 api_packages: ["foo"], 757 system: { 758 enabled: true, 759 }, 760 module_lib: { 761 enabled: true, 762 }, 763 } 764 765 java_sdk_library { 766 name: "foo-system-server", 767 srcs: ["a.java"], 768 api_packages: ["foo"], 769 system_server: { 770 enabled: true, 771 }, 772 } 773 774 java_library { 775 name: "bar", 776 srcs: ["a.java"], 777 libs: ["foo-public", "foo-system", "foo-module-lib", "foo-system-server"], 778 sdk_version: "system_server_current", 779 } 780 `) 781 782 stubsPath := func(name string, scope *apiScope) string { 783 name = scope.stubsLibraryModuleName(name) 784 return fmt.Sprintf("out/soong/.intermediates/%[1]s/android_common/turbine-combined/%[1]s.jar", name) 785 } 786 787 // The bar library should depend on the highest (where system server is highest and public is 788 // lowest) API scopes provided by each of the foo-* modules. The highest API scope provided by the 789 // foo-<x> module is <x>. 790 barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac") 791 stubLibraries := []string{ 792 stubsPath("foo-public", apiScopePublic), 793 stubsPath("foo-system", apiScopeSystem), 794 stubsPath("foo-module-lib", apiScopeModuleLib), 795 stubsPath("foo-system-server", apiScopeSystemServer), 796 } 797 expectedPattern := fmt.Sprintf(`^-classpath .*:\Q%s\E$`, strings.Join(stubLibraries, ":")) 798 if expected, actual := expectedPattern, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 799 t.Errorf("expected pattern %q to match %#q", expected, actual) 800 } 801} 802 803func TestJavaSdkLibrary_MissingScope(t *testing.T) { 804 prepareForJavaTest. 805 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`requires api scope module-lib from foo but it only has \[\] available`)). 806 RunTestWithBp(t, ` 807 java_sdk_library { 808 name: "foo", 809 srcs: ["a.java"], 810 public: { 811 enabled: false, 812 }, 813 } 814 815 java_library { 816 name: "baz", 817 srcs: ["a.java"], 818 libs: ["foo"], 819 sdk_version: "module_current", 820 } 821 `) 822} 823 824func TestJavaSdkLibrary_FallbackScope(t *testing.T) { 825 android.GroupFixturePreparers( 826 prepareForJavaTest, 827 PrepareForTestWithJavaSdkLibraryFiles, 828 FixtureWithLastReleaseApis("foo"), 829 ).RunTestWithBp(t, ` 830 java_sdk_library { 831 name: "foo", 832 srcs: ["a.java"], 833 system: { 834 enabled: true, 835 }, 836 } 837 838 java_library { 839 name: "baz", 840 srcs: ["a.java"], 841 libs: ["foo"], 842 // foo does not have module-lib scope so it should fallback to system 843 sdk_version: "module_current", 844 } 845 `) 846} 847 848func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) { 849 result := android.GroupFixturePreparers( 850 prepareForJavaTest, 851 PrepareForTestWithJavaSdkLibraryFiles, 852 FixtureWithLastReleaseApis("foo"), 853 ).RunTestWithBp(t, ` 854 java_sdk_library { 855 name: "foo", 856 srcs: ["a.java"], 857 system: { 858 enabled: true, 859 }, 860 default_to_stubs: true, 861 } 862 863 java_library { 864 name: "baz", 865 srcs: ["a.java"], 866 libs: ["foo"], 867 // does not have sdk_version set, should fallback to module, 868 // which will then fallback to system because the module scope 869 // is not enabled. 870 } 871 `) 872 // The baz library should depend on the system stubs jar. 873 bazLibrary := result.ModuleForTests("baz", "android_common").Rule("javac") 874 if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs.system\.jar$`, bazLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 875 t.Errorf("expected %q, found %#q", expected, actual) 876 } 877} 878 879func TestJavaSdkLibraryImport(t *testing.T) { 880 result := prepareForJavaTest.RunTestWithBp(t, ` 881 java_library { 882 name: "foo", 883 srcs: ["a.java"], 884 libs: ["sdklib"], 885 sdk_version: "current", 886 } 887 888 java_library { 889 name: "foo.system", 890 srcs: ["a.java"], 891 libs: ["sdklib"], 892 sdk_version: "system_current", 893 } 894 895 java_library { 896 name: "foo.test", 897 srcs: ["a.java"], 898 libs: ["sdklib"], 899 sdk_version: "test_current", 900 } 901 902 java_sdk_library_import { 903 name: "sdklib", 904 public: { 905 jars: ["a.jar"], 906 }, 907 system: { 908 jars: ["b.jar"], 909 }, 910 test: { 911 jars: ["c.jar"], 912 stub_srcs: ["c.java"], 913 }, 914 } 915 `) 916 917 for _, scope := range []string{"", ".system", ".test"} { 918 fooModule := result.ModuleForTests("foo"+scope, "android_common") 919 javac := fooModule.Rule("javac") 920 921 sdklibStubsJar := result.ModuleForTests("sdklib.stubs"+scope, "android_common").Rule("combineJar").Output 922 android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String()) 923 } 924 925 CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ 926 `all_apex_contributions`, 927 `dex2oatd`, 928 `prebuilt_sdklib.stubs`, 929 `prebuilt_sdklib.stubs.source.test`, 930 `prebuilt_sdklib.stubs.system`, 931 `prebuilt_sdklib.stubs.test`, 932 }) 933} 934 935func TestJavaSdkLibraryImport_WithSource(t *testing.T) { 936 result := android.GroupFixturePreparers( 937 prepareForJavaTest, 938 PrepareForTestWithJavaSdkLibraryFiles, 939 FixtureWithLastReleaseApis("sdklib"), 940 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 941 variables.BuildFlags = map[string]string{ 942 "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true", 943 } 944 }), 945 ).RunTestWithBp(t, ` 946 java_sdk_library { 947 name: "sdklib", 948 srcs: ["a.java"], 949 sdk_version: "none", 950 system_modules: "none", 951 public: { 952 enabled: true, 953 }, 954 } 955 956 java_sdk_library_import { 957 name: "sdklib", 958 public: { 959 jars: ["a.jar"], 960 }, 961 } 962 `) 963 964 CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ 965 `dex2oatd`, 966 `prebuilt_sdklib`, 967 `sdklib-removed.api.combined.public.latest`, 968 `sdklib.api.combined.public.latest`, 969 `sdklib.impl`, 970 `sdklib.stubs`, 971 `sdklib.stubs.exportable`, 972 `sdklib.stubs.source`, 973 `sdklib.xml`, 974 }) 975 976 CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ 977 `all_apex_contributions`, 978 `prebuilt_sdklib.stubs`, 979 `sdklib.impl`, 980 // This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the 981 // dependency is added after prebuilts may have been renamed and so has to use 982 // the renamed name. 983 `sdklib.xml`, 984 }) 985} 986 987func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer android.FixturePreparer) { 988 result := android.GroupFixturePreparers( 989 prepareForJavaTest, 990 PrepareForTestWithJavaSdkLibraryFiles, 991 FixtureWithLastReleaseApis("sdklib"), 992 preparer, 993 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 994 variables.BuildFlags = map[string]string{ 995 "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true", 996 } 997 }), 998 ).RunTestWithBp(t, ` 999 java_sdk_library { 1000 name: "sdklib", 1001 srcs: ["a.java"], 1002 sdk_version: "none", 1003 system_modules: "none", 1004 public: { 1005 enabled: true, 1006 }, 1007 } 1008 1009 java_sdk_library_import { 1010 name: "sdklib", 1011 `+prefer+` 1012 public: { 1013 jars: ["a.jar"], 1014 stub_srcs: ["a.java"], 1015 current_api: "current.txt", 1016 removed_api: "removed.txt", 1017 annotations: "annotations.zip", 1018 }, 1019 } 1020 1021 java_library { 1022 name: "combined", 1023 static_libs: [ 1024 "sdklib.stubs", 1025 ], 1026 java_resources: [ 1027 ":sdklib.stubs.source", 1028 ":sdklib{.public.api.txt}", 1029 ":sdklib{.public.removed-api.txt}", 1030 ":sdklib{.public.annotations.zip}", 1031 ], 1032 sdk_version: "none", 1033 system_modules: "none", 1034 } 1035 1036 java_library { 1037 name: "public", 1038 srcs: ["a.java"], 1039 libs: ["sdklib"], 1040 sdk_version: "current", 1041 } 1042 `) 1043 1044 CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ 1045 `prebuilt_sdklib`, 1046 `sdklib-removed.api.combined.public.latest`, 1047 `sdklib.api.combined.public.latest`, 1048 `sdklib.impl`, 1049 `sdklib.stubs`, 1050 `sdklib.stubs.exportable`, 1051 `sdklib.stubs.source`, 1052 `sdklib.xml`, 1053 }) 1054 1055 CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ 1056 `all_apex_contributions`, 1057 `dex2oatd`, 1058 `prebuilt_sdklib.stubs`, 1059 `prebuilt_sdklib.stubs.source`, 1060 `sdklib.impl`, 1061 `sdklib.xml`, 1062 }) 1063 1064 // Make sure that dependencies on child modules use the prebuilt when preferred. 1065 CheckModuleDependencies(t, result.TestContext, "combined", "android_common", []string{ 1066 // Each use of :sdklib{...} adds a dependency onto prebuilt_sdklib. 1067 `prebuilt_sdklib`, 1068 `prebuilt_sdklib`, 1069 `prebuilt_sdklib`, 1070 `prebuilt_sdklib.stubs`, 1071 `prebuilt_sdklib.stubs.source`, 1072 }) 1073 1074 // Make sure that dependencies on sdklib that resolve to one of the child libraries use the 1075 // prebuilt library. 1076 public := result.ModuleForTests("public", "android_common") 1077 rule := public.Output("javac/public.jar") 1078 inputs := rule.Implicits.Strings() 1079 expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/combined/sdklib.stubs.jar" 1080 if !android.InList(expected, inputs) { 1081 t.Errorf("expected %q to contain %q", inputs, expected) 1082 } 1083} 1084 1085func TestJavaSdkLibraryImport_Preferred(t *testing.T) { 1086 t.Run("prefer", func(t *testing.T) { 1087 testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer) 1088 }) 1089} 1090 1091// If a module is listed in `mainline_module_contributions, it should be used 1092// It will supersede any other source vs prebuilt selection mechanism like `prefer` attribute 1093func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) { 1094 bp := ` 1095 apex_contributions { 1096 name: "my_mainline_module_contributions", 1097 api_domain: "my_mainline_module", 1098 contents: [ 1099 // legacy mechanism prefers the prebuilt 1100 // mainline_module_contributions supersedes this since source is listed explicitly 1101 "sdklib.prebuilt_preferred_using_legacy_flags", 1102 1103 // legacy mechanism prefers the source 1104 // mainline_module_contributions supersedes this since prebuilt is listed explicitly 1105 "prebuilt_sdklib.source_preferred_using_legacy_flags", 1106 ], 1107 } 1108 java_sdk_library { 1109 name: "sdklib.prebuilt_preferred_using_legacy_flags", 1110 srcs: ["a.java"], 1111 sdk_version: "none", 1112 system_modules: "none", 1113 public: { 1114 enabled: true, 1115 }, 1116 system: { 1117 enabled: true, 1118 } 1119 } 1120 java_sdk_library_import { 1121 name: "sdklib.prebuilt_preferred_using_legacy_flags", 1122 prefer: true, // prebuilt is preferred using legacy mechanism 1123 public: { 1124 jars: ["a.jar"], 1125 stub_srcs: ["a.java"], 1126 current_api: "current.txt", 1127 removed_api: "removed.txt", 1128 annotations: "annotations.zip", 1129 }, 1130 system: { 1131 jars: ["a.jar"], 1132 stub_srcs: ["a.java"], 1133 current_api: "current.txt", 1134 removed_api: "removed.txt", 1135 annotations: "annotations.zip", 1136 }, 1137 } 1138 java_sdk_library { 1139 name: "sdklib.source_preferred_using_legacy_flags", 1140 srcs: ["a.java"], 1141 sdk_version: "none", 1142 system_modules: "none", 1143 public: { 1144 enabled: true, 1145 }, 1146 system: { 1147 enabled: true, 1148 } 1149 } 1150 java_sdk_library_import { 1151 name: "sdklib.source_preferred_using_legacy_flags", 1152 prefer: false, // source is preferred using legacy mechanism 1153 public: { 1154 jars: ["a.jar"], 1155 stub_srcs: ["a.java"], 1156 current_api: "current.txt", 1157 removed_api: "removed.txt", 1158 annotations: "annotations.zip", 1159 }, 1160 system: { 1161 jars: ["a.jar"], 1162 stub_srcs: ["a.java"], 1163 current_api: "current.txt", 1164 removed_api: "removed.txt", 1165 annotations: "annotations.zip", 1166 }, 1167 } 1168 1169 // rdeps 1170 java_library { 1171 name: "public", 1172 srcs: ["a.java"], 1173 libs: [ 1174 // this should get source since source is listed in my_mainline_module_contributions 1175 "sdklib.prebuilt_preferred_using_legacy_flags.stubs", 1176 "sdklib.prebuilt_preferred_using_legacy_flags.stubs.system", 1177 1178 // this should get prebuilt since source is listed in my_mainline_module_contributions 1179 "sdklib.source_preferred_using_legacy_flags.stubs", 1180 "sdklib.source_preferred_using_legacy_flags.stubs.system", 1181 1182 ], 1183 } 1184 ` 1185 result := android.GroupFixturePreparers( 1186 prepareForJavaTest, 1187 PrepareForTestWithJavaSdkLibraryFiles, 1188 FixtureWithLastReleaseApis("sdklib.source_preferred_using_legacy_flags", "sdklib.prebuilt_preferred_using_legacy_flags"), 1189 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1190 variables.BuildFlags = map[string]string{ 1191 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contributions", 1192 } 1193 }), 1194 ).RunTestWithBp(t, bp) 1195 1196 // Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions 1197 public := result.ModuleForTests("public", "android_common") 1198 rule := public.Output("javac/public.jar") 1199 inputs := rule.Implicits.Strings() 1200 expectedInputs := []string{ 1201 // source 1202 "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.jar", 1203 "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.jar", 1204 1205 // prebuilt 1206 "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.jar", 1207 "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar", 1208 } 1209 for _, expected := range expectedInputs { 1210 if !android.InList(expected, inputs) { 1211 t.Errorf("expected %q to contain %q", inputs, expected) 1212 } 1213 } 1214} 1215 1216func TestJavaSdkLibraryEnforce(t *testing.T) { 1217 partitionToBpOption := func(partition string) string { 1218 switch partition { 1219 case "system": 1220 return "" 1221 case "vendor": 1222 return "soc_specific: true," 1223 case "product": 1224 return "product_specific: true," 1225 default: 1226 panic("Invalid partition group name: " + partition) 1227 } 1228 } 1229 1230 type testConfigInfo struct { 1231 libraryType string 1232 fromPartition string 1233 toPartition string 1234 enforceProductInterface bool 1235 enforceJavaSdkLibraryCheck bool 1236 allowList []string 1237 } 1238 1239 createPreparer := func(info testConfigInfo) android.FixturePreparer { 1240 bpFileTemplate := ` 1241 java_library { 1242 name: "foo", 1243 srcs: ["foo.java"], 1244 libs: ["bar"], 1245 sdk_version: "current", 1246 %s 1247 } 1248 1249 %s { 1250 name: "bar", 1251 srcs: ["bar.java"], 1252 sdk_version: "current", 1253 %s 1254 } 1255 ` 1256 1257 bpFile := fmt.Sprintf(bpFileTemplate, 1258 partitionToBpOption(info.fromPartition), 1259 info.libraryType, 1260 partitionToBpOption(info.toPartition)) 1261 1262 return android.GroupFixturePreparers( 1263 PrepareForTestWithJavaSdkLibraryFiles, 1264 FixtureWithLastReleaseApis("bar"), 1265 android.FixtureWithRootAndroidBp(bpFile), 1266 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1267 variables.EnforceProductPartitionInterface = proptools.BoolPtr(info.enforceProductInterface) 1268 variables.EnforceInterPartitionJavaSdkLibrary = proptools.BoolPtr(info.enforceJavaSdkLibraryCheck) 1269 variables.InterPartitionJavaLibraryAllowList = info.allowList 1270 }), 1271 ) 1272 } 1273 1274 runTest := func(t *testing.T, info testConfigInfo, expectedErrorPattern string) { 1275 t.Run(fmt.Sprintf("%v", info), func(t *testing.T) { 1276 errorHandler := android.FixtureExpectsNoErrors 1277 if expectedErrorPattern != "" { 1278 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorPattern) 1279 } 1280 android.GroupFixturePreparers( 1281 prepareForJavaTest, 1282 createPreparer(info), 1283 ). 1284 ExtendWithErrorHandler(errorHandler). 1285 RunTest(t) 1286 }) 1287 } 1288 1289 errorMessage := "is not allowed across the partitions" 1290 1291 runTest(t, testConfigInfo{ 1292 libraryType: "java_library", 1293 fromPartition: "product", 1294 toPartition: "system", 1295 enforceProductInterface: true, 1296 enforceJavaSdkLibraryCheck: false, 1297 }, "") 1298 1299 runTest(t, testConfigInfo{ 1300 libraryType: "java_library", 1301 fromPartition: "product", 1302 toPartition: "system", 1303 enforceProductInterface: false, 1304 enforceJavaSdkLibraryCheck: true, 1305 }, "") 1306 1307 runTest(t, testConfigInfo{ 1308 libraryType: "java_library", 1309 fromPartition: "product", 1310 toPartition: "system", 1311 enforceProductInterface: true, 1312 enforceJavaSdkLibraryCheck: true, 1313 }, errorMessage) 1314 1315 runTest(t, testConfigInfo{ 1316 libraryType: "java_library", 1317 fromPartition: "vendor", 1318 toPartition: "system", 1319 enforceProductInterface: true, 1320 enforceJavaSdkLibraryCheck: true, 1321 }, errorMessage) 1322 1323 runTest(t, testConfigInfo{ 1324 libraryType: "java_library", 1325 fromPartition: "vendor", 1326 toPartition: "system", 1327 enforceProductInterface: true, 1328 enforceJavaSdkLibraryCheck: true, 1329 allowList: []string{"bar"}, 1330 }, "") 1331 1332 runTest(t, testConfigInfo{ 1333 libraryType: "java_library", 1334 fromPartition: "vendor", 1335 toPartition: "product", 1336 enforceProductInterface: true, 1337 enforceJavaSdkLibraryCheck: true, 1338 }, errorMessage) 1339 1340 runTest(t, testConfigInfo{ 1341 libraryType: "java_sdk_library", 1342 fromPartition: "product", 1343 toPartition: "system", 1344 enforceProductInterface: true, 1345 enforceJavaSdkLibraryCheck: true, 1346 }, "") 1347 1348 runTest(t, testConfigInfo{ 1349 libraryType: "java_sdk_library", 1350 fromPartition: "vendor", 1351 toPartition: "system", 1352 enforceProductInterface: true, 1353 enforceJavaSdkLibraryCheck: true, 1354 }, "") 1355 1356 runTest(t, testConfigInfo{ 1357 libraryType: "java_sdk_library", 1358 fromPartition: "vendor", 1359 toPartition: "product", 1360 enforceProductInterface: true, 1361 enforceJavaSdkLibraryCheck: true, 1362 }, "") 1363} 1364 1365func TestJavaSdkLibraryDist(t *testing.T) { 1366 result := android.GroupFixturePreparers( 1367 PrepareForTestWithJavaBuildComponents, 1368 PrepareForTestWithJavaDefaultModules, 1369 PrepareForTestWithJavaSdkLibraryFiles, 1370 FixtureWithLastReleaseApis( 1371 "sdklib_no_group", 1372 "sdklib_group_foo", 1373 "sdklib_owner_foo", 1374 "foo"), 1375 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1376 variables.BuildFlags = map[string]string{ 1377 "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true", 1378 } 1379 }), 1380 ).RunTestWithBp(t, ` 1381 java_sdk_library { 1382 name: "sdklib_no_group", 1383 srcs: ["foo.java"], 1384 } 1385 1386 java_sdk_library { 1387 name: "sdklib_group_foo", 1388 srcs: ["foo.java"], 1389 dist_group: "foo", 1390 } 1391 1392 java_sdk_library { 1393 name: "sdklib_owner_foo", 1394 srcs: ["foo.java"], 1395 owner: "foo", 1396 } 1397 1398 java_sdk_library { 1399 name: "sdklib_stem_foo", 1400 srcs: ["foo.java"], 1401 dist_stem: "foo", 1402 } 1403 `) 1404 1405 type testCase struct { 1406 module string 1407 distDir string 1408 distStem string 1409 } 1410 testCases := []testCase{ 1411 { 1412 module: "sdklib_no_group", 1413 distDir: "apistubs/unknown/public", 1414 distStem: "sdklib_no_group.jar", 1415 }, 1416 { 1417 module: "sdklib_group_foo", 1418 distDir: "apistubs/foo/public", 1419 distStem: "sdklib_group_foo.jar", 1420 }, 1421 { 1422 // Owner doesn't affect distDir after b/186723288. 1423 module: "sdklib_owner_foo", 1424 distDir: "apistubs/unknown/public", 1425 distStem: "sdklib_owner_foo.jar", 1426 }, 1427 { 1428 module: "sdklib_stem_foo", 1429 distDir: "apistubs/unknown/public", 1430 distStem: "foo.jar", 1431 }, 1432 } 1433 1434 for _, tt := range testCases { 1435 t.Run(tt.module, func(t *testing.T) { 1436 m := result.ModuleForTests(apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library) 1437 dists := m.Dists() 1438 if len(dists) != 1 { 1439 t.Fatalf("expected exactly 1 dist entry, got %d", len(dists)) 1440 } 1441 if g, w := String(dists[0].Dir), tt.distDir; g != w { 1442 t.Errorf("expected dist dir %q, got %q", w, g) 1443 } 1444 if g, w := String(dists[0].Dest), tt.distStem; g != w { 1445 t.Errorf("expected dist stem %q, got %q", w, g) 1446 } 1447 }) 1448 } 1449} 1450 1451func TestSdkLibrary_CheckMinSdkVersion(t *testing.T) { 1452 preparer := android.GroupFixturePreparers( 1453 PrepareForTestWithJavaBuildComponents, 1454 PrepareForTestWithJavaDefaultModules, 1455 PrepareForTestWithJavaSdkLibraryFiles, 1456 ) 1457 1458 preparer.RunTestWithBp(t, ` 1459 java_sdk_library { 1460 name: "sdklib", 1461 srcs: ["a.java"], 1462 static_libs: ["util"], 1463 min_sdk_version: "30", 1464 unsafe_ignore_missing_latest_api: true, 1465 } 1466 1467 java_library { 1468 name: "util", 1469 srcs: ["a.java"], 1470 min_sdk_version: "30", 1471 } 1472 `) 1473 1474 preparer. 1475 RunTestWithBp(t, ` 1476 java_sdk_library { 1477 name: "sdklib", 1478 srcs: ["a.java"], 1479 libs: ["util"], 1480 impl_only_libs: ["util"], 1481 stub_only_libs: ["util"], 1482 stub_only_static_libs: ["util"], 1483 min_sdk_version: "30", 1484 unsafe_ignore_missing_latest_api: true, 1485 } 1486 1487 java_library { 1488 name: "util", 1489 srcs: ["a.java"], 1490 } 1491 `) 1492 1493 preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "util".*should support min_sdk_version\(30\)`)). 1494 RunTestWithBp(t, ` 1495 java_sdk_library { 1496 name: "sdklib", 1497 srcs: ["a.java"], 1498 static_libs: ["util"], 1499 min_sdk_version: "30", 1500 unsafe_ignore_missing_latest_api: true, 1501 } 1502 1503 java_library { 1504 name: "util", 1505 srcs: ["a.java"], 1506 min_sdk_version: "31", 1507 } 1508 `) 1509 1510 preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "another_util".*should support min_sdk_version\(30\)`)). 1511 RunTestWithBp(t, ` 1512 java_sdk_library { 1513 name: "sdklib", 1514 srcs: ["a.java"], 1515 static_libs: ["util"], 1516 min_sdk_version: "30", 1517 unsafe_ignore_missing_latest_api: true, 1518 } 1519 1520 java_library { 1521 name: "util", 1522 srcs: ["a.java"], 1523 static_libs: ["another_util"], 1524 min_sdk_version: "30", 1525 } 1526 1527 java_library { 1528 name: "another_util", 1529 srcs: ["a.java"], 1530 min_sdk_version: "31", 1531 } 1532 `) 1533} 1534 1535func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) { 1536 result := android.GroupFixturePreparers( 1537 prepareForJavaTest, 1538 PrepareForTestWithJavaSdkLibraryFiles, 1539 FixtureWithLastReleaseApis("foo"), 1540 ).RunTestWithBp(t, ` 1541 java_sdk_library { 1542 name: "foo", 1543 srcs: ["a.java"], 1544 public: { 1545 enabled: true, 1546 }, 1547 stub_only_libs: ["bar-lib"], 1548 } 1549 1550 java_library { 1551 name: "bar-lib", 1552 srcs: ["b.java"], 1553 } 1554 `) 1555 1556 // The foo.stubs.source should depend on bar-lib 1557 fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs) 1558 android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib") 1559} 1560 1561func TestJavaSdkLibrary_Scope_Libs_PassedToDroidstubs(t *testing.T) { 1562 result := android.GroupFixturePreparers( 1563 prepareForJavaTest, 1564 PrepareForTestWithJavaSdkLibraryFiles, 1565 FixtureWithLastReleaseApis("foo"), 1566 ).RunTestWithBp(t, ` 1567 java_sdk_library { 1568 name: "foo", 1569 srcs: ["a.java"], 1570 public: { 1571 enabled: true, 1572 libs: ["bar-lib"], 1573 }, 1574 } 1575 1576 java_library { 1577 name: "bar-lib", 1578 srcs: ["b.java"], 1579 } 1580 `) 1581 1582 // The foo.stubs.source should depend on bar-lib 1583 fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs) 1584 android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib") 1585} 1586 1587func TestJavaSdkLibrary_ApiLibrary(t *testing.T) { 1588 result := android.GroupFixturePreparers( 1589 prepareForJavaTest, 1590 PrepareForTestWithJavaSdkLibraryFiles, 1591 FixtureWithLastReleaseApis("foo"), 1592 android.FixtureModifyConfig(func(config android.Config) { 1593 config.SetApiLibraries([]string{"foo"}) 1594 }), 1595 ).RunTestWithBp(t, ` 1596 java_sdk_library { 1597 name: "foo", 1598 srcs: ["a.java", "b.java"], 1599 api_packages: ["foo"], 1600 system: { 1601 enabled: true, 1602 }, 1603 module_lib: { 1604 enabled: true, 1605 }, 1606 test: { 1607 enabled: true, 1608 }, 1609 } 1610 `) 1611 1612 testCases := []struct { 1613 scope *apiScope 1614 apiContributions []string 1615 fullApiSurfaceStub string 1616 }{ 1617 { 1618 scope: apiScopePublic, 1619 apiContributions: []string{"foo.stubs.source.api.contribution"}, 1620 fullApiSurfaceStub: "android_stubs_current", 1621 }, 1622 { 1623 scope: apiScopeSystem, 1624 apiContributions: []string{"foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, 1625 fullApiSurfaceStub: "android_system_stubs_current", 1626 }, 1627 { 1628 scope: apiScopeTest, 1629 apiContributions: []string{"foo.stubs.source.test.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, 1630 fullApiSurfaceStub: "android_test_stubs_current", 1631 }, 1632 { 1633 scope: apiScopeModuleLib, 1634 apiContributions: []string{"foo.stubs.source.module_lib.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, 1635 fullApiSurfaceStub: "android_module_lib_stubs_current_full.from-text", 1636 }, 1637 } 1638 1639 for _, c := range testCases { 1640 m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary) 1641 android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions) 1642 android.AssertStringEquals(t, "Module expected to contain full api surface api library", c.fullApiSurfaceStub, *m.properties.Full_api_surface_stub) 1643 } 1644} 1645 1646func TestStaticDepStubLibrariesVisibility(t *testing.T) { 1647 android.GroupFixturePreparers( 1648 prepareForJavaTest, 1649 PrepareForTestWithJavaSdkLibraryFiles, 1650 FixtureWithLastReleaseApis("foo"), 1651 android.FixtureMergeMockFs( 1652 map[string][]byte{ 1653 "A.java": nil, 1654 "dir/Android.bp": []byte( 1655 ` 1656 java_library { 1657 name: "bar", 1658 srcs: ["A.java"], 1659 libs: ["foo.stubs.from-source"], 1660 } 1661 `), 1662 "dir/A.java": nil, 1663 }, 1664 ).ExtendWithErrorHandler( 1665 android.FixtureExpectsAtLeastOneErrorMatchingPattern( 1666 `module "bar" variant "android_common": depends on //.:foo.stubs.from-source which is not visible to this module`)), 1667 ).RunTestWithBp(t, ` 1668 java_sdk_library { 1669 name: "foo", 1670 srcs: ["A.java"], 1671 } 1672 `) 1673} 1674 1675func TestSdkLibraryDependency(t *testing.T) { 1676 result := android.GroupFixturePreparers( 1677 prepareForJavaTest, 1678 PrepareForTestWithJavaSdkLibraryFiles, 1679 FixtureWithPrebuiltApis(map[string][]string{ 1680 "30": {"bar", "foo"}, 1681 }), 1682 ).RunTestWithBp(t, 1683 ` 1684 java_sdk_library { 1685 name: "foo", 1686 srcs: ["a.java", "b.java"], 1687 api_packages: ["foo"], 1688 } 1689 1690 java_sdk_library { 1691 name: "bar", 1692 srcs: ["c.java", "b.java"], 1693 libs: [ 1694 "foo", 1695 ], 1696 uses_libs: [ 1697 "foo", 1698 ], 1699 } 1700`) 1701 1702 barPermissions := result.ModuleForTests("bar.xml", "android_common").Output("bar.xml") 1703 barContents := android.ContentFromFileRuleForTests(t, result.TestContext, barPermissions) 1704 android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barContents, `dependency="foo"`) 1705} 1706 1707func TestSdkLibraryExportableStubsLibrary(t *testing.T) { 1708 result := android.GroupFixturePreparers( 1709 prepareForJavaTest, 1710 PrepareForTestWithJavaSdkLibraryFiles, 1711 FixtureWithLastReleaseApis("foo"), 1712 android.FixtureModifyConfig(func(config android.Config) { 1713 config.SetApiLibraries([]string{"foo"}) 1714 }), 1715 ).RunTestWithBp(t, ` 1716 aconfig_declarations { 1717 name: "bar", 1718 package: "com.example.package", 1719 container: "com.android.foo", 1720 srcs: [ 1721 "bar.aconfig", 1722 ], 1723 } 1724 java_sdk_library { 1725 name: "foo", 1726 srcs: ["a.java", "b.java"], 1727 api_packages: ["foo"], 1728 system: { 1729 enabled: true, 1730 }, 1731 module_lib: { 1732 enabled: true, 1733 }, 1734 test: { 1735 enabled: true, 1736 }, 1737 aconfig_declarations: [ 1738 "bar", 1739 ], 1740 } 1741 `) 1742 1743 exportableStubsLibraryModuleName := apiScopePublic.exportableStubsLibraryModuleName("foo") 1744 exportableSourceStubsLibraryModuleName := apiScopePublic.exportableSourceStubsLibraryModuleName("foo") 1745 1746 // Check modules generation 1747 topLevelModule := result.ModuleForTests(exportableStubsLibraryModuleName, "android_common") 1748 result.ModuleForTests(exportableSourceStubsLibraryModuleName, "android_common") 1749 1750 // Check static lib dependency 1751 android.AssertBoolEquals(t, "exportable top level stubs library module depends on the"+ 1752 "exportable source stubs library module", true, 1753 CheckModuleHasDependency(t, result.TestContext, exportableStubsLibraryModuleName, 1754 "android_common", exportableSourceStubsLibraryModuleName), 1755 ) 1756 android.AssertArrayString(t, "exportable source stub library is a static lib of the"+ 1757 "top level exportable stubs library", []string{exportableSourceStubsLibraryModuleName}, 1758 topLevelModule.Module().(*Library).properties.Static_libs) 1759} 1760 1761// For java libraries depending on java_sdk_library(_import) via libs, assert that 1762// rdep gets stubs of source if source is listed in apex_contributions and prebuilt has prefer (legacy mechanism) 1763func TestStubResolutionOfJavaSdkLibraryInLibs(t *testing.T) { 1764 bp := ` 1765 apex_contributions { 1766 name: "my_mainline_module_contributions", 1767 api_domain: "my_mainline_module", 1768 contents: ["sdklib"], // source is selected using apex_contributions, but prebuilt is selected using prefer 1769 } 1770 java_sdk_library { 1771 name: "sdklib", 1772 srcs: ["a.java"], 1773 sdk_version: "none", 1774 system_modules: "none", 1775 public: { 1776 enabled: true, 1777 }, 1778 } 1779 java_sdk_library_import { 1780 name: "sdklib", 1781 public: { 1782 jars: ["a.jar"], 1783 stub_srcs: ["a.java"], 1784 current_api: "current.txt", 1785 removed_api: "removed.txt", 1786 annotations: "annotations.zip", 1787 }, 1788 prefer: true, // Set prefer explicitly on the prebuilt. We will assert that rdep gets source in a test case. 1789 } 1790 // rdeps 1791 java_library { 1792 name: "mymodule", 1793 srcs: ["a.java"], 1794 sdk_version: "current", 1795 libs: ["sdklib",], // this should be dynamically resolved to sdklib.stubs (source) or prebuilt_sdklib.stubs (prebuilt) 1796 } 1797 ` 1798 1799 fixture := android.GroupFixturePreparers( 1800 prepareForJavaTest, 1801 PrepareForTestWithJavaSdkLibraryFiles, 1802 FixtureWithLastReleaseApis("sdklib"), 1803 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1804 variables.BuildFlags = map[string]string{ 1805 // We can use any of the apex contribution build flags from build/soong/android/config.go#mainlineApexContributionBuildFlags here 1806 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contributions", 1807 } 1808 }), 1809 ) 1810 1811 result := fixture.RunTestWithBp(t, bp) 1812 // Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions 1813 public := result.ModuleForTests("mymodule", "android_common") 1814 rule := public.Output("javac/mymodule.jar") 1815 inputs := rule.Implicits.Strings() 1816 android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar") 1817} 1818 1819// test that rdep gets resolved to the correct version of a java_sdk_library (source or a specific prebuilt) 1820func TestMultipleSdkLibraryPrebuilts(t *testing.T) { 1821 bp := ` 1822 apex_contributions { 1823 name: "my_mainline_module_contributions", 1824 api_domain: "my_mainline_module", 1825 contents: ["%s"], 1826 } 1827 java_sdk_library { 1828 name: "sdklib", 1829 srcs: ["a.java"], 1830 sdk_version: "none", 1831 system_modules: "none", 1832 public: { 1833 enabled: true, 1834 }, 1835 } 1836 java_sdk_library_import { 1837 name: "sdklib.v1", //prebuilt 1838 source_module_name: "sdklib", 1839 public: { 1840 jars: ["a.jar"], 1841 stub_srcs: ["a.java"], 1842 current_api: "current.txt", 1843 removed_api: "removed.txt", 1844 annotations: "annotations.zip", 1845 }, 1846 } 1847 java_sdk_library_import { 1848 name: "sdklib.v2", //prebuilt 1849 source_module_name: "sdklib", 1850 public: { 1851 jars: ["a.jar"], 1852 stub_srcs: ["a.java"], 1853 current_api: "current.txt", 1854 removed_api: "removed.txt", 1855 annotations: "annotations.zip", 1856 }, 1857 } 1858 // rdeps 1859 java_library { 1860 name: "mymodule", 1861 srcs: ["a.java"], 1862 libs: ["sdklib.stubs",], 1863 } 1864 ` 1865 testCases := []struct { 1866 desc string 1867 selectedDependencyName string 1868 expectedStubPath string 1869 }{ 1870 { 1871 desc: "Source library is selected using apex_contributions", 1872 selectedDependencyName: "sdklib", 1873 expectedStubPath: "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar", 1874 }, 1875 { 1876 desc: "Prebuilt library v1 is selected using apex_contributions", 1877 selectedDependencyName: "prebuilt_sdklib.v1", 1878 expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v1.stubs/android_common/combined/sdklib.stubs.jar", 1879 }, 1880 { 1881 desc: "Prebuilt library v2 is selected using apex_contributions", 1882 selectedDependencyName: "prebuilt_sdklib.v2", 1883 expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v2.stubs/android_common/combined/sdklib.stubs.jar", 1884 }, 1885 } 1886 1887 fixture := android.GroupFixturePreparers( 1888 prepareForJavaTest, 1889 PrepareForTestWithJavaSdkLibraryFiles, 1890 FixtureWithLastReleaseApis("sdklib", "sdklib.v1", "sdklib.v2"), 1891 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1892 variables.BuildFlags = map[string]string{ 1893 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contributions", 1894 } 1895 }), 1896 ) 1897 1898 for _, tc := range testCases { 1899 result := fixture.RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName)) 1900 1901 // Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions 1902 public := result.ModuleForTests("mymodule", "android_common") 1903 rule := public.Output("javac/mymodule.jar") 1904 inputs := rule.Implicits.Strings() 1905 android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, tc.expectedStubPath) 1906 } 1907} 1908