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 prebuilt_visibility: [ 57 "//prebuilts/mysdk", 58 ], 59 java_header_libs: [ 60 "myjavalib", 61 "mypublicjavalib", 62 "mydefaultedjavalib", 63 "myprivatejavalib", 64 ], 65 } 66 67 java_library { 68 name: "myjavalib", 69 // Uses package default visibility 70 srcs: ["Test.java"], 71 system_modules: "none", 72 sdk_version: "none", 73 } 74 75 java_defaults { 76 name: "java-defaults", 77 visibility: ["//other/bar"], 78 } 79 80 java_library { 81 name: "mypublicjavalib", 82 defaults: ["java-defaults"], 83 visibility: ["//visibility:public"], 84 srcs: ["Test.java"], 85 system_modules: "none", 86 sdk_version: "none", 87 } 88 89 java_defaults { 90 name: "myjavadefaults", 91 visibility: ["//other/bar"], 92 } 93 94 java_library { 95 name: "mydefaultedjavalib", 96 defaults: ["myjavadefaults"], 97 srcs: ["Test.java"], 98 system_modules: "none", 99 sdk_version: "none", 100 } 101 102 java_library { 103 name: "myprivatejavalib", 104 srcs: ["Test.java"], 105 visibility: ["//visibility:private"], 106 system_modules: "none", 107 sdk_version: "none", 108 } 109 ` 110 111 result := testSdkWithFs(t, ``, 112 map[string][]byte{ 113 "package/Test.java": nil, 114 "package/Android.bp": []byte(packageBp), 115 }) 116 117 CheckSnapshot(t, result, "mysdk", "package", 118 checkAndroidBpContents(` 119// This is auto-generated. DO NOT EDIT. 120 121java_import { 122 name: "myjavalib", 123 prefer: false, 124 visibility: [ 125 "//other/foo", 126 "//package", 127 "//prebuilts/mysdk", 128 ], 129 apex_available: ["//apex_available:platform"], 130 jars: ["java/myjavalib.jar"], 131} 132 133java_import { 134 name: "mypublicjavalib", 135 prefer: false, 136 visibility: ["//visibility:public"], 137 apex_available: ["//apex_available:platform"], 138 jars: ["java/mypublicjavalib.jar"], 139} 140 141java_import { 142 name: "mydefaultedjavalib", 143 prefer: false, 144 visibility: [ 145 "//other/bar", 146 "//package", 147 "//prebuilts/mysdk", 148 ], 149 apex_available: ["//apex_available:platform"], 150 jars: ["java/mydefaultedjavalib.jar"], 151} 152 153java_import { 154 name: "myprivatejavalib", 155 prefer: false, 156 visibility: [ 157 "//package", 158 "//prebuilts/mysdk", 159 ], 160 apex_available: ["//apex_available:platform"], 161 jars: ["java/myprivatejavalib.jar"], 162} 163`)) 164} 165 166func TestPrebuiltVisibilityProperty_IsValidated(t *testing.T) { 167 testSdkError(t, `prebuilt_visibility: cannot mix "//visibility:private" with any other visibility rules`, ` 168 sdk { 169 name: "mysdk", 170 prebuilt_visibility: [ 171 "//foo", 172 "//visibility:private", 173 ], 174 } 175`) 176} 177 178func TestPrebuiltVisibilityProperty_AddPrivate(t *testing.T) { 179 testSdkError(t, `prebuilt_visibility: "//visibility:private" does not widen the visibility`, ` 180 sdk { 181 name: "mysdk", 182 prebuilt_visibility: [ 183 "//visibility:private", 184 ], 185 java_header_libs: [ 186 "myjavalib", 187 ], 188 } 189 190 java_library { 191 name: "myjavalib", 192 // Uses package default visibility 193 srcs: ["Test.java"], 194 system_modules: "none", 195 sdk_version: "none", 196 } 197`) 198} 199 200func TestSdkInstall(t *testing.T) { 201 sdk := ` 202 sdk { 203 name: "mysdk", 204 } 205 ` 206 result := testSdkWithFs(t, sdk, nil) 207 208 CheckSnapshot(t, result, "mysdk", "", 209 checkAllOtherCopyRules(` 210.intermediates/mysdk/common_os/mysdk-current.info -> mysdk-current.info 211.intermediates/mysdk/common_os/mysdk-current.zip -> mysdk-current.zip 212`)) 213} 214 215type EmbeddedPropertiesStruct struct { 216 S_Embedded_Common string `android:"arch_variant"` 217 S_Embedded_Different string `android:"arch_variant"` 218} 219 220type testPropertiesStruct struct { 221 name string 222 private string 223 Public_Ignore string `sdk:"ignore"` 224 Public_Keep string `sdk:"keep"` 225 S_Common string 226 S_Different string `android:"arch_variant"` 227 A_Common []string 228 A_Different []string `android:"arch_variant"` 229 F_Common *bool 230 F_Different *bool `android:"arch_variant"` 231 EmbeddedPropertiesStruct 232} 233 234func (p *testPropertiesStruct) optimizableProperties() interface{} { 235 return p 236} 237 238func (p *testPropertiesStruct) String() string { 239 return p.name 240} 241 242var _ propertiesContainer = (*testPropertiesStruct)(nil) 243 244func TestCommonValueOptimization(t *testing.T) { 245 common := &testPropertiesStruct{name: "common"} 246 structs := []propertiesContainer{ 247 &testPropertiesStruct{ 248 name: "struct-0", 249 private: "common", 250 Public_Ignore: "common", 251 Public_Keep: "keep", 252 S_Common: "common", 253 S_Different: "upper", 254 A_Common: []string{"first", "second"}, 255 A_Different: []string{"alpha", "beta"}, 256 F_Common: proptools.BoolPtr(false), 257 F_Different: proptools.BoolPtr(false), 258 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 259 S_Embedded_Common: "embedded_common", 260 S_Embedded_Different: "embedded_upper", 261 }, 262 }, 263 &testPropertiesStruct{ 264 name: "struct-1", 265 private: "common", 266 Public_Ignore: "common", 267 Public_Keep: "keep", 268 S_Common: "common", 269 S_Different: "lower", 270 A_Common: []string{"first", "second"}, 271 A_Different: []string{"alpha", "delta"}, 272 F_Common: proptools.BoolPtr(false), 273 F_Different: proptools.BoolPtr(true), 274 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 275 S_Embedded_Common: "embedded_common", 276 S_Embedded_Different: "embedded_lower", 277 }, 278 }, 279 } 280 281 extractor := newCommonValueExtractor(common) 282 283 err := extractor.extractCommonProperties(common, structs) 284 android.AssertDeepEquals(t, "unexpected error", nil, err) 285 286 android.AssertDeepEquals(t, "common properties not correct", 287 &testPropertiesStruct{ 288 name: "common", 289 private: "", 290 Public_Ignore: "", 291 Public_Keep: "keep", 292 S_Common: "common", 293 S_Different: "", 294 A_Common: []string{"first", "second"}, 295 A_Different: []string(nil), 296 F_Common: proptools.BoolPtr(false), 297 F_Different: nil, 298 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 299 S_Embedded_Common: "embedded_common", 300 S_Embedded_Different: "", 301 }, 302 }, 303 common) 304 305 android.AssertDeepEquals(t, "updated properties[0] not correct", 306 &testPropertiesStruct{ 307 name: "struct-0", 308 private: "common", 309 Public_Ignore: "common", 310 Public_Keep: "keep", 311 S_Common: "", 312 S_Different: "upper", 313 A_Common: nil, 314 A_Different: []string{"alpha", "beta"}, 315 F_Common: nil, 316 F_Different: proptools.BoolPtr(false), 317 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 318 S_Embedded_Common: "", 319 S_Embedded_Different: "embedded_upper", 320 }, 321 }, 322 structs[0]) 323 324 android.AssertDeepEquals(t, "updated properties[1] not correct", 325 &testPropertiesStruct{ 326 name: "struct-1", 327 private: "common", 328 Public_Ignore: "common", 329 Public_Keep: "keep", 330 S_Common: "", 331 S_Different: "lower", 332 A_Common: nil, 333 A_Different: []string{"alpha", "delta"}, 334 F_Common: nil, 335 F_Different: proptools.BoolPtr(true), 336 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 337 S_Embedded_Common: "", 338 S_Embedded_Different: "embedded_lower", 339 }, 340 }, 341 structs[1]) 342} 343 344func TestCommonValueOptimization_InvalidArchSpecificVariants(t *testing.T) { 345 common := &testPropertiesStruct{name: "common"} 346 structs := []propertiesContainer{ 347 &testPropertiesStruct{ 348 name: "struct-0", 349 S_Common: "should-be-but-is-not-common0", 350 }, 351 &testPropertiesStruct{ 352 name: "struct-1", 353 S_Common: "should-be-but-is-not-common1", 354 }, 355 } 356 357 extractor := newCommonValueExtractor(common) 358 359 err := extractor.extractCommonProperties(common, structs) 360 android.AssertErrorMessageEquals(t, "unexpected error", `field "S_Common" is not tagged as "arch_variant" but has arch specific properties: 361 "struct-0" has value "should-be-but-is-not-common0" 362 "struct-1" has value "should-be-but-is-not-common1"`, err) 363} 364 365// Ensure that sdk snapshot related environment variables work correctly. 366func TestSnapshot_EnvConfiguration(t *testing.T) { 367 bp := ` 368 sdk { 369 name: "mysdk", 370 java_header_libs: ["myjavalib"], 371 } 372 373 java_library { 374 name: "myjavalib", 375 srcs: ["Test.java"], 376 system_modules: "none", 377 sdk_version: "none", 378 compile_dex: true, 379 host_supported: true, 380 } 381 ` 382 preparer := android.GroupFixturePreparers( 383 prepareForSdkTestWithJava, 384 android.FixtureWithRootAndroidBp(bp), 385 ) 386 387 checkZipFile := func(t *testing.T, result *android.TestResult, expected string) { 388 zipRule := result.ModuleForTests("mysdk", "common_os").Rule("SnapshotZipFiles") 389 android.AssertStringEquals(t, "snapshot zip file", expected, zipRule.Output.String()) 390 } 391 392 t.Run("no env variables", func(t *testing.T) { 393 result := preparer.RunTest(t) 394 395 checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip") 396 397 CheckSnapshot(t, result, "mysdk", "", 398 checkAndroidBpContents(` 399// This is auto-generated. DO NOT EDIT. 400 401java_import { 402 name: "myjavalib", 403 prefer: false, 404 visibility: ["//visibility:public"], 405 apex_available: ["//apex_available:platform"], 406 jars: ["java/myjavalib.jar"], 407} 408 `), 409 ) 410 }) 411 412 t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) { 413 result := android.GroupFixturePreparers( 414 prepareForSdkTestWithJava, 415 java.PrepareForTestWithJavaDefaultModules, 416 java.PrepareForTestWithJavaSdkLibraryFiles, 417 java.FixtureWithLastReleaseApis("mysdklibrary"), 418 android.FixtureWithRootAndroidBp(` 419 sdk { 420 name: "mysdk", 421 bootclasspath_fragments: ["mybootclasspathfragment"], 422 } 423 424 bootclasspath_fragment { 425 name: "mybootclasspathfragment", 426 apex_available: ["myapex"], 427 contents: ["mysdklibrary"], 428 hidden_api: { 429 split_packages: ["*"], 430 }, 431 } 432 433 java_sdk_library { 434 name: "mysdklibrary", 435 srcs: ["Test.java"], 436 compile_dex: true, 437 sdk_version: "S", 438 public: {enabled: true}, 439 permitted_packages: ["mysdklibrary"], 440 } 441 `), 442 android.FixtureMergeEnv(map[string]string{ 443 "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S", 444 }), 445 ).RunTest(t) 446 447 CheckSnapshot(t, result, "mysdk", "", 448 checkAndroidBpContents(` 449// This is auto-generated. DO NOT EDIT. 450 451prebuilt_bootclasspath_fragment { 452 name: "mybootclasspathfragment", 453 prefer: false, 454 visibility: ["//visibility:public"], 455 apex_available: ["myapex"], 456 contents: ["mysdklibrary"], 457 hidden_api: { 458 annotation_flags: "hiddenapi/annotation-flags.csv", 459 metadata: "hiddenapi/metadata.csv", 460 index: "hiddenapi/index.csv", 461 stub_flags: "hiddenapi/stub-flags.csv", 462 all_flags: "hiddenapi/all-flags.csv", 463 }, 464} 465 466java_sdk_library_import { 467 name: "mysdklibrary", 468 prefer: false, 469 visibility: ["//visibility:public"], 470 apex_available: ["//apex_available:platform"], 471 shared_library: true, 472 compile_dex: true, 473 permitted_packages: ["mysdklibrary"], 474 public: { 475 jars: ["sdk_library/public/mysdklibrary-stubs.jar"], 476 stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"], 477 current_api: "sdk_library/public/mysdklibrary.txt", 478 removed_api: "sdk_library/public/mysdklibrary-removed.txt", 479 sdk_version: "current", 480 }, 481} 482`), 483 484 checkAllCopyRules(` 485.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv 486.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv 487.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv 488.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv 489.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv 490.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar 491.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt 492.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt 493`), 494 ) 495 }) 496 497} 498