blob: 861918f16be8dfcdd67d9849b82f9a758d5cfa0d [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"],
Jiyong Parkf21dd652024-04-17 05:22:37 +000087 target: {
88 platform: {
89 required: ["lib_platform_only"],
90 },
91 },
Jiyong Park8bcf3c62024-03-18 18:37:10 +090092 }
93
94 cc_library {
95 name: "libbaz",
Jiyong Parkeec7c382024-02-16 16:10:13 +090096 }
Jiyong Park9c540c82024-03-26 10:48:27 +090097
Jiyong Parkf21dd652024-04-17 05:22:37 +000098 cc_library {
99 name: "lib_platform_only",
100 }
101
Jiyong Park9c540c82024-03-26 10:48:27 +0900102 phony {
103 name: "phony",
Jiyong Park73e5bab2024-04-05 13:37:21 +0900104 required: [
105 "libquz",
106 "myapp",
107 ],
Jiyong Park9c540c82024-03-26 10:48:27 +0900108 }
109
110 cc_library {
111 name: "libquz",
112 }
Jiyong Park73e5bab2024-04-05 13:37:21 +0900113
114 android_app {
115 name: "myapp",
116 platform_apis: true,
117 installable: true,
118 }
Jooyung Han9706cbc2021-04-15 22:43:48 +0900119 `)
120
121 // produces "myfilesystem.img"
122 result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
Jiyong Park06c4cdc2024-02-16 15:35:03 +0900123
124 fs := result.ModuleForTests("myfilesystem", "android_common").Module().(*filesystem)
Jiyong Parkeec7c382024-02-16 16:10:13 +0900125 expected := []string{
Jiyong Park73e5bab2024-04-05 13:37:21 +0900126 "app/myapp/myapp.apk",
Jiyong Parkeec7c382024-02-16 16:10:13 +0900127 "bin/foo",
128 "lib/libbar.so",
129 "lib64/libbar.so",
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900130 "lib64/libbaz.so",
Jiyong Park9c540c82024-03-26 10:48:27 +0900131 "lib64/libquz.so",
Jiyong Parkf21dd652024-04-17 05:22:37 +0000132 "lib64/lib_platform_only.so",
Jiyong Parkeec7c382024-02-16 16:10:13 +0900133 "etc/bpf/bpf.o",
134 }
Jiyong Park06c4cdc2024-02-16 15:35:03 +0900135 for _, e := range expected {
136 android.AssertStringListContains(t, "missing entry", fs.entries, e)
137 }
Jooyung Han9706cbc2021-04-15 22:43:48 +0900138}
Jiyong Parkfa616132021-04-20 11:36:40 +0900139
Cole Faust4a2a7c92024-03-12 12:44:40 -0700140func TestIncludeMakeBuiltFiles(t *testing.T) {
141 result := fixture.RunTestWithBp(t, `
142 android_filesystem {
143 name: "myfilesystem",
144 include_make_built_files: "system",
145 }
146 `)
147
148 output := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
149
150 stampFile := filepath.Join(result.Config.OutDir(), "target/product/test_device/obj/PACKAGING/system_intermediates/staging_dir.stamp")
151 fileListFile := filepath.Join(result.Config.OutDir(), "target/product/test_device/obj/PACKAGING/system_intermediates/file_list.txt")
152 android.AssertStringListContains(t, "deps of filesystem must include the staging dir stamp file", output.Implicits.Strings(), stampFile)
153 android.AssertStringListContains(t, "deps of filesystem must include the staging dir file list", output.Implicits.Strings(), fileListFile)
154}
155
Jiyong Parkfa616132021-04-20 11:36:40 +0900156func TestFileSystemFillsLinkerConfigWithStubLibs(t *testing.T) {
157 result := fixture.RunTestWithBp(t, `
Jooyung Han0fbbc2b2022-03-25 12:35:46 +0900158 android_system_image {
Jiyong Parkfa616132021-04-20 11:36:40 +0900159 name: "myfilesystem",
160 deps: [
161 "libfoo",
Jooyung Han0fbbc2b2022-03-25 12:35:46 +0900162 "libbar",
Jiyong Parkfa616132021-04-20 11:36:40 +0900163 ],
164 linker_config_src: "linker.config.json",
165 }
166
167 cc_library {
168 name: "libfoo",
169 stubs: {
170 symbol_file: "libfoo.map.txt",
171 },
172 }
173
174 cc_library {
175 name: "libbar",
176 }
177 `)
178
179 module := result.ModuleForTests("myfilesystem", "android_common")
180 output := module.Output("system/etc/linker.config.pb")
181
182 android.AssertStringDoesContain(t, "linker.config.pb should have libfoo",
183 output.RuleParams.Command, "libfoo.so")
184 android.AssertStringDoesNotContain(t, "linker.config.pb should not have libbar",
185 output.RuleParams.Command, "libbar.so")
186}
Jooyung Han0fbbc2b2022-03-25 12:35:46 +0900187
188func registerComponent(ctx android.RegistrationContext) {
189 ctx.RegisterModuleType("component", componentFactory)
190}
191
192func componentFactory() android.Module {
193 m := &component{}
194 m.AddProperties(&m.properties)
195 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
196 return m
197}
198
199type component struct {
200 android.ModuleBase
201 properties struct {
202 Install_copy_in_data []string
203 }
204}
205
206func (c *component) GenerateAndroidBuildActions(ctx android.ModuleContext) {
207 output := android.PathForModuleOut(ctx, c.Name())
208 dir := android.PathForModuleInstall(ctx, "components")
209 ctx.InstallFile(dir, c.Name(), output)
210
211 dataDir := android.PathForModuleInPartitionInstall(ctx, "data", "components")
212 for _, d := range c.properties.Install_copy_in_data {
213 ctx.InstallFile(dataDir, d, output)
214 }
215}
216
217func TestFileSystemGathersItemsOnlyInSystemPartition(t *testing.T) {
218 f := android.GroupFixturePreparers(fixture, android.FixtureRegisterWithContext(registerComponent))
219 result := f.RunTestWithBp(t, `
220 android_system_image {
221 name: "myfilesystem",
222 multilib: {
223 common: {
224 deps: ["foo"],
225 },
226 },
227 linker_config_src: "linker.config.json",
228 }
229 component {
230 name: "foo",
231 install_copy_in_data: ["bar"],
232 }
233 `)
234
235 module := result.ModuleForTests("myfilesystem", "android_common").Module().(*systemImage)
236 android.AssertDeepEquals(t, "entries should have foo only", []string{"components/foo"}, module.entries)
237}
Jiyong Parkbc485482022-11-15 22:31:49 +0900238
Alice Wang000e3a32023-01-03 16:11:20 +0000239func TestAvbGenVbmetaImage(t *testing.T) {
240 result := fixture.RunTestWithBp(t, `
241 avb_gen_vbmeta_image {
242 name: "input_hashdesc",
243 src: "input.img",
244 partition_name: "input_partition_name",
245 salt: "2222",
246 }`)
247 cmd := result.ModuleForTests("input_hashdesc", "android_arm64_armv8-a").Rule("avbGenVbmetaImage").RuleParams.Command
248 android.AssertStringDoesContain(t, "Can't find correct --partition_name argument",
249 cmd, "--partition_name input_partition_name")
250 android.AssertStringDoesContain(t, "Can't find --do_not_append_vbmeta_image",
251 cmd, "--do_not_append_vbmeta_image")
252 android.AssertStringDoesContain(t, "Can't find --output_vbmeta_image",
253 cmd, "--output_vbmeta_image ")
254 android.AssertStringDoesContain(t, "Can't find --salt argument",
255 cmd, "--salt 2222")
256}
257
Jiyong Parkbc485482022-11-15 22:31:49 +0900258func TestAvbAddHashFooter(t *testing.T) {
259 result := fixture.RunTestWithBp(t, `
Alice Wang000e3a32023-01-03 16:11:20 +0000260 avb_gen_vbmeta_image {
261 name: "input_hashdesc",
262 src: "input.img",
263 partition_name: "input",
264 salt: "2222",
265 }
266
Jiyong Parkbc485482022-11-15 22:31:49 +0900267 avb_add_hash_footer {
268 name: "myfooter",
269 src: "input.img",
270 filename: "output.img",
271 partition_name: "mypartition",
272 private_key: "mykey",
273 salt: "1111",
274 props: [
275 {
276 name: "prop1",
277 value: "value1",
278 },
279 {
280 name: "prop2",
281 file: "value_file",
282 },
283 ],
Alice Wang000e3a32023-01-03 16:11:20 +0000284 include_descriptors_from_images: ["input_hashdesc"],
Jiyong Parkbc485482022-11-15 22:31:49 +0900285 }
286 `)
287 cmd := result.ModuleForTests("myfooter", "android_arm64_armv8-a").Rule("avbAddHashFooter").RuleParams.Command
288 android.AssertStringDoesContain(t, "Can't find correct --partition_name argument",
289 cmd, "--partition_name mypartition")
290 android.AssertStringDoesContain(t, "Can't find correct --key argument",
291 cmd, "--key mykey")
292 android.AssertStringDoesContain(t, "Can't find --salt argument",
293 cmd, "--salt 1111")
294 android.AssertStringDoesContain(t, "Can't find --prop argument",
295 cmd, "--prop 'prop1:value1'")
296 android.AssertStringDoesContain(t, "Can't find --prop_from_file argument",
297 cmd, "--prop_from_file 'prop2:value_file'")
Alice Wang000e3a32023-01-03 16:11:20 +0000298 android.AssertStringDoesContain(t, "Can't find --include_descriptors_from_image",
299 cmd, "--include_descriptors_from_image ")
Jiyong Parkbc485482022-11-15 22:31:49 +0900300}
Jooyung Han54f78052023-02-20 18:17:47 +0900301
Jooyung Hane6067592023-03-16 13:11:17 +0900302func TestFileSystemWithCoverageVariants(t *testing.T) {
303 context := android.GroupFixturePreparers(
304 fixture,
305 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
306 variables.GcovCoverage = proptools.BoolPtr(true)
307 variables.Native_coverage = proptools.BoolPtr(true)
308 }),
309 )
310
311 result := context.RunTestWithBp(t, `
312 prebuilt_etc {
313 name: "prebuilt",
314 src: ":myfilesystem",
315 }
316
317 android_system_image {
318 name: "myfilesystem",
319 deps: [
320 "libfoo",
321 ],
322 linker_config_src: "linker.config.json",
323 }
324
325 cc_library {
326 name: "libfoo",
327 shared_libs: [
328 "libbar",
329 ],
330 stl: "none",
331 }
332
333 cc_library {
334 name: "libbar",
335 stl: "none",
336 }
337 `)
338
339 filesystem := result.ModuleForTests("myfilesystem", "android_common_cov")
Cole Faust3b806d32024-03-11 15:15:03 -0700340 inputs := filesystem.Output("myfilesystem.img").Implicits
Jooyung Hane6067592023-03-16 13:11:17 +0900341 android.AssertStringListContains(t, "filesystem should have libfoo(cov)",
342 inputs.Strings(),
343 "out/soong/.intermediates/libfoo/android_arm64_armv8-a_shared_cov/libfoo.so")
344 android.AssertStringListContains(t, "filesystem should have libbar(cov)",
345 inputs.Strings(),
346 "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared_cov/libbar.so")
347
348 filesystemOutput := filesystem.Output("myfilesystem.img").Output
349 prebuiltInput := result.ModuleForTests("prebuilt", "android_arm64_armv8-a").Rule("Cp").Input
350 if filesystemOutput != prebuiltInput {
351 t.Error("prebuilt should use cov variant of filesystem")
352 }
353}
Jiyong Parkeaac8232024-03-31 21:27:45 +0900354
355func TestSystemImageDefaults(t *testing.T) {
356 result := fixture.RunTestWithBp(t, `
Jiyong Parkf46b1af2024-04-05 18:13:33 +0900357 android_filesystem_defaults {
Jiyong Parkeaac8232024-03-31 21:27:45 +0900358 name: "defaults",
359 multilib: {
360 common: {
361 deps: [
362 "phony",
363 ],
364 },
365 lib64: {
366 deps: [
367 "libbar",
368 ],
369 },
370 },
371 compile_multilib: "both",
372 }
373
374 android_system_image {
375 name: "system",
376 defaults: ["defaults"],
377 multilib: {
378 lib32: {
379 deps: [
380 "foo",
381 "libbar",
382 ],
383 },
384 },
385 }
386
387 cc_binary {
388 name: "foo",
389 compile_multilib: "prefer32",
390 }
391
392 cc_library {
393 name: "libbar",
394 required: ["libbaz"],
395 }
396
397 cc_library {
398 name: "libbaz",
399 }
400
401 phony {
402 name: "phony",
403 required: ["libquz"],
404 }
405
406 cc_library {
407 name: "libquz",
408 }
409 `)
410
411 fs := result.ModuleForTests("system", "android_common").Module().(*systemImage)
412 expected := []string{
413 "bin/foo",
414 "lib/libbar.so",
415 "lib64/libbar.so",
416 "lib64/libbaz.so",
417 "lib64/libquz.so",
418 }
419 for _, e := range expected {
420 android.AssertStringListContains(t, "missing entry", fs.entries, e)
421 }
422}
Jiyong Parkf46b1af2024-04-05 18:13:33 +0900423
424func TestInconsistentPartitionTypesInDefaults(t *testing.T) {
425 fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(
426 "doesn't match with the partition type")).
427 RunTestWithBp(t, `
428 android_filesystem_defaults {
429 name: "system_ext_def",
430 partition_type: "system_ext",
431 }
432
433 android_filesystem_defaults {
434 name: "system_def",
435 partition_type: "system",
436 defaults: ["system_ext_def"],
437 }
438
439 android_system_image {
440 name: "system",
441 defaults: ["system_def"],
442 }
443 `)
444}
Jiyong Park16ef7ac2024-05-01 12:36:10 +0000445
446func TestPreventDuplicatedEntries(t *testing.T) {
447 fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(
448 "packaging conflict at")).
449 RunTestWithBp(t, `
450 android_filesystem {
451 name: "fs",
452 deps: [
453 "foo",
454 "foo_dup",
455 ],
456 }
457
458 cc_binary {
459 name: "foo",
460 }
461
462 cc_binary {
463 name: "foo_dup",
464 stem: "foo",
465 }
466 `)
467}
Jiyong Parkc4b1d552024-05-13 16:47:30 +0900468
469func TestTrackPhonyAsRequiredDep(t *testing.T) {
470 result := fixture.RunTestWithBp(t, `
471 android_filesystem {
472 name: "fs",
473 deps: ["foo"],
474 }
475
476 cc_binary {
477 name: "foo",
478 required: ["phony"],
479 }
480
481 phony {
482 name: "phony",
483 required: ["libbar"],
484 }
485
486 cc_library {
487 name: "libbar",
488 }
489 `)
490
491 fs := result.ModuleForTests("fs", "android_common").Module().(*filesystem)
492 expected := []string{
493 "bin/foo",
494 "lib64/libbar.so",
495 }
496 for _, e := range expected {
497 android.AssertStringListContains(t, "missing entry", fs.entries, e)
498 }
499}