blob: 2a0f6e9e251f15b024fc2b0c02301d59eb03c896 [file] [log] [blame]
Jingwen Chen889f2f22022-12-16 08:16:01 +00001// Copyright 2022 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.
14package apex
15
16import (
17 "android/soong/android"
18 "android/soong/bazel/cquery"
19 "strings"
20 "testing"
21)
22
23func TestApexImageInMixedBuilds(t *testing.T) {
24 bp := `
25apex_key{
26 name: "foo_key",
27}
Jingwen Chen2d37b642023-03-14 16:11:38 +000028
Jingwen Chen889f2f22022-12-16 08:16:01 +000029apex {
30 name: "foo",
31 key: "foo_key",
32 updatable: true,
33 min_sdk_version: "31",
34 file_contexts: ":myapex-file_contexts",
35 bazel_module: { label: "//:foo" },
36}`
37
38 outputBaseDir := "out/bazel"
39 result := android.GroupFixturePreparers(
40 prepareForApexTest,
41 android.FixtureModifyConfig(func(config android.Config) {
42 config.BazelContext = android.MockBazelContext{
43 OutputBaseDir: outputBaseDir,
44 LabelToApexInfo: map[string]cquery.ApexInfo{
45 "//:foo": cquery.ApexInfo{
Jingwen Chen29743c82023-01-25 17:49:46 +000046 // ApexInfo Starlark provider.
Jingwen Chen94098e82023-01-10 14:50:42 +000047 SignedOutput: "signed_out.apex",
48 SignedCompressedOutput: "signed_out.capex",
49 UnsignedOutput: "unsigned_out.apex",
50 BundleKeyInfo: []string{"public_key", "private_key"},
51 ContainerKeyInfo: []string{"container_cert", "container_private"},
52 SymbolsUsedByApex: "foo_using.txt",
53 JavaSymbolsUsedByApex: "foo_using.xml",
54 BundleFile: "apex_bundle.zip",
55 InstalledFiles: "installed-files.txt",
56 RequiresLibs: []string{"//path/c:c", "//path/d:d"},
Jingwen Chen889f2f22022-12-16 08:16:01 +000057
58 // unused
59 PackageName: "pkg_name",
60 ProvidesLibs: []string{"a", "b"},
Jingwen Chen29743c82023-01-25 17:49:46 +000061
62 // ApexMkInfo Starlark provider
Jingwen Chen2d37b642023-03-14 16:11:38 +000063 PayloadFilesInfo: []map[string]string{
64 {
65 "built_file": "bazel-out/adbd",
66 "install_dir": "bin",
67 "class": "nativeExecutable",
68 "make_module_name": "adbd",
69 "basename": "adbd",
70 "package": "foo",
71 },
72 },
Jingwen Chen29743c82023-01-25 17:49:46 +000073 MakeModulesToInstall: []string{"c"}, // d deliberately omitted
Jingwen Chen889f2f22022-12-16 08:16:01 +000074 },
75 },
76 }
77 }),
78 ).RunTestWithBp(t, bp)
79
80 m := result.ModuleForTests("foo", "android_common_foo_image").Module()
81 ab, ok := m.(*apexBundle)
Jingwen Chen2d37b642023-03-14 16:11:38 +000082
Jingwen Chen889f2f22022-12-16 08:16:01 +000083 if !ok {
84 t.Fatalf("Expected module to be an apexBundle, was not")
85 }
86
Jingwen Chen2d37b642023-03-14 16:11:38 +000087 // TODO: refactor to android.AssertStringEquals
Jingwen Chen889f2f22022-12-16 08:16:01 +000088 if w, g := "out/bazel/execroot/__main__/public_key", ab.publicKeyFile.String(); w != g {
89 t.Errorf("Expected public key %q, got %q", w, g)
90 }
91
92 if w, g := "out/bazel/execroot/__main__/private_key", ab.privateKeyFile.String(); w != g {
93 t.Errorf("Expected private key %q, got %q", w, g)
94 }
95
96 if w, g := "out/bazel/execroot/__main__/container_cert", ab.containerCertificateFile.String(); w != g {
97 t.Errorf("Expected public container key %q, got %q", w, g)
98 }
99
100 if w, g := "out/bazel/execroot/__main__/container_private", ab.containerPrivateKeyFile.String(); w != g {
101 t.Errorf("Expected private container key %q, got %q", w, g)
102 }
103
104 if w, g := "out/bazel/execroot/__main__/signed_out.apex", ab.outputFile.String(); w != g {
105 t.Errorf("Expected output file %q, got %q", w, g)
106 }
107
108 if w, g := "out/bazel/execroot/__main__/foo_using.txt", ab.nativeApisUsedByModuleFile.String(); w != g {
109 t.Errorf("Expected output file %q, got %q", w, g)
110 }
111
112 if w, g := "out/bazel/execroot/__main__/foo_using.xml", ab.javaApisUsedByModuleFile.String(); w != g {
113 t.Errorf("Expected output file %q, got %q", w, g)
114 }
115
116 if w, g := "out/bazel/execroot/__main__/installed-files.txt", ab.installedFilesFile.String(); w != g {
117 t.Errorf("Expected installed-files.txt %q, got %q", w, g)
118 }
119
120 mkData := android.AndroidMkDataForTest(t, result.TestContext, m)
121 var builder strings.Builder
122 mkData.Custom(&builder, "foo", "BAZEL_TARGET_", "", mkData)
123
124 data := builder.String()
125 if w := "ALL_MODULES.$(my_register_name).BUNDLE := out/bazel/execroot/__main__/apex_bundle.zip"; !strings.Contains(data, w) {
126 t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
127 }
128 if w := "$(call dist-for-goals,checkbuild,out/bazel/execroot/__main__/installed-files.txt:foo-installed-files.txt)"; !strings.Contains(data, w) {
129 t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
130 }
Jingwen Chen29743c82023-01-25 17:49:46 +0000131
132 // make modules to be installed to system
133 if len(ab.makeModulesToInstall) != 1 && ab.makeModulesToInstall[0] != "c" {
134 t.Errorf("Expected makeModulesToInstall slice to only contain 'c', got %q", ab.makeModulesToInstall)
135 }
Jingwen Chen2d37b642023-03-14 16:11:38 +0000136 if w := "LOCAL_REQUIRED_MODULES := adbd.foo c"; !strings.Contains(data, w) {
Jingwen Chen889f2f22022-12-16 08:16:01 +0000137 t.Errorf("Expected %q in androidmk data, but did not find it in %q", w, data)
138 }
139}
140
Jingwen Chen2d37b642023-03-14 16:11:38 +0000141func TestApexImageCreatesFilesInfoForMake(t *testing.T) {
142 bp := `
143apex_key{
144 name: "foo_key",
145}
146
147apex {
148 name: "foo",
149 key: "foo_key",
150 updatable: true,
151 min_sdk_version: "31",
152 file_contexts: ":myapex-file_contexts",
153 bazel_module: { label: "//:foo" },
154}`
155
156 outputBaseDir := "out/bazel"
157 result := android.GroupFixturePreparers(
158 prepareForApexTest,
159 android.FixtureModifyConfig(func(config android.Config) {
160 config.BazelContext = android.MockBazelContext{
161 OutputBaseDir: outputBaseDir,
162 LabelToApexInfo: map[string]cquery.ApexInfo{
163 "//:foo": {
164 // ApexInfo Starlark provider. Necessary for the test.
165 SignedOutput: "signed_out.apex",
166 BundleKeyInfo: []string{"public_key", "private_key"},
167 ContainerKeyInfo: []string{"container_cert", "container_private"},
168
169 // ApexMkInfo Starlark provider
170 PayloadFilesInfo: []map[string]string{
171 {
172 "arch": "arm64",
173 "basename": "libcrypto.so",
174 "built_file": "bazel-out/64/libcrypto.so",
175 "class": "nativeSharedLib",
176 "install_dir": "lib64",
177 "make_module_name": "libcrypto",
178 "package": "foo/bar",
179 "unstripped_built_file": "bazel-out/64/unstripped_libcrypto.so",
180 },
181 {
182 "arch": "arm",
183 "basename": "libcrypto.so",
184 "built_file": "bazel-out/32/libcrypto.so",
185 "class": "nativeSharedLib",
186 "install_dir": "lib",
187 "make_module_name": "libcrypto",
188 "package": "foo/bar",
189 },
190 {
191 "arch": "arm64",
192 "basename": "adbd",
193 "built_file": "bazel-out/adbd",
194 "class": "nativeExecutable",
195 "install_dir": "bin",
196 "make_module_name": "adbd",
197 "package": "foo",
198 },
199 },
200 },
201 },
202 }
203 }),
204 ).RunTestWithBp(t, bp)
205
206 m := result.ModuleForTests("foo", "android_common_foo_image").Module()
207 ab, ok := m.(*apexBundle)
208
209 if !ok {
210 t.Fatalf("Expected module to be an apexBundle, was not")
211 }
212
213 expectedFilesInfo := []apexFile{
214 {
215 androidMkModuleName: "libcrypto",
216 builtFile: android.PathForTesting("out/bazel/execroot/__main__/bazel-out/64/libcrypto.so"),
217 class: nativeSharedLib,
218 customStem: "libcrypto.so",
219 installDir: "lib64",
220 moduleDir: "foo/bar",
221 arch: "arm64",
222 unstrippedBuiltFile: android.PathForTesting("out/bazel/execroot/__main__/bazel-out/64/unstripped_libcrypto.so"),
223 },
224 {
225 androidMkModuleName: "libcrypto",
226 builtFile: android.PathForTesting("out/bazel/execroot/__main__/bazel-out/32/libcrypto.so"),
227 class: nativeSharedLib,
228 customStem: "libcrypto.so",
229 installDir: "lib",
230 moduleDir: "foo/bar",
231 arch: "arm",
232 },
233 {
234 androidMkModuleName: "adbd",
235 builtFile: android.PathForTesting("out/bazel/execroot/__main__/bazel-out/adbd"),
236 class: nativeExecutable,
237 customStem: "adbd",
238 installDir: "bin",
239 moduleDir: "foo",
240 arch: "arm64",
241 },
242 }
243
244 if len(ab.filesInfo) != len(expectedFilesInfo) {
245 t.Errorf("Expected %d entries in ab.filesInfo, but got %d", len(ab.filesInfo), len(expectedFilesInfo))
246 }
247
248 for idx, f := range ab.filesInfo {
249 expected := expectedFilesInfo[idx]
250 android.AssertSame(t, "different class", expected.class, f.class)
251 android.AssertStringEquals(t, "different built file", expected.builtFile.String(), f.builtFile.String())
252 android.AssertStringEquals(t, "different custom stem", expected.customStem, f.customStem)
253 android.AssertStringEquals(t, "different install dir", expected.installDir, f.installDir)
254 android.AssertStringEquals(t, "different make module name", expected.androidMkModuleName, f.androidMkModuleName)
255 android.AssertStringEquals(t, "different moduleDir", expected.moduleDir, f.moduleDir)
256 android.AssertStringEquals(t, "different arch", expected.arch, f.arch)
257 if expected.unstrippedBuiltFile != nil {
258 if f.unstrippedBuiltFile == nil {
259 t.Errorf("expected an unstripped built file path.")
260 }
261 android.AssertStringEquals(t, "different unstripped built file", expected.unstrippedBuiltFile.String(), f.unstrippedBuiltFile.String())
262 }
263 }
264}
265
Jingwen Chen94098e82023-01-10 14:50:42 +0000266func TestCompressedApexImageInMixedBuilds(t *testing.T) {
267 bp := `
268apex_key{
269 name: "foo_key",
270}
271apex {
272 name: "foo",
273 key: "foo_key",
274 updatable: true,
275 min_sdk_version: "31",
276 file_contexts: ":myapex-file_contexts",
277 bazel_module: { label: "//:foo" },
278 test_only_force_compression: true, // force compression
279}`
280
281 outputBaseDir := "out/bazel"
282 result := android.GroupFixturePreparers(
283 prepareForApexTest,
284 android.FixtureModifyConfig(func(config android.Config) {
285 config.BazelContext = android.MockBazelContext{
286 OutputBaseDir: outputBaseDir,
287 LabelToApexInfo: map[string]cquery.ApexInfo{
288 "//:foo": cquery.ApexInfo{
289 SignedOutput: "signed_out.apex",
290 SignedCompressedOutput: "signed_out.capex",
291 BundleKeyInfo: []string{"public_key", "private_key"},
292 ContainerKeyInfo: []string{"container_cert", "container_private"},
293 },
294 },
295 }
296 }),
297 ).RunTestWithBp(t, bp)
298
299 m := result.ModuleForTests("foo", "android_common_foo_image").Module()
300 ab, ok := m.(*apexBundle)
301 if !ok {
302 t.Fatalf("Expected module to be an apexBundle, was not")
303 }
304
305 if w, g := "out/bazel/execroot/__main__/signed_out.capex", ab.outputFile.String(); w != g {
306 t.Errorf("Expected output file to be compressed apex %q, got %q", w, g)
307 }
308
309 mkData := android.AndroidMkDataForTest(t, result.TestContext, m)
310 var builder strings.Builder
311 mkData.Custom(&builder, "foo", "BAZEL_TARGET_", "", mkData)
312
313 data := builder.String()
314
315 expectedAndroidMk := []string{
316 "LOCAL_PREBUILT_MODULE_FILE := out/bazel/execroot/__main__/signed_out.capex",
317
318 // Check that the source install file is the capex. The dest is not important.
319 "LOCAL_SOONG_INSTALL_PAIRS := out/bazel/execroot/__main__/signed_out.capex:",
320 }
321 for _, androidMk := range expectedAndroidMk {
322 if !strings.Contains(data, androidMk) {
323 t.Errorf("Expected %q in androidmk data, but did not find %q", androidMk, data)
324 }
325 }
326}
327
Jingwen Chen889f2f22022-12-16 08:16:01 +0000328func TestOverrideApexImageInMixedBuilds(t *testing.T) {
329 bp := `
330apex_key{
331 name: "foo_key",
332}
333apex_key{
334 name: "override_foo_key",
335}
336apex {
337 name: "foo",
338 key: "foo_key",
339 updatable: true,
340 min_sdk_version: "31",
341 package_name: "pkg_name",
342 file_contexts: ":myapex-file_contexts",
343 bazel_module: { label: "//:foo" },
344}
345override_apex {
346 name: "override_foo",
347 key: "override_foo_key",
348 package_name: "override_pkg_name",
349 base: "foo",
350 bazel_module: { label: "//:override_foo" },
351}
352`
353
354 outputBaseDir := "out/bazel"
355 result := android.GroupFixturePreparers(
356 prepareForApexTest,
357 android.FixtureModifyConfig(func(config android.Config) {
358 config.BazelContext = android.MockBazelContext{
359 OutputBaseDir: outputBaseDir,
360 LabelToApexInfo: map[string]cquery.ApexInfo{
361 "//:foo": cquery.ApexInfo{
Jingwen Chen29743c82023-01-25 17:49:46 +0000362 // ApexInfo Starlark provider
Jingwen Chen889f2f22022-12-16 08:16:01 +0000363 SignedOutput: "signed_out.apex",
364 UnsignedOutput: "unsigned_out.apex",
365 BundleKeyInfo: []string{"public_key", "private_key"},
366 ContainerKeyInfo: []string{"container_cert", "container_private"},
367 SymbolsUsedByApex: "foo_using.txt",
368 JavaSymbolsUsedByApex: "foo_using.xml",
369 BundleFile: "apex_bundle.zip",
370 InstalledFiles: "installed-files.txt",
371 RequiresLibs: []string{"//path/c:c", "//path/d:d"},
372
373 // unused
374 PackageName: "pkg_name",
375 ProvidesLibs: []string{"a", "b"},
Jingwen Chen29743c82023-01-25 17:49:46 +0000376
377 // ApexMkInfo Starlark provider
378 MakeModulesToInstall: []string{"c"}, // d deliberately omitted
Jingwen Chen889f2f22022-12-16 08:16:01 +0000379 },
380 "//:override_foo": cquery.ApexInfo{
Jingwen Chen29743c82023-01-25 17:49:46 +0000381 // ApexInfo Starlark provider
Jingwen Chen889f2f22022-12-16 08:16:01 +0000382 SignedOutput: "override_signed_out.apex",
383 UnsignedOutput: "override_unsigned_out.apex",
384 BundleKeyInfo: []string{"override_public_key", "override_private_key"},
385 ContainerKeyInfo: []string{"override_container_cert", "override_container_private"},
386 SymbolsUsedByApex: "override_foo_using.txt",
387 JavaSymbolsUsedByApex: "override_foo_using.xml",
388 BundleFile: "override_apex_bundle.zip",
389 InstalledFiles: "override_installed-files.txt",
390 RequiresLibs: []string{"//path/c:c", "//path/d:d"},
391
392 // unused
393 PackageName: "override_pkg_name",
394 ProvidesLibs: []string{"a", "b"},
Jingwen Chen29743c82023-01-25 17:49:46 +0000395
396 // ApexMkInfo Starlark provider
397 MakeModulesToInstall: []string{"c"}, // d deliberately omitted
Jingwen Chen889f2f22022-12-16 08:16:01 +0000398 },
399 },
400 }
401 }),
402 ).RunTestWithBp(t, bp)
403
404 m := result.ModuleForTests("foo", "android_common_override_foo_foo_image").Module()
405 ab, ok := m.(*apexBundle)
406 if !ok {
407 t.Fatalf("Expected module to be an apexBundle, was not")
408 }
409
410 if w, g := "out/bazel/execroot/__main__/override_public_key", ab.publicKeyFile.String(); w != g {
411 t.Errorf("Expected public key %q, got %q", w, g)
412 }
413
414 if w, g := "out/bazel/execroot/__main__/override_private_key", ab.privateKeyFile.String(); w != g {
415 t.Errorf("Expected private key %q, got %q", w, g)
416 }
417
418 if w, g := "out/bazel/execroot/__main__/override_container_cert", ab.containerCertificateFile.String(); w != g {
419 t.Errorf("Expected public container key %q, got %q", w, g)
420 }
421
422 if w, g := "out/bazel/execroot/__main__/override_container_private", ab.containerPrivateKeyFile.String(); w != g {
423 t.Errorf("Expected private container key %q, got %q", w, g)
424 }
425
426 if w, g := "out/bazel/execroot/__main__/override_signed_out.apex", ab.outputFile.String(); w != g {
427 t.Errorf("Expected output file %q, got %q", w, g)
428 }
429
430 if w, g := "out/bazel/execroot/__main__/override_foo_using.txt", ab.nativeApisUsedByModuleFile.String(); w != g {
431 t.Errorf("Expected output file %q, got %q", w, g)
432 }
433
434 if w, g := "out/bazel/execroot/__main__/override_foo_using.xml", ab.javaApisUsedByModuleFile.String(); w != g {
435 t.Errorf("Expected output file %q, got %q", w, g)
436 }
437
438 if w, g := "out/bazel/execroot/__main__/override_installed-files.txt", ab.installedFilesFile.String(); w != g {
439 t.Errorf("Expected installed-files.txt %q, got %q", w, g)
440 }
441
442 mkData := android.AndroidMkDataForTest(t, result.TestContext, m)
443 var builder strings.Builder
444 mkData.Custom(&builder, "override_foo", "BAZEL_TARGET_", "", mkData)
445
446 data := builder.String()
447 if w := "ALL_MODULES.$(my_register_name).BUNDLE := out/bazel/execroot/__main__/override_apex_bundle.zip"; !strings.Contains(data, w) {
448 t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
449 }
450 if w := "$(call dist-for-goals,checkbuild,out/bazel/execroot/__main__/override_installed-files.txt:override_foo-installed-files.txt)"; !strings.Contains(data, w) {
451 t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
452 }
Jingwen Chen29743c82023-01-25 17:49:46 +0000453
454 // make modules to be installed to system
455 if len(ab.makeModulesToInstall) != 1 && ab.makeModulesToInstall[0] != "c" {
456 t.Errorf("Expected makeModulestoInstall slice to only contain 'c', got %q", ab.makeModulesToInstall)
457 }
458 if w := "LOCAL_REQUIRED_MODULES := c"; !strings.Contains(data, w) {
Jingwen Chen889f2f22022-12-16 08:16:01 +0000459 t.Errorf("Expected %q in androidmk data, but did not find it in %q", w, data)
460 }
461}