1// Copyright (C) 2019 The Android Open Source Project 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 aidl 16 17import ( 18 "fmt" 19 "os" 20 "path/filepath" 21 "strings" 22 "testing" 23 24 "github.com/google/blueprint" 25 "github.com/google/blueprint/proptools" 26 27 "android/soong/aidl_library" 28 "android/soong/android" 29 "android/soong/cc" 30 "android/soong/genrule" 31 "android/soong/java" 32 "android/soong/rust" 33) 34 35func TestMain(m *testing.M) { 36 os.Exit(m.Run()) 37} 38 39func withFiles(files map[string][]byte) android.FixturePreparer { 40 return android.FixtureMergeMockFs(files) 41} 42 43func intPtr(v int) *int { 44 return &v 45} 46 47func setReleaseEnv() android.FixturePreparer { 48 return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 49 variables.Release_aidl_use_unfrozen = proptools.BoolPtr(false) 50 }) 51} 52 53func setTestFreezeEnv() android.FixturePreparer { 54 return android.FixtureMergeEnv(map[string]string{ 55 "AIDL_FROZEN_REL": "true", 56 "AIDL_FROZEN_OWNERS": "aosp test", 57 }) 58} 59 60func setUseUnfrozenOverrideEnvTrue() android.FixturePreparer { 61 return android.FixtureMergeEnv(map[string]string{ 62 "AIDL_USE_UNFROZEN_OVERRIDE": "true", 63 }) 64} 65 66func setUseUnfrozenOverrideEnvFalse() android.FixturePreparer { 67 return android.FixtureMergeEnv(map[string]string{ 68 "AIDL_USE_UNFROZEN_OVERRIDE": "false", 69 }) 70} 71 72func setTransitiveFreezeEnv() android.FixturePreparer { 73 return android.FixtureMergeEnv(map[string]string{ 74 "AIDL_TRANSITIVE_FREEZE": "true", 75 }) 76} 77 78func _testAidl(t *testing.T, bp string, customizers ...android.FixturePreparer) android.FixturePreparer { 79 t.Helper() 80 81 preparers := []android.FixturePreparer{} 82 83 preparers = append(preparers, 84 cc.PrepareForTestWithCcDefaultModules, 85 java.PrepareForTestWithJavaDefaultModules, 86 genrule.PrepareForTestWithGenRuleBuildComponents, 87 android.PrepareForTestWithNamespace, 88 ) 89 90 bp = bp + ` 91 package { 92 default_visibility: ["//visibility:public"], 93 } 94 java_defaults { 95 name: "aidl-java-module-defaults", 96 } 97 cc_defaults { 98 name: "aidl-cpp-module-defaults", 99 } 100 rust_defaults { 101 name: "aidl-rust-module-defaults", 102 } 103 cc_library { 104 name: "libbinder", 105 recovery_available: true, 106 } 107 cc_library_static { 108 name: "aidl-analyzer-main", 109 host_supported: true, 110 vendor_available: true, 111 recovery_available: true, 112 } 113 cc_library { 114 name: "libutils", 115 recovery_available: true, 116 } 117 cc_library { 118 name: "libcutils", 119 recovery_available: true, 120 } 121 cc_library { 122 name: "libbinder_ndk", 123 recovery_available: true, 124 stubs: { 125 versions: ["29"], 126 } 127 } 128 ndk_library { 129 name: "libbinder_ndk", 130 symbol_file: "libbinder_ndk.map.txt", 131 first_version: "29", 132 } 133 cc_library { 134 name: "liblog", 135 no_libcrt: true, 136 nocrt: true, 137 system_shared_libs: [], 138 } 139 rust_library { 140 name: "libstd", 141 crate_name: "std", 142 srcs: [""], 143 no_stdlibs: true, 144 sysroot: true, 145 } 146 rust_library { 147 name: "libtest", 148 crate_name: "test", 149 srcs: [""], 150 no_stdlibs: true, 151 sysroot: true, 152 } 153 rust_library { 154 name: "libbinder_rs", 155 crate_name: "binder", 156 srcs: [""], 157 } 158 rust_library { 159 name: "libstatic_assertions", 160 crate_name: "static_assertions", 161 srcs: [""], 162 } 163 rust_proc_macro { 164 name: "libasync_trait", 165 crate_name: "async_trait", 166 srcs: [""], 167 no_stdlibs: true, 168 } 169 ` 170 preparers = append(preparers, android.FixtureWithRootAndroidBp(bp)) 171 preparers = append(preparers, android.FixtureAddTextFile("system/tools/aidl/build/Android.bp", ` 172 aidl_interfaces_metadata { 173 name: "aidl_metadata_json", 174 visibility: ["//system/tools/aidl:__subpackages__"], 175 } 176 `)) 177 178 preparers = append(preparers, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 179 variables.Release_aidl_use_unfrozen = proptools.BoolPtr(true) 180 })) 181 182 preparers = append(preparers, customizers...) 183 184 preparers = append(preparers, 185 rust.PrepareForTestWithRustBuildComponents, 186 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 187 ctx.RegisterModuleType("aidl_interface", AidlInterfaceFactory) 188 ctx.RegisterModuleType("aidl_interface_defaults", AidlInterfaceDefaultsFactory) 189 ctx.RegisterModuleType("aidl_interfaces_metadata", aidlInterfacesMetadataSingletonFactory) 190 ctx.RegisterModuleType("rust_defaults", func() android.Module { 191 return rust.DefaultsFactory() 192 }) 193 ctx.RegisterModuleType("aidl_library", aidl_library.AidlLibraryFactory) 194 195 ctx.PreArchMutators(registerPreArchMutators) 196 ctx.PostDepsMutators(registerPostDepsMutators) 197 }), 198 ) 199 200 return android.GroupFixturePreparers(preparers...) 201} 202 203func testAidl(t *testing.T, bp string, customizers ...android.FixturePreparer) (*android.TestContext, android.Config) { 204 t.Helper() 205 preparer := _testAidl(t, bp, customizers...) 206 result := preparer.RunTest(t) 207 return result.TestContext, result.Config 208} 209 210func testAidlError(t *testing.T, pattern, bp string, customizers ...android.FixturePreparer) { 211 t.Helper() 212 preparer := _testAidl(t, bp, customizers...) 213 preparer. 214 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). 215 RunTest(t) 216} 217 218// asserts that there are expected module regardless of variants 219func assertModulesExists(t *testing.T, ctx *android.TestContext, names ...string) { 220 t.Helper() 221 missing := []string{} 222 for _, name := range names { 223 variants := ctx.ModuleVariantsForTests(name) 224 if len(variants) == 0 { 225 missing = append(missing, name) 226 } 227 } 228 if len(missing) > 0 { 229 // find all the modules that do exist 230 allModuleNames := make(map[string]bool) 231 ctx.VisitAllModules(func(m blueprint.Module) { 232 allModuleNames[ctx.ModuleName(m)] = true 233 }) 234 t.Errorf("expected modules(%v) not found. all modules: %v", missing, android.SortedKeys(allModuleNames)) 235 } 236} 237 238func assertContains(t *testing.T, actual, expected string) { 239 t.Helper() 240 if !strings.Contains(actual, expected) { 241 t.Errorf("%q is not found in %q.", expected, actual) 242 } 243} 244 245func assertListContains(t *testing.T, actual []string, expected string) { 246 t.Helper() 247 for _, a := range actual { 248 if strings.Contains(a, expected) { 249 return 250 } 251 } 252 t.Errorf("%q is not found in %v.", expected, actual) 253} 254 255// Vintf module must have versions in release version 256func TestVintfWithoutVersionInRelease(t *testing.T) { 257 vintfWithoutVersionBp := ` 258 aidl_interface { 259 name: "foo", 260 stability: "vintf", 261 srcs: [ 262 "IFoo.aidl", 263 ], 264 owner: "test", 265 backend: { 266 rust: { 267 enabled: true, 268 }, 269 }, 270 }` 271 expectedError := `module "foo_interface": versions: must be set \(need to be frozen\) because` 272 testAidlError(t, expectedError, vintfWithoutVersionBp, setTestFreezeEnv()) 273 274 ctx, _ := testAidl(t, vintfWithoutVersionBp, setReleaseEnv()) 275 assertModulesExists(t, ctx, "foo-V1-java", "foo-V1-rust", "foo-V1-cpp", "foo-V1-ndk") 276 ctx, _ = testAidl(t, vintfWithoutVersionBp) 277 assertModulesExists(t, ctx, "foo-V1-java", "foo-V1-rust", "foo-V1-cpp", "foo-V1-ndk") 278} 279 280// Check if using unstable version in release cause an error. 281func TestUnstableVersionUsageInRelease(t *testing.T) { 282 unstableVersionUsageInJavaBp := ` 283 aidl_interface { 284 name: "foo", 285 versions: [ 286 "1", 287 ], 288 srcs: [ 289 "IFoo.aidl", 290 ], 291 } 292 java_library { 293 name: "bar", 294 libs: ["foo-V2-java"], 295 }` 296 files := withFiles(map[string][]byte{ 297 "aidl_api/foo/1/foo.1.aidl": nil, 298 "aidl_api/foo/1/.hash": nil, 299 }) 300 301 expectedError := `foo-V2-java is an unfrozen development version, and it can't be used because` 302 testAidlError(t, expectedError, unstableVersionUsageInJavaBp, setTestFreezeEnv(), files) 303 testAidl(t, unstableVersionUsageInJavaBp, setReleaseEnv(), files) 304 testAidl(t, unstableVersionUsageInJavaBp, files) 305 306 // A stable version can be used in release version 307 stableVersionUsageInJavaBp := ` 308 aidl_interface { 309 name: "foo", 310 versions: [ 311 "1", 312 ], 313 srcs: [ 314 "IFoo.aidl", 315 ], 316 } 317 java_library { 318 name: "bar", 319 libs: ["foo-V1-java"], 320 }` 321 322 testAidl(t, stableVersionUsageInJavaBp, setReleaseEnv(), files) 323 testAidl(t, stableVersionUsageInJavaBp, setTestFreezeEnv(), files) 324 testAidl(t, stableVersionUsageInJavaBp, files) 325} 326 327func TestUsingUnstableVersionIndirectlyInRelease(t *testing.T) { 328 unstableVersionUsageInJavaBp := ` 329 aidl_interface { 330 name: "xxx", 331 srcs: ["IFoo.aidl"], 332 versions: ["1"], 333 } 334 aidl_interface { 335 name: "foo", 336 imports: ["xxx-V2"], // not OK 337 versions: ["1"], 338 srcs: ["IFoo.aidl"], 339 } 340 java_library { 341 name: "bar", 342 libs: ["foo-V1-java"], // OK 343 }` 344 files := withFiles(map[string][]byte{ 345 "aidl_api/foo/1/foo.1.aidl": nil, 346 "aidl_api/foo/1/.hash": nil, 347 "aidl_api/xxx/1/foo.1.aidl": nil, 348 "aidl_api/xxx/1/.hash": nil, 349 }) 350 351 expectedError := `xxx-V2-java is an unfrozen development version` 352 testAidlError(t, expectedError, unstableVersionUsageInJavaBp, setTestFreezeEnv(), files) 353 testAidl(t, unstableVersionUsageInJavaBp, setReleaseEnv(), files) 354 testAidl(t, unstableVersionUsageInJavaBp, files) 355} 356 357func TestFrozenTrueSimple(t *testing.T) { 358 frozenTest := ` 359 aidl_interface { 360 name: "foo", 361 versions: ["1"], 362 frozen: true, 363 srcs: ["IFoo.aidl"], 364 }` 365 files := withFiles(map[string][]byte{ 366 "aidl_api/foo/1/foo.1.aidl": nil, 367 "aidl_api/foo/1/.hash": nil, 368 }) 369 370 testAidl(t, frozenTest, files, setReleaseEnv()) 371 testAidl(t, frozenTest, files, setTestFreezeEnv()) 372 testAidl(t, frozenTest, files) 373} 374 375func TestFrozenWithNoVersions(t *testing.T) { 376 frozenTest := ` 377 aidl_interface { 378 name: "foo", 379 frozen: true, 380 srcs: ["IFoo.aidl"], 381 }` 382 files := withFiles(map[string][]byte{ 383 "aidl_api/foo/1/foo.1.aidl": nil, 384 "aidl_api/foo/1/.hash": nil, 385 }) 386 387 expectedError := `cannot be frozen without versions` 388 testAidlError(t, expectedError, frozenTest, files, setReleaseEnv()) 389 testAidlError(t, expectedError, frozenTest, files, setTestFreezeEnv()) 390 testAidlError(t, expectedError, frozenTest, files) 391} 392 393func TestFrozenImportingFrozen(t *testing.T) { 394 frozenTest := ` 395 aidl_interface { 396 name: "xxx", 397 srcs: ["IFoo.aidl"], 398 frozen: true, 399 versions: ["1"], 400 } 401 aidl_interface { 402 name: "foo", 403 imports: ["xxx-V1"], 404 versions: ["1"], 405 frozen: true, 406 srcs: ["IFoo.aidl"], 407 }` 408 files := withFiles(map[string][]byte{ 409 "aidl_api/foo/1/foo.1.aidl": nil, 410 "aidl_api/foo/1/.hash": nil, 411 "aidl_api/xxx/1/foo.1.aidl": nil, 412 "aidl_api/xxx/1/.hash": nil, 413 }) 414 415 testAidl(t, frozenTest, files, setReleaseEnv()) 416 testAidl(t, frozenTest, files, setTestFreezeEnv()) 417 testAidl(t, frozenTest, files) 418} 419 420func TestFrozenImportingVersionUnfrozen(t *testing.T) { 421 frozenTest := ` 422 aidl_interface { 423 name: "xxx", 424 srcs: ["IFoo.aidl"], 425 frozen: false, 426 versions: ["1"], 427 } 428 aidl_interface { 429 name: "foo", 430 imports: ["xxx-V1"], 431 versions: ["1"], 432 frozen: true, 433 srcs: ["IFoo.aidl"], 434 }` 435 files := withFiles(map[string][]byte{ 436 "aidl_api/foo/1/foo.1.aidl": nil, 437 "aidl_api/foo/1/.hash": nil, 438 "aidl_api/xxx/1/foo.1.aidl": nil, 439 "aidl_api/xxx/1/.hash": nil, 440 }) 441 442 testAidl(t, frozenTest, files, setReleaseEnv()) 443 testAidl(t, frozenTest, files, setTestFreezeEnv()) 444 testAidl(t, frozenTest, files) 445} 446 447func TestFrozenImportingUnfrozenWithFrozen(t *testing.T) { 448 frozenTest := ` 449 aidl_interface { 450 name: "xxx", 451 srcs: ["IFoo.aidl"], 452 frozen: false, 453 versions: ["1"], 454 } 455 aidl_interface { 456 name: "foo", 457 imports: ["xxx"], 458 versions: ["1"], 459 frozen: true, 460 srcs: ["IFoo.aidl"], 461 }` 462 files := withFiles(map[string][]byte{ 463 "aidl_api/foo/1/foo.1.aidl": nil, 464 "aidl_api/foo/1/.hash": nil, 465 "aidl_api/xxx/1/foo.1.aidl": nil, 466 "aidl_api/xxx/1/.hash": nil, 467 }) 468 469 expectedError := `"foo" imports "xxx" which is not frozen. Either "foo" must` 470 testAidlError(t, expectedError, frozenTest, files, setReleaseEnv()) 471 testAidlError(t, expectedError, frozenTest, files, setTestFreezeEnv()) 472 testAidlError(t, expectedError, frozenTest, files) 473} 474 475func TestFrozenImportingUnfrozen(t *testing.T) { 476 frozenTest := ` 477 aidl_interface { 478 name: "xxx", 479 srcs: ["IFoo.aidl"], 480 owner: "test", 481 frozen: false, 482 } 483 aidl_interface { 484 name: "foo", 485 imports: ["xxx"], 486 versions: ["1"], 487 frozen: true, 488 srcs: ["IFoo.aidl"], 489 }` 490 files := withFiles(map[string][]byte{ 491 "aidl_api/foo/1/foo.1.aidl": nil, 492 "aidl_api/foo/1/.hash": nil, 493 "aidl_api/xxx/1/foo.1.aidl": nil, 494 "aidl_api/xxx/1/.hash": nil, 495 }) 496 497 expectedError := `versions: must be set \(need to be frozen\) because` 498 testAidlError(t, expectedError, frozenTest, files, setTestFreezeEnv()) 499 500 expectedError = `"foo" imports "xxx" which is not frozen. Either "foo" must` 501 testAidlError(t, expectedError, frozenTest, files, setReleaseEnv()) 502 testAidlError(t, expectedError, frozenTest, files) 503} 504 505// This is allowed to keep legacy behavior. It could be prevented directly after API-freeze 506// if all frozen interfaces are explicitly marked `frozen: true,`. 507func TestFrozenImportingUnSpecified(t *testing.T) { 508 frozenTrueSimple := ` 509 aidl_interface { 510 name: "xxx", 511 srcs: ["IFoo.aidl"], 512 versions: ["1"], 513 } 514 aidl_interface { 515 name: "foo", 516 imports: ["xxx-V1"], 517 versions: ["1"], 518 frozen: true, 519 srcs: ["IFoo.aidl"], 520 }` 521 files := withFiles(map[string][]byte{ 522 "aidl_api/foo/1/foo.1.aidl": nil, 523 "aidl_api/foo/1/.hash": nil, 524 "aidl_api/xxx/1/foo.1.aidl": nil, 525 "aidl_api/xxx/1/.hash": nil, 526 }) 527 528 testAidl(t, frozenTrueSimple, files, setReleaseEnv()) 529 testAidl(t, frozenTrueSimple, files, setTestFreezeEnv()) 530 testAidl(t, frozenTrueSimple, files) 531} 532 533// Keeping legacy behavior if "frozen" is not specified 534func TestImportingNewLegacy(t *testing.T) { 535 frozenTest := ` 536 aidl_interface { 537 name: "xxx", 538 srcs: ["IFoo.aidl"], 539 versions: ["1"], 540 } 541 aidl_interface { 542 name: "foo", 543 imports: ["xxx-V2"], 544 versions_with_info: [ 545 {version: "1", imports: ["xxx-V1"]}, 546 ], 547 srcs: ["IFoo.aidl"], 548 }` 549 files := withFiles(map[string][]byte{ 550 "aidl_api/foo/1/foo.1.aidl": nil, 551 "aidl_api/foo/1/.hash": nil, 552 "aidl_api/xxx/1/foo.1.aidl": nil, 553 "aidl_api/xxx/1/.hash": nil, 554 }) 555 556 testAidl(t, frozenTest, files, setReleaseEnv()) 557 testAidl(t, frozenTest, files, setTestFreezeEnv()) 558 testAidl(t, frozenTest, files) 559} 560 561// We don't have a way to know if if "xxx" has changes to it and will 562// need a new version without the "frozen" attribute. So we keep the 563// legacy behavior and assume "foo" is still importing the old version. 564func TestFrozenImportingNewLegacy(t *testing.T) { 565 frozenTest := ` 566 aidl_interface { 567 name: "xxx", 568 srcs: ["IFoo.aidl"], 569 versions: ["1"], 570 } 571 aidl_interface { 572 name: "foo", 573 imports: ["xxx-V1"], 574 frozen: true, 575 versions_with_info: [ 576 {version: "1", imports: ["xxx-V1"]}, 577 ], 578 srcs: ["IFoo.aidl"], 579 }` 580 files := withFiles(map[string][]byte{ 581 "aidl_api/foo/1/foo.1.aidl": nil, 582 "aidl_api/foo/1/.hash": nil, 583 "aidl_api/xxx/1/foo.1.aidl": nil, 584 "aidl_api/xxx/1/.hash": nil, 585 }) 586 587 testAidl(t, frozenTest, files, setReleaseEnv()) 588 testAidl(t, frozenTest, files, setTestFreezeEnv()) 589 testAidl(t, frozenTest, files) 590} 591 592func TestFrozenImportingNewImplicit(t *testing.T) { 593 frozenTest := ` 594 aidl_interface { 595 name: "xxx", 596 srcs: ["IFoo.aidl"], 597 frozen: false, 598 versions: ["1"], 599 } 600 aidl_interface { 601 name: "foo", 602 imports: ["xxx"], 603 frozen: true, 604 versions_with_info: [ 605 {version: "1", imports: ["xxx-V1"]}, 606 ], 607 srcs: ["IFoo.aidl"], 608 }` 609 files := withFiles(map[string][]byte{ 610 "aidl_api/foo/1/foo.1.aidl": nil, 611 "aidl_api/foo/1/.hash": nil, 612 "aidl_api/xxx/1/foo.1.aidl": nil, 613 "aidl_api/xxx/1/.hash": nil, 614 }) 615 616 expectedError := `"foo" imports "xxx" which is not frozen. Either "foo" must` 617 testAidlError(t, expectedError, frozenTest, files, setReleaseEnv()) 618 testAidlError(t, expectedError, frozenTest, files, setTestFreezeEnv()) 619 testAidlError(t, expectedError, frozenTest, files) 620} 621 622func TestImportingOwned(t *testing.T) { 623 frozenTest := ` 624 aidl_interface { 625 name: "xxx", 626 srcs: ["IFoo.aidl"], 627 owner: "unknown-owner", 628 frozen: false, 629 } 630 aidl_interface { 631 name: "foo", 632 imports: ["xxx-V1"], 633 frozen: false, 634 versions_with_info: [ 635 {version: "1", imports: []}, 636 ], 637 srcs: ["IFoo.aidl"], 638 }` 639 files := withFiles(map[string][]byte{ 640 "aidl_api/foo/1/foo.1.aidl": nil, 641 "aidl_api/foo/1/.hash": nil, 642 }) 643 644 expectedError := "Android.bp:10:10: module \"foo_interface\": imports: \"foo\" imports \"xxx\" which is an interface owned by \"unknown-owner\". This is not allowed because the owned interface will not be frozen at the same time." 645 testAidlError(t, expectedError, frozenTest, files, setReleaseEnv()) 646 testAidlError(t, expectedError, frozenTest, files, setTestFreezeEnv()) 647 testAidlError(t, expectedError, frozenTest, files) 648} 649 650func TestImportingOwnedBothOwned(t *testing.T) { 651 frozenTest := ` 652 aidl_interface { 653 name: "xxx", 654 srcs: ["IFoo.aidl"], 655 owner: "unknown-owner", 656 frozen: false, 657 } 658 aidl_interface { 659 name: "foo", 660 imports: ["xxx-V1"], 661 frozen: false, 662 versions_with_info: [ 663 {version: "1", imports: []}, 664 ], 665 srcs: ["IFoo.aidl"], 666 owner: "unknown-owner-any", 667 }` 668 files := withFiles(map[string][]byte{ 669 "aidl_api/foo/1/foo.1.aidl": nil, 670 "aidl_api/foo/1/.hash": nil, 671 }) 672 673 testAidl(t, frozenTest, files, setReleaseEnv()) 674 testAidl(t, frozenTest, files, setTestFreezeEnv()) 675 testAidl(t, frozenTest, files) 676} 677 678func TestFrozenImportingNewExplicit(t *testing.T) { 679 frozenTest := ` 680 aidl_interface { 681 name: "xxx", 682 srcs: ["IFoo.aidl"], 683 frozen: false, 684 versions: ["1"], 685 } 686 aidl_interface { 687 name: "foo", 688 imports: ["xxx-V2"], 689 frozen: true, 690 versions_with_info: [ 691 {version: "1", imports: ["xxx-V1"]}, 692 ], 693 srcs: ["IFoo.aidl"], 694 }` 695 files := withFiles(map[string][]byte{ 696 "aidl_api/foo/1/foo.1.aidl": nil, 697 "aidl_api/foo/1/.hash": nil, 698 "aidl_api/xxx/1/foo.1.aidl": nil, 699 "aidl_api/xxx/1/.hash": nil, 700 }) 701 702 expectedError := "This interface is 'frozen: true' but the imports have changed. Set 'frozen: false' to allow changes: \\n Version current imports: map\\[xxx:2\\]\\n Version 1 imports: map\\[xxx:1\\]\\n" 703 testAidlError(t, expectedError, frozenTest, files, setReleaseEnv()) 704 testAidlError(t, expectedError, frozenTest, files, setTestFreezeEnv()) 705 testAidlError(t, expectedError, frozenTest, files) 706} 707 708func TestNonFrozenImportingNewImplicit(t *testing.T) { 709 frozenTest := ` 710 aidl_interface { 711 name: "xxx", 712 srcs: ["IFoo.aidl"], 713 frozen: false, 714 versions: ["1"], 715 } 716 aidl_interface { 717 name: "foo", 718 imports: ["xxx-V1"], 719 frozen: false, 720 versions_with_info: [ 721 {version: "1", imports: ["xxx-V1"]}, 722 ], 723 srcs: ["IFoo.aidl"], 724 }` 725 files := withFiles(map[string][]byte{ 726 "aidl_api/foo/1/foo.1.aidl": nil, 727 "aidl_api/foo/1/.hash": nil, 728 "aidl_api/xxx/1/foo.1.aidl": nil, 729 "aidl_api/xxx/1/.hash": nil, 730 }) 731 732 testAidl(t, frozenTest, files, setReleaseEnv()) 733 testAidl(t, frozenTest, files, setTestFreezeEnv()) 734 testAidl(t, frozenTest, files) 735} 736 737// The module which has never been frozen and is not "unstable" is not allowed in release version. 738func TestNonVersionedModuleUsageInRelease(t *testing.T) { 739 nonVersionedModuleUsageInJavaBp := ` 740 aidl_interface { 741 name: "foo", 742 srcs: [ 743 "IFoo.aidl", 744 ], 745 owner: "test", 746 } 747 748 java_library { 749 name: "bar", 750 libs: ["foo-V1-java"], 751 }` 752 753 expectedError := `"foo_interface": versions: must be set \(need to be frozen\) because` 754 testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv()) 755 testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv()) 756 testAidl(t, nonVersionedModuleUsageInJavaBp) 757 758 nonVersionedUnstableModuleUsageInJavaBp := ` 759 aidl_interface { 760 name: "foo", 761 srcs: [ 762 "IFoo.aidl", 763 ], 764 unstable: true, 765 } 766 767 java_library { 768 name: "bar", 769 libs: ["foo-java"], 770 }` 771 772 testAidl(t, nonVersionedUnstableModuleUsageInJavaBp, setReleaseEnv()) 773 testAidl(t, nonVersionedUnstableModuleUsageInJavaBp, setTestFreezeEnv()) 774 testAidl(t, nonVersionedUnstableModuleUsageInJavaBp) 775} 776 777func TestNonVersionedModuleOwnedByTestUsageInRelease(t *testing.T) { 778 nonVersionedModuleUsageInJavaBp := ` 779 aidl_interface { 780 name: "foo", 781 owner: "test", 782 srcs: [ 783 "IFoo.aidl", 784 ], 785 } 786 787 java_library { 788 name: "bar", 789 libs: ["foo-V1-java"], 790 }` 791 792 expectedError := `"foo_interface": versions: must be set \(need to be frozen\) because` 793 testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv()) 794 testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv()) 795 testAidl(t, nonVersionedModuleUsageInJavaBp) 796} 797 798func TestNonVersionedModuleOwnedByOtherUsageInRelease(t *testing.T) { 799 nonVersionedModuleUsageInJavaBp := ` 800 aidl_interface { 801 name: "foo", 802 owner: "unknown-owner", 803 srcs: [ 804 "IFoo.aidl", 805 ], 806 } 807 808 java_library { 809 name: "bar", 810 libs: ["foo-V1-java"], 811 }` 812 813 testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv()) 814 testAidl(t, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv()) 815 testAidl(t, nonVersionedModuleUsageInJavaBp) 816} 817 818func TestImportInRelease(t *testing.T) { 819 importInRelease := ` 820 aidl_interface { 821 name: "foo", 822 srcs: [ 823 "IFoo.aidl", 824 ], 825 imports: ["bar-V1"], 826 versions: ["1"], 827 } 828 829 aidl_interface { 830 name: "bar", 831 srcs: [ 832 "IBar.aidl", 833 ], 834 versions: ["1"], 835 } 836 ` 837 files := withFiles(map[string][]byte{ 838 "aidl_api/foo/1/foo.1.aidl": nil, 839 "aidl_api/foo/1/.hash": nil, 840 "aidl_api/bar/1/bar.1.aidl": nil, 841 "aidl_api/bar/1/.hash": nil, 842 }) 843 844 testAidl(t, importInRelease, setReleaseEnv(), files) 845 testAidl(t, importInRelease, setTestFreezeEnv(), files) 846 testAidl(t, importInRelease, files) 847} 848 849func TestUnstableVersionedModuleUsageInRelease(t *testing.T) { 850 nonVersionedModuleUsageInJavaBp := ` 851 aidl_interface { 852 name: "foo", 853 srcs: [ 854 "IFoo.aidl", 855 ], 856 versions: ["1"], 857 } 858 859 java_library { 860 name: "bar", 861 libs: ["foo-V2-java"], 862 }` 863 864 expectedError := `module \"bar\" variant \"android_common\": foo-V2-java is an unfrozen development version` 865 testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv()) 866 testAidl(t, nonVersionedModuleUsageInJavaBp, withFiles(map[string][]byte{ 867 "aidl_api/foo/1/foo.1.aidl": nil, 868 "aidl_api/foo/1/.hash": nil, 869 }), setReleaseEnv()) 870 testAidl(t, nonVersionedModuleUsageInJavaBp, withFiles(map[string][]byte{ 871 "aidl_api/foo/1/foo.1.aidl": nil, 872 "aidl_api/foo/1/.hash": nil, 873 })) 874} 875 876func TestUnstableVersionedModuleOwnedByTestUsageInRelease(t *testing.T) { 877 nonVersionedModuleUsageInJavaBp := ` 878 aidl_interface { 879 name: "foo", 880 owner: "test", 881 srcs: [ 882 "IFoo.aidl", 883 ], 884 versions: ["1"], 885 } 886 887 java_library { 888 name: "bar", 889 libs: ["foo-V2-java"], 890 }` 891 files := withFiles(map[string][]byte{ 892 "aidl_api/foo/1/foo.1.aidl": nil, 893 "aidl_api/foo/1/.hash": nil, 894 }) 895 896 expectedError := `Android.bp:11:2: module \"bar\" variant \"android_common\": foo-V2-java is an unfrozen development version` 897 testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv(), files) 898 testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv(), files) 899 testAidl(t, nonVersionedModuleUsageInJavaBp, files) 900} 901 902func TestFrozenModuleUsageInAllEnvs(t *testing.T) { 903 bp := ` 904 aidl_interface { 905 name: "foo", 906 frozen: true, 907 srcs: [ 908 "IFoo.aidl", 909 ], 910 versions: ["1"], 911 } 912 913 java_library { 914 name: "bar", 915 libs: ["foo-V2-java"], 916 }` 917 files := withFiles(map[string][]byte{ 918 "aidl_api/foo/1/foo.1.aidl": nil, 919 "aidl_api/foo/1/.hash": nil, 920 }) 921 922 expectedError := `Android.bp:11:2: module \"bar\" variant \"android_common\": foo-V2-java is an unfrozen development version` 923 testAidlError(t, expectedError, bp, setReleaseEnv(), files) 924 testAidlError(t, expectedError, bp, setTestFreezeEnv(), files) 925 testAidlError(t, expectedError, bp, files) 926} 927 928func TestUnstableVersionedModuleOwnedByOtherUsageInRelease(t *testing.T) { 929 nonVersionedModuleUsageInJavaBp := ` 930 aidl_interface { 931 name: "foo", 932 owner: "unknown-owner", 933 srcs: [ 934 "IFoo.aidl", 935 ], 936 versions: ["1"], 937 } 938 939 java_library { 940 name: "bar", 941 libs: ["foo-V2-java"], 942 }` 943 files := withFiles(map[string][]byte{ 944 "aidl_api/foo/1/foo.1.aidl": nil, 945 "aidl_api/foo/1/.hash": nil, 946 }) 947 948 testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv(), files) 949 testAidl(t, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv(), files) 950 testAidl(t, nonVersionedModuleUsageInJavaBp, files) 951} 952 953func TestUnstableModules(t *testing.T) { 954 testAidlError(t, `module "foo_interface": stability: must be empty when "unstable" is true`, ` 955 aidl_interface { 956 name: "foo", 957 stability: "vintf", 958 unstable: true, 959 srcs: [ 960 "IFoo.aidl", 961 ], 962 backend: { 963 rust: { 964 enabled: true, 965 }, 966 }, 967 } 968 `) 969 970 testAidlError(t, `module "foo_interface": versions: cannot have versions for an unstable interface`, ` 971 aidl_interface { 972 name: "foo", 973 versions: [ 974 "1", 975 ], 976 unstable: true, 977 srcs: [ 978 "IFoo.aidl", 979 ], 980 backend: { 981 rust: { 982 enabled: true, 983 }, 984 }, 985 } 986 `) 987 988 ctx, _ := testAidl(t, ` 989 aidl_interface { 990 name: "foo", 991 unstable: true, 992 srcs: [ 993 "IFoo.aidl", 994 ], 995 backend: { 996 rust: { 997 enabled: true, 998 }, 999 }, 1000 } 1001 `) 1002 1003 assertModulesExists(t, ctx, "foo-java", "foo-rust", "foo-cpp", "foo-ndk") 1004} 1005 1006func TestCreatesModulesWithNoVersions(t *testing.T) { 1007 ctx, _ := testAidl(t, ` 1008 aidl_interface { 1009 name: "foo", 1010 srcs: [ 1011 "IFoo.aidl", 1012 ], 1013 backend: { 1014 rust: { 1015 enabled: true, 1016 }, 1017 }, 1018 } 1019 `) 1020 1021 assertModulesExists(t, ctx, "foo-V1-java", "foo-V1-rust", "foo-V1-cpp", "foo-V1-ndk") 1022} 1023 1024func TestCreatesModulesWithFrozenVersions(t *testing.T) { 1025 // Each version should be under aidl_api/<name>/<ver> 1026 testAidlError(t, `No sources for a previous version in aidl_api/foo/1. Was a version manually added to .bp file?`, ` 1027 aidl_interface { 1028 name: "foo", 1029 srcs: [ 1030 "IFoo.aidl", 1031 ], 1032 versions: [ 1033 "1", 1034 ], 1035 backend: { 1036 rust: { 1037 enabled: true, 1038 }, 1039 }, 1040 } 1041 `) 1042 1043 ctx, _ := testAidl(t, ` 1044 aidl_interface { 1045 name: "foo", 1046 srcs: [ 1047 "IFoo.aidl", 1048 ], 1049 versions: [ 1050 "1", 1051 ], 1052 backend: { 1053 rust: { 1054 enabled: true, 1055 }, 1056 }, 1057 } 1058 `, withFiles(map[string][]byte{ 1059 "aidl_api/foo/1/foo.1.aidl": nil, 1060 "aidl_api/foo/1/.hash": nil, 1061 })) 1062 1063 // For frozen version "1" 1064 assertModulesExists(t, ctx, "foo-V1-java", "foo-V1-rust", "foo-V1-cpp", "foo-V1-ndk") 1065 1066 // For ToT (current) 1067 assertModulesExists(t, ctx, "foo-V2-java", "foo-V2-rust", "foo-V2-cpp", "foo-V2-ndk") 1068} 1069 1070func TestErrorsWithUnsortedVersions(t *testing.T) { 1071 testAidlError(t, `versions: should be sorted`, ` 1072 aidl_interface { 1073 name: "foo", 1074 srcs: [ 1075 "IFoo.aidl", 1076 ], 1077 versions: [ 1078 "2", 1079 "1", 1080 ], 1081 backend: { 1082 rust: { 1083 enabled: true, 1084 }, 1085 }, 1086 } 1087 `) 1088} 1089 1090func TestErrorsWithDuplicateVersions(t *testing.T) { 1091 testAidlError(t, `versions: duplicate`, ` 1092 aidl_interface { 1093 name: "foo", 1094 srcs: [ 1095 "IFoo.aidl", 1096 ], 1097 versions: [ 1098 "1", 1099 "1", 1100 ], 1101 } 1102 `) 1103} 1104 1105func TestErrorsWithNonPositiveVersions(t *testing.T) { 1106 testAidlError(t, `versions: should be > 0`, ` 1107 aidl_interface { 1108 name: "foo", 1109 srcs: [ 1110 "IFoo.aidl", 1111 ], 1112 versions: [ 1113 "-1", 1114 "1", 1115 ], 1116 } 1117 `) 1118} 1119 1120func TestErrorsWithNonIntegerVersions(t *testing.T) { 1121 testAidlError(t, `versions: "first" is not an integer`, ` 1122 aidl_interface { 1123 name: "foo", 1124 srcs: [ 1125 "IFoo.aidl", 1126 ], 1127 versions: [ 1128 "first", 1129 ], 1130 } 1131 `) 1132} 1133 1134const ( 1135 androidVariant = "android_common" 1136 nativeVariant = "android_arm_armv7-a-neon_shared" 1137 nativeRustVariant = "android_arm_armv7-a-neon_dylib" 1138) 1139 1140func TestNativeOutputIsAlwaysVersioned(t *testing.T) { 1141 var ctx *android.TestContext 1142 assertOutput := func(moduleName, variant, outputFilename string) { 1143 t.Helper() 1144 paths := ctx.ModuleForTests(moduleName, variant).OutputFiles(ctx, t, "") 1145 if len(paths) != 1 || paths[0].Base() != outputFilename { 1146 t.Errorf("%s(%s): expected output %q, but got %v", moduleName, variant, outputFilename, paths) 1147 } 1148 } 1149 1150 // No versions 1151 ctx, _ = testAidl(t, ` 1152 aidl_interface { 1153 name: "foo", 1154 srcs: [ 1155 "IFoo.aidl", 1156 ], 1157 backend: { 1158 rust: { 1159 enabled: true, 1160 }, 1161 }, 1162 } 1163 `) 1164 // Even though there is no version, generated modules have version(V1) unless it isn't an unstable interface. 1165 assertOutput("foo-V1-java", androidVariant, "foo-V1-java.jar") 1166 1167 assertOutput("foo-V1-cpp", nativeVariant, "foo-V1-cpp.so") 1168 assertOutput("foo-V1-rust", nativeRustVariant, "libfoo_V1.dylib.so") 1169 1170 // With versions: "1", "2" 1171 ctx, _ = testAidl(t, ` 1172 aidl_interface { 1173 name: "foo", 1174 srcs: [ 1175 "IFoo.aidl", 1176 ], 1177 versions: [ 1178 "1", "2", 1179 ], 1180 backend: { 1181 rust: { 1182 enabled: true, 1183 }, 1184 }, 1185 } 1186 `, withFiles(map[string][]byte{ 1187 "aidl_api/foo/1/foo.1.aidl": nil, 1188 "aidl_api/foo/1/.hash": nil, 1189 "aidl_api/foo/2/foo.2.aidl": nil, 1190 "aidl_api/foo/2/.hash": nil, 1191 })) 1192 1193 // alias for the latest frozen version (=2) 1194 assertOutput("foo-V2-java", androidVariant, "foo-V2-java.jar") 1195 assertOutput("foo-V2-cpp", nativeVariant, "foo-V2-cpp.so") 1196 assertOutput("foo-V2-rust", nativeRustVariant, "libfoo_V2.dylib.so") 1197 1198 // frozen "1" 1199 assertOutput("foo-V1-java", androidVariant, "foo-V1-java.jar") 1200 assertOutput("foo-V1-cpp", nativeVariant, "foo-V1-cpp.so") 1201 assertOutput("foo-V1-rust", nativeRustVariant, "libfoo_V1.dylib.so") 1202 1203 // tot 1204 assertOutput("foo-V3-java", androidVariant, "foo-V3-java.jar") 1205 assertOutput("foo-V3-cpp", nativeVariant, "foo-V3-cpp.so") 1206 assertOutput("foo-V3-rust", nativeRustVariant, "libfoo_V3.dylib.so") 1207 1208 // skip ndk since they follow the same rule with cpp 1209} 1210 1211func TestImports(t *testing.T) { 1212 testAidlError(t, `Import does not exist:`, ` 1213 aidl_interface { 1214 name: "foo", 1215 srcs: [ 1216 "IFoo.aidl", 1217 ], 1218 imports: [ 1219 "bar", 1220 ] 1221 } 1222 `) 1223 1224 testAidlError(t, `backend.java.enabled: Java backend not enabled in the imported AIDL interface "bar"`, ` 1225 aidl_interface { 1226 name: "foo", 1227 srcs: [ 1228 "IFoo.aidl", 1229 ], 1230 imports: [ 1231 "bar-V1", 1232 ] 1233 } 1234 aidl_interface { 1235 name: "bar", 1236 srcs: [ 1237 "IBar.aidl", 1238 ], 1239 backend: { 1240 java: { 1241 enabled: false, 1242 }, 1243 }, 1244 } 1245 `) 1246 1247 testAidlError(t, `backend.cpp.enabled: C\+\+ backend not enabled in the imported AIDL interface "bar"`, ` 1248 aidl_interface { 1249 name: "foo", 1250 srcs: [ 1251 "IFoo.aidl", 1252 ], 1253 imports: [ 1254 "bar-V1", 1255 ] 1256 } 1257 aidl_interface { 1258 name: "bar", 1259 srcs: [ 1260 "IBar.aidl", 1261 ], 1262 backend: { 1263 cpp: { 1264 enabled: false, 1265 }, 1266 }, 1267 } 1268 `) 1269 1270 testAidlError(t, `imports: "foo" depends on "bar" but does not specify a version`, ` 1271 aidl_interface { 1272 name: "foo", 1273 unstable: true, 1274 srcs: [ 1275 "IFoo.aidl", 1276 ], 1277 imports: [ 1278 "bar", 1279 ] 1280 } 1281 aidl_interface { 1282 name: "bar", 1283 srcs: [ 1284 "IBar.aidl", 1285 ], 1286 } 1287 `) 1288 1289 ctx, _ := testAidl(t, ` 1290 aidl_interface_defaults { 1291 name: "foo-defaults", 1292 srcs: [ 1293 "IFoo.aidl", 1294 ], 1295 backend: { 1296 rust: { 1297 enabled: true, 1298 }, 1299 }, 1300 imports: [ 1301 "bar.1-V1", 1302 ] 1303 } 1304 aidl_interface { 1305 name: "foo", 1306 defaults: ["foo-defaults"], 1307 } 1308 aidl_interface { 1309 name: "bar.1", 1310 srcs: [ 1311 "IBar.aidl", 1312 ], 1313 backend: { 1314 rust: { 1315 enabled: true, 1316 }, 1317 }, 1318 } 1319 `) 1320 1321 ldRule := ctx.ModuleForTests("foo-V1-cpp", nativeVariant).Rule("ld") 1322 libFlags := ldRule.Args["libFlags"] 1323 libBar := filepath.Join("bar.1-V1-cpp", nativeVariant, "bar.1-V1-cpp.so") 1324 if !strings.Contains(libFlags, libBar) { 1325 t.Errorf("%q is not found in %q", libBar, libFlags) 1326 } 1327 1328 rustcRule := ctx.ModuleForTests("foo-V1-rust", nativeRustVariant).Rule("rustc") 1329 libFlags = rustcRule.Args["libFlags"] 1330 libBar = filepath.Join("out", "soong", ".intermediates", "bar.1-V1-rust", nativeRustVariant, "unstripped", "libbar_1_V1.dylib.so") 1331 libBarFlag := "--extern bar_1=" + libBar 1332 if !strings.Contains(libFlags, libBarFlag) { 1333 t.Errorf("%q is not found in %q", libBarFlag, libFlags) 1334 } 1335} 1336 1337func TestDuplicatedVersions(t *testing.T) { 1338 // foo depends on myiface-V2-ndk via direct dep and also on 1339 // myiface-V1-ndk via indirect dep. This should be prohibited. 1340 testAidlError(t, `depends on multiple versions of the same aidl_interface: myiface-V1-.*, myiface-V2-.*`, ` 1341 aidl_interface { 1342 name: "myiface", 1343 srcs: ["IFoo.aidl"], 1344 versions: ["1", "2"], 1345 } 1346 1347 cc_library { 1348 name: "foo", 1349 shared_libs: ["myiface-V2-ndk", "bar"], 1350 } 1351 1352 cc_library { 1353 name: "bar", 1354 shared_libs: ["myiface-V1-ndk"], 1355 } 1356 1357 `, withFiles(map[string][]byte{ 1358 "aidl_api/myiface/1/myiface.1.aidl": nil, 1359 "aidl_api/myiface/1/.hash": nil, 1360 "aidl_api/myiface/2/myiface.2.aidl": nil, 1361 "aidl_api/myiface/2/.hash": nil, 1362 })) 1363 testAidlError(t, `depends on multiple versions of the same aidl_interface: myiface-V1-.*, myiface-V2-.*`, ` 1364 aidl_interface { 1365 name: "myiface", 1366 srcs: ["IFoo.aidl"], 1367 versions: ["1"], 1368 } 1369 1370 aidl_interface { 1371 name: "myiface2", 1372 srcs: ["IBar.aidl"], 1373 imports: ["myiface-V2"] 1374 } 1375 1376 cc_library { 1377 name: "foobar", 1378 shared_libs: ["myiface-V1-ndk", "myiface2-V1-ndk"], 1379 } 1380 1381 `, withFiles(map[string][]byte{ 1382 "aidl_api/myiface/1/myiface.1.aidl": nil, 1383 "aidl_api/myiface/1/.hash": nil, 1384 })) 1385 testAidlError(t, `depends on multiple versions of the same aidl_interface: myiface-V1-.*, myiface-V2-.*`, ` 1386 aidl_interface { 1387 name: "myiface", 1388 srcs: ["IFoo.aidl"], 1389 versions: ["1"], 1390 } 1391 1392 aidl_interface { 1393 name: "myiface2", 1394 srcs: ["IBar.aidl"], 1395 imports: ["myiface-V2"] 1396 } 1397 1398 cc_library { 1399 name: "foobar", 1400 srcs: [":myiface-V1-ndk-source"], 1401 shared_libs: ["myiface2-V1-ndk"], 1402 } 1403 1404 `, withFiles(map[string][]byte{ 1405 "aidl_api/myiface/1/myiface.1.aidl": nil, 1406 "aidl_api/myiface/1/.hash": nil, 1407 })) 1408 // Okay to reference two different 1409 testAidl(t, ` 1410 aidl_interface { 1411 name: "myiface", 1412 srcs: ["IFoo.aidl"], 1413 versions: ["1"], 1414 } 1415 cc_library { 1416 name: "foobar", 1417 shared_libs: ["myiface-V1-cpp", "myiface-V1-ndk"], 1418 } 1419 `, withFiles(map[string][]byte{ 1420 "aidl_api/myiface/1/myiface.1.aidl": nil, 1421 "aidl_api/myiface/1/.hash": nil, 1422 })) 1423 testAidl(t, ` 1424 aidl_interface { 1425 name: "myiface", 1426 srcs: ["IFoo.aidl"], 1427 versions: ["1"], 1428 } 1429 1430 aidl_interface { 1431 name: "myiface2", 1432 srcs: ["IBar.aidl"], 1433 imports: ["myiface-V2"] 1434 } 1435 1436 cc_library { 1437 name: "foobar", 1438 srcs: [":myiface-V2-ndk-source"], 1439 shared_libs: ["myiface2-V1-ndk"], 1440 } 1441 1442 `, withFiles(map[string][]byte{ 1443 "aidl_api/myiface/1/myiface.1.aidl": nil, 1444 "aidl_api/myiface/1/.hash": nil, 1445 })) 1446 testAidl(t, ` 1447 aidl_interface { 1448 name: "myiface", 1449 srcs: ["IFoo.aidl"], 1450 versions: ["1"], 1451 } 1452 1453 aidl_interface { 1454 name: "myiface2", 1455 srcs: ["IBar.aidl"], 1456 imports: ["myiface-V2"] 1457 } 1458 1459 cc_library { 1460 name: "foobar", 1461 shared_libs: ["myiface-V2-ndk", "myiface2-V1-ndk"], 1462 } 1463 1464 `, withFiles(map[string][]byte{ 1465 "aidl_api/myiface/1/myiface.1.aidl": nil, 1466 "aidl_api/myiface/1/.hash": nil, 1467 })) 1468} 1469 1470func TestRecoveryAvailable(t *testing.T) { 1471 ctx, _ := testAidl(t, ` 1472 aidl_interface { 1473 name: "myiface", 1474 recovery_available: true, 1475 srcs: ["IFoo.aidl"], 1476 } 1477 `) 1478 ctx.ModuleForTests("myiface-V1-ndk", "android_recovery_arm64_armv8-a_shared") 1479 ctx.ModuleForTests("myiface-V1-cpp", "android_recovery_arm64_armv8-a_shared") 1480} 1481 1482func TestRustDuplicateNames(t *testing.T) { 1483 testAidl(t, ` 1484 aidl_interface { 1485 name: "myiface", 1486 srcs: ["dir/a/Foo.aidl", "dir/b/Foo.aidl"], 1487 backend: { 1488 rust: { 1489 enabled: true, 1490 }, 1491 }, 1492 } 1493 `) 1494} 1495 1496func TestAidlImportFlagsForImportedModules(t *testing.T) { 1497 customizer := withFiles(map[string][]byte{ 1498 "foo/Android.bp": []byte(` 1499 aidl_interface { 1500 name: "foo-iface", 1501 srcs: ["a/Foo.aidl"], 1502 imports: ["bar-iface-V2"], 1503 versions: ["1"], 1504 headers: ["boq-iface-headers"], 1505 } 1506 `), 1507 "foo/a/Foo.aidl": nil, 1508 "foo/aidl_api/foo-iface/current/a/Foo.aidl": nil, 1509 "foo/aidl_api/foo-iface/1/a/Foo.aidl": nil, 1510 "foo/aidl_api/foo-iface/1/.hash": nil, 1511 1512 "bar/Android.bp": []byte(` 1513 aidl_interface { 1514 name: "bar-iface", 1515 srcs: ["b/Bar.aidl"], 1516 imports: ["baz-iface-V1"], 1517 versions: ["1"], 1518 } 1519 `), 1520 "bar/b/Bar.aidl": nil, 1521 "bar/aidl_api/bar-iface/current/b/Bar.aidl": nil, 1522 "bar/aidl_api/bar-iface/1/b/Bar.aidl": nil, 1523 "bar/aidl_api/bar-iface/1/.hash": nil, 1524 1525 "baz/Android.bp": []byte(` 1526 aidl_interface { 1527 name: "baz-iface", 1528 srcs: ["b/Baz.aidl"], 1529 include_dirs: ["baz-include"], 1530 versions: ["1"], 1531 } 1532 `), 1533 "baz/b/Baz.aidl": nil, 1534 "baz/aidl_api/baz-iface/current/b/Baz.aidl": nil, 1535 "baz/aidl_api/baz-iface/1/b/Baz.aidl": nil, 1536 "baz/aidl_api/baz-iface/1/.hash": nil, 1537 1538 "boq/Android.bp": []byte(` 1539 aidl_library { 1540 name: "boq-iface-headers", 1541 srcs: ["b/Boq.aidl"], 1542 } 1543 `), 1544 "boq/b/Baz.aidl": nil, 1545 }) 1546 ctx, _ := testAidl(t, ``, customizer) 1547 1548 // checkapidump rule is to compare "compatibility" between ToT(dump) and "current" 1549 { 1550 rule := ctx.ModuleForTests("foo-iface_interface", "").Output("checkapi_dump.timestamp") 1551 android.AssertStringEquals(t, "checkapi(dump == current) imports", "-Iboq", rule.Args["imports"]) 1552 android.AssertStringDoesContain(t, "checkapi(dump == current) optionalFlags", 1553 rule.Args["optionalFlags"], 1554 "-pout/soong/.intermediates/bar/bar-iface_interface/2/preprocessed.aidl") 1555 } 1556 1557 // has_development rule runs --checkapi for equality between latest("1") 1558 // and ToT 1559 { 1560 rule := ctx.ModuleForTests("foo-iface_interface", "").Output("has_development") 1561 android.AssertStringDoesContain(t, "checkapi(dump == latest(1)) should import import's preprocessed", 1562 rule.RuleParams.Command, 1563 "-pout/soong/.intermediates/bar/bar-iface_interface/2/preprocessed.aidl") 1564 } 1565 1566 // compile (v1) 1567 { 1568 rule := ctx.ModuleForTests("foo-iface-V1-cpp-source", "").Output("a/Foo.cpp") 1569 android.AssertStringEquals(t, "compile(old=1) should import aidl_api/1", 1570 "-Iboq -Nfoo/aidl_api/foo-iface/1", 1571 rule.Args["imports"]+" "+rule.Args["nextImports"]) 1572 android.AssertStringDoesContain(t, "compile(old=1) should import bar.preprocessed", 1573 rule.Args["optionalFlags"], 1574 "-pout/soong/.intermediates/bar/bar-iface_interface/2/preprocessed.aidl") 1575 } 1576 // compile ToT(v2) 1577 { 1578 rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("a/Foo.cpp") 1579 android.AssertStringEquals(t, "compile(tot=2) should import base dirs of srcs", "-Iboq -Nfoo", rule.Args["imports"]+" "+rule.Args["nextImports"]) 1580 android.AssertStringDoesContain(t, "compile(tot=2) should import bar.preprocessed", 1581 rule.Args["optionalFlags"], 1582 "-pout/soong/.intermediates/bar/bar-iface_interface/2/preprocessed.aidl") 1583 } 1584} 1585 1586func TestAidlPreprocess(t *testing.T) { 1587 customizer := withFiles(map[string][]byte{ 1588 "foo/Android.bp": []byte(` 1589 aidl_interface { 1590 name: "foo-iface", 1591 local_include_dir: "src", 1592 include_dirs: [ 1593 "path1", 1594 "path2/sub", 1595 ], 1596 srcs: [ 1597 "src/foo/Foo.aidl", 1598 ], 1599 imports: [ 1600 "bar-iface", 1601 ], 1602 unstable: true, 1603 } 1604 aidl_interface { 1605 name: "bar-iface", 1606 local_include_dir: "src", 1607 srcs: [ 1608 "src/bar/Bar.aidl", 1609 ], 1610 unstable: true, 1611 } 1612 `), 1613 "foo/src/foo/Foo.aidl": nil, 1614 "foo/src/bar/Bar.aidl": nil, 1615 }) 1616 ctx, _ := testAidl(t, ``, customizer) 1617 1618 rule := ctx.ModuleForTests("foo-iface_interface", "").Output("preprocessed.aidl") 1619 android.AssertStringDoesContain(t, "preprocessing should import srcs and include_dirs", 1620 rule.RuleParams.Command, 1621 "-Ifoo/src -Ipath1 -Ipath2/sub") 1622 android.AssertStringDoesContain(t, "preprocessing should import import's preprocess", 1623 rule.RuleParams.Command, 1624 "-pout/soong/.intermediates/foo/bar-iface_interface/preprocessed.aidl") 1625} 1626 1627func TestAidlImportFlagsForUnstable(t *testing.T) { 1628 customizer := withFiles(map[string][]byte{ 1629 "foo/Android.bp": []byte(` 1630 aidl_interface { 1631 name: "foo-iface", 1632 local_include_dir: "src", 1633 include_dirs: [ 1634 "path1", 1635 "path2/sub", 1636 ], 1637 srcs: [ 1638 "src/foo/Foo.aidl", 1639 ], 1640 imports: [ 1641 "bar-iface", 1642 ], 1643 unstable: true, 1644 } 1645 aidl_interface { 1646 name: "bar-iface", 1647 local_include_dir: "src", 1648 srcs: [ 1649 "src/bar/Bar.aidl", 1650 ], 1651 unstable: true, 1652 } 1653 `), 1654 "foo/src/foo/Foo.aidl": nil, 1655 "foo/src/bar/Bar.aidl": nil, 1656 }) 1657 ctx, _ := testAidl(t, ``, customizer) 1658 1659 rule := ctx.ModuleForTests("foo-iface-cpp-source", "").Output("foo/Foo.cpp") 1660 android.AssertStringEquals(t, "compile(unstable) should import foo/base_dirs(target) and bar/base_dirs(imported)", 1661 "-Ipath1 -Ipath2/sub -Nfoo/src", 1662 rule.Args["imports"]+" "+rule.Args["nextImports"]) 1663 android.AssertStringDoesContain(t, "compile(unstable) should import bar.preprocessed", 1664 rule.Args["optionalFlags"], 1665 "-pout/soong/.intermediates/foo/bar-iface_interface/preprocessed.aidl") 1666} 1667 1668func TestSupportsGenruleAndFilegroup(t *testing.T) { 1669 customizer := withFiles(map[string][]byte{ 1670 "foo/Android.bp": []byte(` 1671 aidl_interface { 1672 name: "foo-iface", 1673 local_include_dir: "src", 1674 include_dirs: [ 1675 "path1", 1676 "path2/sub", 1677 ], 1678 srcs: [ 1679 "src/foo/Foo.aidl", 1680 ":filegroup1", 1681 ":gen1", 1682 ], 1683 imports: [ 1684 "bar-iface-V1", 1685 ], 1686 versions: ["1"], 1687 } 1688 filegroup { 1689 name: "filegroup1", 1690 path: "filegroup/sub", 1691 srcs: [ 1692 "filegroup/sub/pkg/Bar.aidl", 1693 ], 1694 } 1695 genrule { 1696 name: "gen1", 1697 cmd: "generate baz/Baz.aidl", 1698 out: [ 1699 "baz/Baz.aidl", 1700 ] 1701 } 1702 aidl_interface { 1703 name: "bar-iface", 1704 local_include_dir: "src", 1705 srcs: [ 1706 "src/bar/Bar.aidl", 1707 ":gen-bar", 1708 ], 1709 } 1710 genrule { 1711 name: "gen-bar", 1712 cmd: "generate gen/GenBar.aidl", 1713 out: [ 1714 "gen/GenBar.aidl", 1715 ] 1716 } 1717 `), 1718 "foo/aidl_api/foo-iface/1/foo/Foo.aidl": nil, 1719 "foo/aidl_api/foo-iface/1/.hash": nil, 1720 "foo/filegroup/sub/pkg/Bar.aidl": nil, 1721 "foo/src/foo/Foo.aidl": nil, 1722 }) 1723 ctx, _ := testAidl(t, ``, customizer) 1724 1725 // aidlCompile for snapshots (v1) 1726 { 1727 rule := ctx.ModuleForTests("foo-iface-V1-cpp-source", "").Output("foo/Foo.cpp") 1728 android.AssertStringEquals(t, "compile(1) should import foo/aidl_api/1", 1729 "-Ipath1 -Ipath2/sub -Nfoo/aidl_api/foo-iface/1", 1730 rule.Args["imports"]+" "+rule.Args["nextImports"]) 1731 android.AssertStringDoesContain(t, "compile(1) should import bar.preprocessed", 1732 rule.Args["optionalFlags"], 1733 "-pout/soong/.intermediates/foo/bar-iface_interface/1/preprocessed.aidl") 1734 } 1735 // aidlCompile for ToT (v2) 1736 { 1737 rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("foo/Foo.cpp") 1738 android.AssertStringEquals(t, "compile(tot=2) should import foo.base_dirs", 1739 "-Ipath1 -Ipath2/sub -Nfoo/src -Nfoo/filegroup/sub -Nout/soong/.intermediates/foo/gen1/gen", 1740 rule.Args["imports"]+" "+rule.Args["nextImports"]) 1741 android.AssertStringDoesContain(t, "compile(tot=2) should import bar.preprocessed", 1742 rule.Args["optionalFlags"], 1743 "-pout/soong/.intermediates/foo/bar-iface_interface/1/preprocessed.aidl") 1744 } 1745 1746 // dumpapi 1747 { 1748 rule := ctx.ModuleForTests("foo-iface_interface", "").Rule("aidlDumpApiRule") 1749 android.AssertPathsRelativeToTopEquals(t, "dumpapi should dump srcs/filegroups/genrules", []string{ 1750 "foo/src/foo/Foo.aidl", 1751 "foo/filegroup/sub/pkg/Bar.aidl", 1752 "out/soong/.intermediates/foo/gen1/gen/baz/Baz.aidl", 1753 }, rule.Inputs) 1754 1755 dumpDir := "out/soong/.intermediates/foo/foo-iface_interface/dump" 1756 android.AssertPathsRelativeToTopEquals(t, "dumpapi should dump with rel paths", []string{ 1757 dumpDir + "/foo/Foo.aidl", 1758 dumpDir + "/pkg/Bar.aidl", 1759 dumpDir + "/baz/Baz.aidl", 1760 dumpDir + "/.hash", 1761 }, rule.Outputs.Paths()) 1762 1763 android.AssertStringEquals(t, "dumpapi should import base_dirs and include_dirs", 1764 "-Ifoo/src -Ifoo/filegroup/sub -Iout/soong/.intermediates/foo/gen1/gen -Ipath1 -Ipath2/sub", 1765 rule.Args["imports"]) 1766 android.AssertStringDoesContain(t, "dumpapi should import bar.preprocessed", 1767 rule.Args["optionalFlags"], 1768 "-pout/soong/.intermediates/foo/bar-iface_interface/1/preprocessed.aidl") 1769 } 1770} 1771 1772func TestAidlFlags(t *testing.T) { 1773 ctx, _ := testAidl(t, ` 1774 aidl_interface { 1775 name: "myiface", 1776 srcs: ["a/Foo.aidl", "b/Bar.aidl"], 1777 flags: ["-Weverything", "-Werror"], 1778 backend: { rust: { enabled: true }} 1779 } 1780 `) 1781 for module, outputs := range map[string][]string{ 1782 "myiface-V1-cpp-source": {"a/Foo.h", "b/Bar.h"}, 1783 "myiface-V1-java-source": {"a/Foo.java", "b/Bar.java"}, 1784 "myiface-V1-ndk-source": {"aidl/a/Foo.h", "aidl/b/Bar.h"}, 1785 "myiface-V1-rust-source": {"a/Foo.rs", "b/Bar.rs"}, 1786 } { 1787 for _, output := range outputs { 1788 t.Run(module+"/"+output, func(t *testing.T) { 1789 params := ctx.ModuleForTests(module, "").Output(output) 1790 assertContains(t, params.Args["optionalFlags"], "-Weverything") 1791 assertContains(t, params.Args["optionalFlags"], "-Werror") 1792 }) 1793 } 1794 } 1795} 1796 1797func TestAidlModuleJavaSdkVersionDeterminesMinSdkVersion(t *testing.T) { 1798 ctx, _ := testAidl(t, ` 1799 aidl_interface { 1800 name: "myiface", 1801 srcs: ["a/Foo.aidl"], 1802 backend: { 1803 java: { 1804 sdk_version: "28", 1805 }, 1806 }, 1807 } 1808 `, java.FixtureWithPrebuiltApis(map[string][]string{"28": {"foo"}})) 1809 params := ctx.ModuleForTests("myiface-V1-java-source", "").Output("a/Foo.java") 1810 assertContains(t, params.Args["optionalFlags"], "--min_sdk_version 28") 1811} 1812 1813func TestAidlModuleNameContainsVersion(t *testing.T) { 1814 testAidlError(t, "aidl_interface should not have '-V<number> suffix", ` 1815 aidl_interface { 1816 name: "myiface-V2", 1817 srcs: ["a/Foo.aidl", "b/Bar.aidl"], 1818 } 1819 `) 1820 // Ugly, but okay 1821 testAidl(t, ` 1822 aidl_interface { 1823 name: "myiface-V2aa", 1824 srcs: ["a/Foo.aidl", "b/Bar.aidl"], 1825 } 1826 `) 1827} 1828 1829func TestExplicitAidlModuleImport(t *testing.T) { 1830 for _, importVersion := range []string{"V1", "V2"} { 1831 1832 ctx, _ := testAidl(t, ` 1833 aidl_interface { 1834 name: "foo", 1835 srcs: ["Foo.aidl"], 1836 versions: [ 1837 "1", 1838 ], 1839 imports: ["bar-`+importVersion+`"] 1840 } 1841 1842 aidl_interface { 1843 name: "bar", 1844 srcs: ["Bar.aidl"], 1845 versions: [ 1846 "1", 1847 ], 1848 } 1849 `, withFiles(map[string][]byte{ 1850 "aidl_api/foo/1/Foo.aidl": nil, 1851 "aidl_api/foo/1/.hash": nil, 1852 "aidl_api/bar/1/Bar.aidl": nil, 1853 "aidl_api/bar/1/.hash": nil, 1854 })) 1855 for _, foo := range []string{"foo-V1-cpp", "foo-V2-cpp"} { 1856 ldRule := ctx.ModuleForTests(foo, nativeVariant).Rule("ld") 1857 libFlags := ldRule.Args["libFlags"] 1858 libBar := filepath.Join("bar-"+importVersion+"-cpp", nativeVariant, "bar-"+importVersion+"-cpp.so") 1859 if !strings.Contains(libFlags, libBar) { 1860 t.Errorf("%q is not found in %q", libBar, libFlags) 1861 } 1862 1863 } 1864 } 1865 1866 testAidlError(t, "module \"foo_interface\": imports: \"foo\" depends on \"bar\" version \"3\"", ` 1867 aidl_interface { 1868 name: "foo", 1869 srcs: ["Foo.aidl"], 1870 versions: [ 1871 "1", 1872 ], 1873 imports: ["bar-V3"] 1874 } 1875 1876 aidl_interface { 1877 name: "bar", 1878 srcs: ["Bar.aidl"], 1879 versions: [ 1880 "1", 1881 ], 1882 } 1883 `, withFiles(map[string][]byte{ 1884 "aidl_api/foo/1/Foo.aidl": nil, 1885 "aidl_api/foo/1/.hash": nil, 1886 "aidl_api/bar/1/Bar.aidl": nil, 1887 "aidl_api/bar/1/.hash": nil, 1888 })) 1889} 1890 1891func TestUseVersionedPreprocessedWhenImporotedWithVersions(t *testing.T) { 1892 ctx, _ := testAidl(t, ` 1893 aidl_interface { 1894 name: "unstable-foo", 1895 srcs: ["foo/Foo.aidl"], 1896 imports: [ 1897 "bar-V2", 1898 "baz-V1", 1899 "unstable-bar", 1900 ], 1901 unstable: true, 1902 } 1903 aidl_interface { 1904 name: "foo", 1905 srcs: ["foo/Foo.aidl"], 1906 imports: [ 1907 "bar-V1", 1908 "baz-V1", 1909 ], 1910 versions: ["1"], 1911 } 1912 aidl_interface { 1913 name: "foo-no-versions", 1914 srcs: ["foo/Foo.aidl"], 1915 imports: [ 1916 "bar-V2", 1917 ], 1918 } 1919 aidl_interface { 1920 name: "bar", 1921 srcs: ["bar/Bar.aidl"], 1922 versions: ["1"], 1923 } 1924 aidl_interface { 1925 name: "unstable-bar", 1926 srcs: ["bar/Bar.aidl"], 1927 unstable: true, 1928 } 1929 aidl_interface { 1930 name: "baz", 1931 srcs: ["baz/Baz.aidl"], 1932 versions: ["1"], 1933 } 1934 `, withFiles(map[string][]byte{ 1935 "foo/Foo.aidl": nil, 1936 "bar/Bar.aidl": nil, 1937 "baz/Baz.aidl": nil, 1938 "aidl_api/foo/1/foo/Foo.aidl": nil, 1939 "aidl_api/foo/1/.hash": nil, 1940 "aidl_api/bar/1/bar/Bar.aidl": nil, 1941 "aidl_api/bar/1/.hash": nil, 1942 "aidl_api/baz/1/baz/Baz.aidl": nil, 1943 "aidl_api/baz/1/.hash": nil, 1944 })) 1945 { 1946 rule := ctx.ModuleForTests("foo-V2-java-source", "").Output("foo/Foo.java") 1947 android.AssertStringDoesContain(t, "foo-V2(tot) imports bar-V1 for 'bar-V1'", rule.Args["optionalFlags"], 1948 "-pout/soong/.intermediates/bar_interface/1/preprocessed.aidl") 1949 android.AssertStringDoesContain(t, "foo-V2(tot) imports baz-V1 for 'baz-V1'", rule.Args["optionalFlags"], 1950 "-pout/soong/.intermediates/baz_interface/1/preprocessed.aidl") 1951 } 1952 { 1953 rule := ctx.ModuleForTests("foo-V1-java-source", "").Output("foo/Foo.java") 1954 android.AssertStringDoesContain(t, "foo-V1 imports bar-V1(latest) for 'bar'", rule.Args["optionalFlags"], 1955 "-pout/soong/.intermediates/bar_interface/1/preprocessed.aidl") 1956 android.AssertStringDoesContain(t, "foo-V1 imports baz-V1 for 'baz-V1'", rule.Args["optionalFlags"], 1957 "-pout/soong/.intermediates/baz_interface/1/preprocessed.aidl") 1958 } 1959 { 1960 rule := ctx.ModuleForTests("unstable-foo-java-source", "").Output("foo/Foo.java") 1961 android.AssertStringDoesContain(t, "unstable-foo imports bar-V2(latest) for 'bar'", rule.Args["optionalFlags"], 1962 "-pout/soong/.intermediates/bar_interface/2/preprocessed.aidl") 1963 android.AssertStringDoesContain(t, "unstable-foo imports baz-V1 for 'baz-V1'", rule.Args["optionalFlags"], 1964 "-pout/soong/.intermediates/baz_interface/1/preprocessed.aidl") 1965 android.AssertStringDoesContain(t, "unstable-foo imports unstable-bar(ToT) for 'unstable-bar'", rule.Args["optionalFlags"], 1966 "-pout/soong/.intermediates/unstable-bar_interface/preprocessed.aidl") 1967 } 1968 { 1969 rule := ctx.ModuleForTests("foo-no-versions-V1-java-source", "").Output("foo/Foo.java") 1970 android.AssertStringDoesContain(t, "foo-no-versions-V1(latest) imports bar-V2(latest) for 'bar'", rule.Args["optionalFlags"], 1971 "-pout/soong/.intermediates/bar_interface/2/preprocessed.aidl") 1972 } 1973} 1974 1975func FindModule(ctx *android.TestContext, name, variant, dir string) android.Module { 1976 var module android.Module 1977 ctx.VisitAllModules(func(m blueprint.Module) { 1978 if ctx.ModuleName(m) == name && ctx.ModuleSubDir(m) == variant && ctx.ModuleDir(m) == dir { 1979 module = m.(android.Module) 1980 } 1981 }) 1982 if module == nil { 1983 m := ctx.ModuleForTests(name, variant).Module() 1984 panic(fmt.Errorf("failed to find module %q variant %q dir %q, but found one in %q", 1985 name, variant, dir, ctx.ModuleDir(m))) 1986 } 1987 return module 1988} 1989 1990func TestDuplicateInterfacesWithTheSameNameInDifferentSoongNamespaces(t *testing.T) { 1991 ctx, _ := testAidl(t, ``, withFiles(map[string][]byte{ 1992 "common/Android.bp": []byte(` 1993 aidl_interface { 1994 name: "common", 1995 srcs: ["ICommon.aidl"], 1996 versions: ["1", "2"], 1997 } 1998 `), 1999 "common/aidl_api/common/1/ICommon.aidl": nil, 2000 "common/aidl_api/common/1/.hash": nil, 2001 "common/aidl_api/common/2/ICommon.aidl": nil, 2002 "common/aidl_api/common/2/.hash": nil, 2003 "vendor/a/Android.bp": []byte(` 2004 soong_namespace {} 2005 `), 2006 "vendor/a/foo/Android.bp": []byte(` 2007 aidl_interface { 2008 name: "foo", 2009 owner: "vendor", 2010 srcs: ["IFoo.aidl"], 2011 imports: ["common-V1"], 2012 } 2013 `), 2014 "vendor/b/Android.bp": []byte(` 2015 soong_namespace {} 2016 `), 2017 "vendor/b/foo/Android.bp": []byte(` 2018 aidl_interface { 2019 name: "foo", 2020 owner: "vendor", 2021 srcs: ["IFoo.aidl"], 2022 imports: ["common-V2"], 2023 } 2024 `), 2025 })) 2026 2027 aFooV1Java := FindModule(ctx, "foo-V1-java", "android_common", "vendor/a/foo").(*java.Library) 2028 android.AssertStringListContains(t, "a/foo deps", aFooV1Java.CompilerDeps(), "common-V1-java") 2029 2030 bFooV1Java := FindModule(ctx, "foo-V1-java", "android_common", "vendor/b/foo").(*java.Library) 2031 android.AssertStringListContains(t, "a/foo deps", bFooV1Java.CompilerDeps(), "common-V2-java") 2032} 2033 2034func TestUnstableChecksForAidlInterfacesInDifferentNamespaces(t *testing.T) { 2035 files := withFiles(map[string][]byte{ 2036 "vendor/a/Android.bp": []byte(` 2037 soong_namespace {} 2038 `), 2039 "vendor/a/foo/Android.bp": []byte(` 2040 aidl_interface { 2041 name: "foo", 2042 owner: "vendor", 2043 srcs: ["IFoo.aidl"], 2044 versions: ["1", "2"], 2045 } 2046 java_library { 2047 name: "bar", 2048 libs: ["foo-V2-java"], // OK 2049 } 2050 `), 2051 "vendor/a/foo/aidl_api/foo/1/IFoo.aidl": nil, 2052 "vendor/a/foo/aidl_api/foo/1/.hash": nil, 2053 "vendor/a/foo/aidl_api/foo/2/IFoo.aidl": nil, 2054 "vendor/a/foo/aidl_api/foo/2/.hash": nil, 2055 "vendor/b/Android.bp": []byte(` 2056 soong_namespace {} 2057 `), 2058 "vendor/b/foo/Android.bp": []byte(` 2059 aidl_interface { 2060 name: "foo", 2061 owner: "vendor", 2062 srcs: ["IFoo.aidl"], 2063 versions: ["1"], 2064 } 2065 java_library { 2066 name: "bar", 2067 libs: ["foo-V1-java"], // OK 2068 } 2069 `), 2070 "vendor/b/foo/aidl_api/foo/1/IFoo.aidl": nil, 2071 "vendor/b/foo/aidl_api/foo/1/.hash": nil, 2072 }) 2073 2074 testAidl(t, ``, files, setReleaseEnv()) 2075 testAidl(t, ``, files, setTestFreezeEnv()) 2076 testAidl(t, ``, files) 2077} 2078 2079func TestVersionsWithInfoAndVersions(t *testing.T) { 2080 conflictingFields := ` 2081 aidl_interface { 2082 name: "foo", 2083 versions: [ 2084 "1", 2085 ], 2086 versions_with_info: [ 2087 { 2088 version: "1", 2089 } 2090 ], 2091 } 2092 ` 2093 files := withFiles(map[string][]byte{ 2094 "aidl_api/foo/1/foo.1.aidl": nil, 2095 "aidl_api/foo/1/.hash": nil, 2096 }) 2097 2098 expectedError := `Use versions_with_info instead of versions.` 2099 testAidlError(t, expectedError, conflictingFields, files) 2100} 2101 2102func TestVersionsWithInfo(t *testing.T) { 2103 ctx, _ := testAidl(t, ``, withFiles(map[string][]byte{ 2104 "common/Android.bp": []byte(` 2105 aidl_interface { 2106 name: "common", 2107 srcs: ["ICommon.aidl"], 2108 versions: ["1", "2"], 2109 } 2110 `), 2111 "common/aidl_api/common/1/ICommon.aidl": nil, 2112 "common/aidl_api/common/1/.hash": nil, 2113 "common/aidl_api/common/2/ICommon.aidl": nil, 2114 "common/aidl_api/common/2/.hash": nil, 2115 "foo/Android.bp": []byte(` 2116 aidl_interface { 2117 name: "foo", 2118 srcs: ["IFoo.aidl"], 2119 imports: ["common-V3"], 2120 versions_with_info: [ 2121 {version: "1", imports: ["common-V1"]}, 2122 {version: "2", imports: ["common-V2"]}, 2123 ] 2124 } 2125 `), 2126 "foo/aidl_api/foo/1/IFoo.aidl": nil, 2127 "foo/aidl_api/foo/1/.hash": nil, 2128 "foo/aidl_api/foo/2/IFoo.aidl": nil, 2129 "foo/aidl_api/foo/2/.hash": nil, 2130 })) 2131 2132 fooV1Java := FindModule(ctx, "foo-V1-java", "android_common", "foo").(*java.Library) 2133 android.AssertStringListContains(t, "a/foo-v1 deps", fooV1Java.CompilerDeps(), "common-V1-java") 2134 2135 fooV2Java := FindModule(ctx, "foo-V2-java", "android_common", "foo").(*java.Library) 2136 android.AssertStringListContains(t, "a/foo-v2 deps", fooV2Java.CompilerDeps(), "common-V2-java") 2137 2138 fooV3Java := FindModule(ctx, "foo-V3-java", "android_common", "foo").(*java.Library) 2139 android.AssertStringListContains(t, "a/foo-v3 deps", fooV3Java.CompilerDeps(), "common-V3-java") 2140} 2141 2142func TestVersionsWithInfoImport(t *testing.T) { 2143 testAidlError(t, "imports in versions_with_info must specify its version", ``, withFiles(map[string][]byte{ 2144 "common/Android.bp": []byte(` 2145 aidl_interface { 2146 name: "common", 2147 srcs: ["ICommon.aidl"], 2148 versions: ["1", "2"], 2149 } 2150 `), 2151 "common/aidl_api/common/1/ICommon.aidl": nil, 2152 "common/aidl_api/common/1/.hash": nil, 2153 "common/aidl_api/common/2/ICommon.aidl": nil, 2154 "common/aidl_api/common/2/.hash": nil, 2155 "foo/Android.bp": []byte(` 2156 aidl_interface { 2157 name: "foo", 2158 srcs: ["IFoo.aidl"], 2159 imports: ["common"], 2160 versions_with_info: [ 2161 {version: "1", imports: ["common"]}, 2162 {version: "2", imports: ["common-V2"]}, 2163 ] 2164 } 2165 `), 2166 "foo/aidl_api/foo/1/IFoo.aidl": nil, 2167 "foo/aidl_api/foo/1/.hash": nil, 2168 "foo/aidl_api/foo/2/IFoo.aidl": nil, 2169 "foo/aidl_api/foo/2/.hash": nil, 2170 })) 2171} 2172 2173func TestFreezeApiDeps(t *testing.T) { 2174 for _, transitive := range []bool{true, false} { 2175 for _, testcase := range []struct { 2176 string 2177 bool 2178 }{{"common-V3", true}, {"common-V2", false}} { 2179 im := testcase.string 2180 customizers := []android.FixturePreparer{ 2181 withFiles(map[string][]byte{ 2182 "common/Android.bp": []byte(` 2183 aidl_interface { 2184 name: "common", 2185 frozen: false, 2186 srcs: ["ICommon.aidl"], 2187 versions: ["1", "2"], 2188 } 2189 `), 2190 "common/aidl_api/common/1/ICommon.aidl": nil, 2191 "common/aidl_api/common/1/.hash": nil, 2192 "common/aidl_api/common/2/ICommon.aidl": nil, 2193 "common/aidl_api/common/2/.hash": nil, 2194 "foo/Android.bp": []byte(fmt.Sprintf(` 2195 aidl_interface { 2196 name: "foo", 2197 srcs: ["IFoo.aidl"], 2198 imports: ["%s"], 2199 frozen: false, 2200 versions_with_info: [ 2201 {version: "1", imports: ["common-V1"]}, 2202 {version: "2", imports: ["common-V2"]}, 2203 ] 2204 } 2205 `, im)), 2206 "foo/aidl_api/foo/1/IFoo.aidl": nil, 2207 "foo/aidl_api/foo/1/.hash": nil, 2208 "foo/aidl_api/foo/2/IFoo.aidl": nil, 2209 "foo/aidl_api/foo/2/.hash": nil, 2210 }), 2211 } 2212 if transitive { 2213 customizers = append(customizers, setTransitiveFreezeEnv()) 2214 } 2215 2216 ctx, _ := testAidl(t, ``, customizers...) 2217 shouldHaveDep := transitive && testcase.bool 2218 fooFreezeApiRule := ctx.ModuleForTests("foo_interface", "").Output("update_or_freeze_api_3.timestamp") 2219 commonFreezeApiOutput := ctx.ModuleForTests("common_interface", "").Output("update_or_freeze_api_3.timestamp").Output.String() 2220 testMethod := android.AssertStringListDoesNotContain 2221 if shouldHaveDep { 2222 testMethod = android.AssertStringListContains 2223 } 2224 testMethod(t, "Only if AIDL_TRANSITIVE_FREEZE is set and an aidl_interface depends on an another aidl_interface's ToT version, an imported aidl_interface should be frozen as well.", 2225 fooFreezeApiRule.Implicits.Strings(), commonFreezeApiOutput) 2226 } 2227 } 2228} 2229 2230func TestAidlNoUnfrozen(t *testing.T) { 2231 customizer := withFiles(map[string][]byte{ 2232 "foo/Android.bp": []byte(` 2233 aidl_interface { 2234 name: "foo-iface", 2235 srcs: ["a/Foo.aidl"], 2236 versions: ["1", "2"], 2237 } 2238 `), 2239 "foo/a/Foo.aidl": nil, 2240 "foo/aidl_api/foo-iface/current/a/Foo.aidl": nil, 2241 "foo/aidl_api/foo-iface/1/a/Foo.aidl": nil, 2242 "foo/aidl_api/foo-iface/1/.hash": nil, 2243 "foo/aidl_api/foo-iface/2/a/Foo.aidl": nil, 2244 "foo/aidl_api/foo-iface/2/.hash": nil, 2245 }) 2246 // setReleaseEnv() to set RELEASE_AIDL_USE_UNFROZEN to false 2247 ctx, _ := testAidl(t, ``, setReleaseEnv(), customizer) 2248 2249 // compile (v1) 2250 { 2251 rule := ctx.ModuleForTests("foo-iface-V1-cpp-source", "").Output("a/Foo.cpp") 2252 android.AssertStringDoesNotContain(t, "Frozen versions should not have the -previous_api_dir set", 2253 rule.Args["optionalFlags"], 2254 "-previous") 2255 } 2256 // compile (v2) 2257 { 2258 rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("a/Foo.cpp") 2259 android.AssertStringDoesNotContain(t, "Frozen versions should not have the -previous_api_dir set", 2260 rule.Args["optionalFlags"], 2261 "-previous") 2262 } 2263 // compile ToT(v3) 2264 { 2265 rule := ctx.ModuleForTests("foo-iface-V3-cpp-source", "").Output("a/Foo.cpp") 2266 android.AssertStringDoesContain(t, "An unfrozen interface with previously frozen version must have --previous_api_dir when RELEASE_AIDL_USE_UNFROZEN is false (setReleaseEnv())", 2267 rule.Args["optionalFlags"], 2268 "-previous_api_dir") 2269 android.AssertStringDoesContain(t, "An unfrozen interface with previously frozen version must have --previous_hash when RELEASE_AIDL_USE_UNFROZEN is false (setReleaseEnv())", 2270 rule.Args["optionalFlags"], 2271 "-previous_hash") 2272 android.AssertStringDoesContain(t, "--previous_hash must use the last frozen version's hash file", 2273 rule.Args["optionalFlags"], 2274 "foo-iface/2/.hash") 2275 } 2276} 2277 2278func TestAidlUsingUnfrozen(t *testing.T) { 2279 customizer := withFiles(map[string][]byte{ 2280 "foo/Android.bp": []byte(` 2281 aidl_interface { 2282 name: "foo-iface", 2283 srcs: ["a/Foo.aidl"], 2284 versions: ["1", "2"], 2285 } 2286 `), 2287 "foo/a/Foo.aidl": nil, 2288 "foo/aidl_api/foo-iface/current/a/Foo.aidl": nil, 2289 "foo/aidl_api/foo-iface/1/a/Foo.aidl": nil, 2290 "foo/aidl_api/foo-iface/1/.hash": nil, 2291 "foo/aidl_api/foo-iface/2/a/Foo.aidl": nil, 2292 "foo/aidl_api/foo-iface/2/.hash": nil, 2293 }) 2294 ctx, _ := testAidl(t, ``, customizer) 2295 2296 // compile (v2) 2297 { 2298 rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("a/Foo.cpp") 2299 android.AssertStringDoesNotContain(t, "Frozen versions should not have the -previous_api_dir set", 2300 rule.Args["optionalFlags"], 2301 "-previous") 2302 } 2303 // compile ToT(v3) 2304 { 2305 rule := ctx.ModuleForTests("foo-iface-V3-cpp-source", "").Output("a/Foo.cpp") 2306 android.AssertStringDoesNotContain(t, "Unfrozen versions should not have the -previous options when RELEASE_AIDL_USE_UNFROZEN is true (default)", 2307 rule.Args["optionalFlags"], 2308 "-previous") 2309 } 2310} 2311 2312func TestAidlUseUnfrozenOverrideFalse(t *testing.T) { 2313 customizer := withFiles(map[string][]byte{ 2314 "foo/Android.bp": []byte(` 2315 aidl_interface { 2316 name: "foo-iface", 2317 srcs: ["a/Foo.aidl"], 2318 versions: ["1"], 2319 } 2320 `), 2321 "foo/a/Foo.aidl": nil, "foo/aidl_api/foo-iface/current/a/Foo.aidl": nil, 2322 "foo/aidl_api/foo-iface/1/a/Foo.aidl": nil, "foo/aidl_api/foo-iface/1/.hash": nil, 2323 }) 2324 ctx, _ := testAidl(t, ``, setUseUnfrozenOverrideEnvFalse(), customizer) 2325 2326 rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("a/Foo.cpp") 2327 android.AssertStringDoesContain(t, "Unfrozen interfaces should have -previous_api_dir set when overriding the RELEASE_AIDL_USE_UNFROZEN flag", 2328 rule.Args["optionalFlags"], 2329 "-previous") 2330} 2331 2332func TestAidlUseUnfrozenOverrideTrue(t *testing.T) { 2333 customizer := withFiles(map[string][]byte{ 2334 "foo/Android.bp": []byte(` 2335 aidl_interface { 2336 name: "foo-iface", 2337 srcs: ["a/Foo.aidl"], 2338 versions: ["1"], 2339 } 2340 `), 2341 "foo/a/Foo.aidl": nil, "foo/aidl_api/foo-iface/current/a/Foo.aidl": nil, 2342 "foo/aidl_api/foo-iface/1/a/Foo.aidl": nil, "foo/aidl_api/foo-iface/1/.hash": nil, 2343 }) 2344 ctx, _ := testAidl(t, ``, setUseUnfrozenOverrideEnvTrue(), customizer) 2345 2346 rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("a/Foo.cpp") 2347 android.AssertStringDoesNotContain(t, "Unfrozen interfaces should not have -previous_api_dir set when overriding the RELEASE_AIDL_USE_UNFROZEN flag", 2348 rule.Args["optionalFlags"], 2349 "-previous") 2350} 2351