blob: 96129b838e59298657819c55a19c52646519a356 [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"
20 "strings"
21 "testing"
22
23 "android/soong/android"
24 "android/soong/apex"
25 "android/soong/cc"
26 "android/soong/java"
27)
28
29func testSdkContext(t *testing.T, bp string) (*android.TestContext, android.Config) {
30 config := android.TestArchConfig(buildDir, nil)
31 ctx := android.NewTestArchContext()
32
33 // from android package
34 ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
35 ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
36 ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
37 })
38 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
39 ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
40 ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
41 })
42
43 // from java package
44 ctx.RegisterModuleType("android_app_certificate", android.ModuleFactoryAdaptor(java.AndroidAppCertificateFactory))
45 ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory))
46 ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory))
47
48 // from cc package
49 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
50 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory))
51 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
52 ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(cc.PrebuiltSharedLibraryFactory))
53 ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(cc.PrebuiltStaticLibraryFactory))
54 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory))
55 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
56 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
57 ctx.BottomUp("image", cc.ImageMutator).Parallel()
58 ctx.BottomUp("link", cc.LinkageMutator).Parallel()
59 ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
60 ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
61 ctx.BottomUp("version", cc.VersionMutator).Parallel()
62 ctx.BottomUp("begin", cc.BeginMutator).Parallel()
63 })
64
65 // from apex package
66 ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apex.BundleFactory))
67 ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apex.ApexKeyFactory))
68 ctx.PostDepsMutators(apex.RegisterPostDepsMutators)
69
70 // from this package
71 ctx.RegisterModuleType("sdk", android.ModuleFactoryAdaptor(ModuleFactory))
Jiyong Park9b409bc2019-10-11 14:59:13 +090072 ctx.RegisterModuleType("sdk_snapshot", android.ModuleFactoryAdaptor(SnapshotModuleFactory))
Jiyong Parkd1063c12019-07-17 20:08:41 +090073 ctx.PreDepsMutators(RegisterPreDepsMutators)
74 ctx.PostDepsMutators(RegisterPostDepsMutators)
75
76 ctx.Register()
77
78 bp = bp + `
79 apex_key {
80 name: "myapex.key",
81 public_key: "myapex.avbpubkey",
82 private_key: "myapex.pem",
83 }
84
85 android_app_certificate {
86 name: "myapex.cert",
87 certificate: "myapex",
88 }
89 ` + cc.GatherRequiredDepsForTest(android.Android)
90
91 ctx.MockFileSystem(map[string][]byte{
92 "Android.bp": []byte(bp),
93 "build/make/target/product/security": nil,
94 "apex_manifest.json": nil,
95 "system/sepolicy/apex/myapex-file_contexts": nil,
96 "system/sepolicy/apex/myapex2-file_contexts": nil,
97 "myapex.avbpubkey": nil,
98 "myapex.pem": nil,
99 "myapex.x509.pem": nil,
100 "myapex.pk8": nil,
101 "Test.java": nil,
102 "Test.cpp": nil,
103 "libfoo.so": nil,
104 })
105
106 return ctx, config
107}
108
109func testSdk(t *testing.T, bp string) (*android.TestContext, android.Config) {
110 ctx, config := testSdkContext(t, bp)
111 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
112 android.FailIfErrored(t, errs)
113 _, errs = ctx.PrepareBuildActions(config)
114 android.FailIfErrored(t, errs)
115 return ctx, config
116}
117
Jiyong Parka7bc8ad2019-10-15 15:20:07 +0900118func testSdkError(t *testing.T, pattern, bp string) {
119 t.Helper()
120 ctx, config := testSdkContext(t, bp)
121 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
122 if len(errs) > 0 {
123 android.FailIfNoMatchingErrors(t, pattern, errs)
124 return
125 }
126 _, errs = ctx.PrepareBuildActions(config)
127 if len(errs) > 0 {
128 android.FailIfNoMatchingErrors(t, pattern, errs)
129 return
130 }
131
132 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
133}
134
Jiyong Parkd1063c12019-07-17 20:08:41 +0900135// ensure that 'result' contains 'expected'
136func ensureContains(t *testing.T, result string, expected string) {
137 t.Helper()
138 if !strings.Contains(result, expected) {
139 t.Errorf("%q is not found in %q", expected, result)
140 }
141}
142
143// ensures that 'result' does not contain 'notExpected'
144func ensureNotContains(t *testing.T, result string, notExpected string) {
145 t.Helper()
146 if strings.Contains(result, notExpected) {
147 t.Errorf("%q is found in %q", notExpected, result)
148 }
149}
150
151func ensureListContains(t *testing.T, result []string, expected string) {
152 t.Helper()
153 if !android.InList(expected, result) {
154 t.Errorf("%q is not found in %v", expected, result)
155 }
156}
157
158func ensureListNotContains(t *testing.T, result []string, notExpected string) {
159 t.Helper()
160 if android.InList(notExpected, result) {
161 t.Errorf("%q is found in %v", notExpected, result)
162 }
163}
164
165func pathsToStrings(paths android.Paths) []string {
166 ret := []string{}
167 for _, p := range paths {
168 ret = append(ret, p.String())
169 }
170 return ret
171}
172
173func TestBasicSdkWithJava(t *testing.T) {
174 ctx, _ := testSdk(t, `
175 sdk {
Jiyong Park9b409bc2019-10-11 14:59:13 +0900176 name: "mysdk",
177 java_libs: ["sdkmember"],
178 }
179
180 sdk_snapshot {
181 name: "mysdk@1",
Jiyong Parkd1063c12019-07-17 20:08:41 +0900182 java_libs: ["sdkmember_mysdk_1"],
183 }
184
Jiyong Park9b409bc2019-10-11 14:59:13 +0900185 sdk_snapshot {
186 name: "mysdk@2",
Jiyong Parkd1063c12019-07-17 20:08:41 +0900187 java_libs: ["sdkmember_mysdk_2"],
188 }
189
190 java_import {
191 name: "sdkmember",
192 prefer: false,
193 host_supported: true,
194 }
195
196 java_import {
197 name: "sdkmember_mysdk_1",
198 sdk_member_name: "sdkmember",
199 host_supported: true,
200 }
201
202 java_import {
203 name: "sdkmember_mysdk_2",
204 sdk_member_name: "sdkmember",
205 host_supported: true,
206 }
207
208 java_library {
209 name: "myjavalib",
210 srcs: ["Test.java"],
211 libs: ["sdkmember"],
212 system_modules: "none",
213 sdk_version: "none",
214 compile_dex: true,
215 host_supported: true,
216 }
217
218 apex {
219 name: "myapex",
220 java_libs: ["myjavalib"],
Jiyong Park9b409bc2019-10-11 14:59:13 +0900221 uses_sdks: ["mysdk@1"],
Jiyong Parkd1063c12019-07-17 20:08:41 +0900222 key: "myapex.key",
223 certificate: ":myapex.cert",
224 }
225
226 apex {
227 name: "myapex2",
228 java_libs: ["myjavalib"],
Jiyong Park9b409bc2019-10-11 14:59:13 +0900229 uses_sdks: ["mysdk@2"],
Jiyong Parkd1063c12019-07-17 20:08:41 +0900230 key: "myapex.key",
231 certificate: ":myapex.cert",
232 }
233 `)
234
235 sdkMemberV1 := ctx.ModuleForTests("sdkmember_mysdk_1", "android_common_myapex").Rule("combineJar").Output
236 sdkMemberV2 := ctx.ModuleForTests("sdkmember_mysdk_2", "android_common_myapex2").Rule("combineJar").Output
237
238 javalibForMyApex := ctx.ModuleForTests("myjavalib", "android_common_myapex")
239 javalibForMyApex2 := ctx.ModuleForTests("myjavalib", "android_common_myapex2")
240
241 // Depending on the uses_sdks value, different libs are linked
242 ensureListContains(t, pathsToStrings(javalibForMyApex.Rule("javac").Implicits), sdkMemberV1.String())
243 ensureListContains(t, pathsToStrings(javalibForMyApex2.Rule("javac").Implicits), sdkMemberV2.String())
244}
245
246func TestBasicSdkWithCc(t *testing.T) {
247 ctx, _ := testSdk(t, `
248 sdk {
Jiyong Park9b409bc2019-10-11 14:59:13 +0900249 name: "mysdk",
250 native_shared_libs: ["sdkmember"],
251 }
252
253 sdk_snapshot {
254 name: "mysdk@1",
Jiyong Parkd1063c12019-07-17 20:08:41 +0900255 native_shared_libs: ["sdkmember_mysdk_1"],
256 }
257
Jiyong Park9b409bc2019-10-11 14:59:13 +0900258 sdk_snapshot {
259 name: "mysdk@2",
Jiyong Parkd1063c12019-07-17 20:08:41 +0900260 native_shared_libs: ["sdkmember_mysdk_2"],
261 }
262
263 cc_prebuilt_library_shared {
264 name: "sdkmember",
265 srcs: ["libfoo.so"],
266 prefer: false,
267 system_shared_libs: [],
268 stl: "none",
269 }
270
271 cc_prebuilt_library_shared {
272 name: "sdkmember_mysdk_1",
273 sdk_member_name: "sdkmember",
274 srcs: ["libfoo.so"],
275 system_shared_libs: [],
276 stl: "none",
277 }
278
279 cc_prebuilt_library_shared {
280 name: "sdkmember_mysdk_2",
281 sdk_member_name: "sdkmember",
282 srcs: ["libfoo.so"],
283 system_shared_libs: [],
284 stl: "none",
285 }
286
287 cc_library_shared {
288 name: "mycpplib",
289 srcs: ["Test.cpp"],
290 shared_libs: ["sdkmember"],
291 system_shared_libs: [],
292 stl: "none",
293 }
294
295 apex {
296 name: "myapex",
297 native_shared_libs: ["mycpplib"],
Jiyong Park9b409bc2019-10-11 14:59:13 +0900298 uses_sdks: ["mysdk@1"],
Jiyong Parkd1063c12019-07-17 20:08:41 +0900299 key: "myapex.key",
300 certificate: ":myapex.cert",
301 }
302
303 apex {
304 name: "myapex2",
305 native_shared_libs: ["mycpplib"],
Jiyong Park9b409bc2019-10-11 14:59:13 +0900306 uses_sdks: ["mysdk@2"],
Jiyong Parkd1063c12019-07-17 20:08:41 +0900307 key: "myapex.key",
308 certificate: ":myapex.cert",
309 }
310 `)
311
312 sdkMemberV1 := ctx.ModuleForTests("sdkmember_mysdk_1", "android_arm64_armv8-a_core_shared_myapex").Rule("toc").Output
313 sdkMemberV2 := ctx.ModuleForTests("sdkmember_mysdk_2", "android_arm64_armv8-a_core_shared_myapex2").Rule("toc").Output
314
315 cpplibForMyApex := ctx.ModuleForTests("mycpplib", "android_arm64_armv8-a_core_shared_myapex")
316 cpplibForMyApex2 := ctx.ModuleForTests("mycpplib", "android_arm64_armv8-a_core_shared_myapex2")
317
318 // Depending on the uses_sdks value, different libs are linked
319 ensureListContains(t, pathsToStrings(cpplibForMyApex.Rule("ld").Implicits), sdkMemberV1.String())
320 ensureListContains(t, pathsToStrings(cpplibForMyApex2.Rule("ld").Implicits), sdkMemberV2.String())
321}
322
Jiyong Parka7bc8ad2019-10-15 15:20:07 +0900323func TestDepNotInRequiredSdks(t *testing.T) {
324 testSdkError(t, `module "myjavalib".*depends on "otherlib".*that isn't part of the required SDKs:.*`, `
325 sdk {
326 name: "mysdk",
327 java_libs: ["sdkmember"],
328 }
329
330 sdk_snapshot {
331 name: "mysdk@1",
332 java_libs: ["sdkmember_mysdk_1"],
333 }
334
335 java_import {
336 name: "sdkmember",
337 prefer: false,
338 host_supported: true,
339 }
340
341 java_import {
342 name: "sdkmember_mysdk_1",
343 sdk_member_name: "sdkmember",
344 host_supported: true,
345 }
346
347 java_library {
348 name: "myjavalib",
349 srcs: ["Test.java"],
350 libs: [
351 "sdkmember",
352 "otherlib",
353 ],
354 system_modules: "none",
355 sdk_version: "none",
356 compile_dex: true,
357 host_supported: true,
358 }
359
360 // this lib is no in mysdk
361 java_library {
362 name: "otherlib",
363 srcs: ["Test.java"],
364 system_modules: "none",
365 sdk_version: "none",
366 compile_dex: true,
367 host_supported: true,
368 }
369
370 apex {
371 name: "myapex",
372 java_libs: ["myjavalib"],
373 uses_sdks: ["mysdk@1"],
374 key: "myapex.key",
375 certificate: ":myapex.cert",
376 }
377 `)
378}
379
Jiyong Park100f3fd2019-11-06 16:03:32 +0900380func TestSdkIsCompileMultilibBoth(t *testing.T) {
381 ctx, _ := testSdk(t, `
382 sdk {
383 name: "mysdk",
384 native_shared_libs: ["sdkmember"],
385 }
386
387 cc_library_shared {
388 name: "sdkmember",
389 srcs: ["Test.cpp"],
390 system_shared_libs: [],
391 stl: "none",
392 }
393 `)
394
395 armOutput := ctx.ModuleForTests("sdkmember", "android_arm_armv7-a-neon_core_shared").Module().(*cc.Module).OutputFile()
396 arm64Output := ctx.ModuleForTests("sdkmember", "android_arm64_armv8-a_core_shared").Module().(*cc.Module).OutputFile()
397
398 var inputs []string
399 buildParams := ctx.ModuleForTests("mysdk", "android_common").Module().BuildParamsForTests()
400 for _, bp := range buildParams {
401 inputs = append(inputs, bp.Implicits.Strings()...)
402 }
403
404 // ensure that both 32/64 outputs are inputs of the sdk snapshot
405 ensureListContains(t, inputs, armOutput.String())
406 ensureListContains(t, inputs, arm64Output.String())
407}
408
Jiyong Parkd1063c12019-07-17 20:08:41 +0900409var buildDir string
410
411func setUp() {
412 var err error
413 buildDir, err = ioutil.TempDir("", "soong_sdk_test")
414 if err != nil {
415 panic(err)
416 }
417}
418
419func tearDown() {
420 os.RemoveAll(buildDir)
421}
422
423func TestMain(m *testing.M) {
424 run := func() int {
425 setUp()
426 defer tearDown()
427
428 return m.Run()
429 }
430
431 os.Exit(run())
432}