1// Copyright 2019 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 sdk 16 17import ( 18 "log" 19 "os" 20 "runtime" 21 "testing" 22 23 "android/soong/android" 24 "android/soong/java" 25 26 "github.com/google/blueprint/proptools" 27) 28 29// Needed in an _test.go file in this package to ensure tests run correctly, particularly in IDE. 30func TestMain(m *testing.M) { 31 if runtime.GOOS != "linux" { 32 // b/145598135 - Generating host snapshots for anything other than linux is not supported. 33 log.Printf("Skipping as sdk snapshot generation is only supported on linux not %s", runtime.GOOS) 34 os.Exit(0) 35 } 36 37 os.Exit(m.Run()) 38} 39 40// Ensure that prebuilt modules have the same effective visibility as the source 41// modules. 42func TestSnapshotVisibility(t *testing.T) { 43 t.Parallel() 44 packageBp := ` 45 package { 46 default_visibility: ["//other/foo"], 47 } 48 49 sdk { 50 name: "mysdk", 51 visibility: [ 52 "//other/foo", 53 // This short form will be replaced with //package:__subpackages__ in the 54 // generated sdk_snapshot. 55 ":__subpackages__", 56 ], 57 java_header_libs: [ 58 "myjavalib", 59 "mypublicjavalib", 60 "mydefaultedjavalib", 61 "myprivatejavalib", 62 ], 63 } 64 65 java_library { 66 name: "myjavalib", 67 // Uses package default visibility 68 srcs: ["Test.java"], 69 system_modules: "none", 70 sdk_version: "none", 71 } 72 73 java_defaults { 74 name: "java-defaults", 75 visibility: ["//other/bar"], 76 } 77 78 java_library { 79 name: "mypublicjavalib", 80 defaults: ["java-defaults"], 81 visibility: ["//visibility:public"], 82 srcs: ["Test.java"], 83 system_modules: "none", 84 sdk_version: "none", 85 } 86 87 java_defaults { 88 name: "myjavadefaults", 89 visibility: ["//other/bar"], 90 } 91 92 java_library { 93 name: "mydefaultedjavalib", 94 defaults: ["myjavadefaults"], 95 srcs: ["Test.java"], 96 system_modules: "none", 97 sdk_version: "none", 98 } 99 100 java_library { 101 name: "myprivatejavalib", 102 srcs: ["Test.java"], 103 visibility: ["//visibility:private"], 104 system_modules: "none", 105 sdk_version: "none", 106 } 107 ` 108 109 result := testSdkWithFs(t, ``, 110 map[string][]byte{ 111 "package/Test.java": nil, 112 "package/Android.bp": []byte(packageBp), 113 }) 114 115 CheckSnapshot(t, result, "mysdk", "package", 116 checkAndroidBpContents(` 117// This is auto-generated. DO NOT EDIT. 118 119apex_contributions_defaults { 120 name: "mysdk.contributions", 121 contents: [ 122 "prebuilt_myjavalib", 123 "prebuilt_mypublicjavalib", 124 "prebuilt_mydefaultedjavalib", 125 "prebuilt_myprivatejavalib", 126 ], 127} 128 129java_import { 130 name: "myjavalib", 131 prefer: false, 132 visibility: ["//visibility:public"], 133 apex_available: ["//apex_available:platform"], 134 jars: ["java/myjavalib.jar"], 135} 136 137java_import { 138 name: "mypublicjavalib", 139 prefer: false, 140 visibility: ["//visibility:public"], 141 apex_available: ["//apex_available:platform"], 142 jars: ["java/mypublicjavalib.jar"], 143} 144 145java_import { 146 name: "mydefaultedjavalib", 147 prefer: false, 148 visibility: ["//visibility:public"], 149 apex_available: ["//apex_available:platform"], 150 jars: ["java/mydefaultedjavalib.jar"], 151} 152 153java_import { 154 name: "myprivatejavalib", 155 prefer: false, 156 visibility: ["//visibility:public"], 157 apex_available: ["//apex_available:platform"], 158 jars: ["java/myprivatejavalib.jar"], 159} 160`)) 161} 162 163func TestSdkInstall(t *testing.T) { 164 t.Parallel() 165 sdk := ` 166 sdk { 167 name: "mysdk", 168 } 169 ` 170 result := testSdkWithFs(t, sdk, nil) 171 172 CheckSnapshot(t, result, "mysdk", "", 173 checkAllOtherCopyRules(` 174.intermediates/mysdk/common_os/mysdk-current.info -> mysdk-current.info 175.intermediates/mysdk/common_os/mysdk-current.zip -> mysdk-current.zip 176`)) 177} 178 179type EmbeddedPropertiesStruct struct { 180 S_Embedded_Common string `android:"arch_variant"` 181 S_Embedded_Different string `android:"arch_variant"` 182} 183 184type testPropertiesStruct struct { 185 name string 186 private string 187 Public_Ignore string `sdk:"ignore"` 188 Public_Keep string `sdk:"keep"` 189 S_Common string 190 S_Different string `android:"arch_variant"` 191 A_Common []string 192 A_Different []string `android:"arch_variant"` 193 F_Common *bool 194 F_Different *bool `android:"arch_variant"` 195 EmbeddedPropertiesStruct 196} 197 198func (p *testPropertiesStruct) optimizableProperties() interface{} { 199 return p 200} 201 202func (p *testPropertiesStruct) String() string { 203 return p.name 204} 205 206var _ propertiesContainer = (*testPropertiesStruct)(nil) 207 208func TestCommonValueOptimization(t *testing.T) { 209 common := &testPropertiesStruct{name: "common"} 210 structs := []propertiesContainer{ 211 &testPropertiesStruct{ 212 name: "struct-0", 213 private: "common", 214 Public_Ignore: "common", 215 Public_Keep: "keep", 216 S_Common: "common", 217 S_Different: "upper", 218 A_Common: []string{"first", "second"}, 219 A_Different: []string{"alpha", "beta"}, 220 F_Common: proptools.BoolPtr(false), 221 F_Different: proptools.BoolPtr(false), 222 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 223 S_Embedded_Common: "embedded_common", 224 S_Embedded_Different: "embedded_upper", 225 }, 226 }, 227 &testPropertiesStruct{ 228 name: "struct-1", 229 private: "common", 230 Public_Ignore: "common", 231 Public_Keep: "keep", 232 S_Common: "common", 233 S_Different: "lower", 234 A_Common: []string{"first", "second"}, 235 A_Different: []string{"alpha", "delta"}, 236 F_Common: proptools.BoolPtr(false), 237 F_Different: proptools.BoolPtr(true), 238 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 239 S_Embedded_Common: "embedded_common", 240 S_Embedded_Different: "embedded_lower", 241 }, 242 }, 243 } 244 245 extractor := newCommonValueExtractor(common) 246 247 err := extractor.extractCommonProperties(common, structs) 248 android.AssertDeepEquals(t, "unexpected error", nil, err) 249 250 android.AssertDeepEquals(t, "common properties not correct", 251 &testPropertiesStruct{ 252 name: "common", 253 private: "", 254 Public_Ignore: "", 255 Public_Keep: "keep", 256 S_Common: "common", 257 S_Different: "", 258 A_Common: []string{"first", "second"}, 259 A_Different: []string(nil), 260 F_Common: proptools.BoolPtr(false), 261 F_Different: nil, 262 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 263 S_Embedded_Common: "embedded_common", 264 S_Embedded_Different: "", 265 }, 266 }, 267 common) 268 269 android.AssertDeepEquals(t, "updated properties[0] not correct", 270 &testPropertiesStruct{ 271 name: "struct-0", 272 private: "common", 273 Public_Ignore: "common", 274 Public_Keep: "keep", 275 S_Common: "", 276 S_Different: "upper", 277 A_Common: nil, 278 A_Different: []string{"alpha", "beta"}, 279 F_Common: nil, 280 F_Different: proptools.BoolPtr(false), 281 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 282 S_Embedded_Common: "", 283 S_Embedded_Different: "embedded_upper", 284 }, 285 }, 286 structs[0]) 287 288 android.AssertDeepEquals(t, "updated properties[1] not correct", 289 &testPropertiesStruct{ 290 name: "struct-1", 291 private: "common", 292 Public_Ignore: "common", 293 Public_Keep: "keep", 294 S_Common: "", 295 S_Different: "lower", 296 A_Common: nil, 297 A_Different: []string{"alpha", "delta"}, 298 F_Common: nil, 299 F_Different: proptools.BoolPtr(true), 300 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 301 S_Embedded_Common: "", 302 S_Embedded_Different: "embedded_lower", 303 }, 304 }, 305 structs[1]) 306} 307 308func TestCommonValueOptimization_InvalidArchSpecificVariants(t *testing.T) { 309 common := &testPropertiesStruct{name: "common"} 310 structs := []propertiesContainer{ 311 &testPropertiesStruct{ 312 name: "struct-0", 313 S_Common: "should-be-but-is-not-common0", 314 }, 315 &testPropertiesStruct{ 316 name: "struct-1", 317 S_Common: "should-be-but-is-not-common1", 318 }, 319 } 320 321 extractor := newCommonValueExtractor(common) 322 323 err := extractor.extractCommonProperties(common, structs) 324 android.AssertErrorMessageEquals(t, "unexpected error", `field "S_Common" is not tagged as "arch_variant" but has arch specific properties: 325 "struct-0" has value "should-be-but-is-not-common0" 326 "struct-1" has value "should-be-but-is-not-common1"`, err) 327} 328 329// Ensure that sdk snapshot related environment variables work correctly. 330func TestSnapshot_EnvConfiguration(t *testing.T) { 331 t.Parallel() 332 bp := ` 333 sdk { 334 name: "mysdk", 335 java_header_libs: ["myjavalib"], 336 } 337 338 java_library { 339 name: "myjavalib", 340 srcs: ["Test.java"], 341 system_modules: "none", 342 sdk_version: "none", 343 compile_dex: true, 344 host_supported: true, 345 } 346 ` 347 preparer := android.GroupFixturePreparers( 348 prepareForSdkTestWithJava, 349 android.FixtureWithRootAndroidBp(bp), 350 ) 351 352 checkZipFile := func(t *testing.T, result *android.TestResult, expected string) { 353 zipRule := result.ModuleForTests(t, "mysdk", "common_os").Rule("SnapshotZipFiles") 354 android.AssertStringEquals(t, "snapshot zip file", expected, zipRule.Output.String()) 355 } 356 357 t.Run("no env variables", func(t *testing.T) { 358 t.Parallel() 359 result := preparer.RunTest(t) 360 361 checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip") 362 363 CheckSnapshot(t, result, "mysdk", "", 364 checkAndroidBpContents(` 365// This is auto-generated. DO NOT EDIT. 366 367apex_contributions_defaults { 368 name: "mysdk.contributions", 369 contents: ["prebuilt_myjavalib"], 370} 371 372java_import { 373 name: "myjavalib", 374 prefer: false, 375 visibility: ["//visibility:public"], 376 apex_available: ["//apex_available:platform"], 377 jars: ["java/myjavalib.jar"], 378} 379 `), 380 ) 381 }) 382 383 t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) { 384 t.Parallel() 385 result := android.GroupFixturePreparers( 386 prepareForSdkTestWithJava, 387 java.PrepareForTestWithJavaDefaultModules, 388 java.PrepareForTestWithJavaSdkLibraryFiles, 389 java.FixtureWithLastReleaseApis("mysdklibrary"), 390 android.FixtureWithRootAndroidBp(` 391 sdk { 392 name: "mysdk", 393 bootclasspath_fragments: ["mybootclasspathfragment"], 394 } 395 396 bootclasspath_fragment { 397 name: "mybootclasspathfragment", 398 apex_available: ["myapex"], 399 contents: ["mysdklibrary"], 400 hidden_api: { 401 split_packages: ["*"], 402 }, 403 } 404 405 java_sdk_library { 406 name: "mysdklibrary", 407 srcs: ["Test.java"], 408 compile_dex: true, 409 sdk_version: "S", 410 public: {enabled: true}, 411 permitted_packages: ["mysdklibrary"], 412 } 413 `), 414 android.FixtureMergeEnv(map[string]string{ 415 "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S", 416 }), 417 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 418 ).RunTest(t) 419 420 CheckSnapshot(t, result, "mysdk", "", 421 checkAndroidBpContents(` 422// This is auto-generated. DO NOT EDIT. 423 424apex_contributions_defaults { 425 name: "mysdk.contributions", 426 contents: ["prebuilt_mysdklibrary"], 427} 428 429prebuilt_bootclasspath_fragment { 430 name: "mybootclasspathfragment", 431 prefer: false, 432 visibility: ["//visibility:public"], 433 apex_available: ["myapex"], 434 contents: ["mysdklibrary"], 435 hidden_api: { 436 annotation_flags: "hiddenapi/annotation-flags.csv", 437 metadata: "hiddenapi/metadata.csv", 438 index: "hiddenapi/index.csv", 439 stub_flags: "hiddenapi/stub-flags.csv", 440 all_flags: "hiddenapi/all-flags.csv", 441 }, 442} 443 444java_sdk_library_import { 445 name: "mysdklibrary", 446 prefer: false, 447 visibility: ["//visibility:public"], 448 apex_available: ["//apex_available:platform"], 449 shared_library: true, 450 compile_dex: true, 451 permitted_packages: ["mysdklibrary"], 452 public: { 453 jars: ["sdk_library/public/mysdklibrary-stubs.jar"], 454 stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"], 455 current_api: "sdk_library/public/mysdklibrary.txt", 456 removed_api: "sdk_library/public/mysdklibrary-removed.txt", 457 sdk_version: "current", 458 }, 459} 460`), 461 462 checkAllCopyRules(` 463.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv 464.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv 465.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv 466.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv 467.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv 468.intermediates/mysdklibrary.stubs.exportable/android_common/combined/mysdklibrary.stubs.exportable.jar -> sdk_library/public/mysdklibrary-stubs.jar 469.intermediates/mysdklibrary.stubs.source/android_common/exportable/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt 470.intermediates/mysdklibrary.stubs.source/android_common/exportable/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt 471`), 472 ) 473 }) 474 475 t.Run("test replacing exportable module", func(t *testing.T) { 476 t.Parallel() 477 result := android.GroupFixturePreparers( 478 prepareForSdkTestWithJava, 479 java.PrepareForTestWithJavaDefaultModules, 480 java.PrepareForTestWithJavaSdkLibraryFiles, 481 java.FixtureWithLastReleaseApis("mysdklibrary", "anothersdklibrary"), 482 android.FixtureWithRootAndroidBp(` 483 sdk { 484 name: "mysdk", 485 bootclasspath_fragments: ["mybootclasspathfragment"], 486 } 487 488 bootclasspath_fragment { 489 name: "mybootclasspathfragment", 490 apex_available: ["myapex"], 491 contents: ["mysdklibrary"], 492 hidden_api: { 493 split_packages: ["*"], 494 }, 495 core_platform_api: { 496 stub_libs: [ 497 "anothersdklibrary.stubs.exportable", 498 ], 499 }, 500 api: { 501 stub_libs: [ 502 "anothersdklibrary", 503 ], 504 }, 505 } 506 507 java_sdk_library { 508 name: "mysdklibrary", 509 srcs: ["Test.java"], 510 compile_dex: true, 511 min_sdk_version: "S", 512 public: {enabled: true}, 513 permitted_packages: ["mysdklibrary"], 514 } 515 516 java_sdk_library { 517 name: "anothersdklibrary", 518 srcs: ["Test.java"], 519 compile_dex: true, 520 min_sdk_version: "S", 521 public: {enabled: true}, 522 system: {enabled: true}, 523 module_lib: {enabled: true}, 524 } 525 `), 526 android.FixtureMergeEnv(map[string]string{ 527 "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S", 528 }), 529 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 530 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu", "S-V2"} 531 }), 532 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 533 ).RunTest(t) 534 535 CheckSnapshot(t, result, "mysdk", "", 536 checkAndroidBpContents(` 537// This is auto-generated. DO NOT EDIT. 538 539prebuilt_bootclasspath_fragment { 540 name: "mybootclasspathfragment", 541 prefer: false, 542 visibility: ["//visibility:public"], 543 apex_available: ["myapex"], 544 contents: ["mysdklibrary"], 545 api: { 546 stub_libs: ["anothersdklibrary"], 547 }, 548 core_platform_api: { 549 stub_libs: ["anothersdklibrary.stubs"], 550 }, 551 hidden_api: { 552 annotation_flags: "hiddenapi/annotation-flags.csv", 553 metadata: "hiddenapi/metadata.csv", 554 index: "hiddenapi/index.csv", 555 stub_flags: "hiddenapi/stub-flags.csv", 556 all_flags: "hiddenapi/all-flags.csv", 557 }, 558} 559 560java_sdk_library_import { 561 name: "mysdklibrary", 562 prefer: false, 563 visibility: ["//visibility:public"], 564 apex_available: ["//apex_available:platform"], 565 shared_library: true, 566 compile_dex: true, 567 permitted_packages: ["mysdklibrary"], 568 public: { 569 jars: ["sdk_library/public/mysdklibrary-stubs.jar"], 570 stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"], 571 current_api: "sdk_library/public/mysdklibrary.txt", 572 removed_api: "sdk_library/public/mysdklibrary-removed.txt", 573 sdk_version: "current", 574 }, 575} 576 577java_sdk_library_import { 578 name: "anothersdklibrary", 579 prefer: false, 580 visibility: ["//visibility:public"], 581 apex_available: ["//apex_available:platform"], 582 shared_library: true, 583 compile_dex: true, 584 public: { 585 jars: ["sdk_library/public/anothersdklibrary-stubs.jar"], 586 stub_srcs: ["sdk_library/public/anothersdklibrary_stub_sources"], 587 current_api: "sdk_library/public/anothersdklibrary.txt", 588 removed_api: "sdk_library/public/anothersdklibrary-removed.txt", 589 sdk_version: "current", 590 }, 591 system: { 592 jars: ["sdk_library/system/anothersdklibrary-stubs.jar"], 593 stub_srcs: ["sdk_library/system/anothersdklibrary_stub_sources"], 594 current_api: "sdk_library/system/anothersdklibrary.txt", 595 removed_api: "sdk_library/system/anothersdklibrary-removed.txt", 596 sdk_version: "system_current", 597 }, 598 module_lib: { 599 jars: ["sdk_library/module-lib/anothersdklibrary-stubs.jar"], 600 stub_srcs: ["sdk_library/module-lib/anothersdklibrary_stub_sources"], 601 current_api: "sdk_library/module-lib/anothersdklibrary.txt", 602 removed_api: "sdk_library/module-lib/anothersdklibrary-removed.txt", 603 sdk_version: "module_current", 604 }, 605} 606`), 607 ) 608 }) 609 610} 611