1// Copyright (C) 2021 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 apex 16 17import ( 18 "strings" 19 "testing" 20 21 "android/soong/android" 22 "android/soong/dexpreopt" 23 "android/soong/java" 24) 25 26var prepareForTestWithSystemserverclasspathFragment = android.GroupFixturePreparers( 27 java.PrepareForTestWithDexpreopt, 28 PrepareForTestWithApexBuildComponents, 29) 30 31func TestSystemserverclasspathFragmentContents(t *testing.T) { 32 t.Parallel() 33 result := android.GroupFixturePreparers( 34 prepareForTestWithSystemserverclasspathFragment, 35 prepareForTestWithMyapex, 36 dexpreopt.FixtureSetApexSystemServerJars("myapex:foo", "myapex:bar", "myapex:baz"), 37 ).RunTestWithBp(t, ` 38 apex { 39 name: "myapex", 40 key: "myapex.key", 41 systemserverclasspath_fragments: [ 42 "mysystemserverclasspathfragment", 43 ], 44 updatable: false, 45 } 46 47 apex_key { 48 name: "myapex.key", 49 public_key: "testkey.avbpubkey", 50 private_key: "testkey.pem", 51 } 52 53 java_library { 54 name: "foo", 55 srcs: ["b.java"], 56 installable: true, 57 apex_available: [ 58 "myapex", 59 ], 60 } 61 62 java_library { 63 name: "bar", 64 srcs: ["c.java"], 65 installable: true, 66 dex_preopt: { 67 profile: "bar-art-profile", 68 }, 69 apex_available: [ 70 "myapex", 71 ], 72 } 73 74 java_library { 75 name: "baz", 76 srcs: ["d.java"], 77 installable: true, 78 dex_preopt: { 79 profile_guided: true, // ignored 80 }, 81 apex_available: [ 82 "myapex", 83 ], 84 sdk_version: "core_current", 85 } 86 87 systemserverclasspath_fragment { 88 name: "mysystemserverclasspathfragment", 89 contents: [ 90 "foo", 91 "bar", 92 "baz", 93 ], 94 apex_available: [ 95 "myapex", 96 ], 97 } 98 `) 99 100 ctx := result.TestContext 101 102 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 103 "etc/classpaths/systemserverclasspath.pb", 104 "javalib/foo.jar", 105 "javalib/bar.jar", 106 "javalib/bar.jar.prof", 107 "javalib/baz.jar", 108 }) 109 110 java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{ 111 `all_apex_contributions`, 112 `dex2oatd`, 113 `myapex.key`, 114 `mysystemserverclasspathfragment`, 115 }) 116 117 assertProfileGuided(t, ctx, "foo", "android_common_apex10000", false) 118 assertProfileGuided(t, ctx, "bar", "android_common_apex10000", true) 119 assertProfileGuided(t, ctx, "baz", "android_common_apex10000", false) 120} 121 122func TestSystemserverclasspathFragmentNoGeneratedProto(t *testing.T) { 123 t.Parallel() 124 result := android.GroupFixturePreparers( 125 prepareForTestWithSystemserverclasspathFragment, 126 prepareForTestWithMyapex, 127 dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"), 128 ).RunTestWithBp(t, ` 129 apex { 130 name: "myapex", 131 key: "myapex.key", 132 systemserverclasspath_fragments: [ 133 "mysystemserverclasspathfragment", 134 ], 135 updatable: false, 136 } 137 138 apex_key { 139 name: "myapex.key", 140 public_key: "testkey.avbpubkey", 141 private_key: "testkey.pem", 142 } 143 144 java_library { 145 name: "foo", 146 srcs: ["b.java"], 147 installable: true, 148 apex_available: [ 149 "myapex", 150 ], 151 } 152 153 systemserverclasspath_fragment { 154 name: "mysystemserverclasspathfragment", 155 generate_classpaths_proto: false, 156 contents: [ 157 "foo", 158 ], 159 apex_available: [ 160 "myapex", 161 ], 162 } 163 `) 164 165 ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex", []string{ 166 "javalib/foo.jar", 167 }) 168 169 java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{ 170 `all_apex_contributions`, 171 `dex2oatd`, 172 `myapex.key`, 173 `mysystemserverclasspathfragment`, 174 }) 175} 176 177func TestSystemServerClasspathFragmentWithContentNotInMake(t *testing.T) { 178 t.Parallel() 179 android.GroupFixturePreparers( 180 prepareForTestWithSystemserverclasspathFragment, 181 prepareForTestWithMyapex, 182 dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"), 183 ). 184 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 185 `in contents must also be declared in PRODUCT_APEX_SYSTEM_SERVER_JARS`)). 186 RunTestWithBp(t, ` 187 apex { 188 name: "myapex", 189 key: "myapex.key", 190 systemserverclasspath_fragments: [ 191 "mysystemserverclasspathfragment", 192 ], 193 updatable: false, 194 } 195 196 apex_key { 197 name: "myapex.key", 198 public_key: "testkey.avbpubkey", 199 private_key: "testkey.pem", 200 } 201 202 java_library { 203 name: "foo", 204 srcs: ["b.java"], 205 installable: true, 206 apex_available: ["myapex"], 207 } 208 209 java_library { 210 name: "bar", 211 srcs: ["b.java"], 212 installable: true, 213 apex_available: ["myapex"], 214 } 215 216 systemserverclasspath_fragment { 217 name: "mysystemserverclasspathfragment", 218 contents: [ 219 "foo", 220 "bar", 221 ], 222 apex_available: [ 223 "myapex", 224 ], 225 } 226 `) 227} 228 229func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { 230 t.Parallel() 231 result := android.GroupFixturePreparers( 232 prepareForTestWithSystemserverclasspathFragment, 233 prepareForTestWithMyapex, 234 dexpreopt.FixtureSetApexSystemServerJars("myapex:foo", "myapex:bar"), 235 ).RunTestWithBp(t, ` 236 prebuilt_apex { 237 name: "myapex", 238 arch: { 239 arm64: { 240 src: "myapex-arm64.apex", 241 }, 242 arm: { 243 src: "myapex-arm.apex", 244 }, 245 }, 246 exported_systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], 247 } 248 249 java_import { 250 name: "foo", 251 jars: ["foo.jar"], 252 apex_available: [ 253 "myapex", 254 ], 255 } 256 257 java_import { 258 name: "bar", 259 jars: ["bar.jar"], 260 dex_preopt: { 261 profile_guided: true, 262 }, 263 apex_available: [ 264 "myapex", 265 ], 266 } 267 268 prebuilt_systemserverclasspath_fragment { 269 name: "mysystemserverclasspathfragment", 270 prefer: true, 271 contents: [ 272 "foo", 273 "bar", 274 ], 275 apex_available: [ 276 "myapex", 277 ], 278 } 279 `) 280 281 ctx := result.TestContext 282 283 java.CheckModuleDependencies(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{ 284 `all_apex_contributions`, 285 `dex2oatd`, 286 `prebuilt_mysystemserverclasspathfragment`, 287 }) 288 289 java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_prebuilt_myapex", []string{ 290 `all_apex_contributions`, 291 `prebuilt_bar`, 292 `prebuilt_foo`, 293 }) 294 295 ensureExactDeapexedContents(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{ 296 "javalib/foo.jar", 297 "javalib/bar.jar", 298 "javalib/bar.jar.prof", 299 }) 300 301 assertProfileGuidedPrebuilt(t, ctx, "myapex", "foo", false) 302 assertProfileGuidedPrebuilt(t, ctx, "myapex", "bar", true) 303} 304 305func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) { 306 t.Parallel() 307 result := android.GroupFixturePreparers( 308 prepareForTestWithSystemserverclasspathFragment, 309 prepareForTestWithMyapex, 310 dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo", "myapex:bar", "myapex:baz"), 311 ).RunTestWithBp(t, ` 312 apex { 313 name: "myapex", 314 key: "myapex.key", 315 systemserverclasspath_fragments: [ 316 "mysystemserverclasspathfragment", 317 ], 318 updatable: false, 319 } 320 321 apex_key { 322 name: "myapex.key", 323 public_key: "testkey.avbpubkey", 324 private_key: "testkey.pem", 325 } 326 327 java_library { 328 name: "foo", 329 srcs: ["b.java"], 330 installable: true, 331 apex_available: [ 332 "myapex", 333 ], 334 } 335 336 java_library { 337 name: "bar", 338 srcs: ["c.java"], 339 dex_preopt: { 340 profile: "bar-art-profile", 341 }, 342 installable: true, 343 apex_available: [ 344 "myapex", 345 ], 346 } 347 348 java_library { 349 name: "baz", 350 srcs: ["d.java"], 351 dex_preopt: { 352 profile_guided: true, // ignored 353 }, 354 installable: true, 355 apex_available: [ 356 "myapex", 357 ], 358 sdk_version: "core_current", 359 } 360 361 systemserverclasspath_fragment { 362 name: "mysystemserverclasspathfragment", 363 standalone_contents: [ 364 "foo", 365 "bar", 366 "baz", 367 ], 368 apex_available: [ 369 "myapex", 370 ], 371 } 372 `) 373 374 ctx := result.TestContext 375 376 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 377 "etc/classpaths/systemserverclasspath.pb", 378 "javalib/foo.jar", 379 "javalib/bar.jar", 380 "javalib/bar.jar.prof", 381 "javalib/baz.jar", 382 }) 383 384 assertProfileGuided(t, ctx, "foo", "android_common_apex10000", false) 385 assertProfileGuided(t, ctx, "bar", "android_common_apex10000", true) 386 assertProfileGuided(t, ctx, "baz", "android_common_apex10000", false) 387} 388 389func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) { 390 t.Parallel() 391 result := android.GroupFixturePreparers( 392 prepareForTestWithSystemserverclasspathFragment, 393 prepareForTestWithMyapex, 394 dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo", "myapex:bar"), 395 ).RunTestWithBp(t, ` 396 prebuilt_apex { 397 name: "myapex", 398 arch: { 399 arm64: { 400 src: "myapex-arm64.apex", 401 }, 402 arm: { 403 src: "myapex-arm.apex", 404 }, 405 }, 406 exported_systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], 407 } 408 409 java_import { 410 name: "foo", 411 jars: ["foo.jar"], 412 apex_available: [ 413 "myapex", 414 ], 415 } 416 417 java_import { 418 name: "bar", 419 jars: ["bar.jar"], 420 dex_preopt: { 421 profile_guided: true, 422 }, 423 apex_available: [ 424 "myapex", 425 ], 426 } 427 428 prebuilt_systemserverclasspath_fragment { 429 name: "mysystemserverclasspathfragment", 430 prefer: true, 431 standalone_contents: [ 432 "foo", 433 "bar", 434 ], 435 apex_available: [ 436 "myapex", 437 ], 438 } 439 `) 440 441 ctx := result.TestContext 442 443 java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_prebuilt_myapex", []string{ 444 `all_apex_contributions`, 445 `prebuilt_bar`, 446 `prebuilt_foo`, 447 }) 448 449 ensureExactDeapexedContents(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{ 450 "javalib/foo.jar", 451 "javalib/bar.jar", 452 "javalib/bar.jar.prof", 453 }) 454 455 assertProfileGuidedPrebuilt(t, ctx, "myapex", "foo", false) 456 assertProfileGuidedPrebuilt(t, ctx, "myapex", "bar", true) 457} 458 459func assertProfileGuided(t *testing.T, ctx *android.TestContext, moduleName string, variant string, expected bool) { 460 dexpreopt := ctx.ModuleForTests(t, moduleName, variant).Rule("dexpreopt") 461 actual := strings.Contains(dexpreopt.RuleParams.Command, "--profile-file=") 462 if expected != actual { 463 t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual) 464 } 465} 466 467func assertProfileGuidedPrebuilt(t *testing.T, ctx *android.TestContext, apexName string, moduleName string, expected bool) { 468 dexpreopt := ctx.ModuleForTests(t, apexName, "android_common_prebuilt_"+apexName).Rule("dexpreopt." + moduleName) 469 actual := strings.Contains(dexpreopt.RuleParams.Command, "--profile-file=") 470 if expected != actual { 471 t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual) 472 } 473} 474 475func TestCheckSystemServerOrderWithArtApex(t *testing.T) { 476 preparers := android.GroupFixturePreparers( 477 java.PrepareForTestWithDexpreopt, 478 java.PrepareForTestWithJavaSdkLibraryFiles, 479 PrepareForTestWithApexBuildComponents, 480 prepareForTestWithArtApex, 481 java.FixtureConfigureBootJars("com.android.art:framework-art"), 482 dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-apex1", "com.android.art:service-art"), 483 java.FixtureWithLastReleaseApis("baz"), 484 ) 485 486 // Creates a com.android.art apex with a bootclasspath fragment and a systemserverclasspath fragment, and a 487 // com.android.apex1 prebuilt whose bootclasspath fragment depends on the com.android.art bootclasspath fragment. 488 // Verifies that the checkSystemServerOrder doesn't get confused by the bootclasspath dependencies and report 489 // that service-apex1 depends on service-art. 490 result := preparers.RunTestWithBp(t, ` 491 apex { 492 name: "com.android.art", 493 key: "com.android.art.key", 494 bootclasspath_fragments: ["art-bootclasspath-fragment"], 495 systemserverclasspath_fragments: ["art-systemserverclasspath-fragment"], 496 updatable: false, 497 } 498 499 apex_key { 500 name: "com.android.art.key", 501 public_key: "com.android.art.avbpubkey", 502 private_key: "com.android.art.pem", 503 } 504 505 bootclasspath_fragment { 506 name: "art-bootclasspath-fragment", 507 image_name: "art", 508 contents: ["framework-art"], 509 apex_available: [ 510 "com.android.art", 511 ], 512 hidden_api: { 513 split_packages: ["*"], 514 }, 515 } 516 517 java_library { 518 name: "framework-art", 519 apex_available: ["com.android.art"], 520 srcs: ["a.java"], 521 compile_dex: true, 522 } 523 524 systemserverclasspath_fragment { 525 name: "art-systemserverclasspath-fragment", 526 apex_available: ["com.android.art"], 527 contents: ["service-art"], 528 } 529 530 java_library { 531 name: "service-art", 532 srcs: ["a.java"], 533 apex_available: ["com.android.art"], 534 compile_dex: true, 535 } 536 537 prebuilt_apex { 538 name: "com.android.apex1", 539 arch: { 540 arm64: { 541 src: "myapex-arm64.apex", 542 }, 543 arm: { 544 src: "myapex-arm.apex", 545 }, 546 }, 547 exported_bootclasspath_fragments: ["com.android.apex1-bootclasspath-fragment"], 548 exported_systemserverclasspath_fragments: ["com.android.apex1-systemserverclasspath-fragment"], 549 } 550 551 prebuilt_bootclasspath_fragment { 552 name: "com.android.apex1-bootclasspath-fragment", 553 visibility: ["//visibility:public"], 554 apex_available: ["com.android.apex1"], 555 contents: ["framework-apex1"], 556 fragments: [ 557 { 558 apex: "com.android.art", 559 module: "art-bootclasspath-fragment", 560 }, 561 ], 562 hidden_api: { 563 annotation_flags: "hiddenapi/annotation-flags.csv", 564 metadata: "hiddenapi/metadata.csv", 565 index: "hiddenapi/index.csv", 566 stub_flags: "hiddenapi/stub-flags.csv", 567 all_flags: "hiddenapi/all-flags.csv", 568 }, 569 } 570 571 java_import { 572 name: "framework-apex1", 573 apex_available: ["com.android.apex1"], 574 } 575 576 prebuilt_systemserverclasspath_fragment { 577 name: "com.android.apex1-systemserverclasspath-fragment", 578 apex_available: ["com.android.apex1"], 579 contents: ["service-apex1"], 580 } 581 582 java_import { 583 name: "service-apex1", 584 installable: true, 585 apex_available: ["com.android.apex1"], 586 sdk_version: "current", 587 }`) 588 589 _ = result 590} 591