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 "android/soong/android" 19 "log" 20 "os" 21 "testing" 22 23 "github.com/google/blueprint/proptools" 24) 25 26// Needed in an _test.go file in this package to ensure tests run correctly, particularly in IDE. 27func TestMain(m *testing.M) { 28 if android.BuildOs != android.Linux { 29 // b/145598135 - Generating host snapshots for anything other than linux is not supported. 30 log.Printf("Skipping as sdk snapshot generation is only supported on %s not %s", android.Linux, android.BuildOs) 31 os.Exit(0) 32 } 33 34 runTestWithBuildDir(m) 35} 36 37func TestDepNotInRequiredSdks(t *testing.T) { 38 testSdkError(t, `module "myjavalib".*depends on "otherlib".*that isn't part of the required SDKs:.*`, ` 39 sdk { 40 name: "mysdk", 41 java_header_libs: ["sdkmember"], 42 } 43 44 sdk_snapshot { 45 name: "mysdk@1", 46 java_header_libs: ["sdkmember_mysdk_1"], 47 } 48 49 java_import { 50 name: "sdkmember", 51 prefer: false, 52 host_supported: true, 53 } 54 55 java_import { 56 name: "sdkmember_mysdk_1", 57 sdk_member_name: "sdkmember", 58 host_supported: true, 59 } 60 61 java_library { 62 name: "myjavalib", 63 srcs: ["Test.java"], 64 libs: [ 65 "sdkmember", 66 "otherlib", 67 ], 68 system_modules: "none", 69 sdk_version: "none", 70 compile_dex: true, 71 host_supported: true, 72 apex_available: ["myapex"], 73 } 74 75 // this lib is no in mysdk 76 java_library { 77 name: "otherlib", 78 srcs: ["Test.java"], 79 system_modules: "none", 80 sdk_version: "none", 81 compile_dex: true, 82 host_supported: true, 83 } 84 85 apex { 86 name: "myapex", 87 java_libs: ["myjavalib"], 88 uses_sdks: ["mysdk@1"], 89 key: "myapex.key", 90 certificate: ":myapex.cert", 91 } 92 `) 93} 94 95// Ensure that prebuilt modules have the same effective visibility as the source 96// modules. 97func TestSnapshotVisibility(t *testing.T) { 98 packageBp := ` 99 package { 100 default_visibility: ["//other/foo"], 101 } 102 103 sdk { 104 name: "mysdk", 105 visibility: [ 106 "//other/foo", 107 // This short form will be replaced with //package:__subpackages__ in the 108 // generated sdk_snapshot. 109 ":__subpackages__", 110 ], 111 java_header_libs: [ 112 "myjavalib", 113 "mypublicjavalib", 114 "mydefaultedjavalib", 115 "myprivatejavalib", 116 ], 117 } 118 119 java_library { 120 name: "myjavalib", 121 // Uses package default visibility 122 srcs: ["Test.java"], 123 system_modules: "none", 124 sdk_version: "none", 125 } 126 127 java_defaults { 128 name: "java-defaults", 129 visibility: ["//other/bar"], 130 } 131 132 java_library { 133 name: "mypublicjavalib", 134 defaults: ["java-defaults"], 135 visibility: ["//visibility:public"], 136 srcs: ["Test.java"], 137 system_modules: "none", 138 sdk_version: "none", 139 } 140 141 java_defaults { 142 name: "myjavadefaults", 143 visibility: ["//other/bar"], 144 } 145 146 java_library { 147 name: "mydefaultedjavalib", 148 defaults: ["myjavadefaults"], 149 srcs: ["Test.java"], 150 system_modules: "none", 151 sdk_version: "none", 152 } 153 154 java_library { 155 name: "myprivatejavalib", 156 srcs: ["Test.java"], 157 visibility: ["//visibility:private"], 158 system_modules: "none", 159 sdk_version: "none", 160 } 161 ` 162 163 result := testSdkWithFs(t, ``, 164 map[string][]byte{ 165 "package/Test.java": nil, 166 "package/Android.bp": []byte(packageBp), 167 }) 168 169 result.CheckSnapshot("mysdk", "package", 170 checkAndroidBpContents(` 171// This is auto-generated. DO NOT EDIT. 172 173java_import { 174 name: "mysdk_myjavalib@current", 175 sdk_member_name: "myjavalib", 176 visibility: [ 177 "//other/foo", 178 "//package", 179 ], 180 jars: ["java/myjavalib.jar"], 181} 182 183java_import { 184 name: "myjavalib", 185 prefer: false, 186 visibility: [ 187 "//other/foo", 188 "//package", 189 ], 190 jars: ["java/myjavalib.jar"], 191} 192 193java_import { 194 name: "mysdk_mypublicjavalib@current", 195 sdk_member_name: "mypublicjavalib", 196 visibility: ["//visibility:public"], 197 jars: ["java/mypublicjavalib.jar"], 198} 199 200java_import { 201 name: "mypublicjavalib", 202 prefer: false, 203 visibility: ["//visibility:public"], 204 jars: ["java/mypublicjavalib.jar"], 205} 206 207java_import { 208 name: "mysdk_mydefaultedjavalib@current", 209 sdk_member_name: "mydefaultedjavalib", 210 visibility: [ 211 "//other/bar", 212 "//package", 213 ], 214 jars: ["java/mydefaultedjavalib.jar"], 215} 216 217java_import { 218 name: "mydefaultedjavalib", 219 prefer: false, 220 visibility: [ 221 "//other/bar", 222 "//package", 223 ], 224 jars: ["java/mydefaultedjavalib.jar"], 225} 226 227java_import { 228 name: "mysdk_myprivatejavalib@current", 229 sdk_member_name: "myprivatejavalib", 230 visibility: ["//package"], 231 jars: ["java/myprivatejavalib.jar"], 232} 233 234java_import { 235 name: "myprivatejavalib", 236 prefer: false, 237 visibility: ["//package"], 238 jars: ["java/myprivatejavalib.jar"], 239} 240 241sdk_snapshot { 242 name: "mysdk@current", 243 visibility: [ 244 "//other/foo", 245 "//package:__subpackages__", 246 ], 247 java_header_libs: [ 248 "mysdk_myjavalib@current", 249 "mysdk_mypublicjavalib@current", 250 "mysdk_mydefaultedjavalib@current", 251 "mysdk_myprivatejavalib@current", 252 ], 253} 254`)) 255} 256 257func TestSDkInstall(t *testing.T) { 258 sdk := ` 259 sdk { 260 name: "mysdk", 261 } 262 ` 263 result := testSdkWithFs(t, ``, 264 map[string][]byte{ 265 "Android.bp": []byte(sdk), 266 }) 267 268 result.CheckSnapshot("mysdk", "", 269 checkAllOtherCopyRules(`.intermediates/mysdk/common_os/mysdk-current.zip -> mysdk-current.zip`), 270 ) 271} 272 273type EmbeddedPropertiesStruct struct { 274 S_Embedded_Common string `android:"arch_variant"` 275 S_Embedded_Different string `android:"arch_variant"` 276} 277 278type testPropertiesStruct struct { 279 name string 280 private string 281 Public_Kept string `sdk:"keep"` 282 S_Common string 283 S_Different string `android:"arch_variant"` 284 A_Common []string 285 A_Different []string `android:"arch_variant"` 286 F_Common *bool 287 F_Different *bool `android:"arch_variant"` 288 EmbeddedPropertiesStruct 289} 290 291func (p *testPropertiesStruct) optimizableProperties() interface{} { 292 return p 293} 294 295func (p *testPropertiesStruct) String() string { 296 return p.name 297} 298 299var _ propertiesContainer = (*testPropertiesStruct)(nil) 300 301func TestCommonValueOptimization(t *testing.T) { 302 common := &testPropertiesStruct{name: "common"} 303 structs := []propertiesContainer{ 304 &testPropertiesStruct{ 305 name: "struct-0", 306 private: "common", 307 Public_Kept: "common", 308 S_Common: "common", 309 S_Different: "upper", 310 A_Common: []string{"first", "second"}, 311 A_Different: []string{"alpha", "beta"}, 312 F_Common: proptools.BoolPtr(false), 313 F_Different: proptools.BoolPtr(false), 314 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 315 S_Embedded_Common: "embedded_common", 316 S_Embedded_Different: "embedded_upper", 317 }, 318 }, 319 &testPropertiesStruct{ 320 name: "struct-1", 321 private: "common", 322 Public_Kept: "common", 323 S_Common: "common", 324 S_Different: "lower", 325 A_Common: []string{"first", "second"}, 326 A_Different: []string{"alpha", "delta"}, 327 F_Common: proptools.BoolPtr(false), 328 F_Different: proptools.BoolPtr(true), 329 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 330 S_Embedded_Common: "embedded_common", 331 S_Embedded_Different: "embedded_lower", 332 }, 333 }, 334 } 335 336 extractor := newCommonValueExtractor(common) 337 338 h := TestHelper{t} 339 340 err := extractor.extractCommonProperties(common, structs) 341 h.AssertDeepEquals("unexpected error", nil, err) 342 343 h.AssertDeepEquals("common properties not correct", 344 &testPropertiesStruct{ 345 name: "common", 346 private: "", 347 Public_Kept: "", 348 S_Common: "common", 349 S_Different: "", 350 A_Common: []string{"first", "second"}, 351 A_Different: []string(nil), 352 F_Common: proptools.BoolPtr(false), 353 F_Different: nil, 354 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 355 S_Embedded_Common: "embedded_common", 356 S_Embedded_Different: "", 357 }, 358 }, 359 common) 360 361 h.AssertDeepEquals("updated properties[0] not correct", 362 &testPropertiesStruct{ 363 name: "struct-0", 364 private: "common", 365 Public_Kept: "common", 366 S_Common: "", 367 S_Different: "upper", 368 A_Common: nil, 369 A_Different: []string{"alpha", "beta"}, 370 F_Common: nil, 371 F_Different: proptools.BoolPtr(false), 372 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 373 S_Embedded_Common: "", 374 S_Embedded_Different: "embedded_upper", 375 }, 376 }, 377 structs[0]) 378 379 h.AssertDeepEquals("updated properties[1] not correct", 380 &testPropertiesStruct{ 381 name: "struct-1", 382 private: "common", 383 Public_Kept: "common", 384 S_Common: "", 385 S_Different: "lower", 386 A_Common: nil, 387 A_Different: []string{"alpha", "delta"}, 388 F_Common: nil, 389 F_Different: proptools.BoolPtr(true), 390 EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{ 391 S_Embedded_Common: "", 392 S_Embedded_Different: "embedded_lower", 393 }, 394 }, 395 structs[1]) 396} 397 398func TestCommonValueOptimization_InvalidArchSpecificVariants(t *testing.T) { 399 common := &testPropertiesStruct{name: "common"} 400 structs := []propertiesContainer{ 401 &testPropertiesStruct{ 402 name: "struct-0", 403 S_Common: "should-be-but-is-not-common0", 404 }, 405 &testPropertiesStruct{ 406 name: "struct-1", 407 S_Common: "should-be-but-is-not-common1", 408 }, 409 } 410 411 extractor := newCommonValueExtractor(common) 412 413 h := TestHelper{t} 414 415 err := extractor.extractCommonProperties(common, structs) 416 h.AssertErrorMessageEquals("unexpected error", `field "S_Common" is not tagged as "arch_variant" but has arch specific properties: 417 "struct-0" has value "should-be-but-is-not-common0" 418 "struct-1" has value "should-be-but-is-not-common1"`, err) 419} 420