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 "strconv" 24 "strings" 25 "testing" 26 27 "github.com/google/blueprint/proptools" 28 29 "android/soong/android" 30 "android/soong/cc" 31 "android/soong/dexpreopt" 32 "android/soong/genrule" 33) 34 35// Legacy preparer used for running tests within the java package. 36// 37// This includes everything that was needed to run any test in the java package prior to the 38// introduction of the test fixtures. Tests that are being converted to use fixtures directly 39// rather than through the testJava...() methods should avoid using this and instead use the 40// various preparers directly, using android.GroupFixturePreparers(...) to group them when 41// necessary. 42// 43// deprecated 44var prepareForJavaTest = android.GroupFixturePreparers( 45 genrule.PrepareForTestWithGenRuleBuildComponents, 46 // Get the CC build components but not default modules. 47 cc.PrepareForTestWithCcBuildComponents, 48 // Include all the default java modules. 49 PrepareForTestWithDexpreopt, 50 PrepareForTestWithOverlayBuildComponents, 51 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 52 ctx.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory) 53 }), 54) 55 56func TestMain(m *testing.M) { 57 os.Exit(m.Run()) 58} 59 60// testJavaError is a legacy way of running tests of java modules that expect errors. 61// 62// See testJava for an explanation as to how to stop using this deprecated method. 63// 64// deprecated 65func testJavaError(t *testing.T, pattern string, bp string) (*android.TestContext, android.Config) { 66 t.Helper() 67 result := android.GroupFixturePreparers( 68 prepareForJavaTest, dexpreopt.PrepareForTestByEnablingDexpreopt). 69 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). 70 RunTestWithBp(t, bp) 71 return result.TestContext, result.Config 72} 73 74// testJavaWithFS runs tests using the prepareForJavaTest 75// 76// See testJava for an explanation as to how to stop using this deprecated method. 77// 78// deprecated 79func testJavaWithFS(t *testing.T, bp string, fs android.MockFS) (*android.TestContext, android.Config) { 80 t.Helper() 81 result := android.GroupFixturePreparers( 82 prepareForJavaTest, fs.AddToFixture()).RunTestWithBp(t, bp) 83 return result.TestContext, result.Config 84} 85 86// testJava runs tests using the prepareForJavaTest 87// 88// Do not add any new usages of this, instead use the prepareForJavaTest directly as it makes it 89// much easier to customize the test behavior. 90// 91// If it is necessary to customize the behavior of an existing test that uses this then please first 92// convert the test to using prepareForJavaTest first and then in a following change add the 93// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify 94// that it did not change the test behavior unexpectedly. 95// 96// deprecated 97func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) { 98 t.Helper() 99 result := prepareForJavaTest.RunTestWithBp(t, bp) 100 return result.TestContext, result.Config 101} 102 103// defaultModuleToPath constructs a path to the turbine generate jar for a default test module that 104// is defined in PrepareForIntegrationTestWithJava 105func defaultModuleToPath(name string) string { 106 switch { 107 case name == `""`: 108 return name 109 case strings.HasSuffix(name, ".jar"): 110 return name 111 default: 112 return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine-combined", name+".jar") 113 } 114} 115 116// Test that the PrepareForTestWithJavaDefaultModules provides all the files that it uses by 117// running it in a fixture that requires all source files to exist. 118func TestPrepareForTestWithJavaDefaultModules(t *testing.T) { 119 android.GroupFixturePreparers( 120 PrepareForTestWithJavaDefaultModules, 121 android.PrepareForTestDisallowNonExistentPaths, 122 ).RunTest(t) 123} 124 125func TestJavaLinkType(t *testing.T) { 126 testJava(t, ` 127 java_library { 128 name: "foo", 129 srcs: ["a.java"], 130 libs: ["bar"], 131 static_libs: ["baz"], 132 } 133 134 java_library { 135 name: "bar", 136 sdk_version: "current", 137 srcs: ["b.java"], 138 } 139 140 java_library { 141 name: "baz", 142 sdk_version: "system_current", 143 srcs: ["c.java"], 144 } 145 `) 146 147 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", ` 148 java_library { 149 name: "foo", 150 srcs: ["a.java"], 151 libs: ["bar"], 152 sdk_version: "current", 153 static_libs: ["baz"], 154 } 155 156 java_library { 157 name: "bar", 158 sdk_version: "current", 159 srcs: ["b.java"], 160 } 161 162 java_library { 163 name: "baz", 164 sdk_version: "system_current", 165 srcs: ["c.java"], 166 } 167 `) 168 169 testJava(t, ` 170 java_library { 171 name: "foo", 172 srcs: ["a.java"], 173 libs: ["bar"], 174 sdk_version: "system_current", 175 static_libs: ["baz"], 176 } 177 178 java_library { 179 name: "bar", 180 sdk_version: "current", 181 srcs: ["b.java"], 182 } 183 184 java_library { 185 name: "baz", 186 sdk_version: "system_current", 187 srcs: ["c.java"], 188 } 189 `) 190 191 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", ` 192 java_library { 193 name: "foo", 194 srcs: ["a.java"], 195 libs: ["bar"], 196 sdk_version: "system_current", 197 static_libs: ["baz"], 198 } 199 200 java_library { 201 name: "bar", 202 sdk_version: "current", 203 srcs: ["b.java"], 204 } 205 206 java_library { 207 name: "baz", 208 srcs: ["c.java"], 209 } 210 `) 211} 212 213func TestSimple(t *testing.T) { 214 ctx, _ := testJava(t, ` 215 java_library { 216 name: "foo", 217 srcs: ["a.java"], 218 libs: ["bar"], 219 static_libs: ["baz"], 220 } 221 222 java_library { 223 name: "bar", 224 srcs: ["b.java"], 225 } 226 227 java_library { 228 name: "baz", 229 srcs: ["c.java"], 230 } 231 `) 232 233 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 234 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") 235 236 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { 237 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) 238 } 239 240 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String() 241 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar") 242 bazTurbine := filepath.Join("out", "soong", ".intermediates", "baz", "android_common", "turbine-combined", "baz.jar") 243 244 android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barTurbine) 245 246 android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazTurbine) 247 248 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz { 249 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz) 250 } 251} 252 253func TestExportedPlugins(t *testing.T) { 254 type Result struct { 255 library string 256 processors string 257 disableTurbine bool 258 } 259 var tests = []struct { 260 name string 261 extra string 262 results []Result 263 }{ 264 { 265 name: "Exported plugin is not a direct plugin", 266 extra: `java_library { name: "exports", srcs: ["a.java"], exported_plugins: ["plugin"] }`, 267 results: []Result{{library: "exports", processors: "-proc:none"}}, 268 }, 269 { 270 name: "Exports plugin to dependee", 271 extra: ` 272 java_library{name: "exports", exported_plugins: ["plugin"]} 273 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 274 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 275 `, 276 results: []Result{ 277 {library: "foo", processors: "-processor com.android.TestPlugin"}, 278 {library: "bar", processors: "-processor com.android.TestPlugin"}, 279 }, 280 }, 281 { 282 name: "Exports plugin to android_library", 283 extra: ` 284 java_library{name: "exports", exported_plugins: ["plugin"]} 285 android_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 286 android_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 287 `, 288 results: []Result{ 289 {library: "foo", processors: "-processor com.android.TestPlugin"}, 290 {library: "bar", processors: "-processor com.android.TestPlugin"}, 291 }, 292 }, 293 { 294 name: "Exports plugin is not propagated via transitive deps", 295 extra: ` 296 java_library{name: "exports", exported_plugins: ["plugin"]} 297 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 298 java_library{name: "bar", srcs: ["a.java"], static_libs: ["foo"]} 299 `, 300 results: []Result{ 301 {library: "foo", processors: "-processor com.android.TestPlugin"}, 302 {library: "bar", processors: "-proc:none"}, 303 }, 304 }, 305 { 306 name: "Exports plugin appends to plugins", 307 extra: ` 308 java_plugin{name: "plugin2", processor_class: "com.android.TestPlugin2"} 309 java_library{name: "exports", exported_plugins: ["plugin"]} 310 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"], plugins: ["plugin2"]} 311 `, 312 results: []Result{ 313 {library: "foo", processors: "-processor com.android.TestPlugin,com.android.TestPlugin2"}, 314 }, 315 }, 316 { 317 name: "Exports plugin to with generates_api to dependee", 318 extra: ` 319 java_library{name: "exports", exported_plugins: ["plugin_generates_api"]} 320 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 321 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 322 `, 323 results: []Result{ 324 {library: "foo", processors: "-processor com.android.TestPlugin", disableTurbine: true}, 325 {library: "bar", processors: "-processor com.android.TestPlugin", disableTurbine: true}, 326 }, 327 }, 328 } 329 330 for _, test := range tests { 331 t.Run(test.name, func(t *testing.T) { 332 ctx, _ := testJava(t, ` 333 java_plugin { 334 name: "plugin", 335 processor_class: "com.android.TestPlugin", 336 } 337 java_plugin { 338 name: "plugin_generates_api", 339 generates_api: true, 340 processor_class: "com.android.TestPlugin", 341 } 342 `+test.extra) 343 344 for _, want := range test.results { 345 javac := ctx.ModuleForTests(want.library, "android_common").Rule("javac") 346 if javac.Args["processor"] != want.processors { 347 t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"]) 348 } 349 turbine := ctx.ModuleForTests(want.library, "android_common").MaybeRule("turbine") 350 disableTurbine := turbine.BuildParams.Rule == nil 351 if disableTurbine != want.disableTurbine { 352 t.Errorf("For library %v, expected disableTurbine %v, found %v", want.library, want.disableTurbine, disableTurbine) 353 } 354 } 355 }) 356 } 357} 358 359func TestSdkVersionByPartition(t *testing.T) { 360 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", ` 361 java_library { 362 name: "foo", 363 srcs: ["a.java"], 364 vendor: true, 365 } 366 `) 367 368 testJava(t, ` 369 java_library { 370 name: "bar", 371 srcs: ["b.java"], 372 } 373 `) 374 375 for _, enforce := range []bool{true, false} { 376 bp := ` 377 java_library { 378 name: "foo", 379 srcs: ["a.java"], 380 product_specific: true, 381 } 382 ` 383 384 errorHandler := android.FixtureExpectsNoErrors 385 if enforce { 386 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product") 387 } 388 389 android.GroupFixturePreparers( 390 PrepareForTestWithJavaDefaultModules, 391 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 392 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce) 393 }), 394 ). 395 ExtendWithErrorHandler(errorHandler). 396 RunTestWithBp(t, bp) 397 } 398} 399 400func TestArchSpecific(t *testing.T) { 401 ctx, _ := testJava(t, ` 402 java_library { 403 name: "foo", 404 srcs: ["a.java"], 405 target: { 406 android: { 407 srcs: ["b.java"], 408 }, 409 }, 410 } 411 `) 412 413 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 414 if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" { 415 t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs) 416 } 417} 418 419func TestBinary(t *testing.T) { 420 ctx, _ := testJava(t, ` 421 java_library_host { 422 name: "foo", 423 srcs: ["a.java"], 424 } 425 426 java_binary_host { 427 name: "bar", 428 srcs: ["b.java"], 429 static_libs: ["foo"], 430 jni_libs: ["libjni"], 431 } 432 433 cc_library_shared { 434 name: "libjni", 435 host_supported: true, 436 device_supported: false, 437 stl: "none", 438 } 439 `) 440 441 buildOS := ctx.Config().BuildOS.String() 442 443 bar := ctx.ModuleForTests("bar", buildOS+"_common") 444 barJar := bar.Output("bar.jar").Output.String() 445 barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64") 446 barWrapperDeps := barWrapper.Output("bar").Implicits.Strings() 447 448 libjni := ctx.ModuleForTests("libjni", buildOS+"_x86_64_shared") 449 libjniSO := libjni.Rule("Cp").Output.String() 450 451 // Test that the install binary wrapper depends on the installed jar file 452 if g, w := barWrapperDeps, barJar; !android.InList(w, g) { 453 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g) 454 } 455 456 // Test that the install binary wrapper depends on the installed JNI libraries 457 if g, w := barWrapperDeps, libjniSO; !android.InList(w, g) { 458 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g) 459 } 460} 461 462func TestTest(t *testing.T) { 463 ctx, _ := testJava(t, ` 464 java_test_host { 465 name: "foo", 466 srcs: ["a.java"], 467 jni_libs: ["libjni"], 468 } 469 470 cc_library_shared { 471 name: "libjni", 472 host_supported: true, 473 device_supported: false, 474 stl: "none", 475 } 476 `) 477 478 buildOS := ctx.Config().BuildOS.String() 479 480 foo := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) 481 482 expected := "lib64/libjni.so" 483 if runtime.GOOS == "darwin" { 484 expected = "lib64/libjni.dylib" 485 } 486 487 fooTestData := foo.data 488 if len(fooTestData) != 1 || fooTestData[0].Rel() != expected { 489 t.Errorf(`expected foo test data relative path [%q], got %q`, 490 expected, fooTestData.Strings()) 491 } 492} 493 494func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) { 495 bp := ` 496 java_library { 497 name: "target_library", 498 srcs: ["a.java"], 499 } 500 501 java_binary_host { 502 name: "host_binary", 503 srcs: ["b.java"], 504 } 505 ` 506 507 result := android.GroupFixturePreparers( 508 PrepareForTestWithJavaDefaultModules, 509 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 510 variables.MinimizeJavaDebugInfo = proptools.BoolPtr(true) 511 }), 512 ).RunTestWithBp(t, bp) 513 514 // first, check that the -g flag is added to target modules 515 targetLibrary := result.ModuleForTests("target_library", "android_common") 516 targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"] 517 if !strings.Contains(targetJavaFlags, "-g:source,lines") { 518 t.Errorf("target library javac flags %v should contain "+ 519 "-g:source,lines override with MinimizeJavaDebugInfo", targetJavaFlags) 520 } 521 522 // check that -g is not overridden for host modules 523 buildOS := result.Config.BuildOS.String() 524 hostBinary := result.ModuleForTests("host_binary", buildOS+"_common") 525 hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"] 526 if strings.Contains(hostJavaFlags, "-g:source,lines") { 527 t.Errorf("java_binary_host javac flags %v should not have "+ 528 "-g:source,lines override with MinimizeJavaDebugInfo", hostJavaFlags) 529 } 530} 531 532func TestPrebuilts(t *testing.T) { 533 ctx, _ := testJava(t, ` 534 java_library { 535 name: "foo", 536 srcs: ["a.java", ":stubs-source"], 537 libs: ["bar", "sdklib"], 538 static_libs: ["baz"], 539 } 540 541 java_import { 542 name: "bar", 543 jars: ["a.jar"], 544 } 545 546 java_import { 547 name: "baz", 548 jars: ["b.jar"], 549 sdk_version: "current", 550 compile_dex: true, 551 } 552 553 dex_import { 554 name: "qux", 555 jars: ["b.jar"], 556 } 557 558 java_sdk_library_import { 559 name: "sdklib", 560 public: { 561 jars: ["c.jar"], 562 }, 563 } 564 565 prebuilt_stubs_sources { 566 name: "stubs-source", 567 srcs: ["stubs/sources"], 568 } 569 570 java_test_import { 571 name: "test", 572 jars: ["a.jar"], 573 test_suites: ["cts"], 574 test_config: "AndroidTest.xml", 575 } 576 `) 577 578 fooModule := ctx.ModuleForTests("foo", "android_common") 579 javac := fooModule.Rule("javac") 580 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") 581 barModule := ctx.ModuleForTests("bar", "android_common") 582 barJar := barModule.Rule("combineJar").Output 583 bazModule := ctx.ModuleForTests("baz", "android_common") 584 bazJar := bazModule.Rule("combineJar").Output 585 sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output 586 587 fooLibrary := fooModule.Module().(*Library) 588 assertDeepEquals(t, "foo unique sources incorrect", 589 []string{"a.java"}, fooLibrary.uniqueSrcFiles.Strings()) 590 591 assertDeepEquals(t, "foo java source jars incorrect", 592 []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"}, 593 android.NormalizePathsForTesting(fooLibrary.compiledSrcJars)) 594 595 if !strings.Contains(javac.Args["classpath"], barJar.String()) { 596 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String()) 597 } 598 599 barDexJar := barModule.Module().(*Import).DexJarBuildPath() 600 if barDexJar.IsSet() { 601 t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar) 602 } 603 604 if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) { 605 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String()) 606 } 607 608 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() { 609 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String()) 610 } 611 612 bazDexJar := bazModule.Module().(*Import).DexJarBuildPath().Path() 613 expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar" 614 android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar) 615 616 ctx.ModuleForTests("qux", "android_common").Rule("Cp") 617 618 entries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0] 619 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 620 entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0] 621 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 622 entries = android.AndroidMkEntriesForTest(t, ctx, ctx.ModuleForTests("sdklib", "android_common").Module())[0] 623 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_sdk_library_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 624} 625 626func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) { 627 if !reflect.DeepEqual(expected, actual) { 628 t.Errorf("%s: expected %q, found %q", message, expected, actual) 629 } 630} 631 632func TestPrebuiltStubsSources(t *testing.T) { 633 test := func(t *testing.T, sourcesPath string, expectedInputs []string) { 634 ctx, _ := testJavaWithFS(t, fmt.Sprintf(` 635prebuilt_stubs_sources { 636 name: "stubs-source", 637 srcs: ["%s"], 638}`, sourcesPath), map[string][]byte{ 639 "stubs/sources/pkg/A.java": nil, 640 "stubs/sources/pkg/B.java": nil, 641 }) 642 643 zipSrc := ctx.ModuleForTests("stubs-source", "android_common").Rule("zip_src") 644 if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) { 645 t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual) 646 } 647 } 648 649 t.Run("empty/missing directory", func(t *testing.T) { 650 test(t, "empty-directory", nil) 651 }) 652 653 t.Run("non-empty set of sources", func(t *testing.T) { 654 test(t, "stubs/sources", []string{ 655 "stubs/sources/pkg/A.java", 656 "stubs/sources/pkg/B.java", 657 }) 658 }) 659} 660 661func TestDefaults(t *testing.T) { 662 ctx, _ := testJava(t, ` 663 java_defaults { 664 name: "defaults", 665 srcs: ["a.java"], 666 libs: ["bar"], 667 static_libs: ["baz"], 668 optimize: {enabled: false}, 669 } 670 671 java_library { 672 name: "foo", 673 defaults: ["defaults"], 674 } 675 676 java_library { 677 name: "bar", 678 srcs: ["b.java"], 679 } 680 681 java_library { 682 name: "baz", 683 srcs: ["c.java"], 684 } 685 686 android_test { 687 name: "atestOptimize", 688 defaults: ["defaults"], 689 optimize: {enabled: true}, 690 } 691 692 android_test { 693 name: "atestNoOptimize", 694 defaults: ["defaults"], 695 } 696 697 android_test { 698 name: "atestDefault", 699 srcs: ["a.java"], 700 } 701 `) 702 703 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 704 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") 705 706 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { 707 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) 708 } 709 710 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar") 711 if !strings.Contains(javac.Args["classpath"], barTurbine) { 712 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine) 713 } 714 715 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String() 716 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz { 717 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz) 718 } 719 720 atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8") 721 if atestOptimize.Output == nil { 722 t.Errorf("atestOptimize should optimize APK") 723 } 724 725 atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8") 726 if atestNoOptimize.Output == nil { 727 t.Errorf("atestNoOptimize should not optimize APK") 728 } 729 730 atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("d8") 731 if atestDefault.Output == nil { 732 t.Errorf("atestDefault should not optimize APK") 733 } 734} 735 736func TestResources(t *testing.T) { 737 var table = []struct { 738 name string 739 prop string 740 extra string 741 args string 742 }{ 743 { 744 // Test that a module with java_resource_dirs includes the files 745 name: "resource dirs", 746 prop: `java_resource_dirs: ["java-res"]`, 747 args: "-C java-res -f java-res/a/a -f java-res/b/b", 748 }, 749 { 750 // Test that a module with java_resources includes the files 751 name: "resource files", 752 prop: `java_resources: ["java-res/a/a", "java-res/b/b"]`, 753 args: "-C . -f java-res/a/a -f java-res/b/b", 754 }, 755 { 756 // Test that a module with a filegroup in java_resources includes the files with the 757 // path prefix 758 name: "resource filegroup", 759 prop: `java_resources: [":foo-res"]`, 760 extra: ` 761 filegroup { 762 name: "foo-res", 763 path: "java-res", 764 srcs: ["java-res/a/a", "java-res/b/b"], 765 }`, 766 args: "-C java-res -f java-res/a/a -f java-res/b/b", 767 }, 768 { 769 // Test that a module with wildcards in java_resource_dirs has the correct path prefixes 770 name: "wildcard dirs", 771 prop: `java_resource_dirs: ["java-res/*"]`, 772 args: "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b", 773 }, 774 { 775 // Test that a module exclude_java_resource_dirs excludes the files 776 name: "wildcard dirs", 777 prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`, 778 args: "-C java-res/a -f java-res/a/a", 779 }, 780 { 781 // Test wildcards in java_resources 782 name: "wildcard files", 783 prop: `java_resources: ["java-res/**/*"]`, 784 args: "-C . -f java-res/a/a -f java-res/b/b", 785 }, 786 { 787 // Test exclude_java_resources with java_resources 788 name: "wildcard files with exclude", 789 prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`, 790 args: "-C . -f java-res/a/a", 791 }, 792 { 793 // Test exclude_java_resources with java_resource_dirs 794 name: "resource dirs with exclude files", 795 prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`, 796 args: "-C java-res -f java-res/a/a", 797 }, 798 { 799 // Test exclude_java_resource_dirs with java_resource_dirs 800 name: "resource dirs with exclude files", 801 prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`, 802 args: "-C java-res -f java-res/a/a -f java-res/b/b", 803 }, 804 } 805 806 for _, test := range table { 807 t.Run(test.name, func(t *testing.T) { 808 ctx, _ := testJavaWithFS(t, ` 809 java_library { 810 name: "foo", 811 srcs: [ 812 "a.java", 813 "b.java", 814 "c.java", 815 ], 816 `+test.prop+`, 817 } 818 `+test.extra, 819 map[string][]byte{ 820 "java-res/a/a": nil, 821 "java-res/b/b": nil, 822 "java-res2/a": nil, 823 }, 824 ) 825 826 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") 827 fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar") 828 829 if !inList(fooRes.Output.String(), foo.Inputs.Strings()) { 830 t.Errorf("foo combined jars %v does not contain %q", 831 foo.Inputs.Strings(), fooRes.Output.String()) 832 } 833 834 if fooRes.Args["jarArgs"] != test.args { 835 t.Errorf("foo resource jar args %q is not %q", 836 fooRes.Args["jarArgs"], test.args) 837 } 838 }) 839 } 840} 841 842func TestIncludeSrcs(t *testing.T) { 843 ctx, _ := testJavaWithFS(t, ` 844 java_library { 845 name: "foo", 846 srcs: [ 847 "a.java", 848 "b.java", 849 "c.java", 850 ], 851 include_srcs: true, 852 } 853 854 java_library { 855 name: "bar", 856 srcs: [ 857 "a.java", 858 "b.java", 859 "c.java", 860 ], 861 java_resource_dirs: ["java-res"], 862 include_srcs: true, 863 } 864 `, map[string][]byte{ 865 "java-res/a/a": nil, 866 "java-res/b/b": nil, 867 "java-res2/a": nil, 868 }) 869 870 // Test a library with include_srcs: true 871 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") 872 fooSrcJar := ctx.ModuleForTests("foo", "android_common").Output("foo.srcjar") 873 874 if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) { 875 t.Errorf("foo combined jars %v does not contain %q", w, g) 876 } 877 878 if g, w := fooSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w { 879 t.Errorf("foo source jar args %q is not %q", w, g) 880 } 881 882 // Test a library with include_srcs: true and resources 883 bar := ctx.ModuleForTests("bar", "android_common").Output("withres/bar.jar") 884 barResCombined := ctx.ModuleForTests("bar", "android_common").Output("res-combined/bar.jar") 885 barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar") 886 barSrcJar := ctx.ModuleForTests("bar", "android_common").Output("bar.srcjar") 887 888 if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) { 889 t.Errorf("bar combined resource jars %v does not contain %q", w, g) 890 } 891 892 if g, w := barRes.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) { 893 t.Errorf("bar combined resource jars %v does not contain %q", w, g) 894 } 895 896 if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) { 897 t.Errorf("bar combined jars %v does not contain %q", w, g) 898 } 899 900 if g, w := barSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w { 901 t.Errorf("bar source jar args %q is not %q", w, g) 902 } 903 904 if g, w := barRes.Args["jarArgs"], "-C java-res -f java-res/a/a -f java-res/b/b"; g != w { 905 t.Errorf("bar resource jar args %q is not %q", w, g) 906 } 907} 908 909func TestGeneratedSources(t *testing.T) { 910 ctx, _ := testJavaWithFS(t, ` 911 java_library { 912 name: "foo", 913 srcs: [ 914 "a*.java", 915 ":gen", 916 "b*.java", 917 ], 918 } 919 920 genrule { 921 name: "gen", 922 tool_files: ["java-res/a"], 923 out: ["gen.java"], 924 } 925 `, map[string][]byte{ 926 "a.java": nil, 927 "b.java": nil, 928 }) 929 930 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 931 genrule := ctx.ModuleForTests("gen", "").Rule("generator") 932 933 if filepath.Base(genrule.Output.String()) != "gen.java" { 934 t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String()) 935 } 936 937 if len(javac.Inputs) != 3 || 938 javac.Inputs[0].String() != "a.java" || 939 javac.Inputs[1].String() != genrule.Output.String() || 940 javac.Inputs[2].String() != "b.java" { 941 t.Errorf(`foo inputs %v != ["a.java", ".../gen.java", "b.java"]`, javac.Inputs) 942 } 943} 944 945func TestTurbine(t *testing.T) { 946 result := android.GroupFixturePreparers( 947 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})). 948 RunTestWithBp(t, ` 949 java_library { 950 name: "foo", 951 srcs: ["a.java"], 952 sdk_version: "14", 953 } 954 955 java_library { 956 name: "bar", 957 srcs: ["b.java"], 958 static_libs: ["foo"], 959 sdk_version: "14", 960 } 961 962 java_library { 963 name: "baz", 964 srcs: ["c.java"], 965 libs: ["bar"], 966 sdk_version: "14", 967 } 968 `) 969 970 fooTurbine := result.ModuleForTests("foo", "android_common").Rule("turbine") 971 barTurbine := result.ModuleForTests("bar", "android_common").Rule("turbine") 972 barJavac := result.ModuleForTests("bar", "android_common").Rule("javac") 973 barTurbineCombined := result.ModuleForTests("bar", "android_common").Description("for turbine") 974 bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac") 975 976 android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs) 977 978 fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar") 979 barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 980 android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar) 981 android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar) 982 android.AssertPathsRelativeToTopEquals(t, "bar turbine combineJar", []string{barTurbineJar, fooHeaderJar}, barTurbineCombined.Inputs) 983 android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "prebuilts/sdk/14/public/android.jar") 984} 985 986func TestSharding(t *testing.T) { 987 ctx, _ := testJava(t, ` 988 java_library { 989 name: "bar", 990 srcs: ["a.java","b.java","c.java"], 991 javac_shard_size: 1 992 } 993 `) 994 995 barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 996 for i := 0; i < 3; i++ { 997 barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i)) 998 if !strings.HasPrefix(barJavac.Args["classpath"], "-classpath "+barHeaderJar+":") { 999 t.Errorf("bar javac classpath %v does start with %q", barJavac.Args["classpath"], barHeaderJar) 1000 } 1001 } 1002} 1003 1004func TestExcludeFileGroupInSrcs(t *testing.T) { 1005 ctx, _ := testJava(t, ` 1006 java_library { 1007 name: "foo", 1008 srcs: ["a.java", ":foo-srcs"], 1009 exclude_srcs: ["a.java", ":foo-excludes"], 1010 } 1011 1012 filegroup { 1013 name: "foo-srcs", 1014 srcs: ["java-fg/a.java", "java-fg/b.java", "java-fg/c.java"], 1015 } 1016 1017 filegroup { 1018 name: "foo-excludes", 1019 srcs: ["java-fg/a.java", "java-fg/b.java"], 1020 } 1021 `) 1022 1023 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 1024 1025 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" { 1026 t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs) 1027 } 1028} 1029 1030func TestJavaLibrary(t *testing.T) { 1031 testJavaWithFS(t, "", map[string][]byte{ 1032 "libcore/Android.bp": []byte(` 1033 java_library { 1034 name: "core", 1035 sdk_version: "none", 1036 system_modules: "none", 1037 } 1038 1039 filegroup { 1040 name: "core-jar", 1041 srcs: [":core{.jar}"], 1042 } 1043 `), 1044 }) 1045} 1046 1047func TestJavaImport(t *testing.T) { 1048 testJavaWithFS(t, "", map[string][]byte{ 1049 "libcore/Android.bp": []byte(` 1050 java_import { 1051 name: "core", 1052 sdk_version: "none", 1053 } 1054 1055 filegroup { 1056 name: "core-jar", 1057 srcs: [":core{.jar}"], 1058 } 1059 `), 1060 }) 1061} 1062 1063var compilerFlagsTestCases = []struct { 1064 in string 1065 out bool 1066}{ 1067 { 1068 in: "a", 1069 out: false, 1070 }, 1071 { 1072 in: "-a", 1073 out: true, 1074 }, 1075 { 1076 in: "-no-jdk", 1077 out: false, 1078 }, 1079 { 1080 in: "-no-stdlib", 1081 out: false, 1082 }, 1083 { 1084 in: "-kotlin-home", 1085 out: false, 1086 }, 1087 { 1088 in: "-kotlin-home /some/path", 1089 out: false, 1090 }, 1091 { 1092 in: "-include-runtime", 1093 out: false, 1094 }, 1095 { 1096 in: "-Xintellij-plugin-root", 1097 out: false, 1098 }, 1099} 1100 1101type mockContext struct { 1102 android.ModuleContext 1103 result bool 1104} 1105 1106func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) { 1107 // CheckBadCompilerFlags calls this function when the flag should be rejected 1108 ctx.result = false 1109} 1110 1111func TestCompilerFlags(t *testing.T) { 1112 for _, testCase := range compilerFlagsTestCases { 1113 ctx := &mockContext{result: true} 1114 CheckKotlincFlags(ctx, []string{testCase.in}) 1115 if ctx.result != testCase.out { 1116 t.Errorf("incorrect output:") 1117 t.Errorf(" input: %#v", testCase.in) 1118 t.Errorf(" expected: %#v", testCase.out) 1119 t.Errorf(" got: %#v", ctx.result) 1120 } 1121 } 1122} 1123 1124// TODO(jungjw): Consider making this more robust by ignoring path order. 1125func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) { 1126 variables := ctx.ModuleForTests(moduleName, "android_common").VariablesForTestsRelativeToTop() 1127 flags := strings.Split(variables["javacFlags"], " ") 1128 got := "" 1129 for _, flag := range flags { 1130 keyEnd := strings.Index(flag, "=") 1131 if keyEnd > -1 && flag[:keyEnd] == "--patch-module" { 1132 got = flag[keyEnd+1:] 1133 break 1134 } 1135 } 1136 if expected != android.StringPathRelativeToTop(ctx.Config().SoongOutDir(), got) { 1137 t.Errorf("Unexpected patch-module flag for module %q - expected %q, but got %q", moduleName, expected, got) 1138 } 1139} 1140 1141func TestPatchModule(t *testing.T) { 1142 t.Run("Java language level 8", func(t *testing.T) { 1143 // Test with legacy javac -source 1.8 -target 1.8 1144 bp := ` 1145 java_library { 1146 name: "foo", 1147 srcs: ["a.java"], 1148 java_version: "1.8", 1149 } 1150 1151 java_library { 1152 name: "bar", 1153 srcs: ["b.java"], 1154 sdk_version: "none", 1155 system_modules: "none", 1156 patch_module: "java.base", 1157 java_version: "1.8", 1158 } 1159 1160 java_library { 1161 name: "baz", 1162 srcs: ["c.java"], 1163 patch_module: "java.base", 1164 java_version: "1.8", 1165 } 1166 ` 1167 ctx, _ := testJava(t, bp) 1168 1169 checkPatchModuleFlag(t, ctx, "foo", "") 1170 checkPatchModuleFlag(t, ctx, "bar", "") 1171 checkPatchModuleFlag(t, ctx, "baz", "") 1172 }) 1173 1174 t.Run("Java language level 9", func(t *testing.T) { 1175 // Test with default javac -source 9 -target 9 1176 bp := ` 1177 java_library { 1178 name: "foo", 1179 srcs: ["a.java"], 1180 } 1181 1182 java_library { 1183 name: "bar", 1184 srcs: ["b.java"], 1185 sdk_version: "none", 1186 system_modules: "none", 1187 patch_module: "java.base", 1188 } 1189 1190 java_library { 1191 name: "baz", 1192 srcs: [ 1193 "c.java", 1194 // Tests for b/150878007 1195 "dir/d.java", 1196 "dir2/e.java", 1197 "dir2/f.java", 1198 "nested/dir/g.java" 1199 ], 1200 patch_module: "java.base", 1201 } 1202 ` 1203 ctx, _ := testJava(t, bp) 1204 1205 checkPatchModuleFlag(t, ctx, "foo", "") 1206 expected := "java.base=.:out/soong" 1207 checkPatchModuleFlag(t, ctx, "bar", expected) 1208 expected = "java.base=" + strings.Join([]string{ 1209 ".", "out/soong", "dir", "dir2", "nested", defaultModuleToPath("ext"), defaultModuleToPath("framework")}, ":") 1210 checkPatchModuleFlag(t, ctx, "baz", expected) 1211 }) 1212} 1213 1214func TestJavaLibraryWithSystemModules(t *testing.T) { 1215 ctx, _ := testJava(t, ` 1216 java_library { 1217 name: "lib-with-source-system-modules", 1218 srcs: [ 1219 "a.java", 1220 ], 1221 sdk_version: "none", 1222 system_modules: "source-system-modules", 1223 } 1224 1225 java_library { 1226 name: "source-jar", 1227 srcs: [ 1228 "a.java", 1229 ], 1230 } 1231 1232 java_system_modules { 1233 name: "source-system-modules", 1234 libs: ["source-jar"], 1235 } 1236 1237 java_library { 1238 name: "lib-with-prebuilt-system-modules", 1239 srcs: [ 1240 "a.java", 1241 ], 1242 sdk_version: "none", 1243 system_modules: "prebuilt-system-modules", 1244 } 1245 1246 java_import { 1247 name: "prebuilt-jar", 1248 jars: ["a.jar"], 1249 } 1250 1251 java_system_modules_import { 1252 name: "prebuilt-system-modules", 1253 libs: ["prebuilt-jar"], 1254 } 1255 `) 1256 1257 checkBootClasspathForSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar") 1258 1259 checkBootClasspathForSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar") 1260} 1261 1262func checkBootClasspathForSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) { 1263 javacRule := ctx.ModuleForTests(moduleName, "android_common").Rule("javac") 1264 bootClasspath := javacRule.Args["bootClasspath"] 1265 if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) { 1266 t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath) 1267 } 1268} 1269 1270func TestAidlExportIncludeDirsFromImports(t *testing.T) { 1271 ctx, _ := testJava(t, ` 1272 java_library { 1273 name: "foo", 1274 srcs: ["aidl/foo/IFoo.aidl"], 1275 libs: ["bar"], 1276 } 1277 1278 java_import { 1279 name: "bar", 1280 jars: ["a.jar"], 1281 aidl: { 1282 export_include_dirs: ["aidl/bar"], 1283 }, 1284 } 1285 `) 1286 1287 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1288 expectedAidlFlag := "-Iaidl/bar" 1289 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1290 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1291 } 1292} 1293 1294func TestAidlIncludeDirFromConvertedFileGroupWithPathPropInMixedBuilds(t *testing.T) { 1295 // TODO(b/247782695), TODO(b/242847534) Fix mixed builds for filegroups 1296 t.Skip("Re-enable once filegroups are corrected for mixed builds") 1297 bp := ` 1298 filegroup { 1299 name: "foo_aidl", 1300 srcs: ["aidl/foo/IFoo.aidl"], 1301 path: "aidl/foo", 1302 bazel_module: { label: "//:foo_aidl" }, 1303 } 1304 java_library { 1305 name: "foo", 1306 srcs: [":foo_aidl"], 1307 } 1308` 1309 1310 outBaseDir := "out/bazel/output" 1311 result := android.GroupFixturePreparers( 1312 prepareForJavaTest, 1313 android.PrepareForTestWithFilegroup, 1314 android.FixtureModifyConfig(func(config android.Config) { 1315 config.BazelContext = android.MockBazelContext{ 1316 OutputBaseDir: outBaseDir, 1317 LabelToOutputFiles: map[string][]string{ 1318 "//:foo_aidl": []string{"aidl/foo/IFoo.aidl"}, 1319 }, 1320 } 1321 }), 1322 ).RunTestWithBp(t, bp) 1323 1324 aidlCommand := result.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1325 expectedAidlFlag := "-I" + outBaseDir + "/execroot/__main__/aidl/foo" 1326 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1327 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1328 } 1329} 1330 1331func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) { 1332 ctx, _ := testJava(t, ` 1333 java_library { 1334 name: "foo", 1335 srcs: ["aidl/foo/IFoo.aidl"], 1336 aidl: { flags: ["-Werror"], }, 1337 } 1338 `) 1339 1340 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1341 expectedAidlFlag := "-Werror" 1342 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1343 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1344 } 1345} 1346 1347func TestAidlFlagsWithMinSdkVersion(t *testing.T) { 1348 fixture := android.GroupFixturePreparers( 1349 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})) 1350 1351 for _, tc := range []struct { 1352 name string 1353 sdkVersion string 1354 expected string 1355 }{ 1356 {"default is current", "", "current"}, 1357 {"use sdk_version", `sdk_version: "14"`, "14"}, 1358 {"system_current", `sdk_version: "system_current"`, "current"}, 1359 } { 1360 t.Run(tc.name, func(t *testing.T) { 1361 ctx := fixture.RunTestWithBp(t, ` 1362 java_library { 1363 name: "foo", 1364 srcs: ["aidl/foo/IFoo.aidl"], 1365 `+tc.sdkVersion+` 1366 } 1367 `) 1368 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1369 expectedAidlFlag := "--min_sdk_version=" + tc.expected 1370 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1371 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1372 } 1373 }) 1374 } 1375} 1376 1377func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) { 1378 bpTemplate := ` 1379 droidstubs { 1380 name: "foo-stubs", 1381 srcs: ["foo.aidl"], 1382 %s 1383 system_modules: "none", 1384 } 1385 ` 1386 testCases := []struct { 1387 desc string 1388 sdkVersionBp string 1389 minSdkVersionExpected string 1390 }{ 1391 { 1392 desc: "sdk_version not set, module compiles against private platform APIs", 1393 sdkVersionBp: ``, 1394 minSdkVersionExpected: "10000", 1395 }, 1396 { 1397 desc: "sdk_version set to none, module does not build against an SDK", 1398 sdkVersionBp: `sdk_version: "none",`, 1399 minSdkVersionExpected: "10000", 1400 }, 1401 } 1402 for _, tc := range testCases { 1403 ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp)) 1404 aidlCmd := ctx.ModuleForTests("foo-stubs", "android_common").Rule("aidl").RuleParams.Command 1405 expected := "--min_sdk_version=" + tc.minSdkVersionExpected 1406 android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected) 1407 } 1408} 1409 1410func TestAidlEnforcePermissions(t *testing.T) { 1411 ctx, _ := testJava(t, ` 1412 java_library { 1413 name: "foo", 1414 srcs: ["aidl/foo/IFoo.aidl"], 1415 aidl: { enforce_permissions: true }, 1416 } 1417 `) 1418 1419 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1420 expectedAidlFlag := "-Wmissing-permission-annotation -Werror" 1421 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1422 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1423 } 1424} 1425 1426func TestAidlEnforcePermissionsException(t *testing.T) { 1427 ctx, _ := testJava(t, ` 1428 java_library { 1429 name: "foo", 1430 srcs: ["aidl/foo/IFoo.aidl", "aidl/foo/IFoo2.aidl"], 1431 aidl: { enforce_permissions: true, enforce_permissions_exceptions: ["aidl/foo/IFoo2.aidl"] }, 1432 } 1433 `) 1434 1435 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1436 expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl" 1437 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1438 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1439 } 1440 expectedAidlFlag = "$$FLAGS aidl/foo/IFoo2.aidl" 1441 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1442 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1443 } 1444} 1445 1446func TestDataNativeBinaries(t *testing.T) { 1447 ctx := android.GroupFixturePreparers( 1448 prepareForJavaTest, 1449 android.PrepareForTestWithAllowMissingDependencies).RunTestWithBp(t, ` 1450 java_test_host { 1451 name: "foo", 1452 srcs: ["a.java"], 1453 data_native_bins: ["bin"] 1454 } 1455 1456 cc_binary_host { 1457 name: "bin", 1458 srcs: ["bin.cpp"], 1459 } 1460 `).TestContext 1461 1462 buildOS := ctx.Config().BuildOS.String() 1463 1464 test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) 1465 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0] 1466 expected := []string{"out/soong/.intermediates/bin/" + buildOS + "_x86_64/bin:bin"} 1467 actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 1468 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_COMPATIBILITY_SUPPORT_FILES", ctx.Config(), expected, actual) 1469} 1470 1471func TestDefaultInstallable(t *testing.T) { 1472 ctx, _ := testJava(t, ` 1473 java_test_host { 1474 name: "foo" 1475 } 1476 `) 1477 1478 buildOS := ctx.Config().BuildOS.String() 1479 module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) 1480 assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true), 1481 module.properties.Installable) 1482} 1483 1484func TestErrorproneEnabled(t *testing.T) { 1485 ctx, _ := testJava(t, ` 1486 java_library { 1487 name: "foo", 1488 srcs: ["a.java"], 1489 errorprone: { 1490 enabled: true, 1491 }, 1492 } 1493 `) 1494 1495 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1496 1497 // Test that the errorprone plugins are passed to javac 1498 expectedSubstring := "-Xplugin:ErrorProne" 1499 if !strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1500 t.Errorf("expected javacFlags to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1501 } 1502 1503 // Modules with errorprone { enabled: true } will include errorprone checks 1504 // in the main javac build rule. Only when RUN_ERROR_PRONE is true will 1505 // the explicit errorprone build rule be created. 1506 errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone") 1507 if errorprone.RuleParams.Description != "" { 1508 t.Errorf("expected errorprone build rule to not exist, but it did") 1509 } 1510} 1511 1512func TestErrorproneDisabled(t *testing.T) { 1513 bp := ` 1514 java_library { 1515 name: "foo", 1516 srcs: ["a.java"], 1517 errorprone: { 1518 enabled: false, 1519 }, 1520 } 1521 ` 1522 ctx := android.GroupFixturePreparers( 1523 PrepareForTestWithJavaDefaultModules, 1524 android.FixtureMergeEnv(map[string]string{ 1525 "RUN_ERROR_PRONE": "true", 1526 }), 1527 ).RunTestWithBp(t, bp) 1528 1529 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1530 1531 // Test that the errorprone plugins are not passed to javac, like they would 1532 // be if enabled was true. 1533 expectedSubstring := "-Xplugin:ErrorProne" 1534 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1535 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1536 } 1537 1538 // Check that no errorprone build rule is created, like there would be 1539 // if enabled was unset and RUN_ERROR_PRONE was true. 1540 errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone") 1541 if errorprone.RuleParams.Description != "" { 1542 t.Errorf("expected errorprone build rule to not exist, but it did") 1543 } 1544} 1545 1546func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) { 1547 bp := ` 1548 java_library { 1549 name: "foo", 1550 srcs: ["a.java"], 1551 } 1552 ` 1553 ctx := android.GroupFixturePreparers( 1554 PrepareForTestWithJavaDefaultModules, 1555 android.FixtureMergeEnv(map[string]string{ 1556 "RUN_ERROR_PRONE": "true", 1557 }), 1558 ).RunTestWithBp(t, bp) 1559 1560 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1561 errorprone := ctx.ModuleForTests("foo", "android_common").Description("errorprone") 1562 1563 // Check that the errorprone plugins are not passed to javac, because they 1564 // will instead be passed to the separate errorprone compilation 1565 expectedSubstring := "-Xplugin:ErrorProne" 1566 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1567 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1568 } 1569 1570 // Check that the errorprone plugin is enabled 1571 if !strings.Contains(errorprone.Args["javacFlags"], expectedSubstring) { 1572 t.Errorf("expected errorprone to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1573 } 1574} 1575 1576func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) { 1577 testCases := []struct { 1578 dataDeviceBinType string 1579 depCompileMultilib string 1580 variants []string 1581 expectedError string 1582 }{ 1583 { 1584 dataDeviceBinType: "first", 1585 depCompileMultilib: "first", 1586 variants: []string{"android_arm64_armv8-a"}, 1587 }, 1588 { 1589 dataDeviceBinType: "first", 1590 depCompileMultilib: "both", 1591 variants: []string{"android_arm64_armv8-a"}, 1592 }, 1593 { 1594 // this is true because our testing framework is set up with 1595 // Targets ~ [<64bit target>, <32bit target>], where 64bit is "first" 1596 dataDeviceBinType: "first", 1597 depCompileMultilib: "32", 1598 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1599 }, 1600 { 1601 dataDeviceBinType: "first", 1602 depCompileMultilib: "64", 1603 variants: []string{"android_arm64_armv8-a"}, 1604 }, 1605 { 1606 dataDeviceBinType: "both", 1607 depCompileMultilib: "both", 1608 variants: []string{ 1609 "android_arm_armv7-a-neon", 1610 "android_arm64_armv8-a", 1611 }, 1612 }, 1613 { 1614 dataDeviceBinType: "both", 1615 depCompileMultilib: "32", 1616 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1617 }, 1618 { 1619 dataDeviceBinType: "both", 1620 depCompileMultilib: "64", 1621 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1622 }, 1623 { 1624 dataDeviceBinType: "both", 1625 depCompileMultilib: "first", 1626 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1627 }, 1628 { 1629 dataDeviceBinType: "32", 1630 depCompileMultilib: "32", 1631 variants: []string{"android_arm_armv7-a-neon"}, 1632 }, 1633 { 1634 dataDeviceBinType: "32", 1635 depCompileMultilib: "first", 1636 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1637 }, 1638 { 1639 dataDeviceBinType: "32", 1640 depCompileMultilib: "both", 1641 variants: []string{"android_arm_armv7-a-neon"}, 1642 }, 1643 { 1644 dataDeviceBinType: "32", 1645 depCompileMultilib: "64", 1646 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1647 }, 1648 { 1649 dataDeviceBinType: "64", 1650 depCompileMultilib: "64", 1651 variants: []string{"android_arm64_armv8-a"}, 1652 }, 1653 { 1654 dataDeviceBinType: "64", 1655 depCompileMultilib: "both", 1656 variants: []string{"android_arm64_armv8-a"}, 1657 }, 1658 { 1659 dataDeviceBinType: "64", 1660 depCompileMultilib: "first", 1661 variants: []string{"android_arm64_armv8-a"}, 1662 }, 1663 { 1664 dataDeviceBinType: "64", 1665 depCompileMultilib: "32", 1666 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1667 }, 1668 { 1669 dataDeviceBinType: "prefer32", 1670 depCompileMultilib: "32", 1671 variants: []string{"android_arm_armv7-a-neon"}, 1672 }, 1673 { 1674 dataDeviceBinType: "prefer32", 1675 depCompileMultilib: "both", 1676 variants: []string{"android_arm_armv7-a-neon"}, 1677 }, 1678 { 1679 dataDeviceBinType: "prefer32", 1680 depCompileMultilib: "first", 1681 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1682 }, 1683 { 1684 dataDeviceBinType: "prefer32", 1685 depCompileMultilib: "64", 1686 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1687 }, 1688 } 1689 1690 bpTemplate := ` 1691 java_test_host { 1692 name: "foo", 1693 srcs: ["test.java"], 1694 data_device_bins_%s: ["bar"], 1695 } 1696 1697 cc_binary { 1698 name: "bar", 1699 compile_multilib: "%s", 1700 } 1701 ` 1702 1703 for _, tc := range testCases { 1704 bp := fmt.Sprintf(bpTemplate, tc.dataDeviceBinType, tc.depCompileMultilib) 1705 1706 errorHandler := android.FixtureExpectsNoErrors 1707 if tc.expectedError != "" { 1708 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError) 1709 } 1710 1711 testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib) 1712 t.Run(testName, func(t *testing.T) { 1713 ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava). 1714 ExtendWithErrorHandler(errorHandler). 1715 RunTestWithBp(t, bp) 1716 if tc.expectedError != "" { 1717 return 1718 } 1719 1720 buildOS := ctx.Config.BuildOS.String() 1721 fooVariant := ctx.ModuleForTests("foo", buildOS+"_common") 1722 fooMod := fooVariant.Module().(*TestHost) 1723 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0] 1724 1725 expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />` 1726 autogen := fooVariant.Rule("autogen") 1727 if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) { 1728 t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig) 1729 } 1730 1731 expectedData := []string{} 1732 for _, variant := range tc.variants { 1733 barVariant := ctx.ModuleForTests("bar", variant) 1734 relocated := barVariant.Output("bar") 1735 expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant) 1736 android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input) 1737 1738 expectedData = append(expectedData, fmt.Sprintf("out/soong/.intermediates/bar/%s/bar:bar", variant)) 1739 } 1740 1741 actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 1742 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData) 1743 }) 1744 } 1745} 1746 1747func TestImportMixedBuild(t *testing.T) { 1748 bp := ` 1749 java_import { 1750 name: "baz", 1751 jars: [ 1752 "test1.jar", 1753 "test2.jar", 1754 ], 1755 bazel_module: { label: "//foo/bar:baz" }, 1756 } 1757 ` 1758 1759 ctx := android.GroupFixturePreparers( 1760 prepareForJavaTest, 1761 android.FixtureModifyConfig(func(config android.Config) { 1762 config.BazelContext = android.MockBazelContext{ 1763 OutputBaseDir: "outputbase", 1764 LabelToOutputFiles: map[string][]string{ 1765 "//foo/bar:baz": []string{"test1.jar", "test2.jar"}, 1766 }, 1767 } 1768 }), 1769 ).RunTestWithBp(t, bp) 1770 1771 bazMod := ctx.ModuleForTests("baz", "android_common").Module() 1772 producer := bazMod.(android.OutputFileProducer) 1773 expectedOutputFiles := []string{".intermediates/baz/android_common/bazelCombined/baz.jar"} 1774 1775 outputFiles, err := producer.OutputFiles("") 1776 if err != nil { 1777 t.Errorf("Unexpected error getting java_import outputfiles %s", err) 1778 } 1779 actualOutputFiles := android.NormalizePathsForTesting(outputFiles) 1780 android.AssertDeepEquals(t, "Output files are produced", expectedOutputFiles, actualOutputFiles) 1781 1782 javaInfoProvider := ctx.ModuleProvider(bazMod, JavaInfoProvider) 1783 javaInfo, ok := javaInfoProvider.(JavaInfo) 1784 if !ok { 1785 t.Error("could not get JavaInfo from java_import module") 1786 } 1787 android.AssertDeepEquals(t, "Header JARs are produced", expectedOutputFiles, android.NormalizePathsForTesting(javaInfo.HeaderJars)) 1788 android.AssertDeepEquals(t, "Implementation/Resources JARs are produced", expectedOutputFiles, android.NormalizePathsForTesting(javaInfo.ImplementationAndResourcesJars)) 1789 android.AssertDeepEquals(t, "Implementation JARs are produced", expectedOutputFiles, android.NormalizePathsForTesting(javaInfo.ImplementationJars)) 1790} 1791 1792func TestGenAidlIncludeFlagsForMixedBuilds(t *testing.T) { 1793 bazelOutputBaseDir := filepath.Join("out", "bazel") 1794 result := android.GroupFixturePreparers( 1795 PrepareForIntegrationTestWithJava, 1796 android.FixtureModifyConfig(func(config android.Config) { 1797 config.BazelContext = android.MockBazelContext{ 1798 OutputBaseDir: bazelOutputBaseDir, 1799 } 1800 }), 1801 ).RunTest(t) 1802 1803 ctx := &android.TestPathContext{TestResult: result} 1804 1805 srcDirectory := filepath.Join("frameworks", "base") 1806 srcDirectoryAlreadyIncluded := filepath.Join("frameworks", "base", "core", "java") 1807 bazelSrcDirectory := android.PathForBazelOut(ctx, srcDirectory) 1808 bazelSrcDirectoryAlreadyIncluded := android.PathForBazelOut(ctx, srcDirectoryAlreadyIncluded) 1809 srcs := android.Paths{ 1810 android.PathForTestingWithRel(bazelSrcDirectory.String(), "bazelAidl.aidl"), 1811 android.PathForTestingWithRel(bazelSrcDirectory.String(), "bazelAidl2.aidl"), 1812 android.PathForTestingWithRel(bazelSrcDirectoryAlreadyIncluded.String(), "bazelAidlExclude.aidl"), 1813 android.PathForTestingWithRel(bazelSrcDirectoryAlreadyIncluded.String(), "bazelAidl2Exclude.aidl"), 1814 } 1815 dirsAlreadyIncluded := android.Paths{ 1816 android.PathForTesting(srcDirectoryAlreadyIncluded), 1817 } 1818 1819 expectedFlags := " -Iout/bazel/execroot/__main__/frameworks/base" 1820 flags := genAidlIncludeFlags(ctx, srcs, dirsAlreadyIncluded) 1821 if flags != expectedFlags { 1822 t.Errorf("expected flags to be %q; was %q", expectedFlags, flags) 1823 } 1824} 1825 1826func TestDeviceBinaryWrapperGeneration(t *testing.T) { 1827 // Scenario 1: java_binary has main_class property in its bp 1828 ctx, _ := testJava(t, ` 1829 java_binary { 1830 name: "foo", 1831 srcs: ["foo.java"], 1832 main_class: "foo.bar.jb", 1833 } 1834 `) 1835 wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_arm64_armv8-a").AllOutputs()) 1836 if !strings.Contains(wrapperPath, "foo.sh") { 1837 t.Errorf("wrapper file foo.sh is not generated") 1838 } 1839 1840 // Scenario 2: java_binary has neither wrapper nor main_class, its build 1841 // is expected to be failed. 1842 testJavaError(t, "main_class property is required for device binary if no default wrapper is assigned", ` 1843 java_binary { 1844 name: "foo", 1845 srcs: ["foo.java"], 1846 }`) 1847} 1848 1849func TestJavaApiContributionEmptyApiFile(t *testing.T) { 1850 testJavaError(t, 1851 "Error: foo has an empty api file.", 1852 `java_api_contribution { 1853 name: "foo", 1854 } 1855 java_api_library { 1856 name: "bar", 1857 api_surface: "public", 1858 api_contributions: ["foo"], 1859 } 1860 `) 1861} 1862 1863func TestJavaApiLibraryAndProviderLink(t *testing.T) { 1864 provider_bp_a := ` 1865 java_api_contribution { 1866 name: "foo1", 1867 api_file: "foo1.txt", 1868 } 1869 ` 1870 provider_bp_b := `java_api_contribution { 1871 name: "foo2", 1872 api_file: "foo2.txt", 1873 } 1874 ` 1875 ctx, _ := testJavaWithFS(t, ` 1876 java_api_library { 1877 name: "bar1", 1878 api_surface: "public", 1879 api_contributions: ["foo1"], 1880 } 1881 1882 java_api_library { 1883 name: "bar2", 1884 api_surface: "system", 1885 api_contributions: ["foo1", "foo2"], 1886 api_files: ["api1/current.txt", "api2/current.txt"] 1887 } 1888 `, 1889 map[string][]byte{ 1890 "a/Android.bp": []byte(provider_bp_a), 1891 "b/Android.bp": []byte(provider_bp_b), 1892 }) 1893 1894 testcases := []struct { 1895 moduleName string 1896 sourceTextFileDirs []string 1897 }{ 1898 { 1899 moduleName: "bar1", 1900 sourceTextFileDirs: []string{"a/foo1.txt"}, 1901 }, 1902 { 1903 moduleName: "bar2", 1904 sourceTextFileDirs: []string{"a/foo1.txt", "b/foo2.txt", "api1/current.txt", "api2/current.txt"}, 1905 }, 1906 } 1907 for _, c := range testcases { 1908 m := ctx.ModuleForTests(c.moduleName, "android_common") 1909 manifest := m.Output("metalava.sbox.textproto") 1910 sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest) 1911 manifestCommand := sboxProto.Commands[0].GetCommand() 1912 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ") 1913 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) 1914 } 1915} 1916 1917func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { 1918 provider_bp_a := ` 1919 java_api_contribution { 1920 name: "foo1", 1921 api_file: "foo1.txt", 1922 } 1923 ` 1924 provider_bp_b := ` 1925 java_api_contribution { 1926 name: "foo2", 1927 api_file: "foo2.txt", 1928 } 1929 ` 1930 provider_bp_c := ` 1931 java_api_contribution { 1932 name: "foo3", 1933 api_file: "foo3.txt", 1934 } 1935 ` 1936 provider_bp_d := ` 1937 java_api_contribution { 1938 name: "foo4", 1939 api_file: "foo4.txt", 1940 } 1941 ` 1942 ctx, _ := testJavaWithFS(t, ` 1943 java_defaults { 1944 name: "baz1", 1945 api_surface: "public", 1946 api_contributions: ["foo1", "foo2"], 1947 } 1948 1949 java_defaults { 1950 name: "baz2", 1951 api_surface: "system", 1952 api_contributions: ["foo3"], 1953 } 1954 1955 java_api_library { 1956 name: "bar1", 1957 api_surface: "public", 1958 api_contributions: ["foo1"], 1959 } 1960 1961 java_api_library { 1962 name: "bar2", 1963 api_surface: "public", 1964 defaults:["baz1"], 1965 } 1966 1967 java_api_library { 1968 name: "bar3", 1969 api_surface: "system", 1970 defaults:["baz1", "baz2"], 1971 api_contributions: ["foo4"], 1972 api_files: ["api1/current.txt", "api2/current.txt"] 1973 } 1974 `, 1975 map[string][]byte{ 1976 "a/Android.bp": []byte(provider_bp_a), 1977 "b/Android.bp": []byte(provider_bp_b), 1978 "c/Android.bp": []byte(provider_bp_c), 1979 "d/Android.bp": []byte(provider_bp_d), 1980 }) 1981 1982 testcases := []struct { 1983 moduleName string 1984 sourceTextFileDirs []string 1985 }{ 1986 { 1987 moduleName: "bar1", 1988 sourceTextFileDirs: []string{"a/foo1.txt"}, 1989 }, 1990 { 1991 moduleName: "bar2", 1992 sourceTextFileDirs: []string{"a/foo1.txt", "b/foo2.txt"}, 1993 }, 1994 { 1995 moduleName: "bar3", 1996 sourceTextFileDirs: []string{"c/foo3.txt", "a/foo1.txt", "b/foo2.txt", "d/foo4.txt", "api1/current.txt", "api2/current.txt"}, 1997 }, 1998 } 1999 for _, c := range testcases { 2000 m := ctx.ModuleForTests(c.moduleName, "android_common") 2001 manifest := m.Output("metalava.sbox.textproto") 2002 sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest) 2003 manifestCommand := sboxProto.Commands[0].GetCommand() 2004 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ") 2005 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) 2006 } 2007} 2008 2009func TestJavaApiLibraryJarGeneration(t *testing.T) { 2010 provider_bp_a := ` 2011 java_api_contribution { 2012 name: "foo1", 2013 api_file: "foo1.txt", 2014 } 2015 ` 2016 provider_bp_b := ` 2017 java_api_contribution { 2018 name: "foo2", 2019 api_file: "foo2.txt", 2020 } 2021 ` 2022 ctx, _ := testJavaWithFS(t, ` 2023 java_api_library { 2024 name: "bar1", 2025 api_surface: "public", 2026 api_contributions: ["foo1"], 2027 } 2028 2029 java_api_library { 2030 name: "bar2", 2031 api_surface: "system", 2032 api_contributions: ["foo1", "foo2"], 2033 } 2034 `, 2035 map[string][]byte{ 2036 "a/Android.bp": []byte(provider_bp_a), 2037 "b/Android.bp": []byte(provider_bp_b), 2038 }) 2039 2040 testcases := []struct { 2041 moduleName string 2042 outputJarName string 2043 }{ 2044 { 2045 moduleName: "bar1", 2046 outputJarName: "bar1/bar1.jar", 2047 }, 2048 { 2049 moduleName: "bar2", 2050 outputJarName: "bar2/bar2.jar", 2051 }, 2052 } 2053 for _, c := range testcases { 2054 m := ctx.ModuleForTests(c.moduleName, "android_common") 2055 outputs := fmt.Sprint(m.AllOutputs()) 2056 if !strings.Contains(outputs, c.outputJarName) { 2057 t.Errorf("Module output does not contain expected jar %s", c.outputJarName) 2058 } 2059 } 2060} 2061 2062func TestJavaApiLibraryLibsLink(t *testing.T) { 2063 provider_bp_a := ` 2064 java_api_contribution { 2065 name: "foo1", 2066 api_file: "foo1.txt", 2067 } 2068 ` 2069 provider_bp_b := ` 2070 java_api_contribution { 2071 name: "foo2", 2072 api_file: "foo2.txt", 2073 } 2074 ` 2075 lib_bp_a := ` 2076 java_library { 2077 name: "lib1", 2078 srcs: ["Lib.java"], 2079 } 2080 ` 2081 lib_bp_b := ` 2082 java_library { 2083 name: "lib2", 2084 srcs: ["Lib.java"], 2085 } 2086 ` 2087 2088 ctx, _ := testJavaWithFS(t, ` 2089 java_api_library { 2090 name: "bar1", 2091 api_surface: "public", 2092 api_contributions: ["foo1"], 2093 libs: ["lib1"], 2094 } 2095 2096 java_api_library { 2097 name: "bar2", 2098 api_surface: "system", 2099 api_contributions: ["foo1", "foo2"], 2100 libs: ["lib1", "lib2", "bar1"], 2101 } 2102 `, 2103 map[string][]byte{ 2104 "a/Android.bp": []byte(provider_bp_a), 2105 "b/Android.bp": []byte(provider_bp_b), 2106 "c/Android.bp": []byte(lib_bp_a), 2107 "c/Lib.java": {}, 2108 "d/Android.bp": []byte(lib_bp_b), 2109 "d/Lib.java": {}, 2110 }) 2111 2112 testcases := []struct { 2113 moduleName string 2114 classPathJarNames []string 2115 }{ 2116 { 2117 moduleName: "bar1", 2118 classPathJarNames: []string{"lib1.jar"}, 2119 }, 2120 { 2121 moduleName: "bar2", 2122 classPathJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"}, 2123 }, 2124 } 2125 for _, c := range testcases { 2126 m := ctx.ModuleForTests(c.moduleName, "android_common") 2127 javacRules := m.Rule("javac") 2128 classPathArgs := javacRules.Args["classpath"] 2129 for _, jarName := range c.classPathJarNames { 2130 if !strings.Contains(classPathArgs, jarName) { 2131 t.Errorf("Module output does not contain expected jar %s", jarName) 2132 } 2133 } 2134 } 2135} 2136 2137func TestJavaApiLibraryStaticLibsLink(t *testing.T) { 2138 provider_bp_a := ` 2139 java_api_contribution { 2140 name: "foo1", 2141 api_file: "foo1.txt", 2142 } 2143 ` 2144 provider_bp_b := ` 2145 java_api_contribution { 2146 name: "foo2", 2147 api_file: "foo2.txt", 2148 } 2149 ` 2150 lib_bp_a := ` 2151 java_library { 2152 name: "lib1", 2153 srcs: ["Lib.java"], 2154 } 2155 ` 2156 lib_bp_b := ` 2157 java_library { 2158 name: "lib2", 2159 srcs: ["Lib.java"], 2160 } 2161 ` 2162 2163 ctx, _ := testJavaWithFS(t, ` 2164 java_api_library { 2165 name: "bar1", 2166 api_surface: "public", 2167 api_contributions: ["foo1"], 2168 static_libs: ["lib1"], 2169 } 2170 2171 java_api_library { 2172 name: "bar2", 2173 api_surface: "system", 2174 api_contributions: ["foo1", "foo2"], 2175 static_libs: ["lib1", "lib2", "bar1"], 2176 } 2177 `, 2178 map[string][]byte{ 2179 "a/Android.bp": []byte(provider_bp_a), 2180 "b/Android.bp": []byte(provider_bp_b), 2181 "c/Android.bp": []byte(lib_bp_a), 2182 "c/Lib.java": {}, 2183 "d/Android.bp": []byte(lib_bp_b), 2184 "d/Lib.java": {}, 2185 }) 2186 2187 testcases := []struct { 2188 moduleName string 2189 staticLibJarNames []string 2190 }{ 2191 { 2192 moduleName: "bar1", 2193 staticLibJarNames: []string{"lib1.jar"}, 2194 }, 2195 { 2196 moduleName: "bar2", 2197 staticLibJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"}, 2198 }, 2199 } 2200 for _, c := range testcases { 2201 m := ctx.ModuleForTests(c.moduleName, "android_common") 2202 mergeZipsCommand := m.Rule("merge_zips").RuleParams.Command 2203 for _, jarName := range c.staticLibJarNames { 2204 if !strings.Contains(mergeZipsCommand, jarName) { 2205 t.Errorf("merge_zips command does not contain expected jar %s", jarName) 2206 } 2207 } 2208 } 2209} 2210 2211func TestJavaApiLibraryDepApiSrcs(t *testing.T) { 2212 provider_bp_a := ` 2213 java_api_contribution { 2214 name: "foo1", 2215 api_file: "foo1.txt", 2216 } 2217 ` 2218 provider_bp_b := ` 2219 java_api_contribution { 2220 name: "foo2", 2221 api_file: "foo2.txt", 2222 } 2223 ` 2224 lib_bp_a := ` 2225 java_api_library { 2226 name: "lib1", 2227 api_surface: "public", 2228 api_contributions: ["foo1", "foo2"], 2229 } 2230 ` 2231 2232 ctx, _ := testJavaWithFS(t, ` 2233 java_api_library { 2234 name: "bar1", 2235 api_surface: "public", 2236 api_contributions: ["foo1"], 2237 dep_api_srcs: "lib1", 2238 } 2239 `, 2240 map[string][]byte{ 2241 "a/Android.bp": []byte(provider_bp_a), 2242 "b/Android.bp": []byte(provider_bp_b), 2243 "c/Android.bp": []byte(lib_bp_a), 2244 }) 2245 2246 m := ctx.ModuleForTests("bar1", "android_common") 2247 manifest := m.Output("metalava.sbox.textproto") 2248 sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest) 2249 manifestCommand := sboxProto.Commands[0].GetCommand() 2250 2251 android.AssertStringDoesContain(t, "Command expected to contain module srcjar file", manifestCommand, "bar1-stubs.srcjar") 2252 android.AssertStringDoesContain(t, "Command expected to contain output files list text file flag", manifestCommand, "--out __SBOX_SANDBOX_DIR__/out/sources.txt") 2253} 2254 2255func TestTradefedOptions(t *testing.T) { 2256 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, ` 2257java_test_host { 2258 name: "foo", 2259 test_options: { 2260 tradefed_options: [ 2261 { 2262 name: "exclude-path", 2263 value: "org/apache" 2264 } 2265 ] 2266 } 2267} 2268`) 2269 2270 buildOS := result.Config.BuildOS.String() 2271 args := result.ModuleForTests("foo", buildOS+"_common"). 2272 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args 2273 expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />") 2274 if args["extraConfigs"] != expected { 2275 t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"]) 2276 } 2277} 2278