1// Copyright 2024 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 fsgen 16 17import ( 18 "android/soong/android" 19 "android/soong/etc" 20 "android/soong/filesystem" 21 "android/soong/java" 22 "testing" 23 24 "github.com/google/blueprint/proptools" 25) 26 27var prepareForTestWithFsgenBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents) 28 29func TestFileSystemCreatorSystemImageProps(t *testing.T) { 30 result := android.GroupFixturePreparers( 31 android.PrepareForIntegrationTestWithAndroid, 32 android.PrepareForTestWithAndroidBuildComponents, 33 android.PrepareForTestWithAllowMissingDependencies, 34 filesystem.PrepareForTestWithFilesystemBuildComponents, 35 prepareForTestWithFsgenBuildComponents, 36 android.FixtureModifyConfig(func(config android.Config) { 37 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.BoardAvbEnable = true 38 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.PartitionQualifiedVariables = 39 map[string]android.PartitionQualifiedVariablesType{ 40 "system": { 41 BoardAvbKeyPath: "external/avb/test/data/testkey_rsa4096.pem", 42 BoardAvbAlgorithm: "SHA256_RSA4096", 43 BoardAvbRollbackIndex: "0", 44 BoardFileSystemType: "ext4", 45 }, 46 } 47 }), 48 android.FixtureMergeMockFs(android.MockFS{ 49 "external/avb/test/data/testkey_rsa4096.pem": nil, 50 "external/avb/test/Android.bp": []byte(` 51 filegroup { 52 name: "avb_testkey_rsa4096", 53 srcs: ["data/testkey_rsa4096.pem"], 54 } 55 `), 56 "build/soong/fsgen/Android.bp": []byte(` 57 soong_filesystem_creator { 58 name: "foo", 59 } 60 `), 61 }), 62 ).RunTest(t) 63 64 fooSystem := result.ModuleForTests("test_product_generated_system_image", "android_common").Module().(interface { 65 FsProps() filesystem.FilesystemProperties 66 }) 67 android.AssertBoolEquals( 68 t, 69 "Property expected to match the product variable 'BOARD_AVB_ENABLE'", 70 true, 71 proptools.Bool(fooSystem.FsProps().Use_avb), 72 ) 73 android.AssertStringEquals( 74 t, 75 "Property the avb_private_key property to be set to the existing filegroup", 76 ":avb_testkey_rsa4096", 77 proptools.String(fooSystem.FsProps().Avb_private_key), 78 ) 79 android.AssertStringEquals( 80 t, 81 "Property expected to match the product variable 'BOARD_AVB_ALGORITHM'", 82 "SHA256_RSA4096", 83 proptools.String(fooSystem.FsProps().Avb_algorithm), 84 ) 85 android.AssertIntEquals( 86 t, 87 "Property expected to match the product variable 'BOARD_AVB_SYSTEM_ROLLBACK_INDEX'", 88 0, 89 proptools.Int(fooSystem.FsProps().Rollback_index), 90 ) 91 android.AssertStringEquals( 92 t, 93 "Property expected to match the product variable 'BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE'", 94 "ext4", 95 proptools.String(fooSystem.FsProps().Type), 96 ) 97} 98 99func TestFileSystemCreatorSetPartitionDeps(t *testing.T) { 100 result := android.GroupFixturePreparers( 101 android.PrepareForIntegrationTestWithAndroid, 102 android.PrepareForTestWithAndroidBuildComponents, 103 android.PrepareForTestWithAllowMissingDependencies, 104 filesystem.PrepareForTestWithFilesystemBuildComponents, 105 prepareForTestWithFsgenBuildComponents, 106 java.PrepareForTestWithJavaBuildComponents, 107 java.PrepareForTestWithJavaDefaultModules, 108 android.FixtureModifyConfig(func(config android.Config) { 109 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"bar", "baz"} 110 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.PartitionQualifiedVariables = 111 map[string]android.PartitionQualifiedVariablesType{ 112 "system": { 113 BoardFileSystemType: "ext4", 114 }, 115 } 116 }), 117 android.FixtureMergeMockFs(android.MockFS{ 118 "external/avb/test/data/testkey_rsa4096.pem": nil, 119 "build/soong/fsgen/Android.bp": []byte(` 120 soong_filesystem_creator { 121 name: "foo", 122 } 123 `), 124 }), 125 ).RunTestWithBp(t, ` 126 java_library { 127 name: "bar", 128 srcs: ["A.java"], 129 } 130 java_library { 131 name: "baz", 132 srcs: ["A.java"], 133 product_specific: true, 134 } 135 `) 136 137 android.AssertBoolEquals( 138 t, 139 "Generated system image expected to depend on system partition installed \"bar\"", 140 true, 141 java.CheckModuleHasDependency(t, result.TestContext, "test_product_generated_system_image", "android_common", "bar"), 142 ) 143 android.AssertBoolEquals( 144 t, 145 "Generated system image expected to not depend on product partition installed \"baz\"", 146 false, 147 java.CheckModuleHasDependency(t, result.TestContext, "test_product_generated_system_image", "android_common", "baz"), 148 ) 149} 150 151func TestFileSystemCreatorDepsWithNamespace(t *testing.T) { 152 result := android.GroupFixturePreparers( 153 android.PrepareForIntegrationTestWithAndroid, 154 android.PrepareForTestWithAndroidBuildComponents, 155 android.PrepareForTestWithAllowMissingDependencies, 156 android.PrepareForTestWithNamespace, 157 android.PrepareForTestWithArchMutator, 158 filesystem.PrepareForTestWithFilesystemBuildComponents, 159 prepareForTestWithFsgenBuildComponents, 160 java.PrepareForTestWithJavaBuildComponents, 161 java.PrepareForTestWithJavaDefaultModules, 162 android.FixtureModifyConfig(func(config android.Config) { 163 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"bar"} 164 config.TestProductVariables.NamespacesToExport = []string{"a/b"} 165 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.PartitionQualifiedVariables = 166 map[string]android.PartitionQualifiedVariablesType{ 167 "system": { 168 BoardFileSystemType: "ext4", 169 }, 170 } 171 }), 172 android.PrepareForNativeBridgeEnabled, 173 android.FixtureMergeMockFs(android.MockFS{ 174 "external/avb/test/data/testkey_rsa4096.pem": nil, 175 "build/soong/fsgen/Android.bp": []byte(` 176 soong_filesystem_creator { 177 name: "foo", 178 } 179 `), 180 "a/b/Android.bp": []byte(` 181 soong_namespace{ 182 } 183 java_library { 184 name: "bar", 185 srcs: ["A.java"], 186 compile_multilib: "64", 187 } 188 `), 189 "c/d/Android.bp": []byte(` 190 soong_namespace{ 191 } 192 java_library { 193 name: "bar", 194 srcs: ["A.java"], 195 } 196 `), 197 }), 198 ).RunTest(t) 199 200 var packagingProps android.PackagingProperties 201 for _, prop := range result.ModuleForTests("test_product_generated_system_image", "android_common").Module().GetProperties() { 202 if packagingPropStruct, ok := prop.(*android.PackagingProperties); ok { 203 packagingProps = *packagingPropStruct 204 } 205 } 206 moduleDeps := packagingProps.Multilib.Lib64.Deps 207 208 eval := result.ModuleForTests("test_product_generated_system_image", "android_common").Module().ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) 209 android.AssertStringListContains( 210 t, 211 "Generated system image expected to depend on \"bar\" defined in \"a/b\" namespace", 212 moduleDeps.GetOrDefault(eval, nil), 213 "//a/b:bar", 214 ) 215 android.AssertStringListDoesNotContain( 216 t, 217 "Generated system image expected to not depend on \"bar\" defined in \"c/d\" namespace", 218 moduleDeps.GetOrDefault(eval, nil), 219 "//c/d:bar", 220 ) 221} 222 223func TestRemoveOverriddenModulesFromDeps(t *testing.T) { 224 result := android.GroupFixturePreparers( 225 android.PrepareForIntegrationTestWithAndroid, 226 android.PrepareForTestWithAndroidBuildComponents, 227 android.PrepareForTestWithAllowMissingDependencies, 228 prepareForTestWithFsgenBuildComponents, 229 java.PrepareForTestWithJavaBuildComponents, 230 android.FixtureMergeMockFs(android.MockFS{ 231 "external/avb/test/data/testkey_rsa4096.pem": nil, 232 "build/soong/fsgen/Android.bp": []byte(` 233 soong_filesystem_creator { 234 name: "foo", 235 } 236 `), 237 }), 238 android.FixtureModifyConfig(func(config android.Config) { 239 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"libfoo", "libbar"} 240 }), 241 ).RunTestWithBp(t, ` 242java_library { 243 name: "libfoo", 244} 245java_library { 246 name: "libbar", 247 required: ["libbaz"], 248} 249java_library { 250 name: "libbaz", 251 overrides: ["libfoo"], // overrides libfoo 252} 253 `) 254 resolvedSystemDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system"] 255 _, libFooInDeps := (*resolvedSystemDeps)["libfoo"] 256 android.AssertBoolEquals(t, "libfoo should not appear in deps because it has been overridden by libbaz. The latter is a required dep of libbar, which is listed in PRODUCT_PACKAGES", false, libFooInDeps) 257} 258 259func TestPrebuiltEtcModuleGen(t *testing.T) { 260 result := android.GroupFixturePreparers( 261 android.PrepareForIntegrationTestWithAndroid, 262 android.PrepareForTestWithAndroidBuildComponents, 263 android.PrepareForTestWithAllowMissingDependencies, 264 filesystem.PrepareForTestWithFilesystemBuildComponents, 265 prepareForTestWithFsgenBuildComponents, 266 android.FixtureModifyConfig(func(config android.Config) { 267 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles = []string{ 268 "frameworks/base/config/preloaded-classes:system/etc/preloaded-classes", 269 "frameworks/base/data/keyboards/Vendor_0079_Product_0011.kl:system/usr/keylayout/subdir/Vendor_0079_Product_0011.kl", 270 "frameworks/base/data/keyboards/Vendor_0079_Product_18d4.kl:system/usr/keylayout/subdir/Vendor_0079_Product_18d4.kl", 271 "some/non/existing/file.txt:system/etc/file.txt", 272 "device/sample/etc/apns-full-conf.xml:product/etc/apns-conf.xml:google", 273 "device/sample/etc/apns-full-conf.xml:product/etc/apns-conf-2.xml", 274 } 275 config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.PartitionQualifiedVariables = 276 map[string]android.PartitionQualifiedVariablesType{ 277 "system": { 278 BoardFileSystemType: "ext4", 279 }, 280 } 281 }), 282 android.FixtureMergeMockFs(android.MockFS{ 283 "external/avb/test/data/testkey_rsa4096.pem": nil, 284 "build/soong/fsgen/Android.bp": []byte(` 285 soong_filesystem_creator { 286 name: "foo", 287 } 288 `), 289 "frameworks/base/config/preloaded-classes": nil, 290 "frameworks/base/data/keyboards/Vendor_0079_Product_0011.kl": nil, 291 "frameworks/base/data/keyboards/Vendor_0079_Product_18d4.kl": nil, 292 "device/sample/etc/apns-full-conf.xml": nil, 293 }), 294 ).RunTest(t) 295 296 checkModuleProp := func(m android.Module, matcher func(actual interface{}) bool) bool { 297 for _, prop := range m.GetProperties() { 298 299 if matcher(prop) { 300 return true 301 } 302 } 303 return false 304 } 305 306 // check generated prebuilt_* module type install path and install partition 307 generatedModule := result.ModuleForTests("system-frameworks_base_config-etc-0", "android_arm64_armv8-a").Module() 308 etcModule, _ := generatedModule.(*etc.PrebuiltEtc) 309 android.AssertStringEquals( 310 t, 311 "module expected to have etc install path", 312 "etc", 313 etcModule.BaseDir(), 314 ) 315 android.AssertBoolEquals( 316 t, 317 "module expected to be installed in system partition", 318 true, 319 !generatedModule.InstallInProduct() && 320 !generatedModule.InstallInVendor() && 321 !generatedModule.InstallInSystemExt(), 322 ) 323 324 // check generated prebuilt_* module specifies correct relative_install_path property 325 generatedModule = result.ModuleForTests("system-frameworks_base_data_keyboards-usr_keylayout_subdir-0", "android_arm64_armv8-a").Module() 326 etcModule, _ = generatedModule.(*etc.PrebuiltEtc) 327 android.AssertStringEquals( 328 t, 329 "module expected to set correct relative_install_path properties", 330 "subdir", 331 etcModule.SubDir(), 332 ) 333 334 // check that prebuilt_* module is not generated for non existing source file 335 android.AssertPanicMessageContains( 336 t, 337 "prebuilt_* module not generated for non existing source file", 338 "failed to find module \"system-some_non_existing-etc-0\"", 339 func() { result.ModuleForTests("system-some_non_existing-etc-0", "android_arm64_armv8-a") }, 340 ) 341 342 // check that duplicate src file can exist in PRODUCT_COPY_FILES and generates separate modules 343 generatedModule0 := result.ModuleForTests("product-device_sample_etc-etc-0", "android_arm64_armv8-a").Module() 344 generatedModule1 := result.ModuleForTests("product-device_sample_etc-etc-1", "android_arm64_armv8-a").Module() 345 346 // check that generated prebuilt_* module sets correct srcs and dsts property 347 eval := generatedModule0.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) 348 android.AssertBoolEquals( 349 t, 350 "module expected to set correct srcs and dsts properties", 351 true, 352 checkModuleProp(generatedModule0, func(actual interface{}) bool { 353 if p, ok := actual.(*etc.PrebuiltEtcProperties); ok { 354 srcs := p.Srcs.GetOrDefault(eval, nil) 355 dsts := p.Dsts.GetOrDefault(eval, nil) 356 return len(srcs) == 1 && 357 srcs[0] == "apns-full-conf.xml" && 358 len(dsts) == 1 && 359 dsts[0] == "apns-conf.xml" 360 } 361 return false 362 }), 363 ) 364 365 // check that generated prebuilt_* module sets correct srcs and dsts property 366 eval = generatedModule1.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) 367 android.AssertBoolEquals( 368 t, 369 "module expected to set correct srcs and dsts properties", 370 true, 371 checkModuleProp(generatedModule1, func(actual interface{}) bool { 372 if p, ok := actual.(*etc.PrebuiltEtcProperties); ok { 373 srcs := p.Srcs.GetOrDefault(eval, nil) 374 dsts := p.Dsts.GetOrDefault(eval, nil) 375 return len(srcs) == 1 && 376 srcs[0] == "apns-full-conf.xml" && 377 len(dsts) == 1 && 378 dsts[0] == "apns-conf-2.xml" 379 } 380 return false 381 }), 382 ) 383} 384