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 "android/soong/python" 34) 35 36// Legacy preparer used for running tests within the java package. 37// 38// This includes everything that was needed to run any test in the java package prior to the 39// introduction of the test fixtures. Tests that are being converted to use fixtures directly 40// rather than through the testJava...() methods should avoid using this and instead use the 41// various preparers directly, using android.GroupFixturePreparers(...) to group them when 42// necessary. 43// 44// deprecated 45var prepareForJavaTest = android.GroupFixturePreparers( 46 genrule.PrepareForTestWithGenRuleBuildComponents, 47 // Get the CC build components but not default modules. 48 cc.PrepareForTestWithCcBuildComponents, 49 // Include all the default java modules. 50 PrepareForTestWithJavaDefaultModules, 51 PrepareForTestWithOverlayBuildComponents, 52 python.PrepareForTestWithPythonBuildComponents, 53 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 54 ctx.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory) 55 }), 56 PrepareForTestWithDexpreopt, 57) 58 59func TestMain(m *testing.M) { 60 os.Exit(m.Run()) 61} 62 63// testJavaError is a legacy way of running tests of java modules that expect errors. 64// 65// See testJava for an explanation as to how to stop using this deprecated method. 66// 67// deprecated 68func testJavaError(t *testing.T, pattern string, bp string) (*android.TestContext, android.Config) { 69 t.Helper() 70 result := android.GroupFixturePreparers( 71 prepareForJavaTest, dexpreopt.PrepareForTestByEnablingDexpreopt). 72 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). 73 RunTestWithBp(t, bp) 74 return result.TestContext, result.Config 75} 76 77// testJavaWithFS runs tests using the prepareForJavaTest 78// 79// See testJava for an explanation as to how to stop using this deprecated method. 80// 81// deprecated 82func testJavaWithFS(t *testing.T, bp string, fs android.MockFS) (*android.TestContext, android.Config) { 83 t.Helper() 84 result := android.GroupFixturePreparers( 85 prepareForJavaTest, fs.AddToFixture()).RunTestWithBp(t, bp) 86 return result.TestContext, result.Config 87} 88 89// testJava runs tests using the prepareForJavaTest 90// 91// Do not add any new usages of this, instead use the prepareForJavaTest directly as it makes it 92// much easier to customize the test behavior. 93// 94// If it is necessary to customize the behavior of an existing test that uses this then please first 95// convert the test to using prepareForJavaTest first and then in a following change add the 96// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify 97// that it did not change the test behavior unexpectedly. 98// 99// deprecated 100func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) { 101 t.Helper() 102 result := prepareForJavaTest.RunTestWithBp(t, bp) 103 return result.TestContext, result.Config 104} 105 106// defaultModuleToPath constructs a path to the turbine generate jar for a default test module that 107// is defined in PrepareForIntegrationTestWithJava 108func defaultModuleToPath(name string) string { 109 switch { 110 case name == `""`: 111 return name 112 case strings.HasSuffix(name, ".jar"): 113 return name 114 default: 115 return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine-combined", name+".jar") 116 } 117} 118 119// Test that the PrepareForTestWithJavaDefaultModules provides all the files that it uses by 120// running it in a fixture that requires all source files to exist. 121func TestPrepareForTestWithJavaDefaultModules(t *testing.T) { 122 android.GroupFixturePreparers( 123 PrepareForTestWithJavaDefaultModules, 124 android.PrepareForTestDisallowNonExistentPaths, 125 ).RunTest(t) 126} 127 128func TestJavaLinkType(t *testing.T) { 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 ctx, _ := testJava(t, ` 218 java_library { 219 name: "foo", 220 srcs: ["a.java"], 221 libs: ["bar"], 222 static_libs: ["baz"], 223 } 224 225 java_library { 226 name: "bar", 227 srcs: ["b.java"], 228 } 229 230 java_library { 231 name: "baz", 232 srcs: ["c.java"], 233 } 234 `) 235 236 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 237 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") 238 239 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { 240 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) 241 } 242 243 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String() 244 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar") 245 bazTurbine := filepath.Join("out", "soong", ".intermediates", "baz", "android_common", "turbine-combined", "baz.jar") 246 247 android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barTurbine) 248 249 android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazTurbine) 250 251 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz { 252 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz) 253 } 254} 255 256func TestExportedPlugins(t *testing.T) { 257 type Result struct { 258 library string 259 processors string 260 disableTurbine bool 261 } 262 var tests = []struct { 263 name string 264 extra string 265 results []Result 266 }{ 267 { 268 name: "Exported plugin is not a direct plugin", 269 extra: `java_library { name: "exports", srcs: ["a.java"], exported_plugins: ["plugin"] }`, 270 results: []Result{{library: "exports", processors: "-proc:none"}}, 271 }, 272 { 273 name: "Exports plugin to dependee", 274 extra: ` 275 java_library{name: "exports", exported_plugins: ["plugin"]} 276 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 277 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 278 `, 279 results: []Result{ 280 {library: "foo", processors: "-processor com.android.TestPlugin"}, 281 {library: "bar", processors: "-processor com.android.TestPlugin"}, 282 }, 283 }, 284 { 285 name: "Exports plugin to android_library", 286 extra: ` 287 java_library{name: "exports", exported_plugins: ["plugin"]} 288 android_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 289 android_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 290 `, 291 results: []Result{ 292 {library: "foo", processors: "-processor com.android.TestPlugin"}, 293 {library: "bar", processors: "-processor com.android.TestPlugin"}, 294 }, 295 }, 296 { 297 name: "Exports plugin is not propagated via transitive deps", 298 extra: ` 299 java_library{name: "exports", exported_plugins: ["plugin"]} 300 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 301 java_library{name: "bar", srcs: ["a.java"], static_libs: ["foo"]} 302 `, 303 results: []Result{ 304 {library: "foo", processors: "-processor com.android.TestPlugin"}, 305 {library: "bar", processors: "-proc:none"}, 306 }, 307 }, 308 { 309 name: "Exports plugin appends to plugins", 310 extra: ` 311 java_plugin{name: "plugin2", processor_class: "com.android.TestPlugin2"} 312 java_library{name: "exports", exported_plugins: ["plugin"]} 313 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"], plugins: ["plugin2"]} 314 `, 315 results: []Result{ 316 {library: "foo", processors: "-processor com.android.TestPlugin,com.android.TestPlugin2"}, 317 }, 318 }, 319 { 320 name: "Exports plugin to with generates_api to dependee", 321 extra: ` 322 java_library{name: "exports", exported_plugins: ["plugin_generates_api"]} 323 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]} 324 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]} 325 `, 326 results: []Result{ 327 {library: "foo", processors: "-processor com.android.TestPlugin", disableTurbine: true}, 328 {library: "bar", processors: "-processor com.android.TestPlugin", disableTurbine: true}, 329 }, 330 }, 331 } 332 333 for _, test := range tests { 334 t.Run(test.name, func(t *testing.T) { 335 ctx, _ := testJava(t, ` 336 java_plugin { 337 name: "plugin", 338 processor_class: "com.android.TestPlugin", 339 } 340 java_plugin { 341 name: "plugin_generates_api", 342 generates_api: true, 343 processor_class: "com.android.TestPlugin", 344 } 345 `+test.extra) 346 347 for _, want := range test.results { 348 javac := ctx.ModuleForTests(want.library, "android_common").Rule("javac") 349 if javac.Args["processor"] != want.processors { 350 t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"]) 351 } 352 turbine := ctx.ModuleForTests(want.library, "android_common").MaybeRule("turbine") 353 disableTurbine := turbine.BuildParams.Rule == nil 354 if disableTurbine != want.disableTurbine { 355 t.Errorf("For library %v, expected disableTurbine %v, found %v", want.library, want.disableTurbine, disableTurbine) 356 } 357 } 358 }) 359 } 360} 361 362func TestSdkVersionByPartition(t *testing.T) { 363 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", ` 364 java_library { 365 name: "foo", 366 srcs: ["a.java"], 367 vendor: true, 368 } 369 `) 370 371 testJava(t, ` 372 java_library { 373 name: "bar", 374 srcs: ["b.java"], 375 } 376 `) 377 378 for _, enforce := range []bool{true, false} { 379 bp := ` 380 java_library { 381 name: "foo", 382 srcs: ["a.java"], 383 product_specific: true, 384 } 385 ` 386 387 errorHandler := android.FixtureExpectsNoErrors 388 if enforce { 389 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product") 390 } 391 392 android.GroupFixturePreparers( 393 PrepareForTestWithJavaDefaultModules, 394 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 395 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce) 396 }), 397 ). 398 ExtendWithErrorHandler(errorHandler). 399 RunTestWithBp(t, bp) 400 } 401} 402 403func TestArchSpecific(t *testing.T) { 404 ctx, _ := testJava(t, ` 405 java_library { 406 name: "foo", 407 srcs: ["a.java"], 408 target: { 409 android: { 410 srcs: ["b.java"], 411 }, 412 }, 413 } 414 `) 415 416 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 417 if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" { 418 t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs) 419 } 420} 421 422func TestBinary(t *testing.T) { 423 ctx, _ := testJava(t, ` 424 java_library_host { 425 name: "foo", 426 srcs: ["a.java"], 427 } 428 429 java_binary_host { 430 name: "bar", 431 srcs: ["b.java"], 432 static_libs: ["foo"], 433 jni_libs: ["libjni"], 434 } 435 436 cc_library_shared { 437 name: "libjni", 438 host_supported: true, 439 device_supported: false, 440 stl: "none", 441 } 442 `) 443 444 buildOS := ctx.Config().BuildOS.String() 445 446 bar := ctx.ModuleForTests("bar", buildOS+"_common") 447 barJar := bar.Output("bar.jar").Output.String() 448 barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64") 449 barWrapperDeps := barWrapper.Output("bar").Implicits.Strings() 450 451 libjni := ctx.ModuleForTests("libjni", buildOS+"_x86_64_shared") 452 libjniSO := libjni.Rule("Cp").Output.String() 453 454 // Test that the install binary wrapper depends on the installed jar file 455 if g, w := barWrapperDeps, barJar; !android.InList(w, g) { 456 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g) 457 } 458 459 // Test that the install binary wrapper depends on the installed JNI libraries 460 if g, w := barWrapperDeps, libjniSO; !android.InList(w, g) { 461 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g) 462 } 463} 464 465func TestTest(t *testing.T) { 466 ctx, _ := testJava(t, ` 467 java_test_host { 468 name: "foo", 469 srcs: ["a.java"], 470 jni_libs: ["libjni"], 471 } 472 473 cc_library_shared { 474 name: "libjni", 475 host_supported: true, 476 device_supported: false, 477 stl: "none", 478 } 479 `) 480 481 buildOS := ctx.Config().BuildOS.String() 482 483 foo := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) 484 485 expected := "lib64/libjni.so" 486 if runtime.GOOS == "darwin" { 487 expected = "lib64/libjni.dylib" 488 } 489 490 fooTestData := foo.data 491 if len(fooTestData) != 1 || fooTestData[0].Rel() != expected { 492 t.Errorf(`expected foo test data relative path [%q], got %q`, 493 expected, fooTestData.Strings()) 494 } 495} 496 497func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) { 498 bp := ` 499 java_library { 500 name: "target_library", 501 srcs: ["a.java"], 502 } 503 504 java_binary_host { 505 name: "host_binary", 506 srcs: ["b.java"], 507 } 508 ` 509 510 result := android.GroupFixturePreparers( 511 PrepareForTestWithJavaDefaultModules, 512 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 513 variables.MinimizeJavaDebugInfo = proptools.BoolPtr(true) 514 }), 515 ).RunTestWithBp(t, bp) 516 517 // first, check that the -g flag is added to target modules 518 targetLibrary := result.ModuleForTests("target_library", "android_common") 519 targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"] 520 if !strings.Contains(targetJavaFlags, "-g:source,lines") { 521 t.Errorf("target library javac flags %v should contain "+ 522 "-g:source,lines override with MinimizeJavaDebugInfo", targetJavaFlags) 523 } 524 525 // check that -g is not overridden for host modules 526 buildOS := result.Config.BuildOS.String() 527 hostBinary := result.ModuleForTests("host_binary", buildOS+"_common") 528 hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"] 529 if strings.Contains(hostJavaFlags, "-g:source,lines") { 530 t.Errorf("java_binary_host javac flags %v should not have "+ 531 "-g:source,lines override with MinimizeJavaDebugInfo", hostJavaFlags) 532 } 533} 534 535func TestPrebuilts(t *testing.T) { 536 ctx, _ := testJava(t, ` 537 java_library { 538 name: "foo", 539 srcs: ["a.java", ":stubs-source"], 540 libs: ["bar", "sdklib"], 541 static_libs: ["baz"], 542 } 543 544 java_import { 545 name: "bar", 546 jars: ["a.jar"], 547 } 548 549 java_import { 550 name: "baz", 551 jars: ["b.jar"], 552 sdk_version: "current", 553 compile_dex: true, 554 } 555 556 dex_import { 557 name: "qux", 558 jars: ["b.jar"], 559 } 560 561 java_sdk_library_import { 562 name: "sdklib", 563 public: { 564 jars: ["c.jar"], 565 }, 566 } 567 568 prebuilt_stubs_sources { 569 name: "stubs-source", 570 srcs: ["stubs/sources"], 571 } 572 573 java_test_import { 574 name: "test", 575 jars: ["a.jar"], 576 test_suites: ["cts"], 577 test_config: "AndroidTest.xml", 578 } 579 `) 580 581 fooModule := ctx.ModuleForTests("foo", "android_common") 582 javac := fooModule.Rule("javac") 583 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") 584 barModule := ctx.ModuleForTests("bar", "android_common") 585 barJar := barModule.Rule("combineJar").Output 586 bazModule := ctx.ModuleForTests("baz", "android_common") 587 bazJar := bazModule.Rule("combineJar").Output 588 sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output 589 590 fooLibrary := fooModule.Module().(*Library) 591 assertDeepEquals(t, "foo java sources incorrect", 592 []string{"a.java"}, fooLibrary.compiledJavaSrcs.Strings()) 593 594 assertDeepEquals(t, "foo java source jars incorrect", 595 []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"}, 596 android.NormalizePathsForTesting(fooLibrary.compiledSrcJars)) 597 598 if !strings.Contains(javac.Args["classpath"], barJar.String()) { 599 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String()) 600 } 601 602 barDexJar := barModule.Module().(*Import).DexJarBuildPath() 603 if barDexJar.IsSet() { 604 t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar) 605 } 606 607 if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) { 608 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String()) 609 } 610 611 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() { 612 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String()) 613 } 614 615 bazDexJar := bazModule.Module().(*Import).DexJarBuildPath().Path() 616 expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar" 617 android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar) 618 619 ctx.ModuleForTests("qux", "android_common").Rule("Cp") 620} 621 622func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) { 623 if !reflect.DeepEqual(expected, actual) { 624 t.Errorf("%s: expected %q, found %q", message, expected, actual) 625 } 626} 627 628func TestPrebuiltStubsSources(t *testing.T) { 629 test := func(t *testing.T, sourcesPath string, expectedInputs []string) { 630 ctx, _ := testJavaWithFS(t, fmt.Sprintf(` 631prebuilt_stubs_sources { 632 name: "stubs-source", 633 srcs: ["%s"], 634}`, sourcesPath), map[string][]byte{ 635 "stubs/sources/pkg/A.java": nil, 636 "stubs/sources/pkg/B.java": nil, 637 }) 638 639 zipSrc := ctx.ModuleForTests("stubs-source", "android_common").Rule("zip_src") 640 if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) { 641 t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual) 642 } 643 } 644 645 t.Run("empty/missing directory", func(t *testing.T) { 646 test(t, "empty-directory", nil) 647 }) 648 649 t.Run("non-empty set of sources", func(t *testing.T) { 650 test(t, "stubs/sources", []string{ 651 "stubs/sources/pkg/A.java", 652 "stubs/sources/pkg/B.java", 653 }) 654 }) 655} 656 657func TestDefaults(t *testing.T) { 658 ctx, _ := testJava(t, ` 659 java_defaults { 660 name: "defaults", 661 srcs: ["a.java"], 662 libs: ["bar"], 663 static_libs: ["baz"], 664 optimize: {enabled: false}, 665 } 666 667 java_library { 668 name: "foo", 669 defaults: ["defaults"], 670 } 671 672 java_library { 673 name: "bar", 674 srcs: ["b.java"], 675 } 676 677 java_library { 678 name: "baz", 679 srcs: ["c.java"], 680 } 681 682 android_test { 683 name: "atestOptimize", 684 defaults: ["defaults"], 685 optimize: {enabled: true}, 686 } 687 688 android_test { 689 name: "atestNoOptimize", 690 defaults: ["defaults"], 691 } 692 693 android_test { 694 name: "atestDefault", 695 srcs: ["a.java"], 696 } 697 `) 698 699 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 700 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") 701 702 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { 703 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) 704 } 705 706 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar") 707 if !strings.Contains(javac.Args["classpath"], barTurbine) { 708 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine) 709 } 710 711 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String() 712 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz { 713 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz) 714 } 715 716 atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8") 717 if atestOptimize.Output == nil { 718 t.Errorf("atestOptimize should optimize APK") 719 } 720 721 atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8") 722 if atestNoOptimize.Output == nil { 723 t.Errorf("atestNoOptimize should not optimize APK") 724 } 725 726 atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("r8") 727 if atestDefault.Output == nil { 728 t.Errorf("atestDefault should optimize APK") 729 } 730} 731 732func TestResources(t *testing.T) { 733 var table = []struct { 734 name string 735 prop string 736 extra string 737 args string 738 }{ 739 { 740 // Test that a module with java_resource_dirs includes the files 741 name: "resource dirs", 742 prop: `java_resource_dirs: ["java-res"]`, 743 args: "-C java-res -f java-res/a/a -f java-res/b/b", 744 }, 745 { 746 // Test that a module with java_resources includes the files 747 name: "resource files", 748 prop: `java_resources: ["java-res/a/a", "java-res/b/b"]`, 749 args: "-C . -f java-res/a/a -f java-res/b/b", 750 }, 751 { 752 // Test that a module with a filegroup in java_resources includes the files with the 753 // path prefix 754 name: "resource filegroup", 755 prop: `java_resources: [":foo-res"]`, 756 extra: ` 757 filegroup { 758 name: "foo-res", 759 path: "java-res", 760 srcs: ["java-res/a/a", "java-res/b/b"], 761 }`, 762 args: "-C java-res -f java-res/a/a -f java-res/b/b", 763 }, 764 { 765 // Test that a module with wildcards in java_resource_dirs has the correct path prefixes 766 name: "wildcard dirs", 767 prop: `java_resource_dirs: ["java-res/*"]`, 768 args: "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b", 769 }, 770 { 771 // Test that a module exclude_java_resource_dirs excludes the files 772 name: "wildcard dirs", 773 prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`, 774 args: "-C java-res/a -f java-res/a/a", 775 }, 776 { 777 // Test wildcards in java_resources 778 name: "wildcard files", 779 prop: `java_resources: ["java-res/**/*"]`, 780 args: "-C . -f java-res/a/a -f java-res/b/b", 781 }, 782 { 783 // Test exclude_java_resources with java_resources 784 name: "wildcard files with exclude", 785 prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`, 786 args: "-C . -f java-res/a/a", 787 }, 788 { 789 // Test exclude_java_resources with java_resource_dirs 790 name: "resource dirs with exclude files", 791 prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`, 792 args: "-C java-res -f java-res/a/a", 793 }, 794 { 795 // Test exclude_java_resource_dirs with java_resource_dirs 796 name: "resource dirs with exclude files", 797 prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`, 798 args: "-C java-res -f java-res/a/a -f java-res/b/b", 799 }, 800 } 801 802 for _, test := range table { 803 t.Run(test.name, func(t *testing.T) { 804 ctx, _ := testJavaWithFS(t, ` 805 java_library { 806 name: "foo", 807 srcs: [ 808 "a.java", 809 "b.java", 810 "c.java", 811 ], 812 `+test.prop+`, 813 } 814 `+test.extra, 815 map[string][]byte{ 816 "java-res/a/a": nil, 817 "java-res/b/b": nil, 818 "java-res2/a": nil, 819 }, 820 ) 821 822 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") 823 fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar") 824 825 if !inList(fooRes.Output.String(), foo.Inputs.Strings()) { 826 t.Errorf("foo combined jars %v does not contain %q", 827 foo.Inputs.Strings(), fooRes.Output.String()) 828 } 829 830 if fooRes.Args["jarArgs"] != test.args { 831 t.Errorf("foo resource jar args %q is not %q", 832 fooRes.Args["jarArgs"], test.args) 833 } 834 }) 835 } 836} 837 838func TestIncludeSrcs(t *testing.T) { 839 ctx, _ := testJavaWithFS(t, ` 840 java_library { 841 name: "foo", 842 srcs: [ 843 "a.java", 844 "b.java", 845 "c.java", 846 ], 847 include_srcs: true, 848 } 849 850 java_library { 851 name: "bar", 852 srcs: [ 853 "a.java", 854 "b.java", 855 "c.java", 856 ], 857 java_resource_dirs: ["java-res"], 858 include_srcs: true, 859 } 860 `, map[string][]byte{ 861 "java-res/a/a": nil, 862 "java-res/b/b": nil, 863 "java-res2/a": nil, 864 }) 865 866 // Test a library with include_srcs: true 867 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") 868 fooSrcJar := ctx.ModuleForTests("foo", "android_common").Output("foo.srcjar") 869 870 if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) { 871 t.Errorf("foo combined jars %v does not contain %q", w, g) 872 } 873 874 if g, w := fooSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w { 875 t.Errorf("foo source jar args %q is not %q", w, g) 876 } 877 878 // Test a library with include_srcs: true and resources 879 bar := ctx.ModuleForTests("bar", "android_common").Output("withres/bar.jar") 880 barResCombined := ctx.ModuleForTests("bar", "android_common").Output("res-combined/bar.jar") 881 barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar") 882 barSrcJar := ctx.ModuleForTests("bar", "android_common").Output("bar.srcjar") 883 884 if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) { 885 t.Errorf("bar combined resource jars %v does not contain %q", w, g) 886 } 887 888 if g, w := barRes.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 := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) { 893 t.Errorf("bar combined jars %v does not contain %q", w, g) 894 } 895 896 if g, w := barSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w { 897 t.Errorf("bar source jar args %q is not %q", w, g) 898 } 899 900 if g, w := barRes.Args["jarArgs"], "-C java-res -f java-res/a/a -f java-res/b/b"; g != w { 901 t.Errorf("bar resource jar args %q is not %q", w, g) 902 } 903} 904 905func TestGeneratedSources(t *testing.T) { 906 ctx, _ := testJavaWithFS(t, ` 907 java_library { 908 name: "foo", 909 srcs: [ 910 "a*.java", 911 ":gen", 912 "b*.java", 913 ], 914 } 915 916 genrule { 917 name: "gen", 918 tool_files: ["java-res/a"], 919 out: ["gen.java"], 920 } 921 `, map[string][]byte{ 922 "a.java": nil, 923 "b.java": nil, 924 }) 925 926 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 927 genrule := ctx.ModuleForTests("gen", "").Rule("generator") 928 929 if filepath.Base(genrule.Output.String()) != "gen.java" { 930 t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String()) 931 } 932 933 if len(javac.Inputs) != 3 || 934 javac.Inputs[0].String() != "a.java" || 935 javac.Inputs[1].String() != genrule.Output.String() || 936 javac.Inputs[2].String() != "b.java" { 937 t.Errorf(`foo inputs %v != ["a.java", ".../gen.java", "b.java"]`, javac.Inputs) 938 } 939} 940 941func TestTurbine(t *testing.T) { 942 result := android.GroupFixturePreparers( 943 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})). 944 RunTestWithBp(t, ` 945 java_library { 946 name: "foo", 947 srcs: ["a.java"], 948 sdk_version: "14", 949 } 950 951 java_library { 952 name: "bar", 953 srcs: ["b.java"], 954 static_libs: ["foo"], 955 sdk_version: "14", 956 } 957 958 java_library { 959 name: "baz", 960 srcs: ["c.java"], 961 libs: ["bar"], 962 sdk_version: "14", 963 } 964 `) 965 966 fooTurbine := result.ModuleForTests("foo", "android_common").Rule("turbine") 967 barTurbine := result.ModuleForTests("bar", "android_common").Rule("turbine") 968 barJavac := result.ModuleForTests("bar", "android_common").Rule("javac") 969 barTurbineCombined := result.ModuleForTests("bar", "android_common").Description("for turbine") 970 bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac") 971 972 android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs) 973 974 fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar") 975 barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 976 android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar) 977 android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar) 978 android.AssertPathsRelativeToTopEquals(t, "bar turbine combineJar", []string{barTurbineJar, fooHeaderJar}, barTurbineCombined.Inputs) 979 android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "prebuilts/sdk/14/public/android.jar") 980} 981 982func TestSharding(t *testing.T) { 983 ctx, _ := testJava(t, ` 984 java_library { 985 name: "bar", 986 srcs: ["a.java","b.java","c.java"], 987 javac_shard_size: 1 988 } 989 `) 990 991 barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 992 for i := 0; i < 3; i++ { 993 barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i)) 994 if !strings.HasPrefix(barJavac.Args["classpath"], "-classpath "+barHeaderJar+":") { 995 t.Errorf("bar javac classpath %v does start with %q", barJavac.Args["classpath"], barHeaderJar) 996 } 997 } 998} 999 1000func TestExcludeFileGroupInSrcs(t *testing.T) { 1001 ctx, _ := testJava(t, ` 1002 java_library { 1003 name: "foo", 1004 srcs: ["a.java", ":foo-srcs"], 1005 exclude_srcs: ["a.java", ":foo-excludes"], 1006 } 1007 1008 filegroup { 1009 name: "foo-srcs", 1010 srcs: ["java-fg/a.java", "java-fg/b.java", "java-fg/c.java"], 1011 } 1012 1013 filegroup { 1014 name: "foo-excludes", 1015 srcs: ["java-fg/a.java", "java-fg/b.java"], 1016 } 1017 `) 1018 1019 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 1020 1021 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" { 1022 t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs) 1023 } 1024} 1025 1026func TestJavaLibrary(t *testing.T) { 1027 testJavaWithFS(t, "", map[string][]byte{ 1028 "libcore/Android.bp": []byte(` 1029 java_library { 1030 name: "core", 1031 sdk_version: "none", 1032 system_modules: "none", 1033 } 1034 1035 filegroup { 1036 name: "core-jar", 1037 srcs: [":core{.jar}"], 1038 } 1039 `), 1040 }) 1041} 1042 1043func TestJavaImport(t *testing.T) { 1044 testJavaWithFS(t, "", map[string][]byte{ 1045 "libcore/Android.bp": []byte(` 1046 java_import { 1047 name: "core", 1048 sdk_version: "none", 1049 } 1050 1051 filegroup { 1052 name: "core-jar", 1053 srcs: [":core{.jar}"], 1054 } 1055 `), 1056 }) 1057} 1058 1059var compilerFlagsTestCases = []struct { 1060 in string 1061 out bool 1062}{ 1063 { 1064 in: "a", 1065 out: false, 1066 }, 1067 { 1068 in: "-a", 1069 out: true, 1070 }, 1071 { 1072 in: "-no-jdk", 1073 out: false, 1074 }, 1075 { 1076 in: "-no-stdlib", 1077 out: false, 1078 }, 1079 { 1080 in: "-kotlin-home", 1081 out: false, 1082 }, 1083 { 1084 in: "-kotlin-home /some/path", 1085 out: false, 1086 }, 1087 { 1088 in: "-include-runtime", 1089 out: false, 1090 }, 1091 { 1092 in: "-Xintellij-plugin-root", 1093 out: false, 1094 }, 1095} 1096 1097type mockContext struct { 1098 android.ModuleContext 1099 result bool 1100} 1101 1102func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) { 1103 // CheckBadCompilerFlags calls this function when the flag should be rejected 1104 ctx.result = false 1105} 1106 1107func TestCompilerFlags(t *testing.T) { 1108 for _, testCase := range compilerFlagsTestCases { 1109 ctx := &mockContext{result: true} 1110 CheckKotlincFlags(ctx, []string{testCase.in}) 1111 if ctx.result != testCase.out { 1112 t.Errorf("incorrect output:") 1113 t.Errorf(" input: %#v", testCase.in) 1114 t.Errorf(" expected: %#v", testCase.out) 1115 t.Errorf(" got: %#v", ctx.result) 1116 } 1117 } 1118} 1119 1120// TODO(jungjw): Consider making this more robust by ignoring path order. 1121func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) { 1122 variables := ctx.ModuleForTests(moduleName, "android_common").VariablesForTestsRelativeToTop() 1123 flags := strings.Split(variables["javacFlags"], " ") 1124 got := "" 1125 for _, flag := range flags { 1126 keyEnd := strings.Index(flag, "=") 1127 if keyEnd > -1 && flag[:keyEnd] == "--patch-module" { 1128 got = flag[keyEnd+1:] 1129 break 1130 } 1131 } 1132 if expected != android.StringPathRelativeToTop(ctx.Config().SoongOutDir(), got) { 1133 t.Errorf("Unexpected patch-module flag for module %q - expected %q, but got %q", moduleName, expected, got) 1134 } 1135} 1136 1137func TestPatchModule(t *testing.T) { 1138 t.Run("Java language level 8", func(t *testing.T) { 1139 // Test with legacy javac -source 1.8 -target 1.8 1140 bp := ` 1141 java_library { 1142 name: "foo", 1143 srcs: ["a.java"], 1144 java_version: "1.8", 1145 } 1146 1147 java_library { 1148 name: "bar", 1149 srcs: ["b.java"], 1150 sdk_version: "none", 1151 system_modules: "none", 1152 patch_module: "java.base", 1153 java_version: "1.8", 1154 } 1155 1156 java_library { 1157 name: "baz", 1158 srcs: ["c.java"], 1159 patch_module: "java.base", 1160 java_version: "1.8", 1161 } 1162 ` 1163 ctx, _ := testJava(t, bp) 1164 1165 checkPatchModuleFlag(t, ctx, "foo", "") 1166 checkPatchModuleFlag(t, ctx, "bar", "") 1167 checkPatchModuleFlag(t, ctx, "baz", "") 1168 }) 1169 1170 t.Run("Java language level 9", func(t *testing.T) { 1171 // Test with default javac -source 9 -target 9 1172 bp := ` 1173 java_library { 1174 name: "foo", 1175 srcs: ["a.java"], 1176 } 1177 1178 java_library { 1179 name: "bar", 1180 srcs: ["b.java"], 1181 sdk_version: "none", 1182 system_modules: "none", 1183 patch_module: "java.base", 1184 } 1185 1186 java_library { 1187 name: "baz", 1188 srcs: [ 1189 "c.java", 1190 // Tests for b/150878007 1191 "dir/d.java", 1192 "dir2/e.java", 1193 "dir2/f.java", 1194 "nested/dir/g.java" 1195 ], 1196 patch_module: "java.base", 1197 } 1198 ` 1199 ctx, _ := testJava(t, bp) 1200 1201 checkPatchModuleFlag(t, ctx, "foo", "") 1202 expected := "java.base=.:out/soong" 1203 checkPatchModuleFlag(t, ctx, "bar", expected) 1204 expected = "java.base=" + strings.Join([]string{ 1205 ".", "out/soong", "dir", "dir2", "nested", defaultModuleToPath("ext"), defaultModuleToPath("framework")}, ":") 1206 checkPatchModuleFlag(t, ctx, "baz", expected) 1207 }) 1208} 1209 1210func TestJavaLibraryWithSystemModules(t *testing.T) { 1211 ctx, _ := testJava(t, ` 1212 java_library { 1213 name: "lib-with-source-system-modules", 1214 srcs: [ 1215 "a.java", 1216 ], 1217 sdk_version: "none", 1218 system_modules: "source-system-modules", 1219 } 1220 1221 java_library { 1222 name: "source-jar", 1223 srcs: [ 1224 "a.java", 1225 ], 1226 } 1227 1228 java_system_modules { 1229 name: "source-system-modules", 1230 libs: ["source-jar"], 1231 } 1232 1233 java_library { 1234 name: "lib-with-prebuilt-system-modules", 1235 srcs: [ 1236 "a.java", 1237 ], 1238 sdk_version: "none", 1239 system_modules: "prebuilt-system-modules", 1240 } 1241 1242 java_import { 1243 name: "prebuilt-jar", 1244 jars: ["a.jar"], 1245 } 1246 1247 java_system_modules_import { 1248 name: "prebuilt-system-modules", 1249 libs: ["prebuilt-jar"], 1250 } 1251 `) 1252 1253 checkBootClasspathForSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar") 1254 1255 checkBootClasspathForSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar") 1256} 1257 1258func checkBootClasspathForSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) { 1259 javacRule := ctx.ModuleForTests(moduleName, "android_common").Rule("javac") 1260 bootClasspath := javacRule.Args["bootClasspath"] 1261 if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) { 1262 t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath) 1263 } 1264} 1265 1266func TestAidlExportIncludeDirsFromImports(t *testing.T) { 1267 ctx, _ := testJava(t, ` 1268 java_library { 1269 name: "foo", 1270 srcs: ["aidl/foo/IFoo.aidl"], 1271 libs: ["bar"], 1272 } 1273 1274 java_import { 1275 name: "bar", 1276 jars: ["a.jar"], 1277 aidl: { 1278 export_include_dirs: ["aidl/bar"], 1279 }, 1280 } 1281 `) 1282 1283 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1284 expectedAidlFlag := "-Iaidl/bar" 1285 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1286 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1287 } 1288} 1289 1290func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) { 1291 ctx, _ := testJava(t, ` 1292 java_library { 1293 name: "foo", 1294 srcs: ["aidl/foo/IFoo.aidl"], 1295 aidl: { flags: ["-Werror"], }, 1296 } 1297 `) 1298 1299 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1300 expectedAidlFlag := "-Werror" 1301 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1302 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1303 } 1304} 1305 1306func TestAidlFlagsWithMinSdkVersion(t *testing.T) { 1307 fixture := android.GroupFixturePreparers( 1308 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})) 1309 1310 for _, tc := range []struct { 1311 name string 1312 sdkVersion string 1313 expected string 1314 }{ 1315 {"default is current", "", "current"}, 1316 {"use sdk_version", `sdk_version: "14"`, "14"}, 1317 {"system_current", `sdk_version: "system_current"`, "current"}, 1318 } { 1319 t.Run(tc.name, func(t *testing.T) { 1320 ctx := fixture.RunTestWithBp(t, ` 1321 java_library { 1322 name: "foo", 1323 srcs: ["aidl/foo/IFoo.aidl"], 1324 `+tc.sdkVersion+` 1325 } 1326 `) 1327 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1328 expectedAidlFlag := "--min_sdk_version=" + tc.expected 1329 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1330 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1331 } 1332 }) 1333 } 1334} 1335 1336func TestAidlEnforcePermissions(t *testing.T) { 1337 ctx, _ := testJava(t, ` 1338 java_library { 1339 name: "foo", 1340 srcs: ["aidl/foo/IFoo.aidl"], 1341 aidl: { enforce_permissions: true }, 1342 } 1343 `) 1344 1345 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1346 expectedAidlFlag := "-Wmissing-permission-annotation -Werror" 1347 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1348 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1349 } 1350} 1351 1352func TestAidlEnforcePermissionsException(t *testing.T) { 1353 ctx, _ := testJava(t, ` 1354 java_library { 1355 name: "foo", 1356 srcs: ["aidl/foo/IFoo.aidl", "aidl/foo/IFoo2.aidl"], 1357 aidl: { enforce_permissions: true, enforce_permissions_exceptions: ["aidl/foo/IFoo2.aidl"] }, 1358 } 1359 `) 1360 1361 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1362 expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl" 1363 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1364 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1365 } 1366 expectedAidlFlag = "$$FLAGS aidl/foo/IFoo2.aidl" 1367 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1368 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1369 } 1370} 1371 1372func TestDataNativeBinaries(t *testing.T) { 1373 ctx, _ := testJava(t, ` 1374 java_test_host { 1375 name: "foo", 1376 srcs: ["a.java"], 1377 data_native_bins: ["bin"] 1378 } 1379 1380 python_binary_host { 1381 name: "bin", 1382 srcs: ["bin.py"], 1383 } 1384 `) 1385 1386 buildOS := ctx.Config().BuildOS.String() 1387 1388 test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) 1389 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0] 1390 expected := []string{"out/soong/.intermediates/bin/" + buildOS + "_x86_64_PY3/bin:bin"} 1391 actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 1392 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_COMPATIBILITY_SUPPORT_FILES", ctx.Config(), expected, actual) 1393} 1394 1395func TestDefaultInstallable(t *testing.T) { 1396 ctx, _ := testJava(t, ` 1397 java_test_host { 1398 name: "foo" 1399 } 1400 `) 1401 1402 buildOS := ctx.Config().BuildOS.String() 1403 module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) 1404 assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true), 1405 module.properties.Installable) 1406} 1407 1408func TestErrorproneEnabled(t *testing.T) { 1409 ctx, _ := testJava(t, ` 1410 java_library { 1411 name: "foo", 1412 srcs: ["a.java"], 1413 errorprone: { 1414 enabled: true, 1415 }, 1416 } 1417 `) 1418 1419 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1420 1421 // Test that the errorprone plugins are passed to javac 1422 expectedSubstring := "-Xplugin:ErrorProne" 1423 if !strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1424 t.Errorf("expected javacFlags to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1425 } 1426 1427 // Modules with errorprone { enabled: true } will include errorprone checks 1428 // in the main javac build rule. Only when RUN_ERROR_PRONE is true will 1429 // the explicit errorprone build rule be created. 1430 errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone") 1431 if errorprone.RuleParams.Description != "" { 1432 t.Errorf("expected errorprone build rule to not exist, but it did") 1433 } 1434} 1435 1436func TestErrorproneDisabled(t *testing.T) { 1437 bp := ` 1438 java_library { 1439 name: "foo", 1440 srcs: ["a.java"], 1441 errorprone: { 1442 enabled: false, 1443 }, 1444 } 1445 ` 1446 ctx := android.GroupFixturePreparers( 1447 PrepareForTestWithJavaDefaultModules, 1448 android.FixtureMergeEnv(map[string]string{ 1449 "RUN_ERROR_PRONE": "true", 1450 }), 1451 ).RunTestWithBp(t, bp) 1452 1453 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1454 1455 // Test that the errorprone plugins are not passed to javac, like they would 1456 // be if enabled was true. 1457 expectedSubstring := "-Xplugin:ErrorProne" 1458 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1459 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1460 } 1461 1462 // Check that no errorprone build rule is created, like there would be 1463 // if enabled was unset and RUN_ERROR_PRONE was true. 1464 errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone") 1465 if errorprone.RuleParams.Description != "" { 1466 t.Errorf("expected errorprone build rule to not exist, but it did") 1467 } 1468} 1469 1470func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) { 1471 bp := ` 1472 java_library { 1473 name: "foo", 1474 srcs: ["a.java"], 1475 } 1476 ` 1477 ctx := android.GroupFixturePreparers( 1478 PrepareForTestWithJavaDefaultModules, 1479 android.FixtureMergeEnv(map[string]string{ 1480 "RUN_ERROR_PRONE": "true", 1481 }), 1482 ).RunTestWithBp(t, bp) 1483 1484 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1485 errorprone := ctx.ModuleForTests("foo", "android_common").Description("errorprone") 1486 1487 // Check that the errorprone plugins are not passed to javac, because they 1488 // will instead be passed to the separate errorprone compilation 1489 expectedSubstring := "-Xplugin:ErrorProne" 1490 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1491 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1492 } 1493 1494 // Check that the errorprone plugin is enabled 1495 if !strings.Contains(errorprone.Args["javacFlags"], expectedSubstring) { 1496 t.Errorf("expected errorprone to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1497 } 1498} 1499 1500func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) { 1501 testCases := []struct { 1502 dataDeviceBinType string 1503 depCompileMultilib string 1504 variants []string 1505 expectedError string 1506 }{ 1507 { 1508 dataDeviceBinType: "first", 1509 depCompileMultilib: "first", 1510 variants: []string{"android_arm64_armv8-a"}, 1511 }, 1512 { 1513 dataDeviceBinType: "first", 1514 depCompileMultilib: "both", 1515 variants: []string{"android_arm64_armv8-a"}, 1516 }, 1517 { 1518 // this is true because our testing framework is set up with 1519 // Targets ~ [<64bit target>, <32bit target>], where 64bit is "first" 1520 dataDeviceBinType: "first", 1521 depCompileMultilib: "32", 1522 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1523 }, 1524 { 1525 dataDeviceBinType: "first", 1526 depCompileMultilib: "64", 1527 variants: []string{"android_arm64_armv8-a"}, 1528 }, 1529 { 1530 dataDeviceBinType: "both", 1531 depCompileMultilib: "both", 1532 variants: []string{ 1533 "android_arm_armv7-a-neon", 1534 "android_arm64_armv8-a", 1535 }, 1536 }, 1537 { 1538 dataDeviceBinType: "both", 1539 depCompileMultilib: "32", 1540 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1541 }, 1542 { 1543 dataDeviceBinType: "both", 1544 depCompileMultilib: "64", 1545 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1546 }, 1547 { 1548 dataDeviceBinType: "both", 1549 depCompileMultilib: "first", 1550 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1551 }, 1552 { 1553 dataDeviceBinType: "32", 1554 depCompileMultilib: "32", 1555 variants: []string{"android_arm_armv7-a-neon"}, 1556 }, 1557 { 1558 dataDeviceBinType: "32", 1559 depCompileMultilib: "first", 1560 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1561 }, 1562 { 1563 dataDeviceBinType: "32", 1564 depCompileMultilib: "both", 1565 variants: []string{"android_arm_armv7-a-neon"}, 1566 }, 1567 { 1568 dataDeviceBinType: "32", 1569 depCompileMultilib: "64", 1570 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1571 }, 1572 { 1573 dataDeviceBinType: "64", 1574 depCompileMultilib: "64", 1575 variants: []string{"android_arm64_armv8-a"}, 1576 }, 1577 { 1578 dataDeviceBinType: "64", 1579 depCompileMultilib: "both", 1580 variants: []string{"android_arm64_armv8-a"}, 1581 }, 1582 { 1583 dataDeviceBinType: "64", 1584 depCompileMultilib: "first", 1585 variants: []string{"android_arm64_armv8-a"}, 1586 }, 1587 { 1588 dataDeviceBinType: "64", 1589 depCompileMultilib: "32", 1590 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1591 }, 1592 { 1593 dataDeviceBinType: "prefer32", 1594 depCompileMultilib: "32", 1595 variants: []string{"android_arm_armv7-a-neon"}, 1596 }, 1597 { 1598 dataDeviceBinType: "prefer32", 1599 depCompileMultilib: "both", 1600 variants: []string{"android_arm_armv7-a-neon"}, 1601 }, 1602 { 1603 dataDeviceBinType: "prefer32", 1604 depCompileMultilib: "first", 1605 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1606 }, 1607 { 1608 dataDeviceBinType: "prefer32", 1609 depCompileMultilib: "64", 1610 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1611 }, 1612 } 1613 1614 bpTemplate := ` 1615 java_test_host { 1616 name: "foo", 1617 srcs: ["test.java"], 1618 data_device_bins_%s: ["bar"], 1619 } 1620 1621 cc_binary { 1622 name: "bar", 1623 compile_multilib: "%s", 1624 } 1625 ` 1626 1627 for _, tc := range testCases { 1628 bp := fmt.Sprintf(bpTemplate, tc.dataDeviceBinType, tc.depCompileMultilib) 1629 1630 errorHandler := android.FixtureExpectsNoErrors 1631 if tc.expectedError != "" { 1632 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError) 1633 } 1634 1635 testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib) 1636 t.Run(testName, func(t *testing.T) { 1637 ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava). 1638 ExtendWithErrorHandler(errorHandler). 1639 RunTestWithBp(t, bp) 1640 if tc.expectedError != "" { 1641 return 1642 } 1643 1644 buildOS := ctx.Config.BuildOS.String() 1645 fooVariant := ctx.ModuleForTests("foo", buildOS+"_common") 1646 fooMod := fooVariant.Module().(*TestHost) 1647 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0] 1648 1649 expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />` 1650 autogen := fooVariant.Rule("autogen") 1651 if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) { 1652 t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig) 1653 } 1654 1655 expectedData := []string{} 1656 for _, variant := range tc.variants { 1657 barVariant := ctx.ModuleForTests("bar", variant) 1658 relocated := barVariant.Output("bar") 1659 expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant) 1660 android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input) 1661 1662 expectedData = append(expectedData, fmt.Sprintf("out/soong/.intermediates/bar/%s/bar:bar", variant)) 1663 } 1664 1665 actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 1666 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData) 1667 }) 1668 } 1669} 1670