blob: 3ce5d4e88f13a275342b80126f1cc6272146c0ee [file] [log] [blame]
Jooyung Han9706cbc2021-04-15 22:43:48 +09001// Copyright 2021 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 filesystem
16
17import (
18 "os"
Cole Faust4a2a7c92024-03-12 12:44:40 -070019 "path/filepath"
Jooyung Han9706cbc2021-04-15 22:43:48 +090020 "testing"
21
22 "android/soong/android"
Jiyong Park06c4cdc2024-02-16 15:35:03 +090023 "android/soong/bpf"
Jiyong Parkfa616132021-04-20 11:36:40 +090024 "android/soong/cc"
Jooyung Hane6067592023-03-16 13:11:17 +090025 "android/soong/etc"
Jiyong Park73e5bab2024-04-05 13:37:21 +090026 "android/soong/java"
Jiyong Park9c540c82024-03-26 10:48:27 +090027 "android/soong/phony"
Jooyung Hane6067592023-03-16 13:11:17 +090028
29 "github.com/google/blueprint/proptools"
Jooyung Han9706cbc2021-04-15 22:43:48 +090030)
31
32func TestMain(m *testing.M) {
33 os.Exit(m.Run())
34}
35
36var fixture = android.GroupFixturePreparers(
37 android.PrepareForIntegrationTestWithAndroid,
Jiyong Park73e5bab2024-04-05 13:37:21 +090038 android.PrepareForTestWithAndroidBuildComponents,
Jiyong Park06c4cdc2024-02-16 15:35:03 +090039 bpf.PrepareForTestWithBpf,
Jiyong Parkfa616132021-04-20 11:36:40 +090040 cc.PrepareForIntegrationTestWithCc,
Jiyong Park73e5bab2024-04-05 13:37:21 +090041 etc.PrepareForTestWithPrebuiltEtc,
42 java.PrepareForTestWithJavaBuildComponents,
43 java.PrepareForTestWithJavaDefaultModules,
Jiyong Park9c540c82024-03-26 10:48:27 +090044 phony.PrepareForTestWithPhony,
Jooyung Han9706cbc2021-04-15 22:43:48 +090045 PrepareForTestWithFilesystemBuildComponents,
46)
47
48func TestFileSystemDeps(t *testing.T) {
49 result := fixture.RunTestWithBp(t, `
50 android_filesystem {
51 name: "myfilesystem",
Jiyong Park06c4cdc2024-02-16 15:35:03 +090052 multilib: {
53 common: {
54 deps: [
55 "bpf.o",
Jiyong Park9c540c82024-03-26 10:48:27 +090056 "phony",
Jiyong Park06c4cdc2024-02-16 15:35:03 +090057 ],
58 },
Jiyong Parkeec7c382024-02-16 16:10:13 +090059 lib32: {
60 deps: [
61 "foo",
62 "libbar",
63 ],
64 },
65 lib64: {
66 deps: [
67 "libbar",
68 ],
69 },
Jiyong Park06c4cdc2024-02-16 15:35:03 +090070 },
Jiyong Parkeec7c382024-02-16 16:10:13 +090071 compile_multilib: "both",
Jiyong Park06c4cdc2024-02-16 15:35:03 +090072 }
73
74 bpf {
75 name: "bpf.o",
76 srcs: ["bpf.c"],
Jooyung Han9706cbc2021-04-15 22:43:48 +090077 }
Jiyong Parkeec7c382024-02-16 16:10:13 +090078
79 cc_binary {
80 name: "foo",
81 compile_multilib: "prefer32",
82 }
83
84 cc_library {
85 name: "libbar",
Jiyong Park8bcf3c62024-03-18 18:37:10 +090086 required: ["libbaz"],
87 }
88
89 cc_library {
90 name: "libbaz",
Jiyong Parkeec7c382024-02-16 16:10:13 +090091 }
Jiyong Park9c540c82024-03-26 10:48:27 +090092
93 phony {
94 name: "phony",
Jiyong Park73e5bab2024-04-05 13:37:21 +090095 required: [
96 "libquz",
97 "myapp",
98 ],
Jiyong Park9c540c82024-03-26 10:48:27 +090099 }
100
101 cc_library {
102 name: "libquz",
103 }
Jiyong Park73e5bab2024-04-05 13:37:21 +0900104
105 android_app {
106 name: "myapp",
107 platform_apis: true,
108 installable: true,
109 }
Jooyung Han9706cbc2021-04-15 22:43:48 +0900110 `)
111
112 // produces "myfilesystem.img"
113 result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
Jiyong Park06c4cdc2024-02-16 15:35:03 +0900114
115 fs := result.ModuleForTests("myfilesystem", "android_common").Module().(*filesystem)
Jiyong Parkeec7c382024-02-16 16:10:13 +0900116 expected := []string{
Jiyong Park73e5bab2024-04-05 13:37:21 +0900117 "app/myapp/myapp.apk",
Jiyong Parkeec7c382024-02-16 16:10:13 +0900118 "bin/foo",
119 "lib/libbar.so",
120 "lib64/libbar.so",
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900121 "lib64/libbaz.so",
Jiyong Park9c540c82024-03-26 10:48:27 +0900122 "lib64/libquz.so",
Jiyong Parkeec7c382024-02-16 16:10:13 +0900123 "etc/bpf/bpf.o",
124 }
Jiyong Park06c4cdc2024-02-16 15:35:03 +0900125 for _, e := range expected {
126 android.AssertStringListContains(t, "missing entry", fs.entries, e)
127 }
Jooyung Han9706cbc2021-04-15 22:43:48 +0900128}
Jiyong Parkfa616132021-04-20 11:36:40 +0900129
Cole Faust4a2a7c92024-03-12 12:44:40 -0700130func TestIncludeMakeBuiltFiles(t *testing.T) {
131 result := fixture.RunTestWithBp(t, `
132 android_filesystem {
133 name: "myfilesystem",
134 include_make_built_files: "system",
135 }
136 `)
137
138 output := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
139
140 stampFile := filepath.Join(result.Config.OutDir(), "target/product/test_device/obj/PACKAGING/system_intermediates/staging_dir.stamp")
141 fileListFile := filepath.Join(result.Config.OutDir(), "target/product/test_device/obj/PACKAGING/system_intermediates/file_list.txt")
142 android.AssertStringListContains(t, "deps of filesystem must include the staging dir stamp file", output.Implicits.Strings(), stampFile)
143 android.AssertStringListContains(t, "deps of filesystem must include the staging dir file list", output.Implicits.Strings(), fileListFile)
144}
145
Jiyong Parkfa616132021-04-20 11:36:40 +0900146func TestFileSystemFillsLinkerConfigWithStubLibs(t *testing.T) {
147 result := fixture.RunTestWithBp(t, `
Jooyung Han0fbbc2b2022-03-25 12:35:46 +0900148 android_system_image {
Jiyong Parkfa616132021-04-20 11:36:40 +0900149 name: "myfilesystem",
150 deps: [
151 "libfoo",
Jooyung Han0fbbc2b2022-03-25 12:35:46 +0900152 "libbar",
Jiyong Parkfa616132021-04-20 11:36:40 +0900153 ],
154 linker_config_src: "linker.config.json",
155 }
156
157 cc_library {
158 name: "libfoo",
159 stubs: {
160 symbol_file: "libfoo.map.txt",
161 },
162 }
163
164 cc_library {
165 name: "libbar",
166 }
167 `)
168
169 module := result.ModuleForTests("myfilesystem", "android_common")
170 output := module.Output("system/etc/linker.config.pb")
171
172 android.AssertStringDoesContain(t, "linker.config.pb should have libfoo",
173 output.RuleParams.Command, "libfoo.so")
174 android.AssertStringDoesNotContain(t, "linker.config.pb should not have libbar",
175 output.RuleParams.Command, "libbar.so")
176}
Jooyung Han0fbbc2b2022-03-25 12:35:46 +0900177
178func registerComponent(ctx android.RegistrationContext) {
179 ctx.RegisterModuleType("component", componentFactory)
180}
181
182func componentFactory() android.Module {
183 m := &component{}
184 m.AddProperties(&m.properties)
185 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
186 return m
187}
188
189type component struct {
190 android.ModuleBase
191 properties struct {
192 Install_copy_in_data []string
193 }
194}
195
196func (c *component) GenerateAndroidBuildActions(ctx android.ModuleContext) {
197 output := android.PathForModuleOut(ctx, c.Name())
198 dir := android.PathForModuleInstall(ctx, "components")
199 ctx.InstallFile(dir, c.Name(), output)
200
201 dataDir := android.PathForModuleInPartitionInstall(ctx, "data", "components")
202 for _, d := range c.properties.Install_copy_in_data {
203 ctx.InstallFile(dataDir, d, output)
204 }
205}
206
207func TestFileSystemGathersItemsOnlyInSystemPartition(t *testing.T) {
208 f := android.GroupFixturePreparers(fixture, android.FixtureRegisterWithContext(registerComponent))
209 result := f.RunTestWithBp(t, `
210 android_system_image {
211 name: "myfilesystem",
212 multilib: {
213 common: {
214 deps: ["foo"],
215 },
216 },
217 linker_config_src: "linker.config.json",
218 }
219 component {
220 name: "foo",
221 install_copy_in_data: ["bar"],
222 }
223 `)
224
225 module := result.ModuleForTests("myfilesystem", "android_common").Module().(*systemImage)
226 android.AssertDeepEquals(t, "entries should have foo only", []string{"components/foo"}, module.entries)
227}
Jiyong Parkbc485482022-11-15 22:31:49 +0900228
Alice Wang000e3a32023-01-03 16:11:20 +0000229func TestAvbGenVbmetaImage(t *testing.T) {
230 result := fixture.RunTestWithBp(t, `
231 avb_gen_vbmeta_image {
232 name: "input_hashdesc",
233 src: "input.img",
234 partition_name: "input_partition_name",
235 salt: "2222",
236 }`)
237 cmd := result.ModuleForTests("input_hashdesc", "android_arm64_armv8-a").Rule("avbGenVbmetaImage").RuleParams.Command
238 android.AssertStringDoesContain(t, "Can't find correct --partition_name argument",
239 cmd, "--partition_name input_partition_name")
240 android.AssertStringDoesContain(t, "Can't find --do_not_append_vbmeta_image",
241 cmd, "--do_not_append_vbmeta_image")
242 android.AssertStringDoesContain(t, "Can't find --output_vbmeta_image",
243 cmd, "--output_vbmeta_image ")
244 android.AssertStringDoesContain(t, "Can't find --salt argument",
245 cmd, "--salt 2222")
246}
247
Jiyong Parkbc485482022-11-15 22:31:49 +0900248func TestAvbAddHashFooter(t *testing.T) {
249 result := fixture.RunTestWithBp(t, `
Alice Wang000e3a32023-01-03 16:11:20 +0000250 avb_gen_vbmeta_image {
251 name: "input_hashdesc",
252 src: "input.img",
253 partition_name: "input",
254 salt: "2222",
255 }
256
Jiyong Parkbc485482022-11-15 22:31:49 +0900257 avb_add_hash_footer {
258 name: "myfooter",
259 src: "input.img",
260 filename: "output.img",
261 partition_name: "mypartition",
262 private_key: "mykey",
263 salt: "1111",
264 props: [
265 {
266 name: "prop1",
267 value: "value1",
268 },
269 {
270 name: "prop2",
271 file: "value_file",
272 },
273 ],
Alice Wang000e3a32023-01-03 16:11:20 +0000274 include_descriptors_from_images: ["input_hashdesc"],
Jiyong Parkbc485482022-11-15 22:31:49 +0900275 }
276 `)
277 cmd := result.ModuleForTests("myfooter", "android_arm64_armv8-a").Rule("avbAddHashFooter").RuleParams.Command
278 android.AssertStringDoesContain(t, "Can't find correct --partition_name argument",
279 cmd, "--partition_name mypartition")
280 android.AssertStringDoesContain(t, "Can't find correct --key argument",
281 cmd, "--key mykey")
282 android.AssertStringDoesContain(t, "Can't find --salt argument",
283 cmd, "--salt 1111")
284 android.AssertStringDoesContain(t, "Can't find --prop argument",
285 cmd, "--prop 'prop1:value1'")
286 android.AssertStringDoesContain(t, "Can't find --prop_from_file argument",
287 cmd, "--prop_from_file 'prop2:value_file'")
Alice Wang000e3a32023-01-03 16:11:20 +0000288 android.AssertStringDoesContain(t, "Can't find --include_descriptors_from_image",
289 cmd, "--include_descriptors_from_image ")
Jiyong Parkbc485482022-11-15 22:31:49 +0900290}
Jooyung Han54f78052023-02-20 18:17:47 +0900291
292func TestFileSystemShouldInstallCoreVariantIfTargetBuildAppsIsSet(t *testing.T) {
293 context := android.GroupFixturePreparers(
294 fixture,
295 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
296 variables.Unbundled_build_apps = []string{"bar"}
297 }),
298 )
299 result := context.RunTestWithBp(t, `
300 android_system_image {
301 name: "myfilesystem",
302 deps: [
303 "libfoo",
304 ],
305 linker_config_src: "linker.config.json",
306 }
307
308 cc_library {
309 name: "libfoo",
310 shared_libs: [
311 "libbar",
312 ],
313 stl: "none",
314 }
315
316 cc_library {
317 name: "libbar",
318 sdk_version: "9",
319 stl: "none",
320 }
321 `)
322
Cole Faust3b806d32024-03-11 15:15:03 -0700323 inputs := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img").Implicits
Jooyung Han54f78052023-02-20 18:17:47 +0900324 android.AssertStringListContains(t, "filesystem should have libbar even for unbundled build",
325 inputs.Strings(),
326 "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so")
327}
Jooyung Hane6067592023-03-16 13:11:17 +0900328
329func TestFileSystemWithCoverageVariants(t *testing.T) {
330 context := android.GroupFixturePreparers(
331 fixture,
332 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
333 variables.GcovCoverage = proptools.BoolPtr(true)
334 variables.Native_coverage = proptools.BoolPtr(true)
335 }),
336 )
337
338 result := context.RunTestWithBp(t, `
339 prebuilt_etc {
340 name: "prebuilt",
341 src: ":myfilesystem",
342 }
343
344 android_system_image {
345 name: "myfilesystem",
346 deps: [
347 "libfoo",
348 ],
349 linker_config_src: "linker.config.json",
350 }
351
352 cc_library {
353 name: "libfoo",
354 shared_libs: [
355 "libbar",
356 ],
357 stl: "none",
358 }
359
360 cc_library {
361 name: "libbar",
362 stl: "none",
363 }
364 `)
365
366 filesystem := result.ModuleForTests("myfilesystem", "android_common_cov")
Cole Faust3b806d32024-03-11 15:15:03 -0700367 inputs := filesystem.Output("myfilesystem.img").Implicits
Jooyung Hane6067592023-03-16 13:11:17 +0900368 android.AssertStringListContains(t, "filesystem should have libfoo(cov)",
369 inputs.Strings(),
370 "out/soong/.intermediates/libfoo/android_arm64_armv8-a_shared_cov/libfoo.so")
371 android.AssertStringListContains(t, "filesystem should have libbar(cov)",
372 inputs.Strings(),
373 "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared_cov/libbar.so")
374
375 filesystemOutput := filesystem.Output("myfilesystem.img").Output
376 prebuiltInput := result.ModuleForTests("prebuilt", "android_arm64_armv8-a").Rule("Cp").Input
377 if filesystemOutput != prebuiltInput {
378 t.Error("prebuilt should use cov variant of filesystem")
379 }
380}
Jiyong Parkeaac8232024-03-31 21:27:45 +0900381
382func TestSystemImageDefaults(t *testing.T) {
383 result := fixture.RunTestWithBp(t, `
384 android_system_image_defaults {
385 name: "defaults",
386 multilib: {
387 common: {
388 deps: [
389 "phony",
390 ],
391 },
392 lib64: {
393 deps: [
394 "libbar",
395 ],
396 },
397 },
398 compile_multilib: "both",
399 }
400
401 android_system_image {
402 name: "system",
403 defaults: ["defaults"],
404 multilib: {
405 lib32: {
406 deps: [
407 "foo",
408 "libbar",
409 ],
410 },
411 },
412 }
413
414 cc_binary {
415 name: "foo",
416 compile_multilib: "prefer32",
417 }
418
419 cc_library {
420 name: "libbar",
421 required: ["libbaz"],
422 }
423
424 cc_library {
425 name: "libbaz",
426 }
427
428 phony {
429 name: "phony",
430 required: ["libquz"],
431 }
432
433 cc_library {
434 name: "libquz",
435 }
436 `)
437
438 fs := result.ModuleForTests("system", "android_common").Module().(*systemImage)
439 expected := []string{
440 "bin/foo",
441 "lib/libbar.so",
442 "lib64/libbar.so",
443 "lib64/libbaz.so",
444 "lib64/libquz.so",
445 }
446 for _, e := range expected {
447 android.AssertStringListContains(t, "missing entry", fs.entries, e)
448 }
449}