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" 28 "github.com/google/blueprint/proptools" 29 30 "android/soong/aconfig" 31 "android/soong/android" 32 "android/soong/cc" 33 "android/soong/dexpreopt" 34 "android/soong/genrule" 35) 36 37// Legacy preparer used for running tests within the java package. 38// 39// This includes everything that was needed to run any test in the java package prior to the 40// introduction of the test fixtures. Tests that are being converted to use fixtures directly 41// rather than through the testJava...() methods should avoid using this and instead use the 42// various preparers directly, using android.GroupFixturePreparers(...) to group them when 43// necessary. 44// 45// deprecated 46var prepareForJavaTest = android.GroupFixturePreparers( 47 genrule.PrepareForTestWithGenRuleBuildComponents, 48 // Get the CC build components but not default modules. 49 cc.PrepareForTestWithCcBuildComponents, 50 // Include all the default java modules. 51 PrepareForTestWithDexpreopt, 52 // Include aconfig modules. 53 aconfig.PrepareForTestWithAconfigBuildComponents, 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 532// A minimal context object for use with DexJarBuildPath 533type moduleErrorfTestCtx struct { 534} 535 536func (ctx moduleErrorfTestCtx) ModuleErrorf(format string, args ...interface{}) { 537} 538 539var _ android.ModuleErrorfContext = (*moduleErrorfTestCtx)(nil) 540 541func TestPrebuilts(t *testing.T) { 542 ctx, _ := testJava(t, ` 543 java_library { 544 name: "foo", 545 srcs: ["a.java", ":stubs-source"], 546 libs: ["bar", "sdklib"], 547 static_libs: ["baz"], 548 } 549 550 java_import { 551 name: "bar", 552 jars: ["a.jar"], 553 } 554 555 java_import { 556 name: "baz", 557 jars: ["b.jar"], 558 sdk_version: "current", 559 compile_dex: true, 560 } 561 562 dex_import { 563 name: "qux", 564 jars: ["b.jar"], 565 } 566 567 java_sdk_library_import { 568 name: "sdklib", 569 public: { 570 jars: ["c.jar"], 571 }, 572 } 573 574 prebuilt_stubs_sources { 575 name: "stubs-source", 576 srcs: ["stubs/sources"], 577 } 578 579 java_test_import { 580 name: "test", 581 jars: ["a.jar"], 582 test_suites: ["cts"], 583 test_config: "AndroidTest.xml", 584 } 585 `) 586 587 fooModule := ctx.ModuleForTests("foo", "android_common") 588 javac := fooModule.Rule("javac") 589 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") 590 barModule := ctx.ModuleForTests("bar", "android_common") 591 barJar := barModule.Output("combined/bar.jar").Output 592 bazModule := ctx.ModuleForTests("baz", "android_common") 593 bazJar := bazModule.Rule("combineJar").Output 594 sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common"). 595 Output("combined/sdklib.stubs.jar").Output 596 597 fooLibrary := fooModule.Module().(*Library) 598 assertDeepEquals(t, "foo unique sources incorrect", 599 []string{"a.java"}, fooLibrary.uniqueSrcFiles.Strings()) 600 601 assertDeepEquals(t, "foo java source jars incorrect", 602 []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"}, 603 android.NormalizePathsForTesting(fooLibrary.compiledSrcJars)) 604 605 if !strings.Contains(javac.Args["classpath"], barJar.String()) { 606 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String()) 607 } 608 609 errCtx := moduleErrorfTestCtx{} 610 barDexJar := barModule.Module().(*Import).DexJarBuildPath(errCtx) 611 if barDexJar.IsSet() { 612 t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar) 613 } 614 615 if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) { 616 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String()) 617 } 618 619 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() { 620 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String()) 621 } 622 623 bazDexJar := bazModule.Module().(*Import).DexJarBuildPath(errCtx).Path() 624 expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar" 625 android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar) 626 627 ctx.ModuleForTests("qux", "android_common").Rule("Cp") 628 629 entries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0] 630 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 631 entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0] 632 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 633} 634 635func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) { 636 if !reflect.DeepEqual(expected, actual) { 637 t.Errorf("%s: expected %q, found %q", message, expected, actual) 638 } 639} 640 641func TestPrebuiltStubsSources(t *testing.T) { 642 test := func(t *testing.T, sourcesPath string, expectedInputs []string) { 643 ctx, _ := testJavaWithFS(t, fmt.Sprintf(` 644prebuilt_stubs_sources { 645 name: "stubs-source", 646 srcs: ["%s"], 647}`, sourcesPath), map[string][]byte{ 648 "stubs/sources/pkg/A.java": nil, 649 "stubs/sources/pkg/B.java": nil, 650 }) 651 652 zipSrc := ctx.ModuleForTests("stubs-source", "android_common").Rule("zip_src") 653 if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) { 654 t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual) 655 } 656 } 657 658 t.Run("empty/missing directory", func(t *testing.T) { 659 test(t, "empty-directory", nil) 660 }) 661 662 t.Run("non-empty set of sources", func(t *testing.T) { 663 test(t, "stubs/sources", []string{ 664 "stubs/sources/pkg/A.java", 665 "stubs/sources/pkg/B.java", 666 }) 667 }) 668} 669 670func TestDefaults(t *testing.T) { 671 ctx, _ := testJava(t, ` 672 java_defaults { 673 name: "defaults", 674 srcs: ["a.java"], 675 libs: ["bar"], 676 static_libs: ["baz"], 677 optimize: {enabled: false}, 678 } 679 680 java_library { 681 name: "foo", 682 defaults: ["defaults"], 683 } 684 685 java_library { 686 name: "bar", 687 srcs: ["b.java"], 688 } 689 690 java_library { 691 name: "baz", 692 srcs: ["c.java"], 693 } 694 695 android_test { 696 name: "atestOptimize", 697 defaults: ["defaults"], 698 optimize: {enabled: true}, 699 } 700 701 android_test { 702 name: "atestNoOptimize", 703 defaults: ["defaults"], 704 } 705 706 android_test { 707 name: "atestDefault", 708 srcs: ["a.java"], 709 } 710 `) 711 712 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 713 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") 714 715 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { 716 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) 717 } 718 719 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar") 720 if !strings.Contains(javac.Args["classpath"], barTurbine) { 721 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine) 722 } 723 724 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String() 725 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz { 726 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz) 727 } 728 729 atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8") 730 if atestOptimize.Output == nil { 731 t.Errorf("atestOptimize should optimize APK") 732 } 733 734 atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8") 735 if atestNoOptimize.Output == nil { 736 t.Errorf("atestNoOptimize should not optimize APK") 737 } 738 739 atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("d8") 740 if atestDefault.Output == nil { 741 t.Errorf("atestDefault should not optimize APK") 742 } 743} 744 745func TestResources(t *testing.T) { 746 var table = []struct { 747 name string 748 prop string 749 extra string 750 args string 751 }{ 752 { 753 // Test that a module with java_resource_dirs includes the files 754 name: "resource dirs", 755 prop: `java_resource_dirs: ["java-res"]`, 756 args: "-C java-res -f java-res/a/a -f java-res/b/b", 757 }, 758 { 759 // Test that a module with java_resources includes the files 760 name: "resource files", 761 prop: `java_resources: ["java-res/a/a", "java-res/b/b"]`, 762 args: "-C . -f java-res/a/a -f java-res/b/b", 763 }, 764 { 765 // Test that a module with a filegroup in java_resources includes the files with the 766 // path prefix 767 name: "resource filegroup", 768 prop: `java_resources: [":foo-res"]`, 769 extra: ` 770 filegroup { 771 name: "foo-res", 772 path: "java-res", 773 srcs: ["java-res/a/a", "java-res/b/b"], 774 }`, 775 args: "-C java-res -f java-res/a/a -f java-res/b/b", 776 }, 777 { 778 // Test that a module with wildcards in java_resource_dirs has the correct path prefixes 779 name: "wildcard dirs", 780 prop: `java_resource_dirs: ["java-res/*"]`, 781 args: "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b", 782 }, 783 { 784 // Test that a module exclude_java_resource_dirs excludes the files 785 name: "wildcard dirs", 786 prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`, 787 args: "-C java-res/a -f java-res/a/a", 788 }, 789 { 790 // Test wildcards in java_resources 791 name: "wildcard files", 792 prop: `java_resources: ["java-res/**/*"]`, 793 args: "-C . -f java-res/a/a -f java-res/b/b", 794 }, 795 { 796 // Test exclude_java_resources with java_resources 797 name: "wildcard files with exclude", 798 prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`, 799 args: "-C . -f java-res/a/a", 800 }, 801 { 802 // Test exclude_java_resources with java_resource_dirs 803 name: "resource dirs with exclude files", 804 prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`, 805 args: "-C java-res -f java-res/a/a", 806 }, 807 { 808 // Test exclude_java_resource_dirs with java_resource_dirs 809 name: "resource dirs with exclude files", 810 prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`, 811 args: "-C java-res -f java-res/a/a -f java-res/b/b", 812 }, 813 } 814 815 for _, test := range table { 816 t.Run(test.name, func(t *testing.T) { 817 ctx, _ := testJavaWithFS(t, ` 818 java_library { 819 name: "foo", 820 srcs: [ 821 "a.java", 822 "b.java", 823 "c.java", 824 ], 825 `+test.prop+`, 826 } 827 `+test.extra, 828 map[string][]byte{ 829 "java-res/a/a": nil, 830 "java-res/b/b": nil, 831 "java-res2/a": nil, 832 }, 833 ) 834 835 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") 836 fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar") 837 838 if !inList(fooRes.Output.String(), foo.Inputs.Strings()) { 839 t.Errorf("foo combined jars %v does not contain %q", 840 foo.Inputs.Strings(), fooRes.Output.String()) 841 } 842 843 if fooRes.Args["jarArgs"] != test.args { 844 t.Errorf("foo resource jar args %q is not %q", 845 fooRes.Args["jarArgs"], test.args) 846 } 847 }) 848 } 849} 850 851func TestIncludeSrcs(t *testing.T) { 852 ctx, _ := testJavaWithFS(t, ` 853 java_library { 854 name: "foo", 855 srcs: [ 856 "a.java", 857 "b.java", 858 "c.java", 859 ], 860 include_srcs: true, 861 } 862 863 java_library { 864 name: "bar", 865 srcs: [ 866 "a.java", 867 "b.java", 868 "c.java", 869 ], 870 java_resource_dirs: ["java-res"], 871 include_srcs: true, 872 } 873 `, map[string][]byte{ 874 "java-res/a/a": nil, 875 "java-res/b/b": nil, 876 "java-res2/a": nil, 877 }) 878 879 // Test a library with include_srcs: true 880 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") 881 fooSrcJar := ctx.ModuleForTests("foo", "android_common").Output("foo.srcjar") 882 883 if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) { 884 t.Errorf("foo combined jars %v does not contain %q", w, g) 885 } 886 887 if g, w := fooSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w { 888 t.Errorf("foo source jar args %q is not %q", w, g) 889 } 890 891 // Test a library with include_srcs: true and resources 892 bar := ctx.ModuleForTests("bar", "android_common").Output("withres/bar.jar") 893 barResCombined := ctx.ModuleForTests("bar", "android_common").Output("res-combined/bar.jar") 894 barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar") 895 barSrcJar := ctx.ModuleForTests("bar", "android_common").Output("bar.srcjar") 896 897 if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) { 898 t.Errorf("bar combined resource jars %v does not contain %q", w, g) 899 } 900 901 if g, w := barRes.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) { 902 t.Errorf("bar combined resource jars %v does not contain %q", w, g) 903 } 904 905 if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) { 906 t.Errorf("bar combined jars %v does not contain %q", w, g) 907 } 908 909 if g, w := barSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w { 910 t.Errorf("bar source jar args %q is not %q", w, g) 911 } 912 913 if g, w := barRes.Args["jarArgs"], "-C java-res -f java-res/a/a -f java-res/b/b"; g != w { 914 t.Errorf("bar resource jar args %q is not %q", w, g) 915 } 916} 917 918func TestGeneratedSources(t *testing.T) { 919 ctx, _ := testJavaWithFS(t, ` 920 java_library { 921 name: "foo", 922 srcs: [ 923 "a*.java", 924 ":gen", 925 "b*.java", 926 ], 927 } 928 929 genrule { 930 name: "gen", 931 tool_files: ["java-res/a"], 932 out: ["gen.java"], 933 } 934 `, map[string][]byte{ 935 "a.java": nil, 936 "b.java": nil, 937 }) 938 939 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 940 genrule := ctx.ModuleForTests("gen", "").Rule("generator") 941 942 if filepath.Base(genrule.Output.String()) != "gen.java" { 943 t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String()) 944 } 945 946 if len(javac.Inputs) != 3 || 947 javac.Inputs[0].String() != "a.java" || 948 javac.Inputs[1].String() != genrule.Output.String() || 949 javac.Inputs[2].String() != "b.java" { 950 t.Errorf(`foo inputs %v != ["a.java", ".../gen.java", "b.java"]`, javac.Inputs) 951 } 952} 953 954func TestTurbine(t *testing.T) { 955 result := android.GroupFixturePreparers( 956 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})). 957 RunTestWithBp(t, ` 958 java_library { 959 name: "foo", 960 srcs: ["a.java"], 961 sdk_version: "14", 962 } 963 964 java_library { 965 name: "bar", 966 srcs: ["b.java"], 967 static_libs: ["foo"], 968 sdk_version: "14", 969 } 970 971 java_library { 972 name: "baz", 973 srcs: ["c.java"], 974 libs: ["bar"], 975 sdk_version: "14", 976 } 977 `) 978 979 fooTurbine := result.ModuleForTests("foo", "android_common").Rule("turbine") 980 barTurbine := result.ModuleForTests("bar", "android_common").Rule("turbine") 981 barJavac := result.ModuleForTests("bar", "android_common").Rule("javac") 982 barTurbineCombined := result.ModuleForTests("bar", "android_common").Description("for turbine") 983 bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac") 984 985 android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs) 986 987 fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar") 988 barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 989 android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar) 990 android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar) 991 android.AssertPathsRelativeToTopEquals(t, "bar turbine combineJar", []string{barTurbineJar, fooHeaderJar}, barTurbineCombined.Inputs) 992 android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "prebuilts/sdk/14/public/android.jar") 993} 994 995func TestSharding(t *testing.T) { 996 ctx, _ := testJava(t, ` 997 java_library { 998 name: "bar", 999 srcs: ["a.java","b.java","c.java"], 1000 javac_shard_size: 1 1001 } 1002 `) 1003 1004 barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") 1005 for i := 0; i < 3; i++ { 1006 barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i)) 1007 if !strings.HasPrefix(barJavac.Args["classpath"], "-classpath "+barHeaderJar+":") { 1008 t.Errorf("bar javac classpath %v does start with %q", barJavac.Args["classpath"], barHeaderJar) 1009 } 1010 } 1011} 1012 1013func TestExcludeFileGroupInSrcs(t *testing.T) { 1014 ctx, _ := testJava(t, ` 1015 java_library { 1016 name: "foo", 1017 srcs: ["a.java", ":foo-srcs"], 1018 exclude_srcs: ["a.java", ":foo-excludes"], 1019 } 1020 1021 filegroup { 1022 name: "foo-srcs", 1023 srcs: ["java-fg/a.java", "java-fg/b.java", "java-fg/c.java"], 1024 } 1025 1026 filegroup { 1027 name: "foo-excludes", 1028 srcs: ["java-fg/a.java", "java-fg/b.java"], 1029 } 1030 `) 1031 1032 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") 1033 1034 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" { 1035 t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs) 1036 } 1037} 1038 1039func TestJavaLibraryOutputFiles(t *testing.T) { 1040 testJavaWithFS(t, "", map[string][]byte{ 1041 "libcore/Android.bp": []byte(` 1042 java_library { 1043 name: "core", 1044 sdk_version: "none", 1045 system_modules: "none", 1046 } 1047 1048 filegroup { 1049 name: "core-jar", 1050 srcs: [":core{.jar}"], 1051 } 1052 `), 1053 }) 1054} 1055 1056func TestJavaImportOutputFiles(t *testing.T) { 1057 testJavaWithFS(t, "", map[string][]byte{ 1058 "libcore/Android.bp": []byte(` 1059 java_import { 1060 name: "core", 1061 sdk_version: "none", 1062 } 1063 1064 filegroup { 1065 name: "core-jar", 1066 srcs: [":core{.jar}"], 1067 } 1068 `), 1069 }) 1070} 1071 1072func TestJavaImport(t *testing.T) { 1073 bp := ` 1074 java_library { 1075 name: "source_library", 1076 srcs: ["source.java"], 1077 } 1078 1079 java_import { 1080 name: "import_with_no_deps", 1081 jars: ["no_deps.jar"], 1082 } 1083 1084 java_import { 1085 name: "import_with_source_deps", 1086 jars: ["source_deps.jar"], 1087 static_libs: ["source_library"], 1088 } 1089 1090 java_import { 1091 name: "import_with_import_deps", 1092 jars: ["import_deps.jar"], 1093 static_libs: ["import_with_no_deps"], 1094 } 1095 ` 1096 ctx := android.GroupFixturePreparers( 1097 PrepareForTestWithJavaDefaultModules, 1098 ).RunTestWithBp(t, bp) 1099 1100 source := ctx.ModuleForTests("source_library", "android_common") 1101 sourceJar := source.Output("javac/source_library.jar") 1102 sourceHeaderJar := source.Output("turbine-combined/source_library.jar") 1103 sourceJavaInfo, _ := android.SingletonModuleProvider(ctx, source.Module(), JavaInfoProvider) 1104 1105 // The source library produces separate implementation and header jars 1106 android.AssertPathsRelativeToTopEquals(t, "source library implementation jar", 1107 []string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars) 1108 android.AssertPathsRelativeToTopEquals(t, "source library header jar", 1109 []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars) 1110 1111 importWithNoDeps := ctx.ModuleForTests("import_with_no_deps", "android_common") 1112 importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar") 1113 importWithNoDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider) 1114 1115 // An import with no deps produces a single jar used as both the header and implementation jar. 1116 android.AssertPathsRelativeToTopEquals(t, "import with no deps implementation jar", 1117 []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.ImplementationAndResourcesJars) 1118 android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar", 1119 []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars) 1120 android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs", 1121 []string{"no_deps.jar"}, importWithNoDepsJar.Inputs) 1122 1123 importWithSourceDeps := ctx.ModuleForTests("import_with_source_deps", "android_common") 1124 importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar") 1125 importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar") 1126 importWithSourceDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider) 1127 1128 // An import with source deps produces separate header and implementation jars. 1129 android.AssertPathsRelativeToTopEquals(t, "import with source deps implementation jar", 1130 []string{importWithSourceDepsJar.Output.String()}, importWithSourceDepsJavaInfo.ImplementationAndResourcesJars) 1131 android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar", 1132 []string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars) 1133 android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs", 1134 []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs) 1135 android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs", 1136 []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs) 1137 1138 importWithImportDeps := ctx.ModuleForTests("import_with_import_deps", "android_common") 1139 importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar") 1140 importWithImportDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider) 1141 1142 // An import with only import deps produces a single jar used as both the header and implementation jar. 1143 android.AssertPathsRelativeToTopEquals(t, "import with import deps implementation jar", 1144 []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.ImplementationAndResourcesJars) 1145 android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar", 1146 []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars) 1147 android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs", 1148 []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs) 1149} 1150 1151var compilerFlagsTestCases = []struct { 1152 in string 1153 out bool 1154}{ 1155 { 1156 in: "a", 1157 out: false, 1158 }, 1159 { 1160 in: "-a", 1161 out: true, 1162 }, 1163 { 1164 in: "-no-jdk", 1165 out: false, 1166 }, 1167 { 1168 in: "-no-stdlib", 1169 out: false, 1170 }, 1171 { 1172 in: "-kotlin-home", 1173 out: false, 1174 }, 1175 { 1176 in: "-kotlin-home /some/path", 1177 out: false, 1178 }, 1179 { 1180 in: "-include-runtime", 1181 out: false, 1182 }, 1183 { 1184 in: "-Xintellij-plugin-root", 1185 out: false, 1186 }, 1187} 1188 1189type mockContext struct { 1190 android.ModuleContext 1191 result bool 1192} 1193 1194func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) { 1195 // CheckBadCompilerFlags calls this function when the flag should be rejected 1196 ctx.result = false 1197} 1198 1199func TestCompilerFlags(t *testing.T) { 1200 for _, testCase := range compilerFlagsTestCases { 1201 ctx := &mockContext{result: true} 1202 CheckKotlincFlags(ctx, []string{testCase.in}) 1203 if ctx.result != testCase.out { 1204 t.Errorf("incorrect output:") 1205 t.Errorf(" input: %#v", testCase.in) 1206 t.Errorf(" expected: %#v", testCase.out) 1207 t.Errorf(" got: %#v", ctx.result) 1208 } 1209 } 1210} 1211 1212// TODO(jungjw): Consider making this more robust by ignoring path order. 1213func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) { 1214 variables := ctx.ModuleForTests(moduleName, "android_common").VariablesForTestsRelativeToTop() 1215 flags := strings.Split(variables["javacFlags"], " ") 1216 got := "" 1217 for _, flag := range flags { 1218 keyEnd := strings.Index(flag, "=") 1219 if keyEnd > -1 && flag[:keyEnd] == "--patch-module" { 1220 got = flag[keyEnd+1:] 1221 break 1222 } 1223 } 1224 if expected != android.StringPathRelativeToTop(ctx.Config().SoongOutDir(), got) { 1225 t.Errorf("Unexpected patch-module flag for module %q - expected %q, but got %q", moduleName, expected, got) 1226 } 1227} 1228 1229func TestPatchModule(t *testing.T) { 1230 t.Run("Java language level 8", func(t *testing.T) { 1231 // Test with legacy javac -source 1.8 -target 1.8 1232 bp := ` 1233 java_library { 1234 name: "foo", 1235 srcs: ["a.java"], 1236 java_version: "1.8", 1237 } 1238 1239 java_library { 1240 name: "bar", 1241 srcs: ["b.java"], 1242 sdk_version: "none", 1243 system_modules: "none", 1244 patch_module: "java.base", 1245 java_version: "1.8", 1246 } 1247 1248 java_library { 1249 name: "baz", 1250 srcs: ["c.java"], 1251 patch_module: "java.base", 1252 java_version: "1.8", 1253 } 1254 ` 1255 ctx, _ := testJava(t, bp) 1256 1257 checkPatchModuleFlag(t, ctx, "foo", "") 1258 checkPatchModuleFlag(t, ctx, "bar", "") 1259 checkPatchModuleFlag(t, ctx, "baz", "") 1260 }) 1261 1262 t.Run("Java language level 9", func(t *testing.T) { 1263 // Test with default javac -source 9 -target 9 1264 bp := ` 1265 java_library { 1266 name: "foo", 1267 srcs: ["a.java"], 1268 } 1269 1270 java_library { 1271 name: "bar", 1272 srcs: ["b.java"], 1273 sdk_version: "none", 1274 system_modules: "none", 1275 patch_module: "java.base", 1276 } 1277 1278 java_library { 1279 name: "baz", 1280 srcs: [ 1281 "c.java", 1282 // Tests for b/150878007 1283 "dir/d.java", 1284 "dir2/e.java", 1285 "dir2/f.java", 1286 "nested/dir/g.java" 1287 ], 1288 patch_module: "java.base", 1289 } 1290 ` 1291 ctx, _ := testJava(t, bp) 1292 1293 checkPatchModuleFlag(t, ctx, "foo", "") 1294 expected := "java.base=.:out/soong" 1295 checkPatchModuleFlag(t, ctx, "bar", expected) 1296 expected = "java.base=" + strings.Join([]string{ 1297 ".", "out/soong", defaultModuleToPath("ext"), defaultModuleToPath("framework")}, ":") 1298 checkPatchModuleFlag(t, ctx, "baz", expected) 1299 }) 1300} 1301 1302func TestJavaLibraryWithSystemModules(t *testing.T) { 1303 ctx, _ := testJava(t, ` 1304 java_library { 1305 name: "lib-with-source-system-modules", 1306 srcs: [ 1307 "a.java", 1308 ], 1309 sdk_version: "none", 1310 system_modules: "source-system-modules", 1311 } 1312 1313 java_library { 1314 name: "source-jar", 1315 srcs: [ 1316 "a.java", 1317 ], 1318 } 1319 1320 java_system_modules { 1321 name: "source-system-modules", 1322 libs: ["source-jar"], 1323 } 1324 1325 java_library { 1326 name: "lib-with-prebuilt-system-modules", 1327 srcs: [ 1328 "a.java", 1329 ], 1330 sdk_version: "none", 1331 system_modules: "prebuilt-system-modules", 1332 } 1333 1334 java_import { 1335 name: "prebuilt-jar", 1336 jars: ["a.jar"], 1337 } 1338 1339 java_system_modules_import { 1340 name: "prebuilt-system-modules", 1341 libs: ["prebuilt-jar"], 1342 } 1343 `) 1344 1345 checkBootClasspathForSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar") 1346 1347 checkBootClasspathForSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar") 1348} 1349 1350func checkBootClasspathForSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) { 1351 javacRule := ctx.ModuleForTests(moduleName, "android_common").Rule("javac") 1352 bootClasspath := javacRule.Args["bootClasspath"] 1353 if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) { 1354 t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath) 1355 } 1356} 1357 1358func TestAidlExportIncludeDirsFromImports(t *testing.T) { 1359 ctx, _ := testJava(t, ` 1360 java_library { 1361 name: "foo", 1362 srcs: ["aidl/foo/IFoo.aidl"], 1363 libs: ["bar"], 1364 } 1365 1366 java_import { 1367 name: "bar", 1368 jars: ["a.jar"], 1369 aidl: { 1370 export_include_dirs: ["aidl/bar"], 1371 }, 1372 } 1373 `) 1374 1375 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1376 expectedAidlFlag := "-Iaidl/bar" 1377 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1378 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1379 } 1380} 1381 1382func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) { 1383 ctx, _ := testJava(t, ` 1384 java_library { 1385 name: "foo", 1386 srcs: ["aidl/foo/IFoo.aidl"], 1387 aidl: { flags: ["-Werror"], }, 1388 } 1389 `) 1390 1391 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1392 expectedAidlFlag := "-Werror" 1393 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1394 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1395 } 1396} 1397 1398func TestAidlFlagsWithMinSdkVersion(t *testing.T) { 1399 fixture := android.GroupFixturePreparers( 1400 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})) 1401 1402 for _, tc := range []struct { 1403 name string 1404 sdkVersion string 1405 expected string 1406 }{ 1407 {"default is current", "", "current"}, 1408 {"use sdk_version", `sdk_version: "14"`, "14"}, 1409 {"system_current", `sdk_version: "system_current"`, "current"}, 1410 } { 1411 t.Run(tc.name, func(t *testing.T) { 1412 ctx := fixture.RunTestWithBp(t, ` 1413 java_library { 1414 name: "foo", 1415 srcs: ["aidl/foo/IFoo.aidl"], 1416 `+tc.sdkVersion+` 1417 } 1418 `) 1419 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1420 expectedAidlFlag := "--min_sdk_version=" + tc.expected 1421 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1422 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1423 } 1424 }) 1425 } 1426} 1427 1428func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) { 1429 bpTemplate := ` 1430 droidstubs { 1431 name: "foo-stubs", 1432 srcs: ["foo.aidl"], 1433 %s 1434 system_modules: "none", 1435 } 1436 ` 1437 testCases := []struct { 1438 desc string 1439 sdkVersionBp string 1440 minSdkVersionExpected string 1441 }{ 1442 { 1443 desc: "sdk_version not set, module compiles against private platform APIs", 1444 sdkVersionBp: ``, 1445 minSdkVersionExpected: "10000", 1446 }, 1447 { 1448 desc: "sdk_version set to none, module does not build against an SDK", 1449 sdkVersionBp: `sdk_version: "none",`, 1450 minSdkVersionExpected: "10000", 1451 }, 1452 } 1453 for _, tc := range testCases { 1454 ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp)) 1455 aidlCmd := ctx.ModuleForTests("foo-stubs", "android_common").Rule("aidl").RuleParams.Command 1456 expected := "--min_sdk_version=" + tc.minSdkVersionExpected 1457 android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected) 1458 } 1459} 1460 1461func TestAidlEnforcePermissions(t *testing.T) { 1462 ctx, _ := testJava(t, ` 1463 java_library { 1464 name: "foo", 1465 srcs: ["aidl/foo/IFoo.aidl"], 1466 aidl: { enforce_permissions: true }, 1467 } 1468 `) 1469 1470 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1471 expectedAidlFlag := "-Wmissing-permission-annotation -Werror" 1472 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1473 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1474 } 1475} 1476 1477func TestAidlEnforcePermissionsException(t *testing.T) { 1478 ctx, _ := testJava(t, ` 1479 java_library { 1480 name: "foo", 1481 srcs: ["aidl/foo/IFoo.aidl", "aidl/foo/IFoo2.aidl"], 1482 aidl: { enforce_permissions: true, enforce_permissions_exceptions: ["aidl/foo/IFoo2.aidl"] }, 1483 } 1484 `) 1485 1486 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command 1487 expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl" 1488 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1489 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1490 } 1491 expectedAidlFlag = "$$FLAGS aidl/foo/IFoo2.aidl" 1492 if !strings.Contains(aidlCommand, expectedAidlFlag) { 1493 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 1494 } 1495} 1496 1497func TestDataNativeBinaries(t *testing.T) { 1498 ctx := android.GroupFixturePreparers( 1499 prepareForJavaTest, 1500 android.PrepareForTestWithAllowMissingDependencies).RunTestWithBp(t, ` 1501 java_test_host { 1502 name: "foo", 1503 srcs: ["a.java"], 1504 data_native_bins: ["bin"] 1505 } 1506 1507 cc_binary_host { 1508 name: "bin", 1509 srcs: ["bin.cpp"], 1510 } 1511 `).TestContext 1512 1513 buildOS := ctx.Config().BuildOS.String() 1514 1515 test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) 1516 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0] 1517 expected := []string{"out/soong/.intermediates/bin/" + buildOS + "_x86_64/bin:bin"} 1518 actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 1519 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_COMPATIBILITY_SUPPORT_FILES", ctx.Config(), expected, actual) 1520} 1521 1522func TestDefaultInstallable(t *testing.T) { 1523 ctx, _ := testJava(t, ` 1524 java_test_host { 1525 name: "foo" 1526 } 1527 `) 1528 1529 buildOS := ctx.Config().BuildOS.String() 1530 module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) 1531 assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true), 1532 module.properties.Installable) 1533} 1534 1535func TestErrorproneEnabled(t *testing.T) { 1536 ctx, _ := testJava(t, ` 1537 java_library { 1538 name: "foo", 1539 srcs: ["a.java"], 1540 errorprone: { 1541 enabled: true, 1542 }, 1543 } 1544 `) 1545 1546 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1547 1548 // Test that the errorprone plugins are passed to javac 1549 expectedSubstring := "-Xplugin:ErrorProne" 1550 if !strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1551 t.Errorf("expected javacFlags to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1552 } 1553 1554 // Modules with errorprone { enabled: true } will include errorprone checks 1555 // in the main javac build rule. Only when RUN_ERROR_PRONE is true will 1556 // the explicit errorprone build rule be created. 1557 errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone") 1558 if errorprone.RuleParams.Description != "" { 1559 t.Errorf("expected errorprone build rule to not exist, but it did") 1560 } 1561} 1562 1563func TestErrorproneDisabled(t *testing.T) { 1564 bp := ` 1565 java_library { 1566 name: "foo", 1567 srcs: ["a.java"], 1568 errorprone: { 1569 enabled: false, 1570 }, 1571 } 1572 ` 1573 ctx := android.GroupFixturePreparers( 1574 PrepareForTestWithJavaDefaultModules, 1575 android.FixtureMergeEnv(map[string]string{ 1576 "RUN_ERROR_PRONE": "true", 1577 }), 1578 ).RunTestWithBp(t, bp) 1579 1580 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1581 1582 // Test that the errorprone plugins are not passed to javac, like they would 1583 // be if enabled was true. 1584 expectedSubstring := "-Xplugin:ErrorProne" 1585 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1586 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1587 } 1588 1589 // Check that no errorprone build rule is created, like there would be 1590 // if enabled was unset and RUN_ERROR_PRONE was true. 1591 errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone") 1592 if errorprone.RuleParams.Description != "" { 1593 t.Errorf("expected errorprone build rule to not exist, but it did") 1594 } 1595} 1596 1597func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) { 1598 bp := ` 1599 java_library { 1600 name: "foo", 1601 srcs: ["a.java"], 1602 } 1603 ` 1604 ctx := android.GroupFixturePreparers( 1605 PrepareForTestWithJavaDefaultModules, 1606 android.FixtureMergeEnv(map[string]string{ 1607 "RUN_ERROR_PRONE": "true", 1608 }), 1609 ).RunTestWithBp(t, bp) 1610 1611 javac := ctx.ModuleForTests("foo", "android_common").Description("javac") 1612 errorprone := ctx.ModuleForTests("foo", "android_common").Description("errorprone") 1613 1614 // Check that the errorprone plugins are not passed to javac, because they 1615 // will instead be passed to the separate errorprone compilation 1616 expectedSubstring := "-Xplugin:ErrorProne" 1617 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) { 1618 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1619 } 1620 1621 // Check that the errorprone plugin is enabled 1622 if !strings.Contains(errorprone.Args["javacFlags"], expectedSubstring) { 1623 t.Errorf("expected errorprone to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) 1624 } 1625} 1626 1627func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) { 1628 testCases := []struct { 1629 dataDeviceBinType string 1630 depCompileMultilib string 1631 variants []string 1632 expectedError string 1633 }{ 1634 { 1635 dataDeviceBinType: "first", 1636 depCompileMultilib: "first", 1637 variants: []string{"android_arm64_armv8-a"}, 1638 }, 1639 { 1640 dataDeviceBinType: "first", 1641 depCompileMultilib: "both", 1642 variants: []string{"android_arm64_armv8-a"}, 1643 }, 1644 { 1645 // this is true because our testing framework is set up with 1646 // Targets ~ [<64bit target>, <32bit target>], where 64bit is "first" 1647 dataDeviceBinType: "first", 1648 depCompileMultilib: "32", 1649 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1650 }, 1651 { 1652 dataDeviceBinType: "first", 1653 depCompileMultilib: "64", 1654 variants: []string{"android_arm64_armv8-a"}, 1655 }, 1656 { 1657 dataDeviceBinType: "both", 1658 depCompileMultilib: "both", 1659 variants: []string{ 1660 "android_arm_armv7-a-neon", 1661 "android_arm64_armv8-a", 1662 }, 1663 }, 1664 { 1665 dataDeviceBinType: "both", 1666 depCompileMultilib: "32", 1667 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1668 }, 1669 { 1670 dataDeviceBinType: "both", 1671 depCompileMultilib: "64", 1672 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1673 }, 1674 { 1675 dataDeviceBinType: "both", 1676 depCompileMultilib: "first", 1677 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1678 }, 1679 { 1680 dataDeviceBinType: "32", 1681 depCompileMultilib: "32", 1682 variants: []string{"android_arm_armv7-a-neon"}, 1683 }, 1684 { 1685 dataDeviceBinType: "32", 1686 depCompileMultilib: "first", 1687 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1688 }, 1689 { 1690 dataDeviceBinType: "32", 1691 depCompileMultilib: "both", 1692 variants: []string{"android_arm_armv7-a-neon"}, 1693 }, 1694 { 1695 dataDeviceBinType: "32", 1696 depCompileMultilib: "64", 1697 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1698 }, 1699 { 1700 dataDeviceBinType: "64", 1701 depCompileMultilib: "64", 1702 variants: []string{"android_arm64_armv8-a"}, 1703 }, 1704 { 1705 dataDeviceBinType: "64", 1706 depCompileMultilib: "both", 1707 variants: []string{"android_arm64_armv8-a"}, 1708 }, 1709 { 1710 dataDeviceBinType: "64", 1711 depCompileMultilib: "first", 1712 variants: []string{"android_arm64_armv8-a"}, 1713 }, 1714 { 1715 dataDeviceBinType: "64", 1716 depCompileMultilib: "32", 1717 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1718 }, 1719 { 1720 dataDeviceBinType: "prefer32", 1721 depCompileMultilib: "32", 1722 variants: []string{"android_arm_armv7-a-neon"}, 1723 }, 1724 { 1725 dataDeviceBinType: "prefer32", 1726 depCompileMultilib: "both", 1727 variants: []string{"android_arm_armv7-a-neon"}, 1728 }, 1729 { 1730 dataDeviceBinType: "prefer32", 1731 depCompileMultilib: "first", 1732 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1733 }, 1734 { 1735 dataDeviceBinType: "prefer32", 1736 depCompileMultilib: "64", 1737 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, 1738 }, 1739 } 1740 1741 bpTemplate := ` 1742 java_test_host { 1743 name: "foo", 1744 srcs: ["test.java"], 1745 data_device_bins_%s: ["bar"], 1746 } 1747 1748 cc_binary { 1749 name: "bar", 1750 compile_multilib: "%s", 1751 } 1752 ` 1753 1754 for _, tc := range testCases { 1755 bp := fmt.Sprintf(bpTemplate, tc.dataDeviceBinType, tc.depCompileMultilib) 1756 1757 errorHandler := android.FixtureExpectsNoErrors 1758 if tc.expectedError != "" { 1759 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError) 1760 } 1761 1762 testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib) 1763 t.Run(testName, func(t *testing.T) { 1764 ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava). 1765 ExtendWithErrorHandler(errorHandler). 1766 RunTestWithBp(t, bp) 1767 if tc.expectedError != "" { 1768 return 1769 } 1770 1771 buildOS := ctx.Config.BuildOS.String() 1772 fooVariant := ctx.ModuleForTests("foo", buildOS+"_common") 1773 fooMod := fooVariant.Module().(*TestHost) 1774 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0] 1775 1776 expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />` 1777 autogen := fooVariant.Rule("autogen") 1778 if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) { 1779 t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig) 1780 } 1781 1782 expectedData := []string{} 1783 for _, variant := range tc.variants { 1784 barVariant := ctx.ModuleForTests("bar", variant) 1785 relocated := barVariant.Output("bar") 1786 expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant) 1787 android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input) 1788 1789 expectedData = append(expectedData, fmt.Sprintf("out/soong/.intermediates/bar/%s/bar:bar", variant)) 1790 } 1791 1792 actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 1793 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData) 1794 }) 1795 } 1796} 1797 1798func TestDeviceBinaryWrapperGeneration(t *testing.T) { 1799 // Scenario 1: java_binary has main_class property in its bp 1800 ctx, _ := testJava(t, ` 1801 java_binary { 1802 name: "foo", 1803 srcs: ["foo.java"], 1804 main_class: "foo.bar.jb", 1805 } 1806 `) 1807 wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_arm64_armv8-a").AllOutputs()) 1808 if !strings.Contains(wrapperPath, "foo.sh") { 1809 t.Errorf("wrapper file foo.sh is not generated") 1810 } 1811 1812 // Scenario 2: java_binary has neither wrapper nor main_class, its build 1813 // is expected to be failed. 1814 testJavaError(t, "main_class property is required for device binary if no default wrapper is assigned", ` 1815 java_binary { 1816 name: "foo", 1817 srcs: ["foo.java"], 1818 }`) 1819} 1820 1821func TestJavaApiContributionEmptyApiFile(t *testing.T) { 1822 android.GroupFixturePreparers( 1823 prepareForJavaTest, 1824 android.FixtureMergeEnv( 1825 map[string]string{ 1826 "DISABLE_STUB_VALIDATION": "true", 1827 }, 1828 ), 1829 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 1830 "Error: foo has an empty api file.", 1831 )).RunTestWithBp(t, ` 1832 java_api_contribution { 1833 name: "foo", 1834 } 1835 java_api_library { 1836 name: "bar", 1837 api_surface: "public", 1838 api_contributions: ["foo"], 1839 stubs_type: "everything", 1840 } 1841 `) 1842} 1843 1844func TestJavaApiLibraryAndProviderLink(t *testing.T) { 1845 provider_bp_a := ` 1846 java_api_contribution { 1847 name: "foo1", 1848 api_file: "current.txt", 1849 api_surface: "public", 1850 } 1851 ` 1852 provider_bp_b := `java_api_contribution { 1853 name: "foo2", 1854 api_file: "current.txt", 1855 api_surface: "public", 1856 } 1857 ` 1858 ctx := android.GroupFixturePreparers( 1859 prepareForJavaTest, 1860 android.FixtureMergeMockFs( 1861 map[string][]byte{ 1862 "a/Android.bp": []byte(provider_bp_a), 1863 "b/Android.bp": []byte(provider_bp_b), 1864 }, 1865 ), 1866 android.FixtureMergeEnv( 1867 map[string]string{ 1868 "DISABLE_STUB_VALIDATION": "true", 1869 }, 1870 ), 1871 ).RunTestWithBp(t, ` 1872 java_api_library { 1873 name: "bar1", 1874 api_surface: "public", 1875 api_contributions: ["foo1"], 1876 stubs_type: "everything", 1877 } 1878 1879 java_api_library { 1880 name: "bar2", 1881 api_surface: "system", 1882 api_contributions: ["foo1", "foo2"], 1883 stubs_type: "everything", 1884 } 1885 `) 1886 1887 testcases := []struct { 1888 moduleName string 1889 sourceTextFileDirs []string 1890 }{ 1891 { 1892 moduleName: "bar1", 1893 sourceTextFileDirs: []string{"a/current.txt"}, 1894 }, 1895 { 1896 moduleName: "bar2", 1897 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"}, 1898 }, 1899 } 1900 for _, c := range testcases { 1901 m := ctx.ModuleForTests(c.moduleName, "android_common") 1902 manifest := m.Output("metalava.sbox.textproto") 1903 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest) 1904 manifestCommand := sboxProto.Commands[0].GetCommand() 1905 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ") 1906 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) 1907 } 1908} 1909 1910func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { 1911 provider_bp_a := ` 1912 java_api_contribution { 1913 name: "foo1", 1914 api_file: "current.txt", 1915 api_surface: "public", 1916 } 1917 ` 1918 provider_bp_b := ` 1919 java_api_contribution { 1920 name: "foo2", 1921 api_file: "current.txt", 1922 api_surface: "public", 1923 } 1924 ` 1925 provider_bp_c := ` 1926 java_api_contribution { 1927 name: "foo3", 1928 api_file: "system-current.txt", 1929 api_surface: "system", 1930 } 1931 ` 1932 provider_bp_d := ` 1933 java_api_contribution { 1934 name: "foo4", 1935 api_file: "system-current.txt", 1936 api_surface: "system", 1937 } 1938 ` 1939 ctx := android.GroupFixturePreparers( 1940 prepareForJavaTest, 1941 android.FixtureMergeMockFs( 1942 map[string][]byte{ 1943 "a/Android.bp": []byte(provider_bp_a), 1944 "b/Android.bp": []byte(provider_bp_b), 1945 "c/Android.bp": []byte(provider_bp_c), 1946 "d/Android.bp": []byte(provider_bp_d), 1947 }, 1948 ), 1949 android.FixtureMergeEnv( 1950 map[string]string{ 1951 "DISABLE_STUB_VALIDATION": "true", 1952 }, 1953 ), 1954 ).RunTestWithBp(t, ` 1955 java_defaults { 1956 name: "baz1", 1957 api_surface: "public", 1958 api_contributions: ["foo1", "foo2"], 1959 } 1960 1961 java_defaults { 1962 name: "baz2", 1963 api_surface: "system", 1964 api_contributions: ["foo3"], 1965 } 1966 1967 java_api_library { 1968 name: "bar1", 1969 api_surface: "public", 1970 api_contributions: ["foo1"], 1971 stubs_type: "everything", 1972 } 1973 1974 java_api_library { 1975 name: "bar2", 1976 api_surface: "public", 1977 defaults:["baz1"], 1978 stubs_type: "everything", 1979 } 1980 1981 java_api_library { 1982 name: "bar3", 1983 api_surface: "system", 1984 defaults:["baz1", "baz2"], 1985 api_contributions: ["foo4"], 1986 stubs_type: "everything", 1987 } 1988 `) 1989 1990 testcases := []struct { 1991 moduleName string 1992 sourceTextFileDirs []string 1993 }{ 1994 { 1995 moduleName: "bar1", 1996 sourceTextFileDirs: []string{"a/current.txt"}, 1997 }, 1998 { 1999 moduleName: "bar2", 2000 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"}, 2001 }, 2002 { 2003 moduleName: "bar3", 2004 // API text files need to be sorted from the narrower api scope to the wider api scope 2005 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "c/system-current.txt", "d/system-current.txt"}, 2006 }, 2007 } 2008 for _, c := range testcases { 2009 m := ctx.ModuleForTests(c.moduleName, "android_common") 2010 manifest := m.Output("metalava.sbox.textproto") 2011 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest) 2012 manifestCommand := sboxProto.Commands[0].GetCommand() 2013 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ") 2014 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) 2015 } 2016} 2017 2018func TestJavaApiLibraryJarGeneration(t *testing.T) { 2019 provider_bp_a := ` 2020 java_api_contribution { 2021 name: "foo1", 2022 api_file: "current.txt", 2023 api_surface: "public", 2024 } 2025 ` 2026 provider_bp_b := ` 2027 java_api_contribution { 2028 name: "foo2", 2029 api_file: "current.txt", 2030 api_surface: "public", 2031 } 2032 ` 2033 ctx := android.GroupFixturePreparers( 2034 prepareForJavaTest, 2035 android.FixtureMergeMockFs( 2036 map[string][]byte{ 2037 "a/Android.bp": []byte(provider_bp_a), 2038 "b/Android.bp": []byte(provider_bp_b), 2039 }, 2040 ), 2041 android.FixtureMergeEnv( 2042 map[string]string{ 2043 "DISABLE_STUB_VALIDATION": "true", 2044 }, 2045 ), 2046 ).RunTestWithBp(t, ` 2047 java_api_library { 2048 name: "bar1", 2049 api_surface: "public", 2050 api_contributions: ["foo1"], 2051 stubs_type: "everything", 2052 } 2053 2054 java_api_library { 2055 name: "bar2", 2056 api_surface: "system", 2057 api_contributions: ["foo1", "foo2"], 2058 stubs_type: "everything", 2059 } 2060 `) 2061 2062 testcases := []struct { 2063 moduleName string 2064 outputJarName string 2065 }{ 2066 { 2067 moduleName: "bar1", 2068 outputJarName: "bar1/bar1.jar", 2069 }, 2070 { 2071 moduleName: "bar2", 2072 outputJarName: "bar2/bar2.jar", 2073 }, 2074 } 2075 for _, c := range testcases { 2076 m := ctx.ModuleForTests(c.moduleName, "android_common") 2077 outputs := fmt.Sprint(m.AllOutputs()) 2078 if !strings.Contains(outputs, c.outputJarName) { 2079 t.Errorf("Module output does not contain expected jar %s", c.outputJarName) 2080 } 2081 } 2082} 2083 2084func TestJavaApiLibraryLibsLink(t *testing.T) { 2085 provider_bp_a := ` 2086 java_api_contribution { 2087 name: "foo1", 2088 api_file: "current.txt", 2089 api_surface: "public", 2090 } 2091 ` 2092 provider_bp_b := ` 2093 java_api_contribution { 2094 name: "foo2", 2095 api_file: "current.txt", 2096 api_surface: "public", 2097 } 2098 ` 2099 lib_bp_a := ` 2100 java_library { 2101 name: "lib1", 2102 srcs: ["Lib.java"], 2103 } 2104 ` 2105 lib_bp_b := ` 2106 java_library { 2107 name: "lib2", 2108 srcs: ["Lib.java"], 2109 } 2110 ` 2111 2112 ctx := android.GroupFixturePreparers( 2113 prepareForJavaTest, 2114 android.FixtureMergeMockFs( 2115 map[string][]byte{ 2116 "a/Android.bp": []byte(provider_bp_a), 2117 "b/Android.bp": []byte(provider_bp_b), 2118 "c/Android.bp": []byte(lib_bp_a), 2119 "c/Lib.java": {}, 2120 "d/Android.bp": []byte(lib_bp_b), 2121 "d/Lib.java": {}, 2122 }, 2123 ), 2124 android.FixtureMergeEnv( 2125 map[string]string{ 2126 "DISABLE_STUB_VALIDATION": "true", 2127 }, 2128 ), 2129 ).RunTestWithBp(t, ` 2130 java_api_library { 2131 name: "bar1", 2132 api_surface: "public", 2133 api_contributions: ["foo1"], 2134 libs: ["lib1"], 2135 stubs_type: "everything", 2136 } 2137 2138 java_api_library { 2139 name: "bar2", 2140 api_surface: "system", 2141 api_contributions: ["foo1", "foo2"], 2142 libs: ["lib1", "lib2", "bar1"], 2143 stubs_type: "everything", 2144 } 2145 `) 2146 2147 testcases := []struct { 2148 moduleName string 2149 classPathJarNames []string 2150 }{ 2151 { 2152 moduleName: "bar1", 2153 classPathJarNames: []string{"lib1.jar"}, 2154 }, 2155 { 2156 moduleName: "bar2", 2157 classPathJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"}, 2158 }, 2159 } 2160 for _, c := range testcases { 2161 m := ctx.ModuleForTests(c.moduleName, "android_common") 2162 javacRules := m.Rule("javac") 2163 classPathArgs := javacRules.Args["classpath"] 2164 for _, jarName := range c.classPathJarNames { 2165 if !strings.Contains(classPathArgs, jarName) { 2166 t.Errorf("Module output does not contain expected jar %s", jarName) 2167 } 2168 } 2169 } 2170} 2171 2172func TestJavaApiLibraryStaticLibsLink(t *testing.T) { 2173 provider_bp_a := ` 2174 java_api_contribution { 2175 name: "foo1", 2176 api_file: "current.txt", 2177 api_surface: "public", 2178 } 2179 ` 2180 provider_bp_b := ` 2181 java_api_contribution { 2182 name: "foo2", 2183 api_file: "current.txt", 2184 api_surface: "public", 2185 } 2186 ` 2187 lib_bp_a := ` 2188 java_library { 2189 name: "lib1", 2190 srcs: ["Lib.java"], 2191 } 2192 ` 2193 lib_bp_b := ` 2194 java_library { 2195 name: "lib2", 2196 srcs: ["Lib.java"], 2197 } 2198 ` 2199 2200 ctx := android.GroupFixturePreparers( 2201 prepareForJavaTest, 2202 android.FixtureMergeMockFs( 2203 map[string][]byte{ 2204 "a/Android.bp": []byte(provider_bp_a), 2205 "b/Android.bp": []byte(provider_bp_b), 2206 "c/Android.bp": []byte(lib_bp_a), 2207 "c/Lib.java": {}, 2208 "d/Android.bp": []byte(lib_bp_b), 2209 "d/Lib.java": {}, 2210 }, 2211 ), 2212 android.FixtureMergeEnv( 2213 map[string]string{ 2214 "DISABLE_STUB_VALIDATION": "true", 2215 }, 2216 ), 2217 ).RunTestWithBp(t, ` 2218 java_api_library { 2219 name: "bar1", 2220 api_surface: "public", 2221 api_contributions: ["foo1"], 2222 static_libs: ["lib1"], 2223 stubs_type: "everything", 2224 } 2225 2226 java_api_library { 2227 name: "bar2", 2228 api_surface: "system", 2229 api_contributions: ["foo1", "foo2"], 2230 static_libs: ["lib1", "lib2", "bar1"], 2231 stubs_type: "everything", 2232 } 2233 `) 2234 2235 testcases := []struct { 2236 moduleName string 2237 staticLibJarNames []string 2238 }{ 2239 { 2240 moduleName: "bar1", 2241 staticLibJarNames: []string{"lib1.jar"}, 2242 }, 2243 { 2244 moduleName: "bar2", 2245 staticLibJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"}, 2246 }, 2247 } 2248 for _, c := range testcases { 2249 m := ctx.ModuleForTests(c.moduleName, "android_common") 2250 mergeZipsCommand := m.Rule("merge_zips").RuleParams.Command 2251 for _, jarName := range c.staticLibJarNames { 2252 if !strings.Contains(mergeZipsCommand, jarName) { 2253 t.Errorf("merge_zips command does not contain expected jar %s", jarName) 2254 } 2255 } 2256 } 2257} 2258 2259func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) { 2260 provider_bp_a := ` 2261 java_api_contribution { 2262 name: "foo1", 2263 api_file: "current.txt", 2264 api_surface: "public", 2265 } 2266 ` 2267 provider_bp_b := ` 2268 java_api_contribution { 2269 name: "foo2", 2270 api_file: "current.txt", 2271 api_surface: "public", 2272 } 2273 ` 2274 lib_bp_a := ` 2275 java_api_library { 2276 name: "lib1", 2277 api_surface: "public", 2278 api_contributions: ["foo1", "foo2"], 2279 stubs_type: "everything", 2280 } 2281 ` 2282 2283 ctx := android.GroupFixturePreparers( 2284 prepareForJavaTest, 2285 android.FixtureMergeMockFs( 2286 map[string][]byte{ 2287 "a/Android.bp": []byte(provider_bp_a), 2288 "b/Android.bp": []byte(provider_bp_b), 2289 "c/Android.bp": []byte(lib_bp_a), 2290 }, 2291 ), 2292 android.FixtureMergeEnv( 2293 map[string]string{ 2294 "DISABLE_STUB_VALIDATION": "true", 2295 }, 2296 ), 2297 ).RunTestWithBp(t, ` 2298 java_api_library { 2299 name: "bar1", 2300 api_surface: "public", 2301 api_contributions: ["foo1"], 2302 full_api_surface_stub: "lib1", 2303 stubs_type: "everything", 2304 } 2305 `) 2306 2307 m := ctx.ModuleForTests("bar1", "android_common") 2308 manifest := m.Output("metalava.sbox.textproto") 2309 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest) 2310 manifestCommand := sboxProto.Commands[0].GetCommand() 2311 android.AssertStringDoesContain(t, "Command expected to contain full_api_surface_stub output jar", manifestCommand, "lib1.jar") 2312} 2313 2314func TestTransitiveSrcFiles(t *testing.T) { 2315 ctx, _ := testJava(t, ` 2316 java_library { 2317 name: "a", 2318 srcs: ["a.java"], 2319 } 2320 java_library { 2321 name: "b", 2322 srcs: ["b.java"], 2323 } 2324 java_library { 2325 name: "c", 2326 srcs: ["c.java"], 2327 libs: ["a"], 2328 static_libs: ["b"], 2329 } 2330 `) 2331 c := ctx.ModuleForTests("c", "android_common").Module() 2332 javaInfo, _ := android.SingletonModuleProvider(ctx, c, JavaInfoProvider) 2333 transitiveSrcFiles := android.Paths(javaInfo.TransitiveSrcFiles.ToList()) 2334 android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings()) 2335} 2336 2337func TestTradefedOptions(t *testing.T) { 2338 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, ` 2339java_test_host { 2340 name: "foo", 2341 test_options: { 2342 tradefed_options: [ 2343 { 2344 name: "exclude-path", 2345 value: "org/apache" 2346 } 2347 ] 2348 } 2349} 2350`) 2351 2352 buildOS := result.Config.BuildOS.String() 2353 args := result.ModuleForTests("foo", buildOS+"_common"). 2354 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args 2355 expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />") 2356 if args["extraConfigs"] != expected { 2357 t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"]) 2358 } 2359} 2360 2361func TestTestRunnerOptions(t *testing.T) { 2362 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, ` 2363java_test_host { 2364 name: "foo", 2365 test_options: { 2366 test_runner_options: [ 2367 { 2368 name: "test-timeout", 2369 value: "10m" 2370 } 2371 ] 2372 } 2373} 2374`) 2375 2376 buildOS := result.Config.BuildOS.String() 2377 args := result.ModuleForTests("foo", buildOS+"_common"). 2378 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args 2379 expected := proptools.NinjaAndShellEscape("<option name=\"test-timeout\" value=\"10m\" />\\n ") 2380 if args["extraTestRunnerConfigs"] != expected { 2381 t.Errorf("Expected args[\"extraTestRunnerConfigs\"] to equal %q, was %q", expected, args["extraTestRunnerConfigs"]) 2382 } 2383} 2384 2385func TestJavaExcludeStaticLib(t *testing.T) { 2386 ctx, _ := testJava(t, ` 2387 java_library { 2388 name: "bar", 2389 } 2390 java_library { 2391 name: "foo", 2392 } 2393 java_library { 2394 name: "baz", 2395 static_libs: [ 2396 "foo", 2397 "bar", 2398 ], 2399 exclude_static_libs: [ 2400 "bar", 2401 ], 2402 } 2403 `) 2404 2405 // "bar" not included as dependency of "baz" 2406 CheckModuleDependencies(t, ctx, "baz", "android_common", []string{ 2407 `core-lambda-stubs`, 2408 `ext`, 2409 `foo`, 2410 `framework`, 2411 `stable-core-platform-api-stubs-system-modules`, 2412 `stable.core.platform.api.stubs`, 2413 }) 2414} 2415 2416func TestJavaLibraryWithResourcesStem(t *testing.T) { 2417 ctx, _ := testJavaWithFS(t, ` 2418 java_library { 2419 name: "foo", 2420 java_resource_dirs: ["test-jar"], 2421 stem: "test", 2422 } 2423 `, 2424 map[string][]byte{ 2425 "test-jar/test/resource.txt": nil, 2426 }) 2427 2428 m := ctx.ModuleForTests("foo", "android_common") 2429 outputs := fmt.Sprint(m.AllOutputs()) 2430 if !strings.Contains(outputs, "test.jar") { 2431 t.Errorf("Module output does not contain expected jar %s", "test.jar") 2432 } 2433} 2434 2435func TestHeadersOnly(t *testing.T) { 2436 ctx, _ := testJava(t, ` 2437 java_library { 2438 name: "foo", 2439 srcs: ["a.java"], 2440 headers_only: true, 2441 } 2442 `) 2443 2444 turbine := ctx.ModuleForTests("foo", "android_common").Rule("turbine") 2445 if len(turbine.Inputs) != 1 || turbine.Inputs[0].String() != "a.java" { 2446 t.Errorf(`foo inputs %v != ["a.java"]`, turbine.Inputs) 2447 } 2448 2449 javac := ctx.ModuleForTests("foo", "android_common").MaybeRule("javac") 2450 android.AssertDeepEquals(t, "javac rule", nil, javac.Rule) 2451} 2452 2453func TestJavaApiContributionImport(t *testing.T) { 2454 ctx := android.GroupFixturePreparers( 2455 prepareForJavaTest, 2456 android.FixtureMergeEnv( 2457 map[string]string{ 2458 "DISABLE_STUB_VALIDATION": "true", 2459 }, 2460 ), 2461 ).RunTestWithBp(t, ` 2462 java_api_library { 2463 name: "foo", 2464 api_contributions: ["bar"], 2465 stubs_type: "everything", 2466 } 2467 java_api_contribution_import { 2468 name: "bar", 2469 api_file: "current.txt", 2470 api_surface: "public", 2471 } 2472 `) 2473 m := ctx.ModuleForTests("foo", "android_common") 2474 manifest := m.Output("metalava.sbox.textproto") 2475 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest) 2476 manifestCommand := sboxProto.Commands[0].GetCommand() 2477 sourceFilesFlag := "--source-files current.txt" 2478 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) 2479} 2480 2481func TestJavaApiLibraryApiFilesSorting(t *testing.T) { 2482 ctx, _ := testJava(t, ` 2483 java_api_library { 2484 name: "foo", 2485 api_contributions: [ 2486 "system-server-api-stubs-docs-non-updatable.api.contribution", 2487 "test-api-stubs-docs-non-updatable.api.contribution", 2488 "system-api-stubs-docs-non-updatable.api.contribution", 2489 "module-lib-api-stubs-docs-non-updatable.api.contribution", 2490 "api-stubs-docs-non-updatable.api.contribution", 2491 ], 2492 stubs_type: "everything", 2493 } 2494 `) 2495 m := ctx.ModuleForTests("foo", "android_common") 2496 manifest := m.Output("metalava.sbox.textproto") 2497 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest) 2498 manifestCommand := sboxProto.Commands[0].GetCommand() 2499 2500 // Api files are sorted from the narrowest api scope to the widest api scope. 2501 // test api and module lib api surface do not have subset/superset relationship, 2502 // but they will never be passed as inputs at the same time. 2503 sourceFilesFlag := "--source-files default/java/api/current.txt " + 2504 "default/java/api/system-current.txt default/java/api/test-current.txt " + 2505 "default/java/api/module-lib-current.txt default/java/api/system-server-current.txt" 2506 android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag) 2507} 2508 2509func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) { 2510 result := android.GroupFixturePreparers( 2511 prepareForJavaTest, 2512 PrepareForTestWithJavaSdkLibraryFiles, 2513 FixtureWithLastReleaseApis("foo"), 2514 android.FixtureModifyConfig(func(config android.Config) { 2515 config.SetApiLibraries([]string{"foo"}) 2516 }), 2517 android.FixtureMergeMockFs( 2518 map[string][]byte{ 2519 "A.java": nil, 2520 }, 2521 ), 2522 ).RunTestWithBp(t, ` 2523 java_library { 2524 name: "bar", 2525 srcs: ["a.java"], 2526 } 2527 java_system_modules { 2528 name: "baz", 2529 libs: ["bar"], 2530 } 2531 java_sdk_library { 2532 name: "foo", 2533 srcs: ["A.java"], 2534 system_modules: "baz", 2535 } 2536 `) 2537 m := result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common") 2538 manifest := m.Output("metalava.sbox.textproto") 2539 sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest) 2540 manifestCommand := sboxProto.Commands[0].GetCommand() 2541 classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar" 2542 android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag) 2543} 2544 2545func TestApiLibraryDroidstubsDependency(t *testing.T) { 2546 result := android.GroupFixturePreparers( 2547 prepareForJavaTest, 2548 PrepareForTestWithJavaSdkLibraryFiles, 2549 FixtureWithLastReleaseApis("foo"), 2550 android.FixtureModifyConfig(func(config android.Config) { 2551 config.SetApiLibraries([]string{"foo"}) 2552 }), 2553 android.FixtureMergeMockFs( 2554 map[string][]byte{ 2555 "A.java": nil, 2556 }, 2557 ), 2558 ).RunTestWithBp(t, ` 2559 java_api_library { 2560 name: "foo", 2561 api_contributions: [ 2562 "api-stubs-docs-non-updatable.api.contribution", 2563 ], 2564 enable_validation: true, 2565 stubs_type: "everything", 2566 } 2567 java_api_library { 2568 name: "bar", 2569 api_contributions: [ 2570 "api-stubs-docs-non-updatable.api.contribution", 2571 ], 2572 enable_validation: false, 2573 stubs_type: "everything", 2574 } 2575 `) 2576 2577 currentApiTimestampPath := "api-stubs-docs-non-updatable/android_common/everything/check_current_api.timestamp" 2578 foo := result.ModuleForTests("foo", "android_common").Module().(*ApiLibrary) 2579 fooValidationPathsString := strings.Join(foo.validationPaths.Strings(), " ") 2580 bar := result.ModuleForTests("bar", "android_common").Module().(*ApiLibrary) 2581 barValidationPathsString := strings.Join(bar.validationPaths.Strings(), " ") 2582 android.AssertStringDoesContain(t, 2583 "Module expected to have validation", 2584 fooValidationPathsString, 2585 currentApiTimestampPath, 2586 ) 2587 android.AssertStringDoesNotContain(t, 2588 "Module expected to not have validation", 2589 barValidationPathsString, 2590 currentApiTimestampPath, 2591 ) 2592} 2593 2594func TestDisableFromTextStubForCoverageBuild(t *testing.T) { 2595 result := android.GroupFixturePreparers( 2596 prepareForJavaTest, 2597 PrepareForTestWithJavaSdkLibraryFiles, 2598 PrepareForTestWithJacocoInstrumentation, 2599 FixtureWithLastReleaseApis("foo"), 2600 android.FixtureModifyConfig(func(config android.Config) { 2601 config.SetApiLibraries([]string{"foo"}) 2602 config.SetBuildFromTextStub(true) 2603 }), 2604 android.FixtureModifyEnv(func(env map[string]string) { 2605 env["EMMA_INSTRUMENT"] = "true" 2606 }), 2607 ).RunTestWithBp(t, ` 2608 java_sdk_library { 2609 name: "foo", 2610 srcs: ["A.java"], 2611 } 2612 `) 2613 android.AssertBoolEquals(t, "stub module expected to depend on from-source stub", 2614 true, CheckModuleHasDependency(t, result.TestContext, 2615 apiScopePublic.stubsLibraryModuleName("foo"), "android_common", 2616 apiScopePublic.sourceStubLibraryModuleName("foo"))) 2617 2618 android.AssertBoolEquals(t, "stub module expected to not depend on from-text stub", 2619 false, CheckModuleHasDependency(t, result.TestContext, 2620 apiScopePublic.stubsLibraryModuleName("foo"), "android_common", 2621 apiScopePublic.apiLibraryModuleName("foo"))) 2622} 2623 2624func TestMultiplePrebuilts(t *testing.T) { 2625 bp := ` 2626 // an rdep 2627 java_library { 2628 name: "foo", 2629 libs: ["bar"], 2630 } 2631 2632 // multiple variations of dep 2633 // source 2634 java_library { 2635 name: "bar", 2636 srcs: ["bar.java"], 2637 } 2638 // prebuilt "v1" 2639 java_import { 2640 name: "bar", 2641 jars: ["bar.jar"], 2642 } 2643 // prebuilt "v2" 2644 java_import { 2645 name: "bar.v2", 2646 source_module_name: "bar", 2647 jars: ["bar.v1.jar"], 2648 } 2649 2650 // selectors 2651 apex_contributions { 2652 name: "myapex_contributions", 2653 contents: ["%v"], 2654 } 2655 ` 2656 hasDep := func(ctx *android.TestResult, m android.Module, wantDep android.Module) bool { 2657 t.Helper() 2658 var found bool 2659 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 2660 if dep == wantDep { 2661 found = true 2662 } 2663 }) 2664 return found 2665 } 2666 2667 hasFileWithStem := func(m android.TestingModule, stem string) bool { 2668 t.Helper() 2669 for _, o := range m.AllOutputs() { 2670 _, file := filepath.Split(o) 2671 if file == stem+".jar" { 2672 return true 2673 } 2674 } 2675 return false 2676 } 2677 2678 testCases := []struct { 2679 desc string 2680 selectedDependencyName string 2681 expectedDependencyName string 2682 }{ 2683 { 2684 desc: "Source library is selected using apex_contributions", 2685 selectedDependencyName: "bar", 2686 expectedDependencyName: "bar", 2687 }, 2688 { 2689 desc: "Prebuilt library v1 is selected using apex_contributions", 2690 selectedDependencyName: "prebuilt_bar", 2691 expectedDependencyName: "prebuilt_bar", 2692 }, 2693 { 2694 desc: "Prebuilt library v2 is selected using apex_contributions", 2695 selectedDependencyName: "prebuilt_bar.v2", 2696 expectedDependencyName: "prebuilt_bar.v2", 2697 }, 2698 } 2699 2700 for _, tc := range testCases { 2701 ctx := android.GroupFixturePreparers( 2702 prepareForJavaTest, 2703 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2704 variables.BuildFlags = map[string]string{ 2705 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions", 2706 } 2707 }), 2708 ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName)) 2709 2710 // check that rdep gets the correct variation of dep 2711 foo := ctx.ModuleForTests("foo", "android_common") 2712 expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_common") 2713 android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module())) 2714 2715 // check that output file of dep is always bar.jar 2716 // The filename should be agnostic to source/prebuilt/prebuilt_version 2717 android.AssertBoolEquals(t, fmt.Sprintf("could not find bar.jar in outputs of %s. All Outputs %v\n", tc.expectedDependencyName, expectedDependency.AllOutputs()), true, hasFileWithStem(expectedDependency, "bar")) 2718 2719 // check LOCAL_MODULE of the selected module name 2720 // the prebuilt should have the same LOCAL_MODULE when exported to make 2721 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, expectedDependency.Module())[0] 2722 android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "bar", entries.EntryMap["LOCAL_MODULE"][0]) 2723 } 2724} 2725 2726func TestMultiplePlatformCompatConfigPrebuilts(t *testing.T) { 2727 bp := ` 2728 // multiple variations of platform_compat_config 2729 // source 2730 platform_compat_config { 2731 name: "myconfig", 2732 } 2733 // prebuilt "v1" 2734 prebuilt_platform_compat_config { 2735 name: "myconfig", 2736 metadata: "myconfig.xml", 2737 } 2738 // prebuilt "v2" 2739 prebuilt_platform_compat_config { 2740 name: "myconfig.v2", 2741 source_module_name: "myconfig", // without source_module_name, the singleton will merge two .xml files 2742 metadata: "myconfig.v2.xml", 2743 } 2744 2745 // selectors 2746 apex_contributions { 2747 name: "myapex_contributions", 2748 contents: ["%v"], 2749 } 2750 ` 2751 testCases := []struct { 2752 desc string 2753 selectedDependencyName string 2754 expectedPlatformCompatConfigXml string 2755 }{ 2756 { 2757 desc: "Source platform_compat_config is selected using apex_contributions", 2758 selectedDependencyName: "myconfig", 2759 expectedPlatformCompatConfigXml: "out/soong/.intermediates/myconfig/android_common/myconfig_meta.xml", 2760 }, 2761 { 2762 desc: "Prebuilt platform_compat_config v1 is selected using apex_contributions", 2763 selectedDependencyName: "prebuilt_myconfig", 2764 expectedPlatformCompatConfigXml: "myconfig.xml", 2765 }, 2766 { 2767 desc: "Prebuilt platform_compat_config v2 is selected using apex_contributions", 2768 selectedDependencyName: "prebuilt_myconfig.v2", 2769 expectedPlatformCompatConfigXml: "myconfig.v2.xml", 2770 }, 2771 } 2772 2773 for _, tc := range testCases { 2774 ctx := android.GroupFixturePreparers( 2775 prepareForJavaTest, 2776 PrepareForTestWithPlatformCompatConfig, 2777 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2778 variables.BuildFlags = map[string]string{ 2779 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions", 2780 } 2781 }), 2782 ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName)) 2783 2784 mergedGlobalConfig := ctx.SingletonForTests("platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml") 2785 android.AssertIntEquals(t, "The merged compat config file should only have a single dependency", 1, len(mergedGlobalConfig.Implicits)) 2786 android.AssertStringEquals(t, "The merged compat config file is missing the appropriate platform compat config", mergedGlobalConfig.Implicits[0].String(), tc.expectedPlatformCompatConfigXml) 2787 } 2788} 2789 2790func TestApiLibraryAconfigDeclarations(t *testing.T) { 2791 result := android.GroupFixturePreparers( 2792 prepareForJavaTest, 2793 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2794 }), 2795 android.FixtureMergeMockFs(map[string][]byte{ 2796 "a/A.java": nil, 2797 "a/current.txt": nil, 2798 "a/removed.txt": nil, 2799 }), 2800 ).RunTestWithBp(t, ` 2801 aconfig_declarations { 2802 name: "bar", 2803 package: "com.example.package", 2804 container: "com.android.foo", 2805 srcs: [ 2806 "bar.aconfig", 2807 ], 2808 } 2809 java_api_contribution { 2810 name: "baz", 2811 api_file: "a/current.txt", 2812 api_surface: "public", 2813 } 2814 java_api_library { 2815 name: "foo", 2816 api_surface: "public", 2817 api_contributions: [ 2818 "baz", 2819 ], 2820 aconfig_declarations: [ 2821 "bar", 2822 ], 2823 stubs_type: "exportable", 2824 enable_validation: false, 2825 } 2826 `) 2827 2828 // Check if java_api_library depends on aconfig_declarations 2829 android.AssertBoolEquals(t, "foo expected to depend on bar", 2830 CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true) 2831 2832 m := result.ModuleForTests("foo", "android_common") 2833 android.AssertStringDoesContain(t, "foo generates revert annotations file", 2834 strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt") 2835 2836 // revert-annotations.txt passed to exportable stubs generation metalava command 2837 manifest := m.Output("metalava.sbox.textproto") 2838 cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command) 2839 android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt") 2840} 2841 2842func TestTestOnly(t *testing.T) { 2843 t.Parallel() 2844 ctx := android.GroupFixturePreparers( 2845 prepareForJavaTest, 2846 ).RunTestWithBp(t, ` 2847 // These should be test-only 2848 java_library { 2849 name: "lib1-test-only", 2850 srcs: ["a.java"], 2851 test_only: true, 2852 } 2853 java_test { 2854 name: "java-test", 2855 } 2856 java_test_host { 2857 name: "java-test-host", 2858 } 2859 java_test_helper_library { 2860 name: "helper-library", 2861 } 2862 java_binary { 2863 name: "java-data-binary", 2864 srcs: ["foo.java"], 2865 main_class: "foo.bar.jb", 2866 test_only: true, 2867 } 2868 2869 // These are NOT 2870 java_library { 2871 name: "lib2-app", 2872 srcs: ["b.java"], 2873 } 2874 java_import { 2875 name: "bar", 2876 jars: ["bar.jar"], 2877 } 2878 java_binary { 2879 name: "java-binary", 2880 srcs: ["foo.java"], 2881 main_class: "foo.bar.jb", 2882 } 2883 `) 2884 2885 expectedTestOnlyModules := []string{ 2886 "lib1-test-only", 2887 "java-test", 2888 "java-test-host", 2889 "helper-library", 2890 "java-data-binary", 2891 } 2892 expectedTopLevelTests := []string{ 2893 "java-test", 2894 "java-test-host", 2895 } 2896 assertTestOnlyAndTopLevel(t, ctx, expectedTestOnlyModules, expectedTopLevelTests) 2897} 2898 2899// Don't allow setting test-only on things that are always tests or never tests. 2900func TestInvalidTestOnlyTargets(t *testing.T) { 2901 testCases := []string{ 2902 ` java_test { name: "java-test", test_only: true, srcs: ["foo.java"], } `, 2903 ` java_test_host { name: "java-test-host", test_only: true, srcs: ["foo.java"], } `, 2904 ` java_test_import { name: "java-test-import", test_only: true, } `, 2905 ` java_api_library { name: "java-api-library", test_only: true, } `, 2906 ` java_test_helper_library { name: "test-help-lib", test_only: true, } `, 2907 ` java_defaults { name: "java-defaults", test_only: true, } `, 2908 } 2909 2910 for i, bp := range testCases { 2911 android.GroupFixturePreparers(prepareForJavaTest). 2912 ExtendWithErrorHandler( 2913 expectOneError("unrecognized property \"test_only\"", 2914 fmt.Sprintf("testcase: %d", i))). 2915 RunTestWithBp(t, bp) 2916 } 2917} 2918 2919// Expect exactly one that matches 'expected'. 2920// Append 'msg' to the Errorf that printed. 2921func expectOneError(expected string, msg string) android.FixtureErrorHandler { 2922 return android.FixtureCustomErrorHandler(func(t *testing.T, result *android.TestResult) { 2923 t.Helper() 2924 if len(result.Errs) != 1 { 2925 t.Errorf("Expected exactly one error, but found: %d when setting test_only on: %s", len(result.Errs), msg) 2926 return 2927 } 2928 actualErrMsg := result.Errs[0].Error() 2929 if !strings.Contains(actualErrMsg, expected) { 2930 t.Errorf("Different error than expected. Received: [%v] on %s expected: %s", actualErrMsg, msg, expected) 2931 } 2932 }) 2933} 2934 2935func TestJavaLibHostWithStem(t *testing.T) { 2936 ctx, _ := testJava(t, ` 2937 java_library_host { 2938 name: "foo", 2939 srcs: ["a.java"], 2940 stem: "foo-new", 2941 } 2942 `) 2943 2944 buildOS := ctx.Config().BuildOS.String() 2945 foo := ctx.ModuleForTests("foo", buildOS+"_common") 2946 2947 outputs := fmt.Sprint(foo.AllOutputs()) 2948 if !strings.Contains(outputs, "foo-new.jar") { 2949 t.Errorf("Module output does not contain expected jar %s", "foo-new.jar") 2950 } 2951} 2952 2953func TestJavaLibWithStem(t *testing.T) { 2954 ctx, _ := testJava(t, ` 2955 java_library { 2956 name: "foo", 2957 srcs: ["a.java"], 2958 stem: "foo-new", 2959 } 2960 `) 2961 2962 foo := ctx.ModuleForTests("foo", "android_common") 2963 2964 outputs := fmt.Sprint(foo.AllOutputs()) 2965 if !strings.Contains(outputs, "foo-new.jar") { 2966 t.Errorf("Module output does not contain expected jar %s", "foo-new.jar") 2967 } 2968} 2969 2970func TestJavaLibraryOutputFilesRel(t *testing.T) { 2971 result := android.GroupFixturePreparers( 2972 PrepareForTestWithJavaDefaultModules, 2973 ).RunTestWithBp(t, ` 2974 java_library { 2975 name: "foo", 2976 srcs: ["a.java"], 2977 } 2978 2979 java_import { 2980 name: "bar", 2981 jars: ["bar.aar"], 2982 2983 } 2984 2985 java_import { 2986 name: "baz", 2987 jars: ["baz.aar"], 2988 static_libs: ["bar"], 2989 } 2990 `) 2991 2992 foo := result.ModuleForTests("foo", "android_common") 2993 bar := result.ModuleForTests("bar", "android_common") 2994 baz := result.ModuleForTests("baz", "android_common") 2995 2996 fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "") 2997 barOutputPath := android.OutputFileForModule(android.PathContext(nil), bar.Module(), "") 2998 bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "") 2999 3000 android.AssertPathRelativeToTopEquals(t, "foo output path", 3001 "out/soong/.intermediates/foo/android_common/javac/foo.jar", fooOutputPath) 3002 android.AssertPathRelativeToTopEquals(t, "bar output path", 3003 "out/soong/.intermediates/bar/android_common/combined/bar.jar", barOutputPath) 3004 android.AssertPathRelativeToTopEquals(t, "baz output path", 3005 "out/soong/.intermediates/baz/android_common/combined/baz.jar", bazOutputPath) 3006 3007 android.AssertStringEquals(t, "foo relative output path", 3008 "foo.jar", fooOutputPath.Rel()) 3009 android.AssertStringEquals(t, "bar relative output path", 3010 "bar.jar", barOutputPath.Rel()) 3011 android.AssertStringEquals(t, "baz relative output path", 3012 "baz.jar", bazOutputPath.Rel()) 3013} 3014 3015func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) { 3016 t.Helper() 3017 actualTrueModules := []string{} 3018 actualTopLevelTests := []string{} 3019 addActuals := func(m blueprint.Module, key blueprint.ProviderKey[android.TestModuleInformation]) { 3020 if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, key); ok { 3021 if provider.TestOnly { 3022 actualTrueModules = append(actualTrueModules, m.Name()) 3023 } 3024 if provider.TopLevelTarget { 3025 actualTopLevelTests = append(actualTopLevelTests, m.Name()) 3026 } 3027 } 3028 } 3029 3030 ctx.VisitAllModules(func(m blueprint.Module) { 3031 addActuals(m, android.TestOnlyProviderKey) 3032 3033 }) 3034 3035 notEqual, left, right := android.ListSetDifference(expectedTestOnly, actualTrueModules) 3036 if notEqual { 3037 t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right) 3038 } 3039 3040 notEqual, left, right = android.ListSetDifference(expectedTopLevel, actualTopLevelTests) 3041 if notEqual { 3042 t.Errorf("top-level: Expected but not found: %v, Found but not expected: %v", left, right) 3043 } 3044} 3045