1// Copyright 2017 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 "os" 20 "path/filepath" 21 "reflect" 22 "runtime" 23 "slices" 24 "strconv" 25 "strings" 26 "testing" 27 28 "github.com/google/blueprint" 29 "github.com/google/blueprint/proptools" 30 31 "android/soong/aconfig" 32 "android/soong/android" 33 "android/soong/cc" 34 "android/soong/dexpreopt" 35 "android/soong/genrule" 36) 37 38// Legacy preparer used for running tests within the java package. 39// 40// This includes everything that was needed to run any test in the java package prior to the 41// introduction of the test fixtures. Tests that are being converted to use fixtures directly 42// rather than through the testJava...() methods should avoid using this and instead use the 43// various preparers directly, using android.GroupFixturePreparers(...) to group them when 44// necessary. 45// 46// deprecated 47var prepareForJavaTest = android.GroupFixturePreparers( 48 genrule.PrepareForTestWithGenRuleBuildComponents, 49 // Get the CC build components but not default modules. 50 cc.PrepareForTestWithCcBuildComponents, 51 // Include all the default java modules. 52 PrepareForTestWithDexpreopt, 53 // Include aconfig modules. 54 aconfig.PrepareForTestWithAconfigBuildComponents, 55) 56 57func TestMain(m *testing.M) { 58 os.Exit(m.Run()) 59} 60 61// testJavaError is a legacy way of running tests of java modules that expect errors. 62// 63// See testJava for an explanation as to how to stop using this deprecated method. 64// 65// deprecated 66func testJavaError(t *testing.T, pattern string, bp string) (*android.TestContext, android.Config) { 67 t.Helper() 68 result := android.GroupFixturePreparers( 69 prepareForJavaTest, dexpreopt.PrepareForTestByEnablingDexpreopt). 70 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). 71 RunTestWithBp(t, bp) 72 return result.TestContext, result.Config 73} 74 75// testJavaWithFS runs tests using the prepareForJavaTest 76// 77// See testJava for an explanation as to how to stop using this deprecated method. 78// 79// deprecated 80func testJavaWithFS(t *testing.T, bp string, fs android.MockFS) (*android.TestContext, android.Config) { 81 t.Helper() 82 result := android.GroupFixturePreparers( 83 prepareForJavaTest, fs.AddToFixture()).RunTestWithBp(t, bp) 84 return result.TestContext, result.Config 85} 86 87// testJava runs tests using the prepareForJavaTest 88// 89// Do not add any new usages of this, instead use the prepareForJavaTest directly as it makes it 90// much easier to customize the test behavior. 91// 92// If it is necessary to customize the behavior of an existing test that uses this then please first 93// convert the test to using prepareForJavaTest first and then in a following change add the 94// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify 95// that it did not change the test behavior unexpectedly. 96// 97// deprecated 98func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) { 99 t.Helper() 100 result := prepareForJavaTest.RunTestWithBp(t, bp) 101 return result.TestContext, result.Config 102} 103 104// defaultModuleToPath constructs a path to the turbine generate jar for a default test module that 105// is defined in PrepareForIntegrationTestWithJava 106func defaultModuleToPath(name string) string { 107 switch { 108 case name == `""`: 109 return name 110 case strings.HasSuffix(name, ".jar"): 111 return name 112 default: 113 return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine", name+".jar") 114 } 115} 116 117// Test that the PrepareForTestWithJavaDefaultModules provides all the files that it uses by 118// running it in a fixture that requires all source files to exist. 119func TestPrepareForTestWithJavaDefaultModules(t *testing.T) { 120 t.Parallel() 121 android.GroupFixturePreparers( 122 PrepareForTestWithJavaDefaultModules, 123 android.PrepareForTestDisallowNonExistentPaths, 124 ).RunTest(t) 125} 126 127func TestJavaLinkType(t *testing.T) { 128 t.Parallel() 129 testJava(t, ` 130 java_library { 131 name: "foo", 132 srcs: ["a.java"], 133 libs: ["bar"], 134 static_libs: ["baz"], 135 } 136 137 java_library { 138 name: "bar", 139 sdk_version: "current", 140 srcs: ["b.java"], 141 } 142 143 java_library { 144 name: "baz", 145 sdk_version: "system_current", 146 srcs: ["c.java"], 147 } 148 `) 149 150 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", ` 151 java_library { 152 name: "foo", 153 srcs: ["a.java"], 154 libs: ["bar"], 155 sdk_version: "current", 156 static_libs: ["baz"], 157 } 158 159 java_library { 160 name: "bar", 161 sdk_version: "current", 162 srcs: ["b.java"], 163 } 164 165 java_library { 166 name: "baz", 167 sdk_version: "system_current", 168 srcs: ["c.java"], 169 } 170 `) 171 172 testJava(t, ` 173 java_library { 174 name: "foo", 175 srcs: ["a.java"], 176 libs: ["bar"], 177 sdk_version: "system_current", 178 static_libs: ["baz"], 179 } 180 181 java_library { 182 name: "bar", 183 sdk_version: "current", 184 srcs: ["b.java"], 185 } 186 187 java_library { 188 name: "baz", 189 sdk_version: "system_current", 190 srcs: ["c.java"], 191 } 192 `) 193 194 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", ` 195 java_library { 196 name: "foo", 197 srcs: ["a.java"], 198 libs: ["bar"], 199 sdk_version: "system_current", 200 static_libs: ["baz"], 201 } 202 203 java_library { 204 name: "bar", 205 sdk_version: "current", 206 srcs: ["b.java"], 207 } 208 209 java_library { 210 name: "baz", 211 srcs: ["c.java"], 212 } 213 `) 214} 215 216func TestSimple(t *testing.T) { 217 t.Parallel() 218 bp := ` 219 java_library { 220 name: "foo", 221 srcs: ["a.java"], 222 libs: ["bar"], 223 static_libs: ["baz"], 224 } 225 226 java_library { 227 name: "bar", 228 srcs: ["b.java"], 229 static_libs: ["quz"], 230 } 231 232 java_library { 233 name: "baz", 234 srcs: ["c.java"], 235 static_libs: ["quz"], 236 } 237 238 java_library { 239 name: "quz", 240 srcs: ["d.java"], 241 }` 242 243 frameworkTurbineJars := []string{ 244 "out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar", 245 "out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar", 246 } 247 248 testCases := []struct { 249 name string 250 251 preparer android.FixturePreparer 252 253 fooJavacInputs []string 254 fooJavacClasspath []string 255 fooCombinedInputs []string 256 fooHeaderCombinedInputs []string 257 258 barJavacInputs []string 259 barJavacClasspath []string 260 barCombinedInputs []string 261 barHeaderCombinedInputs []string 262 }{ 263 { 264 name: "normal", 265 preparer: android.NullFixturePreparer, 266 fooJavacInputs: []string{"a.java"}, 267 fooJavacClasspath: slices.Concat( 268 frameworkTurbineJars, 269 []string{ 270 "out/soong/.intermediates/bar/android_common/turbine/bar.jar", 271 "out/soong/.intermediates/quz/android_common/turbine/quz.jar", 272 "out/soong/.intermediates/baz/android_common/turbine/baz.jar", 273 }, 274 ), 275 fooCombinedInputs: []string{ 276 "out/soong/.intermediates/foo/android_common/javac/foo.jar", 277 "out/soong/.intermediates/baz/android_common/javac/baz.jar", 278 "out/soong/.intermediates/quz/android_common/javac/quz.jar", 279 }, 280 281 fooHeaderCombinedInputs: []string{ 282 "out/soong/.intermediates/foo/android_common/turbine/foo.jar", 283 "out/soong/.intermediates/baz/android_common/turbine/baz.jar", 284 "out/soong/.intermediates/quz/android_common/turbine/quz.jar", 285 }, 286 287 barJavacInputs: []string{"b.java"}, 288 barJavacClasspath: slices.Concat( 289 frameworkTurbineJars, 290 []string{"out/soong/.intermediates/quz/android_common/turbine/quz.jar"}, 291 ), 292 barCombinedInputs: []string{ 293 "out/soong/.intermediates/bar/android_common/javac/bar.jar", 294 "out/soong/.intermediates/quz/android_common/javac/quz.jar", 295 }, 296 barHeaderCombinedInputs: []string{ 297 "out/soong/.intermediates/bar/android_common/turbine/bar.jar", 298 "out/soong/.intermediates/quz/android_common/turbine/quz.jar", 299 }, 300 }, 301 } 302 303 for _, tt := range testCases { 304 t.Run(tt.name, func(t *testing.T) { 305 t.Parallel() 306 result := android.GroupFixturePreparers( 307 PrepareForTestWithJavaDefaultModules, 308 tt.preparer, 309 ).RunTestWithBp(t, bp) 310 foo := result.ModuleForTests(t, "foo", "android_common") 311 312 fooJavac := foo.Rule("javac") 313 android.AssertPathsRelativeToTopEquals(t, "foo javac inputs", tt.fooJavacInputs, fooJavac.Inputs) 314 315 fooJavacClasspath := fooJavac.Args["classpath"] 316 android.AssertStringPathsRelativeToTopEquals(t, "foo javac classpath", result.Config, tt.fooJavacClasspath, 317 strings.Split(strings.TrimPrefix(fooJavacClasspath, "-classpath "), ":")) 318 319 fooCombinedJar := foo.Output("combined/foo.jar") 320 android.AssertPathsRelativeToTopEquals(t, "foo combined inputs", tt.fooCombinedInputs, fooCombinedJar.Inputs) 321 322 fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar") 323 android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs) 324 325 bar := result.ModuleForTests(t, "bar", "android_common") 326 barJavac := bar.Rule("javac") 327 android.AssertPathsRelativeToTopEquals(t, "bar javac inputs", tt.barJavacInputs, barJavac.Inputs) 328 329 barJavacClasspath := barJavac.Args["classpath"] 330 android.AssertStringPathsRelativeToTopEquals(t, "bar javac classpath", result.Config, tt.barJavacClasspath, 331 strings.Split(strings.TrimPrefix(barJavacClasspath, "-classpath "), ":")) 332 333 barCombinedJar := bar.Output("combined/bar.jar") 334 android.AssertPathsRelativeToTopEquals(t, "bar combined inputs", tt.barCombinedInputs, barCombinedJar.Inputs) 335 336 barCombinedHeaderJar := bar.Output("turbine-combined/bar.jar") 337 android.AssertPathsRelativeToTopEquals(t, "bar header combined inputs", tt.barHeaderCombinedInputs, barCombinedHeaderJar.Inputs) 338 }) 339 } 340} 341 342func TestExportedPlugins(t *testing.T) { 343 t.Parallel() 344 type Result struct { 345 library string 346 processors string 347 disableTurbine bool 348 } 349 var tests = []struct { 350 name string 351 extra string 352 results []Result 353 }{ 354 { 355 name: "Exported plugin is not a direct plugin", 356 extra: `java_library { name: "exports", srcs: ["a.java"], exported_plugins: ["plugin"] }`, 357 results: []Result{{library: "exports", processors: "-proc:none"}}, 358 }, 359 { 360 name: "Exports plugin to dependee", 361 extra: ` 362 java_library{name: "exports", exported_plugins: ["plugin"]} 363 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 364 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 365 `, 366 results: []Result{ 367 {library: "foo", processors: "-processor com.android.TestPlugin"}, 368 {library: "bar", processors: "-processor com.android.TestPlugin"}, 369 }, 370 }, 371 { 372 name: "Exports plugin to android_library", 373 extra: ` 374 java_library{name: "exports", exported_plugins: ["plugin"]} 375 android_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 376 android_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 377 `, 378 results: []Result{ 379 {library: "foo", processors: "-processor com.android.TestPlugin"}, 380 {library: "bar", processors: "-processor com.android.TestPlugin"}, 381 }, 382 }, 383 { 384 name: "Exports plugin is not propagated via transitive deps", 385 extra: ` 386 java_library{name: "exports", exported_plugins: ["plugin"]} 387 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 388 java_library{name: "bar", srcs: ["a.java"], static_libs: ["foo"]} 389 `, 390 results: []Result{ 391 {library: "foo", processors: "-processor com.android.TestPlugin"}, 392 {library: "bar", processors: "-proc:none"}, 393 }, 394 }, 395 { 396 name: "Exports plugin appends to plugins", 397 extra: ` 398 java_plugin{name: "plugin2", processor_class: "com.android.TestPlugin2"} 399 java_library{name: "exports", exported_plugins: ["plugin"]} 400 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"], plugins: ["plugin2"]} 401 `, 402 results: []Result{ 403 {library: "foo", processors: "-processor com.android.TestPlugin,com.android.TestPlugin2"}, 404 }, 405 }, 406 { 407 name: "Exports plugin to with generates_api to dependee", 408 extra: ` 409 java_library{name: "exports", exported_plugins: ["plugin_generates_api"]} 410 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 411 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 412 `, 413 results: []Result{ 414 {library: "foo", processors: "-processor com.android.TestPlugin", disableTurbine: true}, 415 {library: "bar", processors: "-processor com.android.TestPlugin", disableTurbine: true}, 416 }, 417 }, 418 } 419 420 for _, test := range tests { 421 t.Run(test.name, func(t *testing.T) { 422 t.Parallel() 423 ctx, _ := testJava(t, ` 424 java_plugin { 425 name: "plugin", 426 processor_class: "com.android.TestPlugin", 427 } 428 java_plugin { 429 name: "plugin_generates_api", 430 generates_api: true, 431 processor_class: "com.android.TestPlugin", 432 } 433 `+test.extra) 434 435 for _, want := range test.results { 436 javac := ctx.ModuleForTests(t, want.library, "android_common").Rule("javac") 437 if javac.Args["processor"] != want.processors { 438 t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"]) 439 } 440 turbine := ctx.ModuleForTests(t, want.library, "android_common").MaybeRule("turbine") 441 disableTurbine := turbine.BuildParams.Rule == nil 442 if disableTurbine != want.disableTurbine { 443 t.Errorf("For library %v, expected disableTurbine %v, found %v", want.library, want.disableTurbine, disableTurbine) 444 } 445 } 446 }) 447 } 448} 449 450func TestSdkVersionByPartition(t *testing.T) { 451 t.Parallel() 452 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", ` 453 java_library { 454 name: "foo", 455 srcs: ["a.java"], 456 vendor: true, 457 } 458 `) 459 460 testJava(t, ` 461 java_library { 462 name: "bar", 463 srcs: ["b.java"], 464 } 465 `) 466 467 for _, enforce := range []bool{true, false} { 468 bp := ` 469 java_library { 470 name: "foo", 471 srcs: ["a.java"], 472 product_specific: true, 473 } 474 ` 475 476 errorHandler := android.FixtureExpectsNoErrors 477 if enforce { 478 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product") 479 } 480 481 android.GroupFixturePreparers( 482 PrepareForTestWithJavaDefaultModules, 483 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 484 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce) 485 }), 486 ). 487 ExtendWithErrorHandler(errorHandler). 488 RunTestWithBp(t, bp) 489 } 490} 491 492func TestArchSpecific(t *testing.T) { 493 t.Parallel() 494 ctx, _ := testJava(t, ` 495 java_library { 496 name: "foo", 497 srcs: ["a.java"], 498 target: { 499 android: { 500 srcs: ["b.java"], 501 }, 502 }, 503 } 504 `) 505 506 javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac") 507 if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" { 508 t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs) 509 } 510} 511 512func TestBinary(t *testing.T) { 513 t.Parallel() 514 ctx, _ := testJava(t, ` 515 java_library_host { 516 name: "foo", 517 srcs: ["a.java"], 518 } 519 520 java_binary_host { 521 name: "bar", 522 srcs: ["b.java"], 523 static_libs: ["foo"], 524 jni_libs: ["libjni"], 525 } 526 527 cc_library_shared { 528 name: "libjni", 529 host_supported: true, 530 device_supported: false, 531 stl: "none", 532 } 533 `) 534 535 buildOS := ctx.Config().BuildOS.String() 536 537 bar := ctx.ModuleForTests(t, "bar", buildOS+"_common") 538 barJar := bar.Output("bar.jar").Output.String() 539 barWrapperDeps := bar.Output("bar").Implicits.Strings() 540 541 libjni := ctx.ModuleForTests(t, "libjni", buildOS+"_x86_64_shared") 542 libjniSO := libjni.Rule("Cp").Output.String() 543 544 // Test that the install binary wrapper depends on the installed jar file 545 if g, w := barWrapperDeps, barJar; !android.InList(w, g) { 546 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g) 547 } 548 549 // Test that the install binary wrapper depends on the installed JNI libraries 550 if g, w := barWrapperDeps, libjniSO; !android.InList(w, g) { 551 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g) 552 } 553} 554 555func TestTest(t *testing.T) { 556 t.Parallel() 557 ctx, _ := testJava(t, ` 558 java_test_host { 559 name: "foo", 560 srcs: ["a.java"], 561 jni_libs: ["libjni"], 562 } 563 564 cc_library_shared { 565 name: "libjni", 566 host_supported: true, 567 device_supported: false, 568 stl: "none", 569 } 570 `) 571 572 buildOS := ctx.Config().BuildOS.String() 573 574 foo := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost) 575 576 expected := "lib64/libjni.so" 577 if runtime.GOOS == "darwin" { 578 expected = "lib64/libjni.dylib" 579 } 580 581 fooTestData := foo.data 582 if len(fooTestData) != 1 || fooTestData[0].Rel() != expected { 583 t.Errorf(`expected foo test data relative path [%q], got %q`, 584 expected, fooTestData.Strings()) 585 } 586} 587 588func TestHostCommonData(t *testing.T) { 589 t.Parallel() 590 ctx, _ := testJava(t, ` 591 java_library_host { 592 name: "host", 593 srcs: ["a.java"], 594 } 595 596 java_test { 597 name: "foo", 598 srcs: ["a.java"], 599 host_common_data: [":host"], 600 } 601 `) 602 603 foo := ctx.ModuleForTests(t, "foo", "android_common").Module().(*Test) 604 host := ctx.ModuleForTests(t, "host", ctx.Config().BuildOSCommonTarget.String()).Module().(*Library) 605 606 if g, w := foo.data.RelativeToTop().Strings(), []string{host.outputFile.RelativeToTop().String()}; !slices.Equal(g, w) { 607 t.Errorf("expected test data %q, got %q\n", w, g) 608 } 609} 610 611func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) { 612 t.Parallel() 613 bp := ` 614 java_library { 615 name: "target_library", 616 srcs: ["a.java"], 617 } 618 619 java_binary_host { 620 name: "host_binary", 621 srcs: ["b.java"], 622 } 623 ` 624 625 result := android.GroupFixturePreparers( 626 PrepareForTestWithJavaDefaultModules, 627 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 628 variables.MinimizeJavaDebugInfo = proptools.BoolPtr(true) 629 }), 630 ).RunTestWithBp(t, bp) 631 632 // first, check that the -g flag is added to target modules 633 targetLibrary := result.ModuleForTests(t, "target_library", "android_common") 634 targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"] 635 if !strings.Contains(targetJavaFlags, "-g:source,lines") { 636 t.Errorf("target library javac flags %v should contain "+ 637 "-g:source,lines override with MinimizeJavaDebugInfo", targetJavaFlags) 638 } 639 640 // check that -g is not overridden for host modules 641 buildOS := result.Config.BuildOS.String() 642 hostBinary := result.ModuleForTests(t, "host_binary", buildOS+"_common") 643 hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"] 644 if strings.Contains(hostJavaFlags, "-g:source,lines") { 645 t.Errorf("java_binary_host javac flags %v should not have "+ 646 "-g:source,lines override with MinimizeJavaDebugInfo", hostJavaFlags) 647 } 648} 649 650// A minimal context object for use with DexJarBuildPath 651type moduleErrorfTestCtx struct { 652} 653 654func (ctx moduleErrorfTestCtx) ModuleErrorf(format string, args ...interface{}) { 655} 656 657var _ android.ModuleErrorfContext = (*moduleErrorfTestCtx)(nil) 658 659func TestPrebuilts(t *testing.T) { 660 t.Parallel() 661 ctx, _ := testJava(t, ` 662 java_library { 663 name: "foo", 664 srcs: ["a.java", ":stubs-source"], 665 libs: ["bar", "sdklib.stubs"], 666 static_libs: ["baz"], 667 } 668 669 java_import { 670 name: "bar", 671 jars: ["a.jar"], 672 } 673 674 java_import { 675 name: "baz", 676 jars: ["b.jar"], 677 sdk_version: "current", 678 compile_dex: true, 679 } 680 681 dex_import { 682 name: "qux", 683 jars: ["b.jar"], 684 } 685 686 java_sdk_library_import { 687 name: "sdklib", 688 public: { 689 jars: ["c.jar"], 690 }, 691 } 692 693 prebuilt_stubs_sources { 694 name: "stubs-source", 695 srcs: ["stubs/sources"], 696 } 697 698 java_test_import { 699 name: "test", 700 jars: ["a.jar"], 701 test_suites: ["cts"], 702 test_config: "AndroidTest.xml", 703 } 704 `) 705 706 fooModule := ctx.ModuleForTests(t, "foo", "android_common") 707 javac := fooModule.Rule("javac") 708 combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac") 709 barModule := ctx.ModuleForTests(t, "bar", "android_common") 710 barJar := barModule.Output("local-combined/bar.jar").Output 711 bazModule := ctx.ModuleForTests(t, "baz", "android_common") 712 bazJar := bazModule.Output("local-combined/baz.jar").Output 713 sdklibStubsJar := ctx.ModuleForTests(t, "sdklib.stubs", "android_common"). 714 Output("local-combined/sdklib.stubs.jar").Output 715 716 fooLibrary := fooModule.Module().(*Library) 717 assertDeepEquals(t, "foo unique sources incorrect", 718 []string{"a.java"}, fooLibrary.uniqueSrcFiles.Strings()) 719 720 assertDeepEquals(t, "foo java source jars incorrect", 721 []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"}, 722 android.NormalizePathsForTesting(fooLibrary.compiledSrcJars)) 723 724 if !strings.Contains(javac.Args["classpath"], barJar.String()) { 725 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String()) 726 } 727 728 errCtx := moduleErrorfTestCtx{} 729 barDexJar := barModule.Module().(*Import).DexJarBuildPath(errCtx) 730 if barDexJar.IsSet() { 731 t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar) 732 } 733 734 if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) { 735 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String()) 736 } 737 738 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() { 739 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String()) 740 } 741 742 bazDexJar := bazModule.Module().(*Import).DexJarBuildPath(errCtx).Path() 743 expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar" 744 android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar) 745 746 ctx.ModuleForTests(t, "qux", "android_common").Rule("Cp") 747 748 entries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0] 749 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 750 entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0] 751 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 752} 753 754func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) { 755 if !reflect.DeepEqual(expected, actual) { 756 t.Errorf("%s: expected %q, found %q", message, expected, actual) 757 } 758} 759 760func TestPrebuiltStubsSources(t *testing.T) { 761 t.Parallel() 762 test := func(t *testing.T, sourcesPath string, expectedInputs []string) { 763 ctx, _ := testJavaWithFS(t, fmt.Sprintf(` 764prebuilt_stubs_sources { 765 name: "stubs-source", 766 srcs: ["%s"], 767}`, sourcesPath), map[string][]byte{ 768 "stubs/sources/pkg/A.java": nil, 769 "stubs/sources/pkg/B.java": nil, 770 }) 771 772 zipSrc := ctx.ModuleForTests(t, "stubs-source", "android_common").Rule("zip_src") 773 if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) { 774 t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual) 775 } 776 } 777 778 t.Run("empty/missing directory", func(t *testing.T) { 779 t.Parallel() 780 test(t, "empty-directory", nil) 781 }) 782 783 t.Run("non-empty set of sources", func(t *testing.T) { 784 t.Parallel() 785 test(t, "stubs/sources", []string{ 786 "stubs/sources/pkg/A.java", 787 "stubs/sources/pkg/B.java", 788 }) 789 }) 790} 791 792func TestDefaults(t *testing.T) { 793 t.Parallel() 794 ctx, _ := testJava(t, ` 795 java_defaults { 796 name: "defaults", 797 srcs: ["a.java"], 798 libs: ["bar"], 799 static_libs: ["baz"], 800 optimize: {enabled: false}, 801 } 802 803 java_library { 804 name: "foo", 805 defaults: ["defaults"], 806 } 807 808 java_library { 809 name: "bar", 810 srcs: ["b.java"], 811 } 812 813 java_library { 814 name: "baz", 815 srcs: ["c.java"], 816 } 817 818 android_test { 819 name: "atestOptimize", 820 defaults: ["defaults"], 821 optimize: {enabled: true}, 822 } 823 824 android_test { 825 name: "atestNoOptimize", 826 defaults: ["defaults"], 827 } 828 829 android_test { 830 name: "atestDefault", 831 srcs: ["a.java"], 832 } 833 `) 834 835 javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac") 836 combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac") 837 838 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { 839 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) 840 } 841 842 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 843 if !strings.Contains(javac.Args["classpath"], barTurbine) { 844 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine) 845 } 846 847 baz := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac").Output.String() 848 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz { 849 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz) 850 } 851 852 atestOptimize := ctx.ModuleForTests(t, "atestOptimize", "android_common").MaybeRule("r8") 853 if atestOptimize.Output == nil { 854 t.Errorf("atestOptimize should optimize APK") 855 } 856 857 atestNoOptimize := ctx.ModuleForTests(t, "atestNoOptimize", "android_common").MaybeRule("d8") 858 if atestNoOptimize.Output == nil { 859 t.Errorf("atestNoOptimize should not optimize APK") 860 } 861 862 atestDefault := ctx.ModuleForTests(t, "atestDefault", "android_common").MaybeRule("d8") 863 if atestDefault.Output == nil { 864 t.Errorf("atestDefault should not optimize APK") 865 } 866} 867 868func TestResources(t *testing.T) { 869 t.Parallel() 870 var table = []struct { 871 name string 872 prop string 873 extra string 874 args string 875 }{ 876 { 877 // Test that a module with java_resource_dirs includes the files 878 name: "resource dirs", 879 prop: `java_resource_dirs: ["java-res"]`, 880 args: "-C java-res -f java-res/a/a -f java-res/b/b", 881 }, 882 { 883 // Test that a module with java_resources includes the files 884 name: "resource files", 885 prop: `java_resources: ["java-res/a/a", "java-res/b/b"]`, 886 args: "-C . -f java-res/a/a -f java-res/b/b", 887 }, 888 { 889 // Test that a module with a filegroup in java_resources includes the files with the 890 // path prefix 891 name: "resource filegroup", 892 prop: `java_resources: [":foo-res"]`, 893 extra: ` 894 filegroup { 895 name: "foo-res", 896 path: "java-res", 897 srcs: ["java-res/a/a", "java-res/b/b"], 898 }`, 899 args: "-C java-res -f java-res/a/a -f java-res/b/b", 900 }, 901 { 902 // Test that a module with wildcards in java_resource_dirs has the correct path prefixes 903 name: "wildcard dirs", 904 prop: `java_resource_dirs: ["java-res/*"]`, 905 args: "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b", 906 }, 907 { 908 // Test that a module exclude_java_resource_dirs excludes the files 909 name: "wildcard dirs", 910 prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`, 911 args: "-C java-res/a -f java-res/a/a", 912 }, 913 { 914 // Test wildcards in java_resources 915 name: "wildcard files", 916 prop: `java_resources: ["java-res/**/*"]`, 917 args: "-C . -f java-res/a/a -f java-res/b/b", 918 }, 919 { 920 // Test exclude_java_resources with java_resources 921 name: "wildcard files with exclude", 922 prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`, 923 args: "-C . -f java-res/a/a", 924 }, 925 { 926 // Test exclude_java_resources with java_resource_dirs 927 name: "resource dirs with exclude files", 928 prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`, 929 args: "-C java-res -f java-res/a/a", 930 }, 931 { 932 // Test exclude_java_resource_dirs with java_resource_dirs 933 name: "resource dirs with exclude files", 934 prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`, 935 args: "-C java-res -f java-res/a/a -f java-res/b/b", 936 }, 937 } 938 939 for _, test := range table { 940 t.Run(test.name, func(t *testing.T) { 941 t.Parallel() 942 ctx, _ := testJavaWithFS(t, ` 943 java_library { 944 name: "foo", 945 srcs: [ 946 "a.java", 947 "b.java", 948 "c.java", 949 ], 950 `+test.prop+`, 951 } 952 `+test.extra, 953 map[string][]byte{ 954 "java-res/a/a": nil, 955 "java-res/b/b": nil, 956 "java-res2/a": nil, 957 }, 958 ) 959 960 foo := ctx.ModuleForTests(t, "foo", "android_common").Output("withres/foo.jar") 961 fooRes := ctx.ModuleForTests(t, "foo", "android_common").Output("res/foo.jar") 962 963 if !inList(fooRes.Output.String(), foo.Inputs.Strings()) { 964 t.Errorf("foo combined jars %v does not contain %q", 965 foo.Inputs.Strings(), fooRes.Output.String()) 966 } 967 968 if fooRes.Args["jarArgs"] != test.args { 969 t.Errorf("foo resource jar args %q is not %q", 970 fooRes.Args["jarArgs"], test.args) 971 } 972 }) 973 } 974} 975 976func TestIncludeSrcs(t *testing.T) { 977 t.Parallel() 978 ctx, _ := testJavaWithFS(t, ` 979 java_library { 980 name: "foo", 981 srcs: [ 982 "a.java", 983 "b.java", 984 "c.java", 985 ], 986 include_srcs: true, 987 } 988 989 java_library { 990 name: "bar", 991 srcs: [ 992 "a.java", 993 "b.java", 994 "c.java", 995 ], 996 java_resource_dirs: ["java-res"], 997 include_srcs: true, 998 } 999 `, map[string][]byte{ 1000 "java-res/a/a": nil, 1001 "java-res/b/b": nil, 1002 "java-res2/a": nil, 1003 }) 1004 1005 // Test a library with include_srcs: true 1006 foo := ctx.ModuleForTests(t, "foo", "android_common").Output("withres/foo.jar") 1007 fooSrcJar := ctx.ModuleForTests(t, "foo", "android_common").Output("foo.srcjar") 1008 1009 if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) { 1010 t.Errorf("foo combined jars %v does not contain %q", w, g) 1011 } 1012 1013 if g, w := fooSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w { 1014 t.Errorf("foo source jar args %q is not %q", w, g) 1015 } 1016 1017 // Test a library with include_srcs: true and resources 1018 bar := ctx.ModuleForTests(t, "bar", "android_common").Output("withres/bar.jar") 1019 barResCombined := ctx.ModuleForTests(t, "bar", "android_common").Output("res-combined/bar.jar") 1020 barRes := ctx.ModuleForTests(t, "bar", "android_common").Output("res/bar.jar") 1021 barSrcJar := ctx.ModuleForTests(t, "bar", "android_common").Output("bar.srcjar") 1022 1023 if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) { 1024 t.Errorf("bar combined resource jars %v does not contain %q", w, g) 1025 } 1026 1027 if g, w := barRes.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) { 1028 t.Errorf("bar combined resource jars %v does not contain %q", w, g) 1029 } 1030 1031 if g, w := barRes.Output.String(), bar.Inputs.Strings(); !inList(g, w) { 1032 t.Errorf("bar combined jars %v does not contain %q", w, g) 1033 } 1034 1035 if g, w := barSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w { 1036 t.Errorf("bar source jar args %q is not %q", w, g) 1037 } 1038 1039 if g, w := barRes.Args["jarArgs"], "-C java-res -f java-res/a/a -f java-res/b/b"; g != w { 1040 t.Errorf("bar resource jar args %q is not %q", w, g) 1041 } 1042} 1043 1044func TestGeneratedSources(t *testing.T) { 1045 t.Parallel() 1046 ctx, _ := testJavaWithFS(t, ` 1047 java_library { 1048 name: "foo", 1049 srcs: [ 1050 "a*.java", 1051 ":gen", 1052 "b*.java", 1053 ], 1054 } 1055 1056 genrule { 1057 name: "gen", 1058 tool_files: ["java-res/a"], 1059 out: ["gen.java"], 1060 } 1061 `, map[string][]byte{ 1062 "a.java": nil, 1063 "b.java": nil, 1064 }) 1065 1066 javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac") 1067 genrule := ctx.ModuleForTests(t, "gen", "").Rule("generator") 1068 1069 if filepath.Base(genrule.Output.String()) != "gen.java" { 1070 t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String()) 1071 } 1072 1073 if len(javac.Inputs) != 3 || 1074 javac.Inputs[0].String() != "a.java" || 1075 javac.Inputs[1].String() != genrule.Output.String() || 1076 javac.Inputs[2].String() != "b.java" { 1077 t.Errorf(`foo inputs %v != ["a.java", ".../gen.java", "b.java"]`, javac.Inputs) 1078 } 1079} 1080 1081func TestTurbine(t *testing.T) { 1082 t.Parallel() 1083 result := android.GroupFixturePreparers( 1084 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})). 1085 RunTestWithBp(t, ` 1086 java_library { 1087 name: "foo", 1088 srcs: ["a.java"], 1089 sdk_version: "14", 1090 } 1091 1092 java_library { 1093 name: "bar", 1094 srcs: ["b.java"], 1095 static_libs: ["foo"], 1096 sdk_version: "14", 1097 } 1098 1099 java_library { 1100 name: "baz", 1101 srcs: ["c.java"], 1102 libs: ["bar"], 1103 sdk_version: "14", 1104 } 1105 `) 1106 1107 fooTurbine := result.ModuleForTests(t, "foo", "android_common").Rule("turbine") 1108 barTurbine := result.ModuleForTests(t, "bar", "android_common").Rule("turbine") 1109 barJavac := result.ModuleForTests(t, "bar", "android_common").Rule("javac") 1110 barTurbineCombined := result.ModuleForTests(t, "bar", "android_common").Description("for turbine") 1111 bazJavac := result.ModuleForTests(t, "baz", "android_common").Rule("javac") 1112 1113 android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs) 1114 1115 fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine", "foo.jar") 1116 barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 1117 android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar) 1118 android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar) 1119 android.AssertPathsRelativeToTopEquals(t, "bar turbine combineJar", []string{barTurbineJar, fooHeaderJar}, barTurbineCombined.Inputs) 1120 android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "prebuilts/sdk/14/public/android.jar") 1121} 1122 1123func TestSharding(t *testing.T) { 1124 t.Parallel() 1125 ctx, _ := testJava(t, ` 1126 java_library { 1127 name: "bar", 1128 srcs: ["a.java","b.java","c.java"], 1129 javac_shard_size: 1 1130 } 1131 `) 1132 1133 barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 1134 for i := 0; i < 3; i++ { 1135 barJavac := ctx.ModuleForTests(t, "bar", "android_common").Description("javac" + strconv.Itoa(i)) 1136 if !strings.HasPrefix(barJavac.Args["classpath"], "-classpath "+barHeaderJar+":") { 1137 t.Errorf("bar javac classpath %v does start with %q", barJavac.Args["classpath"], barHeaderJar) 1138 } 1139 } 1140} 1141 1142func TestExcludeFileGroupInSrcs(t *testing.T) { 1143 t.Parallel() 1144 ctx, _ := testJava(t, ` 1145 java_library { 1146 name: "foo", 1147 srcs: ["a.java", ":foo-srcs"], 1148 exclude_srcs: ["a.java", ":foo-excludes"], 1149 } 1150 1151 filegroup { 1152 name: "foo-srcs", 1153 srcs: ["java-fg/a.java", "java-fg/b.java", "java-fg/c.java"], 1154 } 1155 1156 filegroup { 1157 name: "foo-excludes", 1158 srcs: ["java-fg/a.java", "java-fg/b.java"], 1159 } 1160 `) 1161 1162 javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac") 1163 1164 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" { 1165 t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs) 1166 } 1167} 1168 1169func TestJavaLibraryOutputFiles(t *testing.T) { 1170 t.Parallel() 1171 testJavaWithFS(t, "", map[string][]byte{ 1172 "libcore/Android.bp": []byte(` 1173 java_library { 1174 name: "core", 1175 sdk_version: "none", 1176 system_modules: "none", 1177 } 1178 1179 filegroup { 1180 name: "core-jar", 1181 device_common_srcs: [":core{.jar}"], 1182 } 1183 `), 1184 }) 1185} 1186 1187func TestJavaImportOutputFiles(t *testing.T) { 1188 t.Parallel() 1189 testJavaWithFS(t, "", map[string][]byte{ 1190 "libcore/Android.bp": []byte(` 1191 java_import { 1192 name: "core", 1193 sdk_version: "none", 1194 } 1195 1196 filegroup { 1197 name: "core-jar", 1198 device_common_srcs: [":core{.jar}"], 1199 } 1200 `), 1201 }) 1202} 1203 1204func TestJavaImport(t *testing.T) { 1205 t.Parallel() 1206 bp := ` 1207 java_library { 1208 name: "source_library", 1209 srcs: ["source.java"], 1210 } 1211 1212 java_import { 1213 name: "import_with_no_deps", 1214 jars: ["no_deps.jar"], 1215 } 1216 1217 java_import { 1218 name: "import_with_source_deps", 1219 jars: ["source_deps.jar"], 1220 static_libs: ["source_library"], 1221 } 1222 1223 java_import { 1224 name: "import_with_import_deps", 1225 jars: ["import_deps.jar"], 1226 static_libs: ["import_with_no_deps"], 1227 } 1228 ` 1229 ctx := android.GroupFixturePreparers( 1230 PrepareForTestWithJavaDefaultModules, 1231 ).RunTestWithBp(t, bp) 1232 1233 source := ctx.ModuleForTests(t, "source_library", "android_common") 1234 sourceJar := source.Output("javac/source_library.jar") 1235 sourceHeaderJar := source.Output("turbine/source_library.jar") 1236 sourceCombinedHeaderJar := source.Output("turbine-combined/source_library.jar") 1237 sourceJavaInfo, _ := android.OtherModuleProvider(ctx, source.Module(), JavaInfoProvider) 1238 1239 // The source library produces separate implementation and header jars 1240 android.AssertPathsRelativeToTopEquals(t, "source library implementation jar", 1241 []string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars) 1242 android.AssertPathsRelativeToTopEquals(t, "source library header jar", 1243 []string{sourceCombinedHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars) 1244 1245 importWithNoDeps := ctx.ModuleForTests(t, "import_with_no_deps", "android_common") 1246 importWithNoDepsLocalJar := importWithNoDeps.Output("local-combined/import_with_no_deps.jar") 1247 importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar") 1248 importWithNoDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider) 1249 1250 // An import with no deps produces a single jar used as both the header and implementation jar. 1251 android.AssertPathsRelativeToTopEquals(t, "import with no deps implementation jar", 1252 []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.ImplementationAndResourcesJars) 1253 android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar", 1254 []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars) 1255 android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs", 1256 []string{importWithNoDepsLocalJar.Output.String()}, importWithNoDepsJar.Inputs) 1257 android.AssertPathsRelativeToTopEquals(t, "import with no deps local combined inputs", 1258 []string{"no_deps.jar"}, importWithNoDepsLocalJar.Inputs) 1259 1260 importWithSourceDeps := ctx.ModuleForTests(t, "import_with_source_deps", "android_common") 1261 importWithSourceDepsLocalJar := importWithSourceDeps.Output("local-combined/import_with_source_deps.jar") 1262 importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar") 1263 importWithSourceDepsLocalHeaderJar := importWithSourceDeps.Output("local-combined/import_with_source_deps.jar") 1264 importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar") 1265 importWithSourceDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider) 1266 1267 // An import with source deps produces separate header and implementation jars. 1268 android.AssertPathsRelativeToTopEquals(t, "import with source deps implementation jar", 1269 []string{importWithSourceDepsJar.Output.String()}, importWithSourceDepsJavaInfo.ImplementationAndResourcesJars) 1270 android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar", 1271 []string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars) 1272 android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs", 1273 []string{importWithSourceDepsLocalJar.Output.String(), sourceJar.Output.String()}, importWithSourceDepsJar.Inputs) 1274 android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs", 1275 []string{importWithSourceDepsLocalHeaderJar.Output.String(), sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs) 1276 android.AssertPathsRelativeToTopEquals(t, "import with source deps local combined implementation jar inputs", 1277 []string{"source_deps.jar"}, importWithSourceDepsLocalJar.Inputs) 1278 android.AssertPathsRelativeToTopEquals(t, "import with source deps local combined header jar inputs", 1279 []string{"source_deps.jar"}, importWithSourceDepsLocalHeaderJar.Inputs) 1280 1281 importWithImportDeps := ctx.ModuleForTests(t, "import_with_import_deps", "android_common") 1282 importWithImportDepsLocalJar := importWithImportDeps.Output("local-combined/import_with_import_deps.jar") 1283 importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar") 1284 importWithImportDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider) 1285 1286 // An import with only import deps produces a single jar used as both the header and implementation jar. 1287 android.AssertPathsRelativeToTopEquals(t, "import with import deps implementation jar", 1288 []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.ImplementationAndResourcesJars) 1289 android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar", 1290 []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars) 1291 android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs", 1292 []string{importWithImportDepsLocalJar.Output.String(), importWithNoDepsLocalJar.Output.String()}, importWithImportDepsJar.Inputs) 1293 android.AssertPathsRelativeToTopEquals(t, "import with import deps local combined implementation jar inputs", 1294 []string{"import_deps.jar"}, importWithImportDepsLocalJar.Inputs) 1295} 1296 1297var compilerFlagsTestCases = []struct { 1298 in string 1299 out bool 1300}{ 1301 { 1302 in: "a", 1303 out: false, 1304 }, 1305 { 1306 in: "-a", 1307 out: true, 1308 }, 1309 { 1310 in: "-no-jdk", 1311 out: false, 1312 }, 1313 { 1314 in: "-no-stdlib", 1315 out: false, 1316 }, 1317 { 1318 in: "-kotlin-home", 1319 out: false, 1320 }, 1321 { 1322 in: "-kotlin-home /some/path", 1323 out: false, 1324 }, 1325 { 1326 in: "-include-runtime", 1327 out: false, 1328 }, 1329 { 1330 in: "-Xintellij-plugin-root", 1331 out: false, 1332 }, 1333} 1334 1335type mockContext struct { 1336 android.ModuleContext 1337 result bool 1338} 1339 1340func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) { 1341 // CheckBadCompilerFlags calls this function when the flag should be rejected 1342 ctx.result = false 1343} 1344 1345func TestCompilerFlags(t *testing.T) { 1346 t.Parallel() 1347 for _, testCase := range compilerFlagsTestCases { 1348 ctx := &mockContext{result: true} 1349 CheckKotlincFlags(ctx, []string{testCase.in}) 1350 if ctx.result != testCase.out { 1351 t.Errorf("incorrect output:") 1352 t.Errorf(" input: %#v", testCase.in) 1353 t.Errorf(" expected: %#v", testCase.out) 1354 t.Errorf(" got: %#v", ctx.result) 1355 } 1356 } 1357} 1358 1359// TODO(jungjw): Consider making this more robust by ignoring path order. 1360func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) { 1361 t.Helper() 1362 variables := ctx.ModuleForTests(t, moduleName, "android_common").VariablesForTestsRelativeToTop() 1363 flags := strings.Split(variables["javacFlags"], " ") 1364 got := "" 1365 for _, flag := range flags { 1366 keyEnd := strings.Index(flag, "=") 1367 if keyEnd > -1 && flag[:keyEnd] == "--patch-module" { 1368 got = flag[keyEnd+1:] 1369 break 1370 } 1371 } 1372 if expected != android.StringPathRelativeToTop(ctx.Config().SoongOutDir(), got) { 1373 t.Errorf("Unexpected patch-module flag for module %q - expected %q, but got %q", moduleName, expected, got) 1374 } 1375} 1376 1377func TestPatchModule(t *testing.T) { 1378 t.Parallel() 1379 t.Run("Java language level 8", func(t *testing.T) { 1380 t.Parallel() 1381 // Test with legacy javac -source 1.8 -target 1.8 1382 bp := ` 1383 java_library { 1384 name: "foo", 1385 srcs: ["a.java"], 1386 java_version: "1.8", 1387 } 1388 1389 java_library { 1390 name: "bar", 1391 srcs: ["b.java"], 1392 sdk_version: "none", 1393 system_modules: "none", 1394 patch_module: "java.base", 1395 java_version: "1.8", 1396 } 1397 1398 java_library { 1399 name: "baz", 1400 srcs: ["c.java"], 1401 patch_module: "java.base", 1402 java_version: "1.8", 1403 } 1404 ` 1405 ctx, _ := testJava(t, bp) 1406 1407 checkPatchModuleFlag(t, ctx, "foo", "") 1408 checkPatchModuleFlag(t, ctx, "bar", "") 1409 checkPatchModuleFlag(t, ctx, "baz", "") 1410 }) 1411 1412 t.Run("Java language level 9", func(t *testing.T) { 1413 t.Parallel() 1414 // Test with default javac -source 9 -target 9 1415 bp := ` 1416 java_library { 1417 name: "foo", 1418 srcs: ["a.java"], 1419 } 1420 1421 java_library { 1422 name: "bar", 1423 srcs: ["b.java"], 1424 sdk_version: "none", 1425 system_modules: "none", 1426 patch_module: "java.base", 1427 } 1428 1429 java_library { 1430 name: "baz", 1431 srcs: [ 1432 "c.java", 1433 // Tests for b/150878007 1434 "dir/d.java", 1435 "dir2/e.java", 1436 "dir2/f.java", 1437 "nested/dir/g.java" 1438 ], 1439 patch_module: "java.base", 1440 } 1441 ` 1442 ctx, _ := testJava(t, bp) 1443 1444 checkPatchModuleFlag(t, ctx, "foo", "") 1445 expected := "java.base=.:out/soong" 1446 checkPatchModuleFlag(t, ctx, "bar", expected) 1447 expected = "java.base=" + strings.Join([]string{ 1448 ".", "out/soong", defaultModuleToPath("ext"), defaultModuleToPath("framework")}, ":") 1449 checkPatchModuleFlag(t, ctx, "baz", expected) 1450 }) 1451} 1452 1453func TestJavaLibraryWithSystemModules(t *testing.T) { 1454 t.Parallel() 1455 ctx, _ := testJava(t, ` 1456 java_library { 1457 name: "lib-with-source-system-modules", 1458 srcs: [ 1459 "a.java", 1460 ], 1461 sdk_version: "none", 1462 system_modules: "source-system-modules", 1463 } 1464 1465 java_library { 1466 name: "source-jar", 1467 srcs: [ 1468 "a.java", 1469 ], 1470 } 1471 1472 java_system_modules { 1473 name: "source-system-modules", 1474 libs: ["source-jar"], 1475 } 1476 1477 java_library { 1478 name: "lib-with-prebuilt-system-modules", 1479 srcs: [ 1480 "a.java", 1481 ], 1482 sdk_version: "none", 1483 system_modules: "prebuilt-system-modules", 1484 } 1485 1486 java_import { 1487 name: "prebuilt-jar", 1488 jars: ["a.jar"], 1489 } 1490 1491 java_system_modules_import { 1492 name: "prebuilt-system-modules", 1493 libs: ["prebuilt-jar"], 1494 } 1495 `) 1496 1497 checkBootClasspathForLibWithSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar") 1498 1499 checkBootClasspathForLibWithSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar") 1500} 1501 1502func checkBootClasspathForLibWithSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) { 1503 javacRule := ctx.ModuleForTests(t, moduleName, "android_common").Rule("javac") 1504 bootClasspath := javacRule.Args["bootClasspath"] 1505 if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) { 1506 t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath) 1507 } 1508} 1509 1510func TestAidlExportIncludeDirsFromImports(t *testing.T) { 1511 t.Parallel() 1512 ctx, _ := testJava(t, ` 1513 java_library { 1514 name: "foo", 1515 srcs: ["aidl/foo/IFoo.aidl"], 1516 libs: ["bar"], 1517 } 1518 1519 java_import { 1520 name: "bar", 1521 jars: ["a.jar"], 1522 aidl: { 1523 export_include_dirs: ["aidl/bar"], 1524 }, 1525 } 1526 `) 1527 1528 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command 1529 expectedAidlFlag := "-Iaidl/bar" 1530 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1531 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1532 } 1533} 1534 1535func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) { 1536 t.Parallel() 1537 ctx, _ := testJava(t, ` 1538 java_library { 1539 name: "foo", 1540 srcs: ["aidl/foo/IFoo.aidl"], 1541 aidl: { flags: ["-Werror"], }, 1542 } 1543 `) 1544 1545 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command 1546 expectedAidlFlag := "-Werror" 1547 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1548 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1549 } 1550} 1551 1552func TestAidlFlagsWithMinSdkVersion(t *testing.T) { 1553 t.Parallel() 1554 fixture := android.GroupFixturePreparers( 1555 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})) 1556 1557 for _, tc := range []struct { 1558 name string 1559 sdkVersion string 1560 expected string 1561 }{ 1562 {"default is current", "", "current"}, 1563 {"use sdk_version", `sdk_version: "14"`, "14"}, 1564 {"system_current", `sdk_version: "system_current"`, "current"}, 1565 } { 1566 t.Run(tc.name, func(t *testing.T) { 1567 t.Parallel() 1568 ctx := fixture.RunTestWithBp(t, ` 1569 java_library { 1570 name: "foo", 1571 srcs: ["aidl/foo/IFoo.aidl"], 1572 `+tc.sdkVersion+` 1573 } 1574 `) 1575 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command 1576 expectedAidlFlag := "--min_sdk_version=" + tc.expected 1577 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1578 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1579 } 1580 }) 1581 } 1582} 1583 1584func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) { 1585 t.Parallel() 1586 bpTemplate := ` 1587 droidstubs { 1588 name: "foo-stubs", 1589 srcs: ["foo.aidl"], 1590 %s 1591 system_modules: "none", 1592 } 1593 ` 1594 testCases := []struct { 1595 desc string 1596 sdkVersionBp string 1597 minSdkVersionExpected string 1598 }{ 1599 { 1600 desc: "sdk_version not set, module compiles against private platform APIs", 1601 sdkVersionBp: ``, 1602 minSdkVersionExpected: "10000", 1603 }, 1604 { 1605 desc: "sdk_version set to none, module does not build against an SDK", 1606 sdkVersionBp: `sdk_version: "none",`, 1607 minSdkVersionExpected: "10000", 1608 }, 1609 } 1610 for _, tc := range testCases { 1611 ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp)) 1612 aidlCmd := ctx.ModuleForTests(t, "foo-stubs", "android_common").Rule("aidl").RuleParams.Command 1613 expected := "--min_sdk_version=" + tc.minSdkVersionExpected 1614 android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected) 1615 } 1616} 1617 1618func TestAidlEnforcePermissions(t *testing.T) { 1619 t.Parallel() 1620 ctx, _ := testJava(t, ` 1621 java_library { 1622 name: "foo", 1623 srcs: ["aidl/foo/IFoo.aidl"], 1624 aidl: { enforce_permissions: true }, 1625 } 1626 `) 1627 1628 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command 1629 expectedAidlFlag := "-Wmissing-permission-annotation -Werror" 1630 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1631 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1632 } 1633} 1634 1635func TestAidlEnforcePermissionsException(t *testing.T) { 1636 t.Parallel() 1637 ctx, _ := testJava(t, ` 1638 java_library { 1639 name: "foo", 1640 srcs: ["aidl/foo/IFoo.aidl", "aidl/foo/IFoo2.aidl"], 1641 aidl: { enforce_permissions: true, enforce_permissions_exceptions: ["aidl/foo/IFoo2.aidl"] }, 1642 } 1643 `) 1644 1645 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command 1646 expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl" 1647 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1648 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1649 } 1650 expectedAidlFlag = "$$FLAGS aidl/foo/IFoo2.aidl" 1651 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1652 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1653 } 1654} 1655 1656func TestDataNativeBinaries(t *testing.T) { 1657 t.Parallel() 1658 ctx := android.GroupFixturePreparers( 1659 prepareForJavaTest, 1660 android.PrepareForTestWithAllowMissingDependencies).RunTestWithBp(t, ` 1661 java_test_host { 1662 name: "foo", 1663 srcs: ["a.java"], 1664 data_native_bins: ["bin"] 1665 } 1666 1667 cc_binary_host { 1668 name: "bin", 1669 srcs: ["bin.cpp"], 1670 } 1671 `).TestContext 1672 1673 buildOS := ctx.Config().BuildOS.String() 1674 1675 test := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost) 1676 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0] 1677 expected := []string{"out/soong/.intermediates/bin/" + buildOS + "_x86_64/bin:bin"} 1678 actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 1679 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_COMPATIBILITY_SUPPORT_FILES", ctx.Config(), expected, actual) 1680} 1681 1682func TestDefaultInstallable(t *testing.T) { 1683 t.Parallel() 1684 ctx, _ := testJava(t, ` 1685 java_test_host { 1686 name: "foo" 1687 } 1688 `) 1689 1690 buildOS := ctx.Config().BuildOS.String() 1691 module := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost) 1692 assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true), 1693 module.properties.Installable) 1694} 1695 1696func TestErrorproneEnabled(t *testing.T) { 1697 t.Parallel() 1698 ctx, _ := testJava(t, ` 1699 java_library { 1700 name: "foo", 1701 srcs: ["a.java"], 1702 errorprone: { 1703 enabled: true, 1704 }, 1705 } 1706 `) 1707 1708 javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac") 1709 1710 // Test that the errorprone plugins are passed to javac 1711 expectedSubstring := "-Xplugin:ErrorProne" 1712 if !strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1713 t.Errorf("expected javacFlags to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1714 } 1715 1716 // Modules with errorprone { enabled: true } will include errorprone checks 1717 // in the main javac build rule. Only when RUN_ERROR_PRONE is true will 1718 // the explicit errorprone build rule be created. 1719 errorprone := ctx.ModuleForTests(t, "foo", "android_common").MaybeDescription("errorprone") 1720 if errorprone.RuleParams.Description != "" { 1721 t.Errorf("expected errorprone build rule to not exist, but it did") 1722 } 1723} 1724 1725func TestErrorproneDisabled(t *testing.T) { 1726 t.Parallel() 1727 bp := ` 1728 java_library { 1729 name: "foo", 1730 srcs: ["a.java"], 1731 errorprone: { 1732 enabled: false, 1733 }, 1734 } 1735 ` 1736 ctx := android.GroupFixturePreparers( 1737 PrepareForTestWithJavaDefaultModules, 1738 android.FixtureMergeEnv(map[string]string{ 1739 "RUN_ERROR_PRONE": "true", 1740 }), 1741 ).RunTestWithBp(t, bp) 1742 1743 javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac") 1744 1745 // Test that the errorprone plugins are not passed to javac, like they would 1746 // be if enabled was true. 1747 expectedSubstring := "-Xplugin:ErrorProne" 1748 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1749 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1750 } 1751 1752 // Check that no errorprone build rule is created, like there would be 1753 // if enabled was unset and RUN_ERROR_PRONE was true. 1754 errorprone := ctx.ModuleForTests(t, "foo", "android_common").MaybeDescription("errorprone") 1755 if errorprone.RuleParams.Description != "" { 1756 t.Errorf("expected errorprone build rule to not exist, but it did") 1757 } 1758} 1759 1760func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) { 1761 t.Parallel() 1762 bp := ` 1763 java_library { 1764 name: "foo", 1765 srcs: ["a.java"], 1766 } 1767 ` 1768 ctx := android.GroupFixturePreparers( 1769 PrepareForTestWithJavaDefaultModules, 1770 android.FixtureMergeEnv(map[string]string{ 1771 "RUN_ERROR_PRONE": "true", 1772 }), 1773 ).RunTestWithBp(t, bp) 1774 1775 javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac") 1776 errorprone := ctx.ModuleForTests(t, "foo", "android_common").Description("errorprone") 1777 1778 // Check that the errorprone plugins are not passed to javac, because they 1779 // will instead be passed to the separate errorprone compilation 1780 expectedSubstring := "-Xplugin:ErrorProne" 1781 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1782 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1783 } 1784 1785 // Check that the errorprone plugin is enabled 1786 if !strings.Contains(errorprone.Args["javacFlags"], expectedSubstring) { 1787 t.Errorf("expected errorprone to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1788 } 1789} 1790 1791func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) { 1792 t.Parallel() 1793 testCases := []struct { 1794 dataDeviceBinType string 1795 depCompileMultilib string 1796 variants []string 1797 expectedError string 1798 }{ 1799 { 1800 dataDeviceBinType: "first", 1801 depCompileMultilib: "first", 1802 variants: []string{"android_arm64_armv8-a"}, 1803 }, 1804 { 1805 dataDeviceBinType: "first", 1806 depCompileMultilib: "both", 1807 variants: []string{"android_arm64_armv8-a"}, 1808 }, 1809 { 1810 // this is true because our testing framework is set up with 1811 // Targets ~ [<64bit target>, <32bit target>], where 64bit is "first" 1812 dataDeviceBinType: "first", 1813 depCompileMultilib: "32", 1814 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1815 }, 1816 { 1817 dataDeviceBinType: "first", 1818 depCompileMultilib: "64", 1819 variants: []string{"android_arm64_armv8-a"}, 1820 }, 1821 { 1822 dataDeviceBinType: "both", 1823 depCompileMultilib: "both", 1824 variants: []string{ 1825 "android_arm_armv7-a-neon", 1826 "android_arm64_armv8-a", 1827 }, 1828 }, 1829 { 1830 dataDeviceBinType: "both", 1831 depCompileMultilib: "32", 1832 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1833 }, 1834 { 1835 dataDeviceBinType: "both", 1836 depCompileMultilib: "64", 1837 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1838 }, 1839 { 1840 dataDeviceBinType: "both", 1841 depCompileMultilib: "first", 1842 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1843 }, 1844 { 1845 dataDeviceBinType: "32", 1846 depCompileMultilib: "32", 1847 variants: []string{"android_arm_armv7-a-neon"}, 1848 }, 1849 { 1850 dataDeviceBinType: "32", 1851 depCompileMultilib: "first", 1852 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1853 }, 1854 { 1855 dataDeviceBinType: "32", 1856 depCompileMultilib: "both", 1857 variants: []string{"android_arm_armv7-a-neon"}, 1858 }, 1859 { 1860 dataDeviceBinType: "32", 1861 depCompileMultilib: "64", 1862 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1863 }, 1864 { 1865 dataDeviceBinType: "64", 1866 depCompileMultilib: "64", 1867 variants: []string{"android_arm64_armv8-a"}, 1868 }, 1869 { 1870 dataDeviceBinType: "64", 1871 depCompileMultilib: "both", 1872 variants: []string{"android_arm64_armv8-a"}, 1873 }, 1874 { 1875 dataDeviceBinType: "64", 1876 depCompileMultilib: "first", 1877 variants: []string{"android_arm64_armv8-a"}, 1878 }, 1879 { 1880 dataDeviceBinType: "64", 1881 depCompileMultilib: "32", 1882 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1883 }, 1884 { 1885 dataDeviceBinType: "prefer32", 1886 depCompileMultilib: "32", 1887 variants: []string{"android_arm_armv7-a-neon"}, 1888 }, 1889 { 1890 dataDeviceBinType: "prefer32", 1891 depCompileMultilib: "both", 1892 variants: []string{"android_arm_armv7-a-neon"}, 1893 }, 1894 { 1895 dataDeviceBinType: "prefer32", 1896 depCompileMultilib: "first", 1897 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1898 }, 1899 { 1900 dataDeviceBinType: "prefer32", 1901 depCompileMultilib: "64", 1902 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1903 }, 1904 } 1905 1906 bpTemplate := ` 1907 java_test_host { 1908 name: "foo", 1909 srcs: ["test.java"], 1910 data_device_bins_%s: ["bar"], 1911 } 1912 1913 cc_binary { 1914 name: "bar", 1915 compile_multilib: "%s", 1916 } 1917 ` 1918 1919 for _, tc := range testCases { 1920 bp := fmt.Sprintf(bpTemplate, tc.dataDeviceBinType, tc.depCompileMultilib) 1921 1922 errorHandler := android.FixtureExpectsNoErrors 1923 if tc.expectedError != "" { 1924 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError) 1925 } 1926 1927 testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib) 1928 t.Run(testName, func(t *testing.T) { 1929 t.Parallel() 1930 ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava). 1931 ExtendWithErrorHandler(errorHandler). 1932 RunTestWithBp(t, bp) 1933 if tc.expectedError != "" { 1934 return 1935 } 1936 1937 buildOS := ctx.Config.BuildOS.String() 1938 fooVariant := ctx.ModuleForTests(t, "foo", buildOS+"_common") 1939 fooMod := fooVariant.Module().(*TestHost) 1940 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0] 1941 1942 expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />` 1943 autogen := fooVariant.Rule("autogen") 1944 if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) { 1945 t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig) 1946 } 1947 1948 expectedData := []string{} 1949 for _, variant := range tc.variants { 1950 barVariant := ctx.ModuleForTests(t, "bar", variant) 1951 relocated := barVariant.Output("bar") 1952 expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant) 1953 android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input) 1954 1955 expectedData = append(expectedData, fmt.Sprintf("out/soong/.intermediates/bar/%s/bar:bar", variant)) 1956 } 1957 1958 actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 1959 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, android.SortedUniqueStrings(expectedData), android.SortedUniqueStrings(actualData)) 1960 }) 1961 } 1962} 1963 1964func TestDeviceBinaryWrapperGeneration(t *testing.T) { 1965 t.Parallel() 1966 // Scenario 1: java_binary has main_class property in its bp 1967 ctx, _ := testJava(t, ` 1968 java_binary { 1969 name: "foo", 1970 srcs: ["foo.java"], 1971 main_class: "foo.bar.jb", 1972 } 1973 `) 1974 wrapperPath := fmt.Sprint(ctx.ModuleForTests(t, "foo", "android_common").AllOutputs()) 1975 if !strings.Contains(wrapperPath, "foo.sh") { 1976 t.Errorf("wrapper file foo.sh is not generated") 1977 } 1978 1979 // Scenario 2: java_binary has neither wrapper nor main_class, its build 1980 // is expected to be failed. 1981 testJavaError(t, "main_class property is required for device binary if no default wrapper is assigned", ` 1982 java_binary { 1983 name: "foo", 1984 srcs: ["foo.java"], 1985 }`) 1986} 1987 1988func TestJavaApiContributionEmptyApiFile(t *testing.T) { 1989 t.Parallel() 1990 android.GroupFixturePreparers( 1991 prepareForJavaTest, 1992 android.FixtureMergeEnv( 1993 map[string]string{ 1994 "DISABLE_STUB_VALIDATION": "true", 1995 }, 1996 ), 1997 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 1998 "Error: foo has an empty api file.", 1999 )).RunTestWithBp(t, ` 2000 java_api_contribution { 2001 name: "foo", 2002 } 2003 java_api_library { 2004 name: "bar", 2005 api_surface: "public", 2006 api_contributions: ["foo"], 2007 stubs_type: "everything", 2008 } 2009 `) 2010} 2011 2012func TestJavaApiLibraryAndProviderLink(t *testing.T) { 2013 t.Parallel() 2014 provider_bp_a := ` 2015 java_api_contribution { 2016 name: "foo1", 2017 api_file: "current.txt", 2018 api_surface: "public", 2019 } 2020 ` 2021 provider_bp_b := `java_api_contribution { 2022 name: "foo2", 2023 api_file: "current.txt", 2024 api_surface: "public", 2025 } 2026 ` 2027 ctx := android.GroupFixturePreparers( 2028 prepareForJavaTest, 2029 android.FixtureMergeMockFs( 2030 map[string][]byte{ 2031 "a/Android.bp": []byte(provider_bp_a), 2032 "b/Android.bp": []byte(provider_bp_b), 2033 }, 2034 ), 2035 android.FixtureMergeEnv( 2036 map[string]string{ 2037 "DISABLE_STUB_VALIDATION": "true", 2038 }, 2039 ), 2040 ).RunTestWithBp(t, ` 2041 java_api_library { 2042 name: "bar1", 2043 api_surface: "public", 2044 api_contributions: ["foo1"], 2045 stubs_type: "everything", 2046 } 2047 2048 java_api_library { 2049 name: "bar2", 2050 api_surface: "system", 2051 api_contributions: ["foo1", "foo2"], 2052 stubs_type: "everything", 2053 } 2054 `) 2055 2056 testcases := []struct { 2057 moduleName string 2058 sourceTextFileDirs []string 2059 }{ 2060 { 2061 moduleName: "bar1", 2062 sourceTextFileDirs: []string{"a/current.txt"}, 2063 }, 2064 { 2065 moduleName: "bar2", 2066 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"}, 2067 }, 2068 } 2069 for _, c := range testcases { 2070 m := ctx.ModuleForTests(t, c.moduleName, "android_common") 2071 manifest := m.Output("metalava.sbox.textproto") 2072 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest) 2073 manifestCommand := sboxProto.Commands[0].GetCommand() 2074 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ") 2075 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) 2076 } 2077} 2078 2079func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { 2080 t.Parallel() 2081 provider_bp_a := ` 2082 java_api_contribution { 2083 name: "foo1", 2084 api_file: "current.txt", 2085 api_surface: "public", 2086 } 2087 ` 2088 provider_bp_b := ` 2089 java_api_contribution { 2090 name: "foo2", 2091 api_file: "current.txt", 2092 api_surface: "public", 2093 } 2094 ` 2095 provider_bp_c := ` 2096 java_api_contribution { 2097 name: "foo3", 2098 api_file: "system-current.txt", 2099 api_surface: "system", 2100 } 2101 ` 2102 provider_bp_d := ` 2103 java_api_contribution { 2104 name: "foo4", 2105 api_file: "system-current.txt", 2106 api_surface: "system", 2107 } 2108 ` 2109 ctx := android.GroupFixturePreparers( 2110 prepareForJavaTest, 2111 android.FixtureMergeMockFs( 2112 map[string][]byte{ 2113 "a/Android.bp": []byte(provider_bp_a), 2114 "b/Android.bp": []byte(provider_bp_b), 2115 "c/Android.bp": []byte(provider_bp_c), 2116 "d/Android.bp": []byte(provider_bp_d), 2117 }, 2118 ), 2119 android.FixtureMergeEnv( 2120 map[string]string{ 2121 "DISABLE_STUB_VALIDATION": "true", 2122 }, 2123 ), 2124 ).RunTestWithBp(t, ` 2125 java_defaults { 2126 name: "baz1", 2127 api_surface: "public", 2128 api_contributions: ["foo1", "foo2"], 2129 } 2130 2131 java_defaults { 2132 name: "baz2", 2133 api_surface: "system", 2134 api_contributions: ["foo3"], 2135 } 2136 2137 java_api_library { 2138 name: "bar1", 2139 api_surface: "public", 2140 api_contributions: ["foo1"], 2141 stubs_type: "everything", 2142 } 2143 2144 java_api_library { 2145 name: "bar2", 2146 api_surface: "public", 2147 defaults:["baz1"], 2148 stubs_type: "everything", 2149 } 2150 2151 java_api_library { 2152 name: "bar3", 2153 api_surface: "system", 2154 defaults:["baz1", "baz2"], 2155 api_contributions: ["foo4"], 2156 stubs_type: "everything", 2157 } 2158 `) 2159 2160 testcases := []struct { 2161 moduleName string 2162 sourceTextFileDirs []string 2163 }{ 2164 { 2165 moduleName: "bar1", 2166 sourceTextFileDirs: []string{"a/current.txt"}, 2167 }, 2168 { 2169 moduleName: "bar2", 2170 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"}, 2171 }, 2172 { 2173 moduleName: "bar3", 2174 // API text files need to be sorted from the narrower api scope to the wider api scope 2175 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "c/system-current.txt", "d/system-current.txt"}, 2176 }, 2177 } 2178 for _, c := range testcases { 2179 m := ctx.ModuleForTests(t, c.moduleName, "android_common") 2180 manifest := m.Output("metalava.sbox.textproto") 2181 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest) 2182 manifestCommand := sboxProto.Commands[0].GetCommand() 2183 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ") 2184 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) 2185 } 2186} 2187 2188func TestJavaApiLibraryJarGeneration(t *testing.T) { 2189 t.Parallel() 2190 provider_bp_a := ` 2191 java_api_contribution { 2192 name: "foo1", 2193 api_file: "current.txt", 2194 api_surface: "public", 2195 } 2196 ` 2197 provider_bp_b := ` 2198 java_api_contribution { 2199 name: "foo2", 2200 api_file: "current.txt", 2201 api_surface: "public", 2202 } 2203 ` 2204 ctx := android.GroupFixturePreparers( 2205 prepareForJavaTest, 2206 android.FixtureMergeMockFs( 2207 map[string][]byte{ 2208 "a/Android.bp": []byte(provider_bp_a), 2209 "b/Android.bp": []byte(provider_bp_b), 2210 }, 2211 ), 2212 android.FixtureMergeEnv( 2213 map[string]string{ 2214 "DISABLE_STUB_VALIDATION": "true", 2215 }, 2216 ), 2217 ).RunTestWithBp(t, ` 2218 java_api_library { 2219 name: "bar1", 2220 api_surface: "public", 2221 api_contributions: ["foo1"], 2222 stubs_type: "everything", 2223 } 2224 2225 java_api_library { 2226 name: "bar2", 2227 api_surface: "system", 2228 api_contributions: ["foo1", "foo2"], 2229 stubs_type: "everything", 2230 } 2231 `) 2232 2233 testcases := []struct { 2234 moduleName string 2235 outputJarName string 2236 }{ 2237 { 2238 moduleName: "bar1", 2239 outputJarName: "bar1/bar1.jar", 2240 }, 2241 { 2242 moduleName: "bar2", 2243 outputJarName: "bar2/bar2.jar", 2244 }, 2245 } 2246 for _, c := range testcases { 2247 m := ctx.ModuleForTests(t, c.moduleName, "android_common") 2248 outputs := fmt.Sprint(m.AllOutputs()) 2249 if !strings.Contains(outputs, c.outputJarName) { 2250 t.Errorf("Module output does not contain expected jar %s", c.outputJarName) 2251 } 2252 } 2253} 2254 2255func TestJavaApiLibraryLibsLink(t *testing.T) { 2256 t.Parallel() 2257 provider_bp_a := ` 2258 java_api_contribution { 2259 name: "foo1", 2260 api_file: "current.txt", 2261 api_surface: "public", 2262 } 2263 ` 2264 provider_bp_b := ` 2265 java_api_contribution { 2266 name: "foo2", 2267 api_file: "current.txt", 2268 api_surface: "public", 2269 } 2270 ` 2271 lib_bp_a := ` 2272 java_library { 2273 name: "lib1", 2274 srcs: ["Lib.java"], 2275 } 2276 ` 2277 lib_bp_b := ` 2278 java_library { 2279 name: "lib2", 2280 srcs: ["Lib.java"], 2281 } 2282 ` 2283 2284 ctx := android.GroupFixturePreparers( 2285 prepareForJavaTest, 2286 android.FixtureMergeMockFs( 2287 map[string][]byte{ 2288 "a/Android.bp": []byte(provider_bp_a), 2289 "b/Android.bp": []byte(provider_bp_b), 2290 "c/Android.bp": []byte(lib_bp_a), 2291 "c/Lib.java": {}, 2292 "d/Android.bp": []byte(lib_bp_b), 2293 "d/Lib.java": {}, 2294 }, 2295 ), 2296 android.FixtureMergeEnv( 2297 map[string]string{ 2298 "DISABLE_STUB_VALIDATION": "true", 2299 }, 2300 ), 2301 ).RunTestWithBp(t, ` 2302 java_api_library { 2303 name: "bar1", 2304 api_surface: "public", 2305 api_contributions: ["foo1"], 2306 libs: ["lib1"], 2307 stubs_type: "everything", 2308 } 2309 2310 java_api_library { 2311 name: "bar2", 2312 api_surface: "system", 2313 api_contributions: ["foo1", "foo2"], 2314 libs: ["lib1", "lib2", "bar1"], 2315 stubs_type: "everything", 2316 } 2317 `) 2318 2319 testcases := []struct { 2320 moduleName string 2321 classPathJarNames []string 2322 }{ 2323 { 2324 moduleName: "bar1", 2325 classPathJarNames: []string{"lib1.jar"}, 2326 }, 2327 { 2328 moduleName: "bar2", 2329 classPathJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"}, 2330 }, 2331 } 2332 for _, c := range testcases { 2333 m := ctx.ModuleForTests(t, c.moduleName, "android_common") 2334 javacRules := m.Rule("javac") 2335 classPathArgs := javacRules.Args["classpath"] 2336 for _, jarName := range c.classPathJarNames { 2337 if !strings.Contains(classPathArgs, jarName) { 2338 t.Errorf("Module output does not contain expected jar %s", jarName) 2339 } 2340 } 2341 } 2342} 2343 2344func TestJavaApiLibraryStaticLibsLink(t *testing.T) { 2345 t.Parallel() 2346 provider_bp_a := ` 2347 java_api_contribution { 2348 name: "foo1", 2349 api_file: "current.txt", 2350 api_surface: "public", 2351 } 2352 ` 2353 provider_bp_b := ` 2354 java_api_contribution { 2355 name: "foo2", 2356 api_file: "current.txt", 2357 api_surface: "public", 2358 } 2359 ` 2360 lib_bp_a := ` 2361 java_library { 2362 name: "lib1", 2363 srcs: ["Lib.java"], 2364 } 2365 ` 2366 lib_bp_b := ` 2367 java_library { 2368 name: "lib2", 2369 srcs: ["Lib.java"], 2370 } 2371 ` 2372 2373 ctx := android.GroupFixturePreparers( 2374 prepareForJavaTest, 2375 android.FixtureMergeMockFs( 2376 map[string][]byte{ 2377 "a/Android.bp": []byte(provider_bp_a), 2378 "b/Android.bp": []byte(provider_bp_b), 2379 "c/Android.bp": []byte(lib_bp_a), 2380 "c/Lib.java": {}, 2381 "d/Android.bp": []byte(lib_bp_b), 2382 "d/Lib.java": {}, 2383 }, 2384 ), 2385 android.FixtureMergeEnv( 2386 map[string]string{ 2387 "DISABLE_STUB_VALIDATION": "true", 2388 }, 2389 ), 2390 ).RunTestWithBp(t, ` 2391 java_api_library { 2392 name: "bar1", 2393 api_surface: "public", 2394 api_contributions: ["foo1"], 2395 static_libs: ["lib1"], 2396 stubs_type: "everything", 2397 } 2398 2399 java_api_library { 2400 name: "bar2", 2401 api_surface: "system", 2402 api_contributions: ["foo1", "foo2"], 2403 static_libs: ["lib1", "lib2", "bar1"], 2404 stubs_type: "everything", 2405 } 2406 `) 2407 2408 testcases := []struct { 2409 moduleName string 2410 staticLibJarNames []string 2411 }{ 2412 { 2413 moduleName: "bar1", 2414 staticLibJarNames: []string{"lib1.jar"}, 2415 }, 2416 { 2417 moduleName: "bar2", 2418 staticLibJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"}, 2419 }, 2420 } 2421 for _, c := range testcases { 2422 m := ctx.ModuleForTests(t, c.moduleName, "android_common") 2423 mergeZipsCommand := m.Rule("merge_zips").RuleParams.Command 2424 for _, jarName := range c.staticLibJarNames { 2425 if !strings.Contains(mergeZipsCommand, jarName) { 2426 t.Errorf("merge_zips command does not contain expected jar %s", jarName) 2427 } 2428 } 2429 } 2430} 2431 2432func TestTransitiveSrcFiles(t *testing.T) { 2433 t.Parallel() 2434 ctx, _ := testJava(t, ` 2435 java_library { 2436 name: "a", 2437 srcs: ["a.java"], 2438 } 2439 java_library { 2440 name: "b", 2441 srcs: ["b.java"], 2442 } 2443 java_library { 2444 name: "c", 2445 srcs: ["c.java"], 2446 libs: ["a"], 2447 static_libs: ["b"], 2448 } 2449 `) 2450 c := ctx.ModuleForTests(t, "c", "android_common").Module() 2451 javaInfo, _ := android.OtherModuleProvider(ctx, c, JavaInfoProvider) 2452 transitiveSrcFiles := android.Paths(javaInfo.TransitiveSrcFiles.ToList()) 2453 android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings()) 2454} 2455 2456func TestTradefedOptions(t *testing.T) { 2457 t.Parallel() 2458 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, ` 2459java_test_host { 2460 name: "foo", 2461 test_options: { 2462 tradefed_options: [ 2463 { 2464 name: "exclude-path", 2465 value: "org/apache" 2466 } 2467 ] 2468 } 2469} 2470`) 2471 2472 buildOS := result.Config.BuildOS.String() 2473 args := result.ModuleForTests(t, "foo", buildOS+"_common"). 2474 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args 2475 expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />") 2476 if args["extraConfigs"] != expected { 2477 t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"]) 2478 } 2479} 2480 2481func TestTestRunnerOptions(t *testing.T) { 2482 t.Parallel() 2483 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, ` 2484java_test_host { 2485 name: "foo", 2486 test_options: { 2487 test_runner_options: [ 2488 { 2489 name: "test-timeout", 2490 value: "10m" 2491 } 2492 ] 2493 } 2494} 2495`) 2496 2497 buildOS := result.Config.BuildOS.String() 2498 args := result.ModuleForTests(t, "foo", buildOS+"_common"). 2499 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args 2500 expected := proptools.NinjaAndShellEscape("<option name=\"test-timeout\" value=\"10m\" />\\n ") 2501 if args["extraTestRunnerConfigs"] != expected { 2502 t.Errorf("Expected args[\"extraTestRunnerConfigs\"] to equal %q, was %q", expected, args["extraTestRunnerConfigs"]) 2503 } 2504} 2505 2506func TestJavaLibraryWithResourcesStem(t *testing.T) { 2507 t.Parallel() 2508 ctx, _ := testJavaWithFS(t, ` 2509 java_library { 2510 name: "foo", 2511 java_resource_dirs: ["test-jar"], 2512 stem: "test", 2513 } 2514 `, 2515 map[string][]byte{ 2516 "test-jar/test/resource.txt": nil, 2517 }) 2518 2519 m := ctx.ModuleForTests(t, "foo", "android_common") 2520 outputs := fmt.Sprint(m.AllOutputs()) 2521 if !strings.Contains(outputs, "test.jar") { 2522 t.Errorf("Module output does not contain expected jar %s", "test.jar") 2523 } 2524} 2525 2526func TestHeadersOnly(t *testing.T) { 2527 t.Parallel() 2528 ctx, _ := testJava(t, ` 2529 java_library { 2530 name: "foo", 2531 srcs: ["a.java"], 2532 headers_only: true, 2533 } 2534 `) 2535 2536 turbine := ctx.ModuleForTests(t, "foo", "android_common").Rule("turbine") 2537 if len(turbine.Inputs) != 1 || turbine.Inputs[0].String() != "a.java" { 2538 t.Errorf(`foo inputs %v != ["a.java"]`, turbine.Inputs) 2539 } 2540 2541 javac := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("javac") 2542 android.AssertDeepEquals(t, "javac rule", nil, javac.Rule) 2543} 2544 2545func TestJavaApiContributionImport(t *testing.T) { 2546 t.Parallel() 2547 ctx := android.GroupFixturePreparers( 2548 prepareForJavaTest, 2549 android.FixtureMergeEnv( 2550 map[string]string{ 2551 "DISABLE_STUB_VALIDATION": "true", 2552 }, 2553 ), 2554 ).RunTestWithBp(t, ` 2555 java_api_library { 2556 name: "foo", 2557 api_contributions: ["bar"], 2558 stubs_type: "everything", 2559 } 2560 java_api_contribution_import { 2561 name: "bar", 2562 api_file: "current.txt", 2563 api_surface: "public", 2564 } 2565 `) 2566 m := ctx.ModuleForTests(t, "foo", "android_common") 2567 manifest := m.Output("metalava.sbox.textproto") 2568 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest) 2569 manifestCommand := sboxProto.Commands[0].GetCommand() 2570 sourceFilesFlag := "--source-files current.txt" 2571 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) 2572} 2573 2574func TestJavaApiLibraryApiFilesSorting(t *testing.T) { 2575 t.Parallel() 2576 ctx, _ := testJava(t, ` 2577 java_api_library { 2578 name: "foo", 2579 api_contributions: [ 2580 "system-server-api-stubs-docs-non-updatable.api.contribution", 2581 "test-api-stubs-docs-non-updatable.api.contribution", 2582 "system-api-stubs-docs-non-updatable.api.contribution", 2583 "module-lib-api-stubs-docs-non-updatable.api.contribution", 2584 "api-stubs-docs-non-updatable.api.contribution", 2585 ], 2586 stubs_type: "everything", 2587 } 2588 `) 2589 m := ctx.ModuleForTests(t, "foo", "android_common") 2590 manifest := m.Output("metalava.sbox.textproto") 2591 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest) 2592 manifestCommand := sboxProto.Commands[0].GetCommand() 2593 2594 // Api files are sorted from the narrowest api scope to the widest api scope. 2595 // test api and module lib api surface do not have subset/superset relationship, 2596 // but they will never be passed as inputs at the same time. 2597 sourceFilesFlag := "--source-files default/java/api/current.txt " + 2598 "default/java/api/system-current.txt default/java/api/test-current.txt " + 2599 "default/java/api/module-lib-current.txt default/java/api/system-server-current.txt" 2600 android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag) 2601} 2602 2603func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) { 2604 t.Parallel() 2605 result := android.GroupFixturePreparers( 2606 prepareForJavaTest, 2607 PrepareForTestWithJavaSdkLibraryFiles, 2608 FixtureWithLastReleaseApis("foo"), 2609 android.FixtureMergeMockFs( 2610 map[string][]byte{ 2611 "A.java": nil, 2612 }, 2613 ), 2614 ).RunTestWithBp(t, ` 2615 java_library { 2616 name: "bar", 2617 srcs: ["a.java"], 2618 } 2619 java_system_modules { 2620 name: "baz", 2621 libs: ["bar"], 2622 } 2623 java_sdk_library { 2624 name: "foo", 2625 srcs: ["A.java"], 2626 system_modules: "baz", 2627 } 2628 `) 2629 2630 checkBootClasspathForLibWithSystemModule(t, result.TestContext, apiScopePublic.apiLibraryModuleName("foo"), "/bar.jar") 2631} 2632 2633func TestApiLibraryDroidstubsDependency(t *testing.T) { 2634 t.Parallel() 2635 result := android.GroupFixturePreparers( 2636 prepareForJavaTest, 2637 PrepareForTestWithJavaSdkLibraryFiles, 2638 FixtureWithLastReleaseApis("foo"), 2639 android.FixtureMergeMockFs( 2640 map[string][]byte{ 2641 "A.java": nil, 2642 }, 2643 ), 2644 ).RunTestWithBp(t, ` 2645 java_api_library { 2646 name: "foo", 2647 api_contributions: [ 2648 "api-stubs-docs-non-updatable.api.contribution", 2649 ], 2650 enable_validation: true, 2651 stubs_type: "everything", 2652 } 2653 java_api_library { 2654 name: "bar", 2655 api_contributions: [ 2656 "api-stubs-docs-non-updatable.api.contribution", 2657 ], 2658 enable_validation: false, 2659 stubs_type: "everything", 2660 } 2661 `) 2662 2663 currentApiTimestampPath := "api-stubs-docs-non-updatable/android_common/everything/check_current_api.timestamp" 2664 foo := result.ModuleForTests(t, "foo", "android_common").Module().(*ApiLibrary) 2665 fooValidationPathsString := strings.Join(foo.validationPaths.Strings(), " ") 2666 bar := result.ModuleForTests(t, "bar", "android_common").Module().(*ApiLibrary) 2667 barValidationPathsString := strings.Join(bar.validationPaths.Strings(), " ") 2668 android.AssertStringDoesContain(t, 2669 "Module expected to have validation", 2670 fooValidationPathsString, 2671 currentApiTimestampPath, 2672 ) 2673 android.AssertStringDoesNotContain(t, 2674 "Module expected to not have validation", 2675 barValidationPathsString, 2676 currentApiTimestampPath, 2677 ) 2678} 2679 2680func TestDisableFromTextStubForCoverageBuild(t *testing.T) { 2681 t.Parallel() 2682 result := android.GroupFixturePreparers( 2683 prepareForJavaTest, 2684 PrepareForTestWithJavaSdkLibraryFiles, 2685 PrepareForTestWithJacocoInstrumentation, 2686 FixtureWithLastReleaseApis("foo"), 2687 android.FixtureModifyConfig(func(config android.Config) { 2688 config.SetBuildFromTextStub(true) 2689 }), 2690 android.FixtureModifyEnv(func(env map[string]string) { 2691 env["EMMA_INSTRUMENT"] = "true" 2692 }), 2693 ).RunTestWithBp(t, ` 2694 java_sdk_library { 2695 name: "foo", 2696 srcs: ["A.java"], 2697 } 2698 `) 2699 android.AssertBoolEquals(t, "stub module expected to depend on from-source stub", 2700 true, CheckModuleHasDependency(t, result.TestContext, 2701 apiScopePublic.stubsLibraryModuleName("foo"), "android_common", 2702 apiScopePublic.sourceStubsLibraryModuleName("foo"))) 2703 2704 android.AssertBoolEquals(t, "stub module expected to not depend on from-text stub", 2705 false, CheckModuleHasDependency(t, result.TestContext, 2706 apiScopePublic.stubsLibraryModuleName("foo"), "android_common", 2707 apiScopePublic.apiLibraryModuleName("foo"))) 2708} 2709 2710func TestMultiplePrebuilts(t *testing.T) { 2711 t.Parallel() 2712 bp := ` 2713 // an rdep 2714 java_library { 2715 name: "foo", 2716 libs: ["bar"], 2717 } 2718 2719 // multiple variations of dep 2720 // source 2721 java_library { 2722 name: "bar", 2723 srcs: ["bar.java"], 2724 } 2725 // prebuilt "v1" 2726 java_import { 2727 name: "bar", 2728 jars: ["bar.jar"], 2729 } 2730 // prebuilt "v2" 2731 java_import { 2732 name: "bar.v2", 2733 source_module_name: "bar", 2734 jars: ["bar.v1.jar"], 2735 } 2736 2737 // selectors 2738 apex_contributions { 2739 name: "myapex_contributions", 2740 contents: ["%v"], 2741 } 2742 ` 2743 hasDep := func(ctx *android.TestResult, m android.Module, wantDep android.Module) bool { 2744 t.Helper() 2745 var found bool 2746 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 2747 if dep == wantDep { 2748 found = true 2749 } 2750 }) 2751 return found 2752 } 2753 2754 hasFileWithStem := func(m android.TestingModule, stem string) bool { 2755 t.Helper() 2756 for _, o := range m.AllOutputs() { 2757 _, file := filepath.Split(o) 2758 if file == stem+".jar" { 2759 return true 2760 } 2761 } 2762 return false 2763 } 2764 2765 testCases := []struct { 2766 desc string 2767 selectedDependencyName string 2768 expectedDependencyName string 2769 }{ 2770 { 2771 desc: "Source library is selected using apex_contributions", 2772 selectedDependencyName: "bar", 2773 expectedDependencyName: "bar", 2774 }, 2775 { 2776 desc: "Prebuilt library v1 is selected using apex_contributions", 2777 selectedDependencyName: "prebuilt_bar", 2778 expectedDependencyName: "prebuilt_bar", 2779 }, 2780 { 2781 desc: "Prebuilt library v2 is selected using apex_contributions", 2782 selectedDependencyName: "prebuilt_bar.v2", 2783 expectedDependencyName: "prebuilt_bar.v2", 2784 }, 2785 } 2786 2787 for _, tc := range testCases { 2788 ctx := android.GroupFixturePreparers( 2789 prepareForJavaTest, 2790 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"), 2791 ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName)) 2792 2793 // check that rdep gets the correct variation of dep 2794 foo := ctx.ModuleForTests(t, "foo", "android_common") 2795 expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_common") 2796 android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module())) 2797 2798 // check that output file of dep is always bar.jar 2799 // The filename should be agnostic to source/prebuilt/prebuilt_version 2800 android.AssertBoolEquals(t, fmt.Sprintf("could not find bar.jar in outputs of %s. All Outputs %v\n", tc.expectedDependencyName, expectedDependency.AllOutputs()), true, hasFileWithStem(expectedDependency, "bar")) 2801 2802 // check LOCAL_MODULE of the selected module name 2803 // the prebuilt should have the same LOCAL_MODULE when exported to make 2804 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, expectedDependency.Module())[0] 2805 android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "bar", entries.EntryMap["LOCAL_MODULE"][0]) 2806 } 2807} 2808 2809func TestMultiplePlatformCompatConfigPrebuilts(t *testing.T) { 2810 t.Parallel() 2811 bp := ` 2812 // multiple variations of platform_compat_config 2813 // source 2814 platform_compat_config { 2815 name: "myconfig", 2816 } 2817 // prebuilt "v1" 2818 prebuilt_platform_compat_config { 2819 name: "myconfig", 2820 metadata: "myconfig.xml", 2821 } 2822 // prebuilt "v2" 2823 prebuilt_platform_compat_config { 2824 name: "myconfig.v2", 2825 source_module_name: "myconfig", // without source_module_name, the singleton will merge two .xml files 2826 metadata: "myconfig.v2.xml", 2827 } 2828 2829 // selectors 2830 apex_contributions { 2831 name: "myapex_contributions", 2832 contents: ["%v"], 2833 } 2834 ` 2835 testCases := []struct { 2836 desc string 2837 selectedDependencyName string 2838 expectedPlatformCompatConfigXml string 2839 }{ 2840 { 2841 desc: "Source platform_compat_config is selected using apex_contributions", 2842 selectedDependencyName: "myconfig", 2843 expectedPlatformCompatConfigXml: "out/soong/.intermediates/myconfig/android_common/myconfig_meta.xml", 2844 }, 2845 { 2846 desc: "Prebuilt platform_compat_config v1 is selected using apex_contributions", 2847 selectedDependencyName: "prebuilt_myconfig", 2848 expectedPlatformCompatConfigXml: "myconfig.xml", 2849 }, 2850 { 2851 desc: "Prebuilt platform_compat_config v2 is selected using apex_contributions", 2852 selectedDependencyName: "prebuilt_myconfig.v2", 2853 expectedPlatformCompatConfigXml: "myconfig.v2.xml", 2854 }, 2855 } 2856 2857 for _, tc := range testCases { 2858 ctx := android.GroupFixturePreparers( 2859 prepareForJavaTest, 2860 PrepareForTestWithPlatformCompatConfig, 2861 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"), 2862 ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName)) 2863 2864 mergedGlobalConfig := ctx.SingletonForTests(t, "platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml") 2865 android.AssertIntEquals(t, "The merged compat config file should only have a single dependency", 1, len(mergedGlobalConfig.Implicits)) 2866 android.AssertStringEquals(t, "The merged compat config file is missing the appropriate platform compat config", mergedGlobalConfig.Implicits[0].String(), tc.expectedPlatformCompatConfigXml) 2867 } 2868} 2869 2870func TestApiLibraryAconfigDeclarations(t *testing.T) { 2871 t.Parallel() 2872 result := android.GroupFixturePreparers( 2873 prepareForJavaTest, 2874 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2875 }), 2876 android.FixtureMergeMockFs(map[string][]byte{ 2877 "a/A.java": nil, 2878 "a/current.txt": nil, 2879 "a/removed.txt": nil, 2880 }), 2881 ).RunTestWithBp(t, ` 2882 aconfig_declarations { 2883 name: "bar", 2884 package: "com.example.package", 2885 container: "com.android.foo", 2886 srcs: [ 2887 "bar.aconfig", 2888 ], 2889 } 2890 java_api_contribution { 2891 name: "baz", 2892 api_file: "a/current.txt", 2893 api_surface: "public", 2894 } 2895 java_api_library { 2896 name: "foo", 2897 api_surface: "public", 2898 api_contributions: [ 2899 "baz", 2900 ], 2901 aconfig_declarations: [ 2902 "bar", 2903 ], 2904 stubs_type: "exportable", 2905 enable_validation: false, 2906 } 2907 `) 2908 2909 // Check if java_api_library depends on aconfig_declarations 2910 android.AssertBoolEquals(t, "foo expected to depend on bar", 2911 CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true) 2912 2913 m := result.ModuleForTests(t, "foo", "android_common") 2914 android.AssertStringDoesContain(t, "foo generates revert annotations file", 2915 strings.Join(m.AllOutputs(), ""), "flags-config-exportable.xml") 2916 2917 // revert-annotations.txt passed to exportable stubs generation metalava command 2918 manifest := m.Output("metalava.sbox.textproto") 2919 cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command) 2920 android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "flags-config-exportable.xml") 2921} 2922 2923func TestTestOnly(t *testing.T) { 2924 t.Parallel() 2925 ctx := android.GroupFixturePreparers( 2926 prepareForJavaTest, 2927 ).RunTestWithBp(t, ` 2928 // These should be test-only 2929 java_library { 2930 name: "lib1-test-only", 2931 srcs: ["a.java"], 2932 test_only: true, 2933 } 2934 java_test { 2935 name: "java-test", 2936 } 2937 java_test_host { 2938 name: "java-test-host", 2939 } 2940 java_test_helper_library { 2941 name: "helper-library", 2942 } 2943 java_binary { 2944 name: "java-data-binary", 2945 srcs: ["foo.java"], 2946 main_class: "foo.bar.jb", 2947 test_only: true, 2948 } 2949 2950 // These are NOT 2951 java_library { 2952 name: "lib2-app", 2953 srcs: ["b.java"], 2954 } 2955 java_import { 2956 name: "bar", 2957 jars: ["bar.jar"], 2958 } 2959 java_binary { 2960 name: "java-binary", 2961 srcs: ["foo.java"], 2962 main_class: "foo.bar.jb", 2963 } 2964 `) 2965 2966 expectedTestOnlyModules := []string{ 2967 "lib1-test-only", 2968 "java-test", 2969 "java-test-host", 2970 "helper-library", 2971 "java-data-binary", 2972 } 2973 expectedTopLevelTests := []string{ 2974 "java-test", 2975 "java-test-host", 2976 } 2977 assertTestOnlyAndTopLevel(t, ctx, expectedTestOnlyModules, expectedTopLevelTests) 2978} 2979 2980// Don't allow setting test-only on things that are always tests or never tests. 2981func TestInvalidTestOnlyTargets(t *testing.T) { 2982 t.Parallel() 2983 testCases := []string{ 2984 ` java_test { name: "java-test", test_only: true, srcs: ["foo.java"], } `, 2985 ` java_test_host { name: "java-test-host", test_only: true, srcs: ["foo.java"], } `, 2986 ` java_test_import { name: "java-test-import", test_only: true, } `, 2987 ` java_api_library { name: "java-api-library", test_only: true, } `, 2988 ` java_test_helper_library { name: "test-help-lib", test_only: true, } `, 2989 ` java_defaults { name: "java-defaults", test_only: true, } `, 2990 } 2991 2992 for i, bp := range testCases { 2993 android.GroupFixturePreparers(prepareForJavaTest). 2994 ExtendWithErrorHandler( 2995 expectOneError("unrecognized property \"test_only\"", 2996 fmt.Sprintf("testcase: %d", i))). 2997 RunTestWithBp(t, bp) 2998 } 2999} 3000 3001// Expect exactly one that matches 'expected'. 3002// Append 'msg' to the Errorf that printed. 3003func expectOneError(expected string, msg string) android.FixtureErrorHandler { 3004 return android.FixtureCustomErrorHandler(func(t *testing.T, result *android.TestResult) { 3005 t.Helper() 3006 if len(result.Errs) != 1 { 3007 t.Errorf("Expected exactly one error, but found: %d when setting test_only on: %s", len(result.Errs), msg) 3008 return 3009 } 3010 actualErrMsg := result.Errs[0].Error() 3011 if !strings.Contains(actualErrMsg, expected) { 3012 t.Errorf("Different error than expected. Received: [%v] on %s expected: %s", actualErrMsg, msg, expected) 3013 } 3014 }) 3015} 3016 3017func TestJavaLibHostWithStem(t *testing.T) { 3018 t.Parallel() 3019 ctx, _ := testJava(t, ` 3020 java_library_host { 3021 name: "foo", 3022 srcs: ["a.java"], 3023 stem: "foo-new", 3024 } 3025 `) 3026 3027 buildOS := ctx.Config().BuildOS.String() 3028 foo := ctx.ModuleForTests(t, "foo", buildOS+"_common") 3029 3030 outputs := fmt.Sprint(foo.AllOutputs()) 3031 if !strings.Contains(outputs, "foo-new.jar") { 3032 t.Errorf("Module output does not contain expected jar %s", "foo-new.jar") 3033 } 3034} 3035 3036func TestJavaLibWithStem(t *testing.T) { 3037 t.Parallel() 3038 ctx, _ := testJava(t, ` 3039 java_library { 3040 name: "foo", 3041 srcs: ["a.java"], 3042 stem: "foo-new", 3043 } 3044 `) 3045 3046 foo := ctx.ModuleForTests(t, "foo", "android_common") 3047 3048 outputs := fmt.Sprint(foo.AllOutputs()) 3049 if !strings.Contains(outputs, "foo-new.jar") { 3050 t.Errorf("Module output does not contain expected jar %s", "foo-new.jar") 3051 } 3052} 3053 3054func TestJavaLibraryOutputFilesRel(t *testing.T) { 3055 t.Parallel() 3056 result := android.GroupFixturePreparers( 3057 PrepareForTestWithJavaDefaultModules, 3058 ).RunTestWithBp(t, ` 3059 java_library { 3060 name: "foo", 3061 srcs: ["a.java"], 3062 } 3063 3064 java_import { 3065 name: "bar", 3066 jars: ["bar.aar"], 3067 3068 } 3069 3070 java_import { 3071 name: "baz", 3072 jars: ["baz.aar"], 3073 static_libs: ["bar"], 3074 } 3075 `) 3076 3077 foo := result.ModuleForTests(t, "foo", "android_common") 3078 bar := result.ModuleForTests(t, "bar", "android_common") 3079 baz := result.ModuleForTests(t, "baz", "android_common") 3080 3081 fooOutputPaths := foo.OutputFiles(result.TestContext, t, "") 3082 barOutputPaths := bar.OutputFiles(result.TestContext, t, "") 3083 bazOutputPaths := baz.OutputFiles(result.TestContext, t, "") 3084 3085 android.AssertPathsRelativeToTopEquals(t, "foo output path", 3086 []string{"out/soong/.intermediates/foo/android_common/javac/foo.jar"}, fooOutputPaths) 3087 android.AssertPathsRelativeToTopEquals(t, "bar output path", 3088 []string{"out/soong/.intermediates/bar/android_common/combined/bar.jar"}, barOutputPaths) 3089 android.AssertPathsRelativeToTopEquals(t, "baz output path", 3090 []string{"out/soong/.intermediates/baz/android_common/combined/baz.jar"}, bazOutputPaths) 3091 3092 android.AssertStringEquals(t, "foo relative output path", 3093 "foo.jar", fooOutputPaths[0].Rel()) 3094 android.AssertStringEquals(t, "bar relative output path", 3095 "bar.jar", barOutputPaths[0].Rel()) 3096 android.AssertStringEquals(t, "baz relative output path", 3097 "baz.jar", bazOutputPaths[0].Rel()) 3098} 3099 3100func TestCoverage(t *testing.T) { 3101 t.Parallel() 3102 result := android.GroupFixturePreparers( 3103 PrepareForTestWithJavaDefaultModules, 3104 prepareForTestWithFrameworkJacocoInstrumentation, 3105 ).RunTestWithBp(t, ` 3106 android_app { 3107 name: "foo", 3108 srcs: ["foo.java"], 3109 static_libs: ["android.car"], 3110 platform_apis: true, 3111 } 3112 3113 // A library in InstrumentFrameworkModules 3114 java_library { 3115 name: "android.car", 3116 srcs: ["android.car.java"], 3117 installable: true, 3118 } 3119 `) 3120 3121 foo := result.ModuleForTests(t, "foo", "android_common") 3122 androidCar := result.ModuleForTests(t, "android.car", "android_common") 3123 3124 fooJacoco := foo.Rule("jacoco") 3125 fooCombine := foo.Description("for javac") 3126 3127 androidCarJacoco := androidCar.Rule("jacoco") 3128 androidCarJavac := androidCar.Rule("javac") 3129 3130 android.AssertStringEquals(t, "foo instrumentation rule inputs", fooJacoco.Input.String(), fooCombine.Output.String()) 3131 android.AssertStringEquals(t, "android.car instrumentation rule inputs", androidCarJacoco.Input.String(), androidCarJavac.Output.String()) 3132 3133 // The input to instrumentation for the `foo` app contains the non-instrumented android.car classes. 3134 android.AssertStringListContains(t, "foo combined inputs", fooCombine.Inputs.Strings(), androidCarJavac.Output.String()) 3135 android.AssertStringListDoesNotContain(t, "foo combined inputs", fooCombine.Inputs.Strings(), androidCarJacoco.Output.String()) 3136} 3137 3138func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) { 3139 t.Helper() 3140 actualTrueModules := []string{} 3141 actualTopLevelTests := []string{} 3142 addActuals := func(m blueprint.Module, key blueprint.ProviderKey[android.TestModuleInformation]) { 3143 if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, key); ok { 3144 if provider.TestOnly { 3145 actualTrueModules = append(actualTrueModules, m.Name()) 3146 } 3147 if provider.TopLevelTarget { 3148 actualTopLevelTests = append(actualTopLevelTests, m.Name()) 3149 } 3150 } 3151 } 3152 3153 ctx.VisitAllModules(func(m blueprint.Module) { 3154 addActuals(m, android.TestOnlyProviderKey) 3155 3156 }) 3157 3158 notEqual, left, right := android.ListSetDifference(expectedTestOnly, actualTrueModules) 3159 if notEqual { 3160 t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right) 3161 } 3162 3163 notEqual, left, right = android.ListSetDifference(expectedTopLevel, actualTopLevelTests) 3164 if notEqual { 3165 t.Errorf("top-level: Expected but not found: %v, Found but not expected: %v", left, right) 3166 } 3167} 3168 3169// Test that a dependency edge is created to the matching variant of a native library listed in `jni_libs` of java_binary 3170func TestNativeRequiredDepOfJavaBinary(t *testing.T) { 3171 t.Parallel() 3172 findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module { 3173 var ret []blueprint.Module 3174 ctx.VisitDirectDeps(module, func(dep blueprint.Module) { 3175 if dep.Name() == depName { 3176 ret = append(ret, dep) 3177 } 3178 }) 3179 return ret 3180 } 3181 3182 bp := cc.GatherRequiredDepsForTest(android.Android) + ` 3183java_binary { 3184 name: "myjavabin", 3185 main_class: "com.android.MyJava", 3186 jni_libs: ["mynativelib"], 3187} 3188cc_library_shared { 3189 name: "mynativelib", 3190} 3191` 3192 res, _ := testJava(t, bp) 3193 deps := findDepsOfModule(res, res.ModuleForTests(t, "myjavabin", "android_common").Module(), "mynativelib") 3194 android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(deps)) 3195} 3196 3197func TestBootJarNotInUsesLibs(t *testing.T) { 3198 t.Parallel() 3199 result := android.GroupFixturePreparers( 3200 PrepareForTestWithJavaDefaultModules, 3201 PrepareForTestWithJavaSdkLibraryFiles, 3202 FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary"), 3203 FixtureConfigureApexBootJars("myapex:mysdklibrary"), 3204 ).RunTestWithBp(t, ` 3205 bootclasspath_fragment { 3206 name: "myfragment", 3207 contents: ["mysdklibrary"], 3208 hidden_api: { 3209 split_packages: ["*"], 3210 }, 3211 } 3212 3213 java_sdk_library { 3214 name: "mysdklibrary", 3215 srcs: ["Test.java"], 3216 compile_dex: true, 3217 public: {enabled: true}, 3218 min_sdk_version: "2", 3219 permitted_packages: ["mysdklibrary"], 3220 sdk_version: "current", 3221 } 3222 3223 java_sdk_library { 3224 name: "myothersdklibrary", 3225 srcs: ["Test.java"], 3226 compile_dex: true, 3227 public: {enabled: true}, 3228 min_sdk_version: "2", 3229 permitted_packages: ["myothersdklibrary"], 3230 sdk_version: "current", 3231 } 3232 3233 java_library { 3234 name: "foo", 3235 libs: [ 3236 "bar", 3237 "mysdklibrary.stubs", 3238 ], 3239 srcs: ["A.java"], 3240 } 3241 3242 java_library { 3243 name: "bar", 3244 libs: [ 3245 "myothersdklibrary.stubs" 3246 ], 3247 } 3248 `) 3249 ctx := result.TestContext 3250 fooModule := ctx.ModuleForTests(t, "foo", "android_common") 3251 3252 androidMkEntries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0] 3253 localExportSdkLibraries := androidMkEntries.EntryMap["LOCAL_EXPORT_SDK_LIBRARIES"] 3254 android.AssertStringListDoesNotContain(t, 3255 "boot jar should not be included in uses libs entries", 3256 localExportSdkLibraries, 3257 "mysdklibrary", 3258 ) 3259 android.AssertStringListContains(t, 3260 "non boot jar is included in uses libs entries", 3261 localExportSdkLibraries, 3262 "myothersdklibrary", 3263 ) 3264} 3265