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 | } |
| 171 | config.Targets[android.Android] = []android.Target{ |
| 172 | {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: "", HostCross: false}, |
| 173 | {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: "", HostCross: false}, |
| 174 | {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86_64", NativeBridgeRelativePath: "arm64", HostCross: false}, |
| 175 | {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86", NativeBridgeRelativePath: "arm", HostCross: false}, |
| 176 | } |
| 177 | }), |
| 178 | android.FixtureMergeMockFs(android.MockFS{ |
| 179 | "external/avb/test/data/testkey_rsa4096.pem": nil, |
| 180 | "build/soong/fsgen/Android.bp": []byte(` |
| 181 | soong_filesystem_creator { |
| 182 | name: "foo", |
| 183 | } |
| 184 | `), |
| 185 | "a/b/Android.bp": []byte(` |
| 186 | soong_namespace{ |
| 187 | } |
| 188 | java_library { |
| 189 | name: "bar", |
| 190 | srcs: ["A.java"], |
| 191 | compile_multilib: "64", |
| 192 | } |
| 193 | `), |
| 194 | "c/d/Android.bp": []byte(` |
| 195 | soong_namespace{ |
| 196 | } |
| 197 | java_library { |
| 198 | name: "bar", |
| 199 | srcs: ["A.java"], |
| 200 | } |
| 201 | `), |
| 202 | }), |
| 203 | ).RunTest(t) |
| 204 | |
| 205 | var packagingProps android.PackagingProperties |
| 206 | for _, prop := range result.ModuleForTests("test_product_generated_system_image", "android_common").Module().GetProperties() { |
| 207 | if packagingPropStruct, ok := prop.(*android.PackagingProperties); ok { |
| 208 | packagingProps = *packagingPropStruct |
| 209 | } |
| 210 | } |
| 211 | moduleDeps := packagingProps.Multilib.Lib64.Deps |
| 212 | |
| 213 | eval := result.ModuleForTests("test_product_generated_system_image", "android_common").Module().ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) |
| 214 | android.AssertStringListContains( |
| 215 | t, |
| 216 | "Generated system image expected to depend on \"bar\" defined in \"a/b\" namespace", |
| 217 | moduleDeps.GetOrDefault(eval, nil), |
| 218 | "//a/b:bar", |
| 219 | ) |
| 220 | android.AssertStringListDoesNotContain( |
| 221 | t, |
| 222 | "Generated system image expected to not depend on \"bar\" defined in \"c/d\" namespace", |
| 223 | moduleDeps.GetOrDefault(eval, nil), |
| 224 | "//c/d:bar", |
| 225 | ) |
| 226 | } |
Spandan Das | e1860e4 | 2024-10-24 22:29:50 +0000 | [diff] [blame] | 227 | |
| 228 | func TestRemoveOverriddenModulesFromDeps(t *testing.T) { |
| 229 | result := android.GroupFixturePreparers( |
| 230 | android.PrepareForIntegrationTestWithAndroid, |
| 231 | android.PrepareForTestWithAndroidBuildComponents, |
| 232 | android.PrepareForTestWithAllowMissingDependencies, |
| 233 | prepareForTestWithFsgenBuildComponents, |
| 234 | java.PrepareForTestWithJavaBuildComponents, |
| 235 | android.FixtureMergeMockFs(android.MockFS{ |
| 236 | "external/avb/test/data/testkey_rsa4096.pem": nil, |
| 237 | "build/soong/fsgen/Android.bp": []byte(` |
| 238 | soong_filesystem_creator { |
| 239 | name: "foo", |
| 240 | } |
| 241 | `), |
| 242 | }), |
| 243 | android.FixtureModifyConfig(func(config android.Config) { |
| 244 | config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"libfoo", "libbar"} |
| 245 | }), |
| 246 | ).RunTestWithBp(t, ` |
| 247 | java_library { |
| 248 | name: "libfoo", |
| 249 | } |
| 250 | java_library { |
| 251 | name: "libbar", |
| 252 | required: ["libbaz"], |
| 253 | } |
| 254 | java_library { |
| 255 | name: "libbaz", |
| 256 | overrides: ["libfoo"], // overrides libfoo |
| 257 | } |
| 258 | `) |
| 259 | resolvedSystemDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system"] |
| 260 | _, libFooInDeps := (*resolvedSystemDeps)["libfoo"] |
| 261 | 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) |
| 262 | } |
Jihoon Kang | 69725b3 | 2024-11-12 03:08:49 +0000 | [diff] [blame] | 263 | |
| 264 | func TestPrebuiltEtcModuleGen(t *testing.T) { |
| 265 | result := android.GroupFixturePreparers( |
| 266 | android.PrepareForIntegrationTestWithAndroid, |
| 267 | android.PrepareForTestWithAndroidBuildComponents, |
| 268 | android.PrepareForTestWithAllowMissingDependencies, |
| 269 | filesystem.PrepareForTestWithFilesystemBuildComponents, |
| 270 | prepareForTestWithFsgenBuildComponents, |
| 271 | android.FixtureModifyConfig(func(config android.Config) { |
| 272 | config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles = []string{ |
| 273 | "frameworks/base/config/preloaded-classes:system/etc/preloaded-classes", |
| 274 | "frameworks/base/data/keyboards/Vendor_0079_Product_0011.kl:system/usr/keylayout/subdir/Vendor_0079_Product_0011.kl", |
| 275 | "frameworks/base/data/keyboards/Vendor_0079_Product_18d4.kl:system/usr/keylayout/subdir/Vendor_0079_Product_18d4.kl", |
| 276 | "some/non/existing/file.txt:system/etc/file.txt", |
| 277 | "device/sample/etc/apns-full-conf.xml:product/etc/apns-conf.xml:google", |
| 278 | "device/sample/etc/apns-full-conf.xml:product/etc/apns-conf-2.xml", |
| 279 | } |
| 280 | config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.PartitionQualifiedVariables = |
| 281 | map[string]android.PartitionQualifiedVariablesType{ |
| 282 | "system": { |
| 283 | BoardFileSystemType: "ext4", |
| 284 | }, |
| 285 | } |
| 286 | }), |
| 287 | android.FixtureMergeMockFs(android.MockFS{ |
| 288 | "external/avb/test/data/testkey_rsa4096.pem": nil, |
| 289 | "build/soong/fsgen/Android.bp": []byte(` |
| 290 | soong_filesystem_creator { |
| 291 | name: "foo", |
| 292 | } |
| 293 | `), |
| 294 | "frameworks/base/config/preloaded-classes": nil, |
| 295 | "frameworks/base/data/keyboards/Vendor_0079_Product_0011.kl": nil, |
| 296 | "frameworks/base/data/keyboards/Vendor_0079_Product_18d4.kl": nil, |
| 297 | "device/sample/etc/apns-full-conf.xml": nil, |
| 298 | }), |
| 299 | ).RunTest(t) |
| 300 | |
| 301 | checkModuleProp := func(m android.Module, matcher func(actual interface{}) bool) bool { |
| 302 | for _, prop := range m.GetProperties() { |
| 303 | |
| 304 | if matcher(prop) { |
| 305 | return true |
| 306 | } |
| 307 | } |
| 308 | return false |
| 309 | } |
| 310 | |
| 311 | // check generated prebuilt_* module type install path and install partition |
| 312 | generatedModule := result.ModuleForTests("system-frameworks_base_config-etc-0", "android_arm64_armv8-a").Module() |
| 313 | etcModule, _ := generatedModule.(*etc.PrebuiltEtc) |
| 314 | android.AssertStringEquals( |
| 315 | t, |
| 316 | "module expected to have etc install path", |
| 317 | "etc", |
| 318 | etcModule.BaseDir(), |
| 319 | ) |
| 320 | android.AssertBoolEquals( |
| 321 | t, |
| 322 | "module expected to be installed in system partition", |
| 323 | true, |
| 324 | !generatedModule.InstallInProduct() && |
| 325 | !generatedModule.InstallInVendor() && |
| 326 | !generatedModule.InstallInSystemExt(), |
| 327 | ) |
| 328 | |
| 329 | // check generated prebuilt_* module specifies correct relative_install_path property |
| 330 | generatedModule = result.ModuleForTests("system-frameworks_base_data_keyboards-usr_keylayout_subdir-0", "android_arm64_armv8-a").Module() |
| 331 | etcModule, _ = generatedModule.(*etc.PrebuiltEtc) |
| 332 | android.AssertStringEquals( |
| 333 | t, |
| 334 | "module expected to set correct relative_install_path properties", |
| 335 | "subdir", |
| 336 | etcModule.SubDir(), |
| 337 | ) |
| 338 | |
| 339 | // check that prebuilt_* module is not generated for non existing source file |
| 340 | android.AssertPanicMessageContains( |
| 341 | t, |
| 342 | "prebuilt_* module not generated for non existing source file", |
| 343 | "failed to find module \"system-some_non_existing-etc-0\"", |
| 344 | func() { result.ModuleForTests("system-some_non_existing-etc-0", "android_arm64_armv8-a") }, |
| 345 | ) |
| 346 | |
| 347 | // check that duplicate src file can exist in PRODUCT_COPY_FILES and generates separate modules |
| 348 | generatedModule0 := result.ModuleForTests("product-device_sample_etc-etc-0", "android_arm64_armv8-a").Module() |
| 349 | generatedModule1 := result.ModuleForTests("product-device_sample_etc-etc-1", "android_arm64_armv8-a").Module() |
| 350 | |
| 351 | // check that generated prebuilt_* module sets correct srcs and dsts property |
| 352 | eval := generatedModule0.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) |
| 353 | android.AssertBoolEquals( |
| 354 | t, |
| 355 | "module expected to set correct srcs and dsts properties", |
| 356 | true, |
| 357 | checkModuleProp(generatedModule0, func(actual interface{}) bool { |
| 358 | if p, ok := actual.(*etc.PrebuiltEtcProperties); ok { |
| 359 | srcs := p.Srcs.GetOrDefault(eval, nil) |
| 360 | dsts := p.Dsts.GetOrDefault(eval, nil) |
| 361 | return len(srcs) == 1 && |
| 362 | srcs[0] == "apns-full-conf.xml" && |
| 363 | len(dsts) == 1 && |
| 364 | dsts[0] == "apns-conf.xml" |
| 365 | } |
| 366 | return false |
| 367 | }), |
| 368 | ) |
| 369 | |
| 370 | // check that generated prebuilt_* module sets correct srcs and dsts property |
| 371 | eval = generatedModule1.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) |
| 372 | android.AssertBoolEquals( |
| 373 | t, |
| 374 | "module expected to set correct srcs and dsts properties", |
| 375 | true, |
| 376 | checkModuleProp(generatedModule1, func(actual interface{}) bool { |
| 377 | if p, ok := actual.(*etc.PrebuiltEtcProperties); ok { |
| 378 | srcs := p.Srcs.GetOrDefault(eval, nil) |
| 379 | dsts := p.Dsts.GetOrDefault(eval, nil) |
| 380 | return len(srcs) == 1 && |
| 381 | srcs[0] == "apns-full-conf.xml" && |
| 382 | len(dsts) == 1 && |
| 383 | dsts[0] == "apns-conf-2.xml" |
| 384 | } |
| 385 | return false |
| 386 | }), |
| 387 | ) |
| 388 | } |