blob: 99192be0a695506772eec9683006245741ec8759 [file] [log] [blame]
Jiyong Parkd1063c12019-07-17 20:08:41 +09001// Copyright 2019 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 sdk
16
17import (
18 "io/ioutil"
19 "os"
Jiyong Park232e7852019-11-04 12:23:40 +090020 "path/filepath"
Jiyong Parkd1063c12019-07-17 20:08:41 +090021 "strings"
22 "testing"
23
24 "android/soong/android"
25 "android/soong/apex"
26 "android/soong/cc"
27 "android/soong/java"
28)
29
30func testSdkContext(t *testing.T, bp string) (*android.TestContext, android.Config) {
31 config := android.TestArchConfig(buildDir, nil)
32 ctx := android.NewTestArchContext()
33
34 // from android package
35 ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
36 ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
37 ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
38 })
39 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
40 ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
41 ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
42 })
43
44 // from java package
45 ctx.RegisterModuleType("android_app_certificate", android.ModuleFactoryAdaptor(java.AndroidAppCertificateFactory))
46 ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory))
47 ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory))
Paul Duffin91547182019-11-12 19:39:36 +000048 ctx.RegisterModuleType("droidstubs", android.ModuleFactoryAdaptor(java.DroidstubsFactory))
49 ctx.RegisterModuleType("prebuilt_stubs_sources", android.ModuleFactoryAdaptor(java.PrebuiltStubsSourcesFactory))
Jiyong Parkd1063c12019-07-17 20:08:41 +090050
51 // from cc package
52 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
53 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory))
54 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
55 ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(cc.PrebuiltSharedLibraryFactory))
56 ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(cc.PrebuiltStaticLibraryFactory))
57 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory))
58 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
59 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
60 ctx.BottomUp("image", cc.ImageMutator).Parallel()
61 ctx.BottomUp("link", cc.LinkageMutator).Parallel()
62 ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
63 ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
64 ctx.BottomUp("version", cc.VersionMutator).Parallel()
65 ctx.BottomUp("begin", cc.BeginMutator).Parallel()
66 })
67
68 // from apex package
69 ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apex.BundleFactory))
70 ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apex.ApexKeyFactory))
71 ctx.PostDepsMutators(apex.RegisterPostDepsMutators)
72
73 // from this package
74 ctx.RegisterModuleType("sdk", android.ModuleFactoryAdaptor(ModuleFactory))
Jiyong Park9b409bc2019-10-11 14:59:13 +090075 ctx.RegisterModuleType("sdk_snapshot", android.ModuleFactoryAdaptor(SnapshotModuleFactory))
Jiyong Parkd1063c12019-07-17 20:08:41 +090076 ctx.PreDepsMutators(RegisterPreDepsMutators)
77 ctx.PostDepsMutators(RegisterPostDepsMutators)
78
79 ctx.Register()
80
81 bp = bp + `
82 apex_key {
83 name: "myapex.key",
84 public_key: "myapex.avbpubkey",
85 private_key: "myapex.pem",
86 }
87
88 android_app_certificate {
89 name: "myapex.cert",
90 certificate: "myapex",
91 }
92 ` + cc.GatherRequiredDepsForTest(android.Android)
93
94 ctx.MockFileSystem(map[string][]byte{
95 "Android.bp": []byte(bp),
96 "build/make/target/product/security": nil,
97 "apex_manifest.json": nil,
98 "system/sepolicy/apex/myapex-file_contexts": nil,
99 "system/sepolicy/apex/myapex2-file_contexts": nil,
100 "myapex.avbpubkey": nil,
101 "myapex.pem": nil,
102 "myapex.x509.pem": nil,
103 "myapex.pk8": nil,
104 "Test.java": nil,
105 "Test.cpp": nil,
Jiyong Park232e7852019-11-04 12:23:40 +0900106 "include/Test.h": nil,
107 "aidl/foo/bar/Test.aidl": nil,
Jiyong Parkd1063c12019-07-17 20:08:41 +0900108 "libfoo.so": nil,
Paul Duffin91547182019-11-12 19:39:36 +0000109 "stubs-sources/foo/bar/Foo.java": nil,
110 "foo/bar/Foo.java": nil,
Jiyong Parkd1063c12019-07-17 20:08:41 +0900111 })
112
113 return ctx, config
114}
115
116func testSdk(t *testing.T, bp string) (*android.TestContext, android.Config) {
117 ctx, config := testSdkContext(t, bp)
118 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
119 android.FailIfErrored(t, errs)
120 _, errs = ctx.PrepareBuildActions(config)
121 android.FailIfErrored(t, errs)
122 return ctx, config
123}
124
Jiyong Parka7bc8ad2019-10-15 15:20:07 +0900125func testSdkError(t *testing.T, pattern, bp string) {
126 t.Helper()
127 ctx, config := testSdkContext(t, bp)
128 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
129 if len(errs) > 0 {
130 android.FailIfNoMatchingErrors(t, pattern, errs)
131 return
132 }
133 _, errs = ctx.PrepareBuildActions(config)
134 if len(errs) > 0 {
135 android.FailIfNoMatchingErrors(t, pattern, errs)
136 return
137 }
138
139 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
140}
141
Jiyong Parkd1063c12019-07-17 20:08:41 +0900142// ensure that 'result' contains 'expected'
143func ensureContains(t *testing.T, result string, expected string) {
144 t.Helper()
145 if !strings.Contains(result, expected) {
146 t.Errorf("%q is not found in %q", expected, result)
147 }
148}
149
150// ensures that 'result' does not contain 'notExpected'
151func ensureNotContains(t *testing.T, result string, notExpected string) {
152 t.Helper()
153 if strings.Contains(result, notExpected) {
154 t.Errorf("%q is found in %q", notExpected, result)
155 }
156}
157
158func ensureListContains(t *testing.T, result []string, expected string) {
159 t.Helper()
160 if !android.InList(expected, result) {
161 t.Errorf("%q is not found in %v", expected, result)
162 }
163}
164
165func ensureListNotContains(t *testing.T, result []string, notExpected string) {
166 t.Helper()
167 if android.InList(notExpected, result) {
168 t.Errorf("%q is found in %v", notExpected, result)
169 }
170}
171
172func pathsToStrings(paths android.Paths) []string {
173 ret := []string{}
174 for _, p := range paths {
175 ret = append(ret, p.String())
176 }
177 return ret
178}
179
180func TestBasicSdkWithJava(t *testing.T) {
181 ctx, _ := testSdk(t, `
182 sdk {
Jiyong Park9b409bc2019-10-11 14:59:13 +0900183 name: "mysdk",
184 java_libs: ["sdkmember"],
185 }
186
187 sdk_snapshot {
188 name: "mysdk@1",
Jiyong Parkd1063c12019-07-17 20:08:41 +0900189 java_libs: ["sdkmember_mysdk_1"],
190 }
191
Jiyong Park9b409bc2019-10-11 14:59:13 +0900192 sdk_snapshot {
193 name: "mysdk@2",
Jiyong Parkd1063c12019-07-17 20:08:41 +0900194 java_libs: ["sdkmember_mysdk_2"],
195 }
196
197 java_import {
198 name: "sdkmember",
199 prefer: false,
200 host_supported: true,
201 }
202
203 java_import {
204 name: "sdkmember_mysdk_1",
205 sdk_member_name: "sdkmember",
206 host_supported: true,
207 }
208
209 java_import {
210 name: "sdkmember_mysdk_2",
211 sdk_member_name: "sdkmember",
212 host_supported: true,
213 }
214
215 java_library {
216 name: "myjavalib",
217 srcs: ["Test.java"],
218 libs: ["sdkmember"],
219 system_modules: "none",
220 sdk_version: "none",
221 compile_dex: true,
222 host_supported: true,
223 }
224
225 apex {
226 name: "myapex",
227 java_libs: ["myjavalib"],
Jiyong Park9b409bc2019-10-11 14:59:13 +0900228 uses_sdks: ["mysdk@1"],
Jiyong Parkd1063c12019-07-17 20:08:41 +0900229 key: "myapex.key",
230 certificate: ":myapex.cert",
231 }
232
233 apex {
234 name: "myapex2",
235 java_libs: ["myjavalib"],
Jiyong Park9b409bc2019-10-11 14:59:13 +0900236 uses_sdks: ["mysdk@2"],
Jiyong Parkd1063c12019-07-17 20:08:41 +0900237 key: "myapex.key",
238 certificate: ":myapex.cert",
239 }
240 `)
241
242 sdkMemberV1 := ctx.ModuleForTests("sdkmember_mysdk_1", "android_common_myapex").Rule("combineJar").Output
243 sdkMemberV2 := ctx.ModuleForTests("sdkmember_mysdk_2", "android_common_myapex2").Rule("combineJar").Output
244
245 javalibForMyApex := ctx.ModuleForTests("myjavalib", "android_common_myapex")
246 javalibForMyApex2 := ctx.ModuleForTests("myjavalib", "android_common_myapex2")
247
248 // Depending on the uses_sdks value, different libs are linked
249 ensureListContains(t, pathsToStrings(javalibForMyApex.Rule("javac").Implicits), sdkMemberV1.String())
250 ensureListContains(t, pathsToStrings(javalibForMyApex2.Rule("javac").Implicits), sdkMemberV2.String())
251}
252
253func TestBasicSdkWithCc(t *testing.T) {
254 ctx, _ := testSdk(t, `
255 sdk {
Jiyong Park9b409bc2019-10-11 14:59:13 +0900256 name: "mysdk",
257 native_shared_libs: ["sdkmember"],
258 }
259
260 sdk_snapshot {
261 name: "mysdk@1",
Jiyong Parkd1063c12019-07-17 20:08:41 +0900262 native_shared_libs: ["sdkmember_mysdk_1"],
263 }
264
Jiyong Park9b409bc2019-10-11 14:59:13 +0900265 sdk_snapshot {
266 name: "mysdk@2",
Jiyong Parkd1063c12019-07-17 20:08:41 +0900267 native_shared_libs: ["sdkmember_mysdk_2"],
268 }
269
270 cc_prebuilt_library_shared {
271 name: "sdkmember",
272 srcs: ["libfoo.so"],
273 prefer: false,
274 system_shared_libs: [],
275 stl: "none",
276 }
277
278 cc_prebuilt_library_shared {
279 name: "sdkmember_mysdk_1",
280 sdk_member_name: "sdkmember",
281 srcs: ["libfoo.so"],
282 system_shared_libs: [],
283 stl: "none",
284 }
285
286 cc_prebuilt_library_shared {
287 name: "sdkmember_mysdk_2",
288 sdk_member_name: "sdkmember",
289 srcs: ["libfoo.so"],
290 system_shared_libs: [],
291 stl: "none",
292 }
293
294 cc_library_shared {
295 name: "mycpplib",
296 srcs: ["Test.cpp"],
297 shared_libs: ["sdkmember"],
298 system_shared_libs: [],
299 stl: "none",
300 }
301
302 apex {
303 name: "myapex",
304 native_shared_libs: ["mycpplib"],
Jiyong Park9b409bc2019-10-11 14:59:13 +0900305 uses_sdks: ["mysdk@1"],
Jiyong Parkd1063c12019-07-17 20:08:41 +0900306 key: "myapex.key",
307 certificate: ":myapex.cert",
308 }
309
310 apex {
311 name: "myapex2",
312 native_shared_libs: ["mycpplib"],
Jiyong Park9b409bc2019-10-11 14:59:13 +0900313 uses_sdks: ["mysdk@2"],
Jiyong Parkd1063c12019-07-17 20:08:41 +0900314 key: "myapex.key",
315 certificate: ":myapex.cert",
316 }
317 `)
318
319 sdkMemberV1 := ctx.ModuleForTests("sdkmember_mysdk_1", "android_arm64_armv8-a_core_shared_myapex").Rule("toc").Output
320 sdkMemberV2 := ctx.ModuleForTests("sdkmember_mysdk_2", "android_arm64_armv8-a_core_shared_myapex2").Rule("toc").Output
321
322 cpplibForMyApex := ctx.ModuleForTests("mycpplib", "android_arm64_armv8-a_core_shared_myapex")
323 cpplibForMyApex2 := ctx.ModuleForTests("mycpplib", "android_arm64_armv8-a_core_shared_myapex2")
324
325 // Depending on the uses_sdks value, different libs are linked
326 ensureListContains(t, pathsToStrings(cpplibForMyApex.Rule("ld").Implicits), sdkMemberV1.String())
327 ensureListContains(t, pathsToStrings(cpplibForMyApex2.Rule("ld").Implicits), sdkMemberV2.String())
328}
329
Paul Duffin91547182019-11-12 19:39:36 +0000330// Note: This test does not verify that a droidstubs can be referenced, either
331// directly or indirectly from an APEX as droidstubs can never be a part of an
332// apex.
333func TestBasicSdkWithDroidstubs(t *testing.T) {
334 testSdk(t, `
335 sdk {
336 name: "mysdk",
337 stubs_sources: ["mystub"],
338 }
339 sdk_snapshot {
340 name: "mysdk@10",
341 stubs_sources: ["mystub_mysdk@10"],
342 }
343 prebuilt_stubs_sources {
344 name: "mystub_mysdk@10",
345 sdk_member_name: "mystub",
346 srcs: ["stubs-sources/foo/bar/Foo.java"],
347 }
348 droidstubs {
349 name: "mystub",
350 srcs: ["foo/bar/Foo.java"],
351 sdk_version: "none",
352 system_modules: "none",
353 }
354 java_library {
355 name: "myjavalib",
356 srcs: [":mystub"],
357 sdk_version: "none",
358 system_modules: "none",
359 }
360 `)
361}
362
Jiyong Parka7bc8ad2019-10-15 15:20:07 +0900363func TestDepNotInRequiredSdks(t *testing.T) {
364 testSdkError(t, `module "myjavalib".*depends on "otherlib".*that isn't part of the required SDKs:.*`, `
365 sdk {
366 name: "mysdk",
367 java_libs: ["sdkmember"],
368 }
369
370 sdk_snapshot {
371 name: "mysdk@1",
372 java_libs: ["sdkmember_mysdk_1"],
373 }
374
375 java_import {
376 name: "sdkmember",
377 prefer: false,
378 host_supported: true,
379 }
380
381 java_import {
382 name: "sdkmember_mysdk_1",
383 sdk_member_name: "sdkmember",
384 host_supported: true,
385 }
386
387 java_library {
388 name: "myjavalib",
389 srcs: ["Test.java"],
390 libs: [
391 "sdkmember",
392 "otherlib",
393 ],
394 system_modules: "none",
395 sdk_version: "none",
396 compile_dex: true,
397 host_supported: true,
398 }
399
400 // this lib is no in mysdk
401 java_library {
402 name: "otherlib",
403 srcs: ["Test.java"],
404 system_modules: "none",
405 sdk_version: "none",
406 compile_dex: true,
407 host_supported: true,
408 }
409
410 apex {
411 name: "myapex",
412 java_libs: ["myjavalib"],
413 uses_sdks: ["mysdk@1"],
414 key: "myapex.key",
415 certificate: ":myapex.cert",
416 }
417 `)
418}
419
Jiyong Park100f3fd2019-11-06 16:03:32 +0900420func TestSdkIsCompileMultilibBoth(t *testing.T) {
421 ctx, _ := testSdk(t, `
422 sdk {
423 name: "mysdk",
424 native_shared_libs: ["sdkmember"],
425 }
426
427 cc_library_shared {
428 name: "sdkmember",
429 srcs: ["Test.cpp"],
430 system_shared_libs: [],
431 stl: "none",
432 }
433 `)
434
435 armOutput := ctx.ModuleForTests("sdkmember", "android_arm_armv7-a-neon_core_shared").Module().(*cc.Module).OutputFile()
436 arm64Output := ctx.ModuleForTests("sdkmember", "android_arm64_armv8-a_core_shared").Module().(*cc.Module).OutputFile()
437
438 var inputs []string
439 buildParams := ctx.ModuleForTests("mysdk", "android_common").Module().BuildParamsForTests()
440 for _, bp := range buildParams {
Jiyong Park232e7852019-11-04 12:23:40 +0900441 if bp.Input != nil {
442 inputs = append(inputs, bp.Input.String())
443 }
Jiyong Park100f3fd2019-11-06 16:03:32 +0900444 }
445
446 // ensure that both 32/64 outputs are inputs of the sdk snapshot
447 ensureListContains(t, inputs, armOutput.String())
448 ensureListContains(t, inputs, arm64Output.String())
449}
450
Jiyong Park232e7852019-11-04 12:23:40 +0900451func TestSnapshot(t *testing.T) {
452 ctx, config := testSdk(t, `
453 sdk {
454 name: "mysdk",
455 java_libs: ["myjavalib"],
456 native_shared_libs: ["mynativelib"],
Paul Duffin91547182019-11-12 19:39:36 +0000457 stubs_sources: ["myjavaapistubs"],
Jiyong Park232e7852019-11-04 12:23:40 +0900458 }
459
460 java_library {
461 name: "myjavalib",
462 srcs: ["Test.java"],
463 aidl: {
464 export_include_dirs: ["aidl"],
465 },
466 system_modules: "none",
467 sdk_version: "none",
468 compile_dex: true,
469 host_supported: true,
470 }
471
472 cc_library_shared {
473 name: "mynativelib",
474 srcs: [
475 "Test.cpp",
476 "aidl/foo/bar/Test.aidl",
477 ],
478 export_include_dirs: ["include"],
479 aidl: {
480 export_aidl_headers: true,
481 },
482 system_shared_libs: [],
483 stl: "none",
484 }
Paul Duffin91547182019-11-12 19:39:36 +0000485
486 droidstubs {
487 name: "myjavaapistubs",
488 srcs: ["foo/bar/Foo.java"],
489 system_modules: "none",
490 sdk_version: "none",
491 }
Jiyong Park232e7852019-11-04 12:23:40 +0900492 `)
493
494 var copySrcs []string
495 var copyDests []string
496 buildParams := ctx.ModuleForTests("mysdk", "android_common").Module().BuildParamsForTests()
Paul Duffin91547182019-11-12 19:39:36 +0000497 var zipBp android.BuildParams
Jiyong Park232e7852019-11-04 12:23:40 +0900498 for _, bp := range buildParams {
Paul Duffin91547182019-11-12 19:39:36 +0000499 ruleString := bp.Rule.String()
500 if ruleString == "android/soong/android.Cp" {
Jiyong Park232e7852019-11-04 12:23:40 +0900501 copySrcs = append(copySrcs, bp.Input.String())
502 copyDests = append(copyDests, bp.Output.Rel()) // rooted at the snapshot root
Paul Duffin91547182019-11-12 19:39:36 +0000503 } else if ruleString == "<local rule>:m.mysdk_android_common.snapshot" {
504 zipBp = bp
Jiyong Park232e7852019-11-04 12:23:40 +0900505 }
506 }
507
508 buildDir := config.BuildDir()
509 ensureListContains(t, copySrcs, "aidl/foo/bar/Test.aidl")
510 ensureListContains(t, copySrcs, "include/Test.h")
511 ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/BnTest.h"))
512 ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/BpTest.h"))
513 ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/Test.h"))
514 ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/myjavalib/android_common/turbine-combined/myjavalib.jar"))
515 ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/mynativelib.so"))
516
517 ensureListContains(t, copyDests, "aidl/aidl/foo/bar/Test.aidl")
518 ensureListContains(t, copyDests, "arm64/include/include/Test.h")
519 ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/BnTest.h")
520 ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/BpTest.h")
521 ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/Test.h")
522 ensureListContains(t, copyDests, "java/myjavalib.jar")
523 ensureListContains(t, copyDests, "arm64/lib/mynativelib.so")
Paul Duffin91547182019-11-12 19:39:36 +0000524
525 // Ensure that the droidstubs .srcjar as repackaged into a temporary zip file
526 // and then merged together with the intermediate snapshot zip.
527 snapshotCreationInputs := zipBp.Implicits.Strings()
528 ensureListContains(t, snapshotCreationInputs,
529 filepath.Join(buildDir, ".intermediates/mysdk/android_common/tmp/java/myjavaapistubs_stubs_sources.zip"))
530 ensureListContains(t, snapshotCreationInputs,
531 filepath.Join(buildDir, ".intermediates/mysdk/android_common/mysdk-current.unmerged.zip"))
532 actual := zipBp.Output.String()
533 expected := filepath.Join(buildDir, ".intermediates/mysdk/android_common/mysdk-current.zip")
534 if actual != expected {
535 t.Errorf("Expected snapshot output to be %q but was %q", expected, actual)
536 }
Jiyong Park232e7852019-11-04 12:23:40 +0900537}
538
Jiyong Parkd1063c12019-07-17 20:08:41 +0900539var buildDir string
540
541func setUp() {
542 var err error
543 buildDir, err = ioutil.TempDir("", "soong_sdk_test")
544 if err != nil {
545 panic(err)
546 }
547}
548
549func tearDown() {
550 os.RemoveAll(buildDir)
551}
552
553func TestMain(m *testing.M) {
554 run := func() int {
555 setUp()
556 defer tearDown()
557
558 return m.Run()
559 }
560
561 os.Exit(run())
562}