Jihoon Kang | 98047cf | 2024-10-02 17:13:54 +0000 | [diff] [blame] | 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 | |
| 15 | package fsgen |
| 16 | |
| 17 | import ( |
| 18 | "android/soong/android" |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 19 | "android/soong/etc" |
Jihoon Kang | 98047cf | 2024-10-02 17:13:54 +0000 | [diff] [blame] | 20 | "android/soong/filesystem" |
Jihoon Kang | 0d545b8 | 2024-10-11 00:21:57 +0000 | [diff] [blame] | 21 | "android/soong/java" |
Jihoon Kang | 98047cf | 2024-10-02 17:13:54 +0000 | [diff] [blame] | 22 | "testing" |
| 23 | |
| 24 | "github.com/google/blueprint/proptools" |
| 25 | ) |
| 26 | |
| 27 | var prepareForTestWithFsgenBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents) |
| 28 | |
| 29 | func TestFileSystemCreatorSystemImageProps(t *testing.T) { |
| 30 | result := android.GroupFixturePreparers( |
| 31 | android.PrepareForIntegrationTestWithAndroid, |
| 32 | android.PrepareForTestWithAndroidBuildComponents, |
Jihoon Kang | 0d545b8 | 2024-10-11 00:21:57 +0000 | [diff] [blame] | 33 | android.PrepareForTestWithAllowMissingDependencies, |
Jihoon Kang | 98047cf | 2024-10-02 17:13:54 +0000 | [diff] [blame] | 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, |
Cole Faust | 953476f | 2024-11-14 14:11:29 -0800 | [diff] [blame] | 50 | "external/avb/test/Android.bp": []byte(` |
| 51 | filegroup { |
| 52 | name: "avb_testkey_rsa4096", |
| 53 | srcs: ["data/testkey_rsa4096.pem"], |
| 54 | } |
| 55 | `), |
Cole Faust | 92ccbe2 | 2024-10-03 14:38:37 -0700 | [diff] [blame] | 56 | "build/soong/fsgen/Android.bp": []byte(` |
| 57 | soong_filesystem_creator { |
| 58 | name: "foo", |
| 59 | } |
| 60 | `), |
Jihoon Kang | 98047cf | 2024-10-02 17:13:54 +0000 | [diff] [blame] | 61 | }), |
Cole Faust | 92ccbe2 | 2024-10-03 14:38:37 -0700 | [diff] [blame] | 62 | ).RunTest(t) |
Jihoon Kang | 98047cf | 2024-10-02 17:13:54 +0000 | [diff] [blame] | 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, |
Cole Faust | 953476f | 2024-11-14 14:11:29 -0800 | [diff] [blame] | 75 | "Property the avb_private_key property to be set to the existing filegroup", |
| 76 | ":avb_testkey_rsa4096", |
Jihoon Kang | 98047cf | 2024-10-02 17:13:54 +0000 | [diff] [blame] | 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 | } |
Jihoon Kang | 0d545b8 | 2024-10-11 00:21:57 +0000 | [diff] [blame] | 98 | |
| 99 | func 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 | |
| 151 | func 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 | } |
Jihoon Kang | 0d545b8 | 2024-10-11 00:21:57 +0000 | [diff] [blame] | 171 | }), |
Spandan Das | 45e4001 | 2024-12-02 22:45:48 +0000 | [diff] [blame] | 172 | android.PrepareForNativeBridgeEnabled, |
Jihoon Kang | 0d545b8 | 2024-10-11 00:21:57 +0000 | [diff] [blame] | 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 | } |
Spandan Das | e1860e4 | 2024-10-24 22:29:50 +0000 | [diff] [blame] | 222 | |
| 223 | func 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, ` |
| 242 | java_library { |
| 243 | name: "libfoo", |
| 244 | } |
| 245 | java_library { |
| 246 | name: "libbar", |
| 247 | required: ["libbaz"], |
| 248 | } |
| 249 | java_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 | } |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 258 | |
| 259 | func 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", |
Jihoon Kang | 3e14966 | 2025-03-12 22:14:39 +0000 | [diff] [blame] | 274 | "device/sample/etc/apns-full-conf.xml:system/foo/file.txt", |
| 275 | "device/sample/etc/apns-full-conf.xml:system/foo/apns-full-conf.xml", |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 276 | } |
| 277 | config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.PartitionQualifiedVariables = |
| 278 | map[string]android.PartitionQualifiedVariablesType{ |
| 279 | "system": { |
| 280 | BoardFileSystemType: "ext4", |
| 281 | }, |
| 282 | } |
| 283 | }), |
| 284 | android.FixtureMergeMockFs(android.MockFS{ |
| 285 | "external/avb/test/data/testkey_rsa4096.pem": nil, |
| 286 | "build/soong/fsgen/Android.bp": []byte(` |
| 287 | soong_filesystem_creator { |
| 288 | name: "foo", |
| 289 | } |
| 290 | `), |
| 291 | "frameworks/base/config/preloaded-classes": nil, |
| 292 | "frameworks/base/data/keyboards/Vendor_0079_Product_0011.kl": nil, |
| 293 | "frameworks/base/data/keyboards/Vendor_0079_Product_18d4.kl": nil, |
| 294 | "device/sample/etc/apns-full-conf.xml": nil, |
| 295 | }), |
| 296 | ).RunTest(t) |
| 297 | |
| 298 | checkModuleProp := func(m android.Module, matcher func(actual interface{}) bool) bool { |
| 299 | for _, prop := range m.GetProperties() { |
| 300 | |
| 301 | if matcher(prop) { |
| 302 | return true |
| 303 | } |
| 304 | } |
| 305 | return false |
| 306 | } |
| 307 | |
| 308 | // check generated prebuilt_* module type install path and install partition |
| 309 | generatedModule := result.ModuleForTests("system-frameworks_base_config-etc-0", "android_arm64_armv8-a").Module() |
| 310 | etcModule, _ := generatedModule.(*etc.PrebuiltEtc) |
| 311 | android.AssertStringEquals( |
| 312 | t, |
| 313 | "module expected to have etc install path", |
| 314 | "etc", |
| 315 | etcModule.BaseDir(), |
| 316 | ) |
| 317 | android.AssertBoolEquals( |
| 318 | t, |
| 319 | "module expected to be installed in system partition", |
| 320 | true, |
| 321 | !generatedModule.InstallInProduct() && |
| 322 | !generatedModule.InstallInVendor() && |
| 323 | !generatedModule.InstallInSystemExt(), |
| 324 | ) |
| 325 | |
| 326 | // check generated prebuilt_* module specifies correct relative_install_path property |
| 327 | generatedModule = result.ModuleForTests("system-frameworks_base_data_keyboards-usr_keylayout_subdir-0", "android_arm64_armv8-a").Module() |
| 328 | etcModule, _ = generatedModule.(*etc.PrebuiltEtc) |
| 329 | android.AssertStringEquals( |
| 330 | t, |
| 331 | "module expected to set correct relative_install_path properties", |
| 332 | "subdir", |
| 333 | etcModule.SubDir(), |
| 334 | ) |
| 335 | |
| 336 | // check that prebuilt_* module is not generated for non existing source file |
| 337 | android.AssertPanicMessageContains( |
| 338 | t, |
| 339 | "prebuilt_* module not generated for non existing source file", |
| 340 | "failed to find module \"system-some_non_existing-etc-0\"", |
| 341 | func() { result.ModuleForTests("system-some_non_existing-etc-0", "android_arm64_armv8-a") }, |
| 342 | ) |
| 343 | |
| 344 | // check that duplicate src file can exist in PRODUCT_COPY_FILES and generates separate modules |
| 345 | generatedModule0 := result.ModuleForTests("product-device_sample_etc-etc-0", "android_arm64_armv8-a").Module() |
| 346 | generatedModule1 := result.ModuleForTests("product-device_sample_etc-etc-1", "android_arm64_armv8-a").Module() |
| 347 | |
| 348 | // check that generated prebuilt_* module sets correct srcs and dsts property |
| 349 | eval := generatedModule0.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) |
| 350 | android.AssertBoolEquals( |
| 351 | t, |
Jihoon Kang | 723f122 | 2025-03-12 22:24:52 +0000 | [diff] [blame^] | 352 | "module expected to set correct srcs property", |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 353 | true, |
| 354 | checkModuleProp(generatedModule0, func(actual interface{}) bool { |
| 355 | if p, ok := actual.(*etc.PrebuiltEtcProperties); ok { |
| 356 | srcs := p.Srcs.GetOrDefault(eval, nil) |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 357 | return len(srcs) == 1 && |
Jihoon Kang | 723f122 | 2025-03-12 22:24:52 +0000 | [diff] [blame^] | 358 | srcs[0] == "apns-full-conf.xml" |
| 359 | } |
| 360 | return false |
| 361 | }), |
| 362 | ) |
| 363 | android.AssertBoolEquals( |
| 364 | t, |
| 365 | "module expected to set correct dsts property", |
| 366 | true, |
| 367 | checkModuleProp(generatedModule0, func(actual interface{}) bool { |
| 368 | if p, ok := actual.(*etc.PrebuiltDstsProperties); ok { |
| 369 | dsts := p.Dsts.GetOrDefault(eval, nil) |
| 370 | return len(dsts) == 1 && |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 371 | dsts[0] == "apns-conf.xml" |
| 372 | } |
| 373 | return false |
| 374 | }), |
| 375 | ) |
| 376 | |
| 377 | // check that generated prebuilt_* module sets correct srcs and dsts property |
| 378 | eval = generatedModule1.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) |
| 379 | android.AssertBoolEquals( |
| 380 | t, |
Jihoon Kang | 723f122 | 2025-03-12 22:24:52 +0000 | [diff] [blame^] | 381 | "module expected to set correct srcs property", |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 382 | true, |
| 383 | checkModuleProp(generatedModule1, func(actual interface{}) bool { |
| 384 | if p, ok := actual.(*etc.PrebuiltEtcProperties); ok { |
| 385 | srcs := p.Srcs.GetOrDefault(eval, nil) |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 386 | return len(srcs) == 1 && |
Jihoon Kang | 723f122 | 2025-03-12 22:24:52 +0000 | [diff] [blame^] | 387 | srcs[0] == "apns-full-conf.xml" |
| 388 | } |
| 389 | return false |
| 390 | }), |
| 391 | ) |
| 392 | android.AssertBoolEquals( |
| 393 | t, |
| 394 | "module expected to set correct dsts property", |
| 395 | true, |
| 396 | checkModuleProp(generatedModule1, func(actual interface{}) bool { |
| 397 | if p, ok := actual.(*etc.PrebuiltDstsProperties); ok { |
| 398 | dsts := p.Dsts.GetOrDefault(eval, nil) |
| 399 | return len(dsts) == 1 && |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 400 | dsts[0] == "apns-conf-2.xml" |
| 401 | } |
| 402 | return false |
| 403 | }), |
| 404 | ) |
| 405 | } |