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