blob: 9c5680b0cdb1ff3dfddfdfe2d00f9e7eb5291f2d [file] [log] [blame]
Colin Cross72bb3632017-07-13 16:23:21 -07001// Copyright 2017 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 java
16
17import (
Colin Cross72bb3632017-07-13 16:23:21 -070018 "io/ioutil"
19 "os"
20 "path/filepath"
Colin Crossc0806172019-06-14 18:51:47 -070021 "reflect"
Nan Zhang61eaedb2017-11-02 13:28:15 -070022 "strconv"
Colin Cross72bb3632017-07-13 16:23:21 -070023 "strings"
24 "testing"
Colin Cross86a60ae2018-05-29 14:44:55 -070025
Jeongik Cha28df2572019-11-11 10:46:36 +090026 "github.com/google/blueprint/proptools"
27
Colin Crossa4f08812018-10-02 22:03:40 -070028 "android/soong/android"
29 "android/soong/cc"
Colin Crossc28bb0b2019-02-25 14:20:47 -080030 "android/soong/dexpreopt"
Colin Crossa4f08812018-10-02 22:03:40 -070031 "android/soong/genrule"
Colin Cross72bb3632017-07-13 16:23:21 -070032)
33
34var buildDir string
35
36func setUp() {
37 var err error
38 buildDir, err = ioutil.TempDir("", "soong_java_test")
39 if err != nil {
40 panic(err)
41 }
42}
43
44func tearDown() {
45 os.RemoveAll(buildDir)
46}
47
48func TestMain(m *testing.M) {
49 run := func() int {
50 setUp()
51 defer tearDown()
52
53 return m.Run()
54 }
55
56 os.Exit(run())
57}
Colin Cross527012a2017-11-30 22:56:16 -080058
Colin Cross98be1bb2019-12-13 20:41:13 -080059func testConfig(env map[string]string, bp string, fs map[string][]byte) android.Config {
Martin Stjernholm75a48d82020-01-10 20:32:59 +000060 config := TestConfig(buildDir, env, bp, fs)
61
62 // Set up the global Once cache used for dexpreopt.GlobalSoongConfig, so that
63 // it doesn't create a real one, which would fail.
64 _ = dexpreopt.GlobalSoongConfigForTests(config)
65
66 return config
Colin Cross1369cdb2017-09-29 17:58:17 -070067}
68
Colin Cross98be1bb2019-12-13 20:41:13 -080069func testContext() *android.TestContext {
Colin Cross72bb3632017-07-13 16:23:21 -070070
Colin Cross4c428df2017-09-15 17:36:05 -070071 ctx := android.NewTestArchContext()
Paul Duffinf9b1da02019-12-18 19:51:55 +000072 RegisterJavaBuildComponents(ctx)
73 RegisterAppBuildComponents(ctx)
74 RegisterAARBuildComponents(ctx)
Paul Duffinb0f85072019-12-19 10:28:56 +000075 RegisterGenRuleBuildComponents(ctx)
Paul Duffin43dc1cc2019-12-19 11:18:54 +000076 RegisterSystemModulesBuildComponents(ctx)
Colin Cross4b49b762019-11-22 15:25:03 -080077 ctx.RegisterModuleType("java_plugin", PluginFactory)
Colin Cross4b49b762019-11-22 15:25:03 -080078 ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
79 ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
Paul Duffin884363e2019-12-19 10:21:09 +000080 RegisterDocsBuildComponents(ctx)
81 RegisterStubsBuildComponents(ctx)
Paul Duffin43dc1cc2019-12-19 11:18:54 +000082 RegisterSdkLibraryBuildComponents(ctx)
Colin Cross89536d42017-07-07 14:35:50 -070083 ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
Paul Duffina48f7582019-12-19 11:25:19 +000084
85 RegisterPrebuiltApisBuildComponents(ctx)
86
Jaewoong Jungb639a6a2019-05-10 15:16:29 -070087 ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080088 ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
Colin Cross3047fa22019-04-18 10:56:44 -070089 ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory))
Colin Crossa4f08812018-10-02 22:03:40 -070090
91 // Register module types and mutators from cc needed for JNI testing
Paul Duffin77980a82019-12-19 16:01:36 +000092 cc.RegisterRequiredBuildComponentsForTest(ctx)
Colin Cross4b49b762019-11-22 15:25:03 -080093 ctx.RegisterModuleType("ndk_prebuilt_shared_stl", cc.NdkPrebuiltSharedStlFactory)
Colin Crossa4f08812018-10-02 22:03:40 -070094
Colin Cross527012a2017-11-30 22:56:16 -080095 return ctx
96}
97
98func run(t *testing.T, ctx *android.TestContext, config android.Config) {
Colin Cross6b4a32d2017-12-05 13:42:45 -080099 t.Helper()
Colin Crossc28bb0b2019-02-25 14:20:47 -0800100
Colin Cross98be1bb2019-12-13 20:41:13 -0800101 pathCtx := android.PathContextForTesting(config)
Hans Boehm453bf092020-01-25 01:44:30 +0000102 setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
Colin Crossc28bb0b2019-02-25 14:20:47 -0800103
Colin Cross98be1bb2019-12-13 20:41:13 -0800104 ctx.Register(config)
Paul Duffinbaccf7e2019-06-11 11:58:30 +0100105 _, errs := ctx.ParseBlueprintsFiles("Android.bp")
Logan Chien42039712018-03-12 16:29:17 +0800106 android.FailIfErrored(t, errs)
Colin Cross72bb3632017-07-13 16:23:21 -0700107 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800108 android.FailIfErrored(t, errs)
Colin Cross527012a2017-11-30 22:56:16 -0800109}
110
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900111func testJavaError(t *testing.T, pattern string, bp string) (*android.TestContext, android.Config) {
Jeongik Cha538c0d02019-07-11 15:54:27 +0900112 t.Helper()
Colin Cross98be1bb2019-12-13 20:41:13 -0800113 return testJavaErrorWithConfig(t, pattern, testConfig(nil, bp, nil))
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900114}
115
Colin Cross98be1bb2019-12-13 20:41:13 -0800116func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config) (*android.TestContext, android.Config) {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900117 t.Helper()
Colin Cross98be1bb2019-12-13 20:41:13 -0800118 ctx := testContext()
Jeongik Cha538c0d02019-07-11 15:54:27 +0900119
Colin Cross98be1bb2019-12-13 20:41:13 -0800120 pathCtx := android.PathContextForTesting(config)
Hans Boehm453bf092020-01-25 01:44:30 +0000121 setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
Jeongik Cha538c0d02019-07-11 15:54:27 +0900122
Colin Cross98be1bb2019-12-13 20:41:13 -0800123 ctx.Register(config)
Jeongik Cha538c0d02019-07-11 15:54:27 +0900124 _, errs := ctx.ParseBlueprintsFiles("Android.bp")
125 if len(errs) > 0 {
126 android.FailIfNoMatchingErrors(t, pattern, errs)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900127 return ctx, config
Jeongik Cha538c0d02019-07-11 15:54:27 +0900128 }
129 _, errs = ctx.PrepareBuildActions(config)
130 if len(errs) > 0 {
131 android.FailIfNoMatchingErrors(t, pattern, errs)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900132 return ctx, config
Jeongik Cha538c0d02019-07-11 15:54:27 +0900133 }
134
135 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900136
137 return ctx, config
Jeongik Cha538c0d02019-07-11 15:54:27 +0900138}
139
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700140func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) {
Colin Cross6b4a32d2017-12-05 13:42:45 -0800141 t.Helper()
Colin Cross98be1bb2019-12-13 20:41:13 -0800142 return testJavaWithConfig(t, testConfig(nil, bp, nil))
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900143}
144
Colin Cross98be1bb2019-12-13 20:41:13 -0800145func testJavaWithConfig(t *testing.T, config android.Config) (*android.TestContext, android.Config) {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900146 t.Helper()
Colin Cross98be1bb2019-12-13 20:41:13 -0800147 ctx := testContext()
Colin Cross527012a2017-11-30 22:56:16 -0800148 run(t, ctx, config)
Colin Cross72bb3632017-07-13 16:23:21 -0700149
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700150 return ctx, config
Colin Cross72bb3632017-07-13 16:23:21 -0700151}
152
Colin Cross2acdae82017-09-15 19:44:24 -0700153func moduleToPath(name string) string {
154 switch {
155 case name == `""`:
156 return name
Colin Crossfc3674a2017-09-18 17:41:52 -0700157 case strings.HasSuffix(name, ".jar"):
158 return name
Nan Zhanged19fc32017-10-19 13:06:22 -0700159 default:
160 return filepath.Join(buildDir, ".intermediates", name, "android_common", "turbine-combined", name+".jar")
Colin Cross2acdae82017-09-15 19:44:24 -0700161 }
162}
163
Jeongik Chae403e9e2019-12-07 00:16:24 +0900164func TestJavaLinkType(t *testing.T) {
165 testJava(t, `
166 java_library {
167 name: "foo",
168 srcs: ["a.java"],
169 libs: ["bar"],
170 static_libs: ["baz"],
171 }
172
173 java_library {
174 name: "bar",
175 sdk_version: "current",
176 srcs: ["b.java"],
177 }
178
179 java_library {
180 name: "baz",
181 sdk_version: "system_current",
182 srcs: ["c.java"],
183 }
184 `)
185
186 testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
187 java_library {
188 name: "foo",
189 srcs: ["a.java"],
190 libs: ["bar"],
191 sdk_version: "current",
192 static_libs: ["baz"],
193 }
194
195 java_library {
196 name: "bar",
197 sdk_version: "current",
198 srcs: ["b.java"],
199 }
200
201 java_library {
202 name: "baz",
203 sdk_version: "system_current",
204 srcs: ["c.java"],
205 }
206 `)
207
208 testJava(t, `
209 java_library {
210 name: "foo",
211 srcs: ["a.java"],
212 libs: ["bar"],
213 sdk_version: "system_current",
214 static_libs: ["baz"],
215 }
216
217 java_library {
218 name: "bar",
219 sdk_version: "current",
220 srcs: ["b.java"],
221 }
222
223 java_library {
224 name: "baz",
225 sdk_version: "system_current",
226 srcs: ["c.java"],
227 }
228 `)
229
230 testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
231 java_library {
232 name: "foo",
233 srcs: ["a.java"],
234 libs: ["bar"],
235 sdk_version: "system_current",
236 static_libs: ["baz"],
237 }
238
239 java_library {
240 name: "bar",
241 sdk_version: "current",
242 srcs: ["b.java"],
243 }
244
245 java_library {
246 name: "baz",
247 srcs: ["c.java"],
248 }
249 `)
250}
251
Colin Cross72bb3632017-07-13 16:23:21 -0700252func TestSimple(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700253 ctx, _ := testJava(t, `
Colin Cross72bb3632017-07-13 16:23:21 -0700254 java_library {
255 name: "foo",
256 srcs: ["a.java"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700257 libs: ["bar"],
258 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700259 }
260
261 java_library {
262 name: "bar",
263 srcs: ["b.java"],
264 }
265
266 java_library {
267 name: "baz",
268 srcs: ["c.java"],
269 }
Colin Crossd5934c82017-10-02 13:55:26 -0700270 `)
Colin Cross72bb3632017-07-13 16:23:21 -0700271
Colin Cross4c428df2017-09-15 17:36:05 -0700272 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700273 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Colin Cross72bb3632017-07-13 16:23:21 -0700274
275 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
276 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
277 }
278
Colin Cross1ee23172017-10-18 14:44:18 -0700279 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
Nan Zhanged19fc32017-10-19 13:06:22 -0700280 barTurbine := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
281 bazTurbine := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "turbine-combined", "baz.jar")
Colin Cross0a6e0072017-08-30 14:24:55 -0700282
Nan Zhanged19fc32017-10-19 13:06:22 -0700283 if !strings.Contains(javac.Args["classpath"], barTurbine) {
284 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
Colin Cross72bb3632017-07-13 16:23:21 -0700285 }
286
Nan Zhanged19fc32017-10-19 13:06:22 -0700287 if !strings.Contains(javac.Args["classpath"], bazTurbine) {
288 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bazTurbine)
Colin Cross0a6e0072017-08-30 14:24:55 -0700289 }
290
291 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
292 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross72bb3632017-07-13 16:23:21 -0700293 }
294}
295
Artur Satayev9cf46692019-11-26 18:08:34 +0000296func TestExportedPlugins(t *testing.T) {
297 type Result struct {
298 library string
299 processors string
300 }
301 var tests = []struct {
302 name string
303 extra string
304 results []Result
305 }{
306 {
307 name: "Exported plugin is not a direct plugin",
308 extra: `java_library { name: "exports", srcs: ["a.java"], exported_plugins: ["plugin"] }`,
309 results: []Result{{library: "exports", processors: "-proc:none"}},
310 },
311 {
312 name: "Exports plugin to dependee",
313 extra: `
314 java_library{name: "exports", exported_plugins: ["plugin"]}
315 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
316 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
317 `,
318 results: []Result{
319 {library: "foo", processors: "-processor com.android.TestPlugin"},
320 {library: "bar", processors: "-processor com.android.TestPlugin"},
321 },
322 },
323 {
324 name: "Exports plugin to android_library",
325 extra: `
326 java_library{name: "exports", exported_plugins: ["plugin"]}
327 android_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
328 android_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
329 `,
330 results: []Result{
331 {library: "foo", processors: "-processor com.android.TestPlugin"},
332 {library: "bar", processors: "-processor com.android.TestPlugin"},
333 },
334 },
335 {
336 name: "Exports plugin is not propagated via transitive deps",
337 extra: `
338 java_library{name: "exports", exported_plugins: ["plugin"]}
339 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
340 java_library{name: "bar", srcs: ["a.java"], static_libs: ["foo"]}
341 `,
342 results: []Result{
343 {library: "foo", processors: "-processor com.android.TestPlugin"},
344 {library: "bar", processors: "-proc:none"},
345 },
346 },
347 {
348 name: "Exports plugin appends to plugins",
349 extra: `
350 java_plugin{name: "plugin2", processor_class: "com.android.TestPlugin2"}
351 java_library{name: "exports", exported_plugins: ["plugin"]}
352 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"], plugins: ["plugin2"]}
353 `,
354 results: []Result{
355 {library: "foo", processors: "-processor com.android.TestPlugin,com.android.TestPlugin2"},
356 },
357 },
358 }
359
360 for _, test := range tests {
361 t.Run(test.name, func(t *testing.T) {
362 ctx, _ := testJava(t, `
363 java_plugin {
364 name: "plugin",
365 processor_class: "com.android.TestPlugin",
366 }
367 `+test.extra)
368
369 for _, want := range test.results {
370 javac := ctx.ModuleForTests(want.library, "android_common").Rule("javac")
371 if javac.Args["processor"] != want.processors {
372 t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"])
373 }
374 }
375 })
376 }
377}
378
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900379func TestSdkVersionByPartition(t *testing.T) {
380 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900381 java_library {
382 name: "foo",
383 srcs: ["a.java"],
384 vendor: true,
385 }
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900386 `)
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900387
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900388 testJava(t, `
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900389 java_library {
390 name: "bar",
391 srcs: ["b.java"],
392 }
393 `)
394
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900395 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900396 bp := `
397 java_library {
398 name: "foo",
399 srcs: ["a.java"],
400 product_specific: true,
401 }
402 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800403
404 config := testConfig(nil, bp, nil)
405 config.TestProductVariables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900406 if enforce {
Colin Cross98be1bb2019-12-13 20:41:13 -0800407 testJavaErrorWithConfig(t, "sdk_version must have a value when the module is located at vendor or product", config)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900408 } else {
Colin Cross98be1bb2019-12-13 20:41:13 -0800409 testJavaWithConfig(t, config)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900410 }
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900411 }
412}
413
Colin Crossd5934c82017-10-02 13:55:26 -0700414func TestArchSpecific(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700415 ctx, _ := testJava(t, `
Colin Crossd5934c82017-10-02 13:55:26 -0700416 java_library {
417 name: "foo",
418 srcs: ["a.java"],
419 target: {
420 android: {
421 srcs: ["b.java"],
422 },
423 },
424 }
425 `)
426
427 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
428 if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" {
429 t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs)
430 }
431}
432
Colin Cross6b4a32d2017-12-05 13:42:45 -0800433func TestBinary(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700434 ctx, _ := testJava(t, `
Colin Cross6b4a32d2017-12-05 13:42:45 -0800435 java_library_host {
436 name: "foo",
437 srcs: ["a.java"],
438 }
439
440 java_binary_host {
441 name: "bar",
442 srcs: ["b.java"],
443 static_libs: ["foo"],
444 }
445 `)
446
447 buildOS := android.BuildOs.String()
448
449 bar := ctx.ModuleForTests("bar", buildOS+"_common")
450 barJar := bar.Output("bar.jar").Output.String()
451 barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64")
452 barWrapperDeps := barWrapper.Output("bar").Implicits.Strings()
453
454 // Test that the install binary wrapper depends on the installed jar file
455 if len(barWrapperDeps) != 1 || barWrapperDeps[0] != barJar {
456 t.Errorf("expected binary wrapper implicits [%q], got %v",
457 barJar, barWrapperDeps)
458 }
459
460}
461
Colin Cross72bb3632017-07-13 16:23:21 -0700462func TestPrebuilts(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700463 ctx, _ := testJava(t, `
Colin Cross72bb3632017-07-13 16:23:21 -0700464 java_library {
465 name: "foo",
Paul Duffin91547182019-11-12 19:39:36 +0000466 srcs: ["a.java", ":stubs-source"],
Paul Duffinfcfd7912020-01-31 17:54:30 +0000467 libs: ["bar", "sdklib"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700468 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700469 }
470
Colin Cross74d73e22017-08-02 11:05:49 -0700471 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700472 name: "bar",
Colin Cross74d73e22017-08-02 11:05:49 -0700473 jars: ["a.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700474 }
475
Colin Cross74d73e22017-08-02 11:05:49 -0700476 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700477 name: "baz",
Colin Cross74d73e22017-08-02 11:05:49 -0700478 jars: ["b.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700479 }
Colin Cross42be7612019-02-21 18:12:14 -0800480
481 dex_import {
482 name: "qux",
483 jars: ["b.jar"],
484 }
Colin Cross79c7c262019-04-17 11:11:46 -0700485
486 java_sdk_library_import {
Paul Duffin56d44902020-01-31 13:36:25 +0000487 name: "sdklib",
488 public: {
489 jars: ["c.jar"],
490 },
491 }
492
Paul Duffin91547182019-11-12 19:39:36 +0000493 prebuilt_stubs_sources {
494 name: "stubs-source",
Paul Duffin9b478b02019-12-10 13:41:51 +0000495 srcs: ["stubs/sources"],
Paul Duffin91547182019-11-12 19:39:36 +0000496 }
Paul Duffin1b82e6a2019-12-03 18:06:47 +0000497
498 java_test_import {
499 name: "test",
500 jars: ["a.jar"],
501 test_suites: ["cts"],
502 test_config: "AndroidTest.xml",
503 }
Colin Cross72bb3632017-07-13 16:23:21 -0700504 `)
505
Paul Duffin9b478b02019-12-10 13:41:51 +0000506 fooModule := ctx.ModuleForTests("foo", "android_common")
507 javac := fooModule.Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700508 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Colin Cross37f6d792018-07-12 12:28:41 -0700509 barJar := ctx.ModuleForTests("bar", "android_common").Rule("combineJar").Output
510 bazJar := ctx.ModuleForTests("baz", "android_common").Rule("combineJar").Output
Colin Cross79c7c262019-04-17 11:11:46 -0700511 sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
Colin Cross72bb3632017-07-13 16:23:21 -0700512
Paul Duffin9b478b02019-12-10 13:41:51 +0000513 fooLibrary := fooModule.Module().(*Library)
514 assertDeepEquals(t, "foo java sources incorrect",
515 []string{"a.java"}, fooLibrary.compiledJavaSrcs.Strings())
Paul Duffin91547182019-11-12 19:39:36 +0000516
Paul Duffin9b478b02019-12-10 13:41:51 +0000517 assertDeepEquals(t, "foo java source jars incorrect",
518 []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"},
519 android.NormalizePathsForTesting(fooLibrary.compiledSrcJars))
Paul Duffin91547182019-11-12 19:39:36 +0000520
Colin Cross37f6d792018-07-12 12:28:41 -0700521 if !strings.Contains(javac.Args["classpath"], barJar.String()) {
522 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String())
Colin Cross72bb3632017-07-13 16:23:21 -0700523 }
524
Colin Cross79c7c262019-04-17 11:11:46 -0700525 if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
526 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String())
527 }
528
Colin Cross37f6d792018-07-12 12:28:41 -0700529 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() {
530 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
Colin Cross72bb3632017-07-13 16:23:21 -0700531 }
Colin Cross42be7612019-02-21 18:12:14 -0800532
533 ctx.ModuleForTests("qux", "android_common").Rule("Cp")
Colin Cross72bb3632017-07-13 16:23:21 -0700534}
535
Paul Duffin9b478b02019-12-10 13:41:51 +0000536func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) {
537 if !reflect.DeepEqual(expected, actual) {
538 t.Errorf("%s: expected %q, found %q", message, expected, actual)
539 }
540}
541
Paul Duffin56d44902020-01-31 13:36:25 +0000542func TestJavaSdkLibraryImport(t *testing.T) {
543 ctx, _ := testJava(t, `
544 java_library {
545 name: "foo",
546 srcs: ["a.java"],
547 libs: ["sdklib"],
548 sdk_version: "current",
549 }
550
551 java_library {
552 name: "foo.system",
553 srcs: ["a.java"],
554 libs: ["sdklib"],
555 sdk_version: "system_current",
556 }
557
558 java_library {
559 name: "foo.test",
560 srcs: ["a.java"],
561 libs: ["sdklib"],
562 sdk_version: "test_current",
563 }
564
565 java_sdk_library_import {
566 name: "sdklib",
567 public: {
568 jars: ["a.jar"],
569 },
570 system: {
571 jars: ["b.jar"],
572 },
573 test: {
574 jars: ["c.jar"],
575 },
576 }
577 `)
578
579 for _, scope := range []string{"", ".system", ".test"} {
580 fooModule := ctx.ModuleForTests("foo"+scope, "android_common")
581 javac := fooModule.Rule("javac")
582
583 sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs"+scope, "android_common").Rule("combineJar").Output
584 if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
585 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String())
586 }
587 }
588}
589
Colin Cross89536d42017-07-07 14:35:50 -0700590func TestDefaults(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700591 ctx, _ := testJava(t, `
Colin Cross89536d42017-07-07 14:35:50 -0700592 java_defaults {
593 name: "defaults",
594 srcs: ["a.java"],
595 libs: ["bar"],
596 static_libs: ["baz"],
Sasha Smundak2057f822019-04-16 17:16:58 -0700597 optimize: {enabled: false},
Colin Cross89536d42017-07-07 14:35:50 -0700598 }
599
600 java_library {
601 name: "foo",
602 defaults: ["defaults"],
603 }
604
605 java_library {
606 name: "bar",
607 srcs: ["b.java"],
608 }
609
610 java_library {
611 name: "baz",
612 srcs: ["c.java"],
613 }
Sasha Smundak2057f822019-04-16 17:16:58 -0700614
615 android_test {
616 name: "atestOptimize",
617 defaults: ["defaults"],
618 optimize: {enabled: true},
619 }
620
621 android_test {
622 name: "atestNoOptimize",
623 defaults: ["defaults"],
624 }
625
626 android_test {
627 name: "atestDefault",
628 srcs: ["a.java"],
629 }
Colin Cross89536d42017-07-07 14:35:50 -0700630 `)
631
Colin Cross4c428df2017-09-15 17:36:05 -0700632 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700633 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Colin Cross89536d42017-07-07 14:35:50 -0700634
635 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
636 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
637 }
638
Nan Zhanged19fc32017-10-19 13:06:22 -0700639 barTurbine := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
640 if !strings.Contains(javac.Args["classpath"], barTurbine) {
641 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
Colin Cross89536d42017-07-07 14:35:50 -0700642 }
643
Colin Cross1ee23172017-10-18 14:44:18 -0700644 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
Colin Cross0a6e0072017-08-30 14:24:55 -0700645 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
646 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross89536d42017-07-07 14:35:50 -0700647 }
Sasha Smundak2057f822019-04-16 17:16:58 -0700648
649 atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8")
650 if atestOptimize.Output == nil {
651 t.Errorf("atestOptimize should optimize APK")
652 }
653
654 atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8")
655 if atestNoOptimize.Output == nil {
656 t.Errorf("atestNoOptimize should not optimize APK")
657 }
658
659 atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("r8")
660 if atestDefault.Output == nil {
661 t.Errorf("atestDefault should optimize APK")
662 }
Colin Cross89536d42017-07-07 14:35:50 -0700663}
664
Colin Cross0f37af02017-09-27 17:42:05 -0700665func TestResources(t *testing.T) {
666 var table = []struct {
667 name string
668 prop string
669 extra string
670 args string
671 }{
672 {
Colin Crossaf9c55b2017-10-03 14:50:08 -0700673 // Test that a module with java_resource_dirs includes the files
Colin Cross0f37af02017-09-27 17:42:05 -0700674 name: "resource dirs",
Colin Cross824bee32017-11-22 17:27:51 -0800675 prop: `java_resource_dirs: ["java-res"]`,
Colin Cross0ead1d72018-04-10 13:07:42 -0700676 args: "-C java-res -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700677 },
678 {
679 // Test that a module with java_resources includes the files
680 name: "resource files",
Colin Cross0ead1d72018-04-10 13:07:42 -0700681 prop: `java_resources: ["java-res/a/a", "java-res/b/b"]`,
682 args: "-C . -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700683 },
684 {
685 // Test that a module with a filegroup in java_resources includes the files with the
686 // path prefix
687 name: "resource filegroup",
688 prop: `java_resources: [":foo-res"]`,
689 extra: `
690 filegroup {
691 name: "foo-res",
Colin Cross824bee32017-11-22 17:27:51 -0800692 path: "java-res",
Colin Cross0ead1d72018-04-10 13:07:42 -0700693 srcs: ["java-res/a/a", "java-res/b/b"],
Colin Cross0f37af02017-09-27 17:42:05 -0700694 }`,
Colin Cross0ead1d72018-04-10 13:07:42 -0700695 args: "-C java-res -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700696 },
697 {
Colin Cross0ead1d72018-04-10 13:07:42 -0700698 // Test that a module with wildcards in java_resource_dirs has the correct path prefixes
699 name: "wildcard dirs",
700 prop: `java_resource_dirs: ["java-res/*"]`,
701 args: "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b",
702 },
703 {
704 // Test that a module exclude_java_resource_dirs excludes the files
705 name: "wildcard dirs",
706 prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`,
707 args: "-C java-res/a -f java-res/a/a",
708 },
Colin Crosscedd4762018-09-13 11:26:19 -0700709 {
710 // Test wildcards in java_resources
711 name: "wildcard files",
712 prop: `java_resources: ["java-res/**/*"]`,
713 args: "-C . -f java-res/a/a -f java-res/b/b",
714 },
715 {
716 // Test exclude_java_resources with java_resources
717 name: "wildcard files with exclude",
718 prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`,
719 args: "-C . -f java-res/a/a",
720 },
721 {
722 // Test exclude_java_resources with java_resource_dirs
723 name: "resource dirs with exclude files",
724 prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`,
725 args: "-C java-res -f java-res/a/a",
726 },
727 {
728 // Test exclude_java_resource_dirs with java_resource_dirs
729 name: "resource dirs with exclude files",
730 prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`,
731 args: "-C java-res -f java-res/a/a -f java-res/b/b",
732 },
Colin Cross0f37af02017-09-27 17:42:05 -0700733 }
734
735 for _, test := range table {
736 t.Run(test.name, func(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700737 ctx, _ := testJava(t, `
Colin Cross0f37af02017-09-27 17:42:05 -0700738 java_library {
739 name: "foo",
740 srcs: [
741 "a.java",
742 "b.java",
743 "c.java",
744 ],
745 `+test.prop+`,
746 }
747 `+test.extra)
748
Colin Cross331a1212018-08-15 20:40:52 -0700749 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
Colin Cross1ee23172017-10-18 14:44:18 -0700750 fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar")
Colin Cross0f37af02017-09-27 17:42:05 -0700751
752 if !inList(fooRes.Output.String(), foo.Inputs.Strings()) {
753 t.Errorf("foo combined jars %v does not contain %q",
754 foo.Inputs.Strings(), fooRes.Output.String())
755 }
756
Colin Crossaf9c55b2017-10-03 14:50:08 -0700757 if fooRes.Args["jarArgs"] != test.args {
758 t.Errorf("foo resource jar args %q is not %q",
Colin Cross0f37af02017-09-27 17:42:05 -0700759 fooRes.Args["jarArgs"], test.args)
760 }
761 })
762 }
763}
764
Colin Cross0c4ce212019-05-03 15:28:19 -0700765func TestIncludeSrcs(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700766 ctx, _ := testJava(t, `
Colin Cross0c4ce212019-05-03 15:28:19 -0700767 java_library {
768 name: "foo",
769 srcs: [
770 "a.java",
771 "b.java",
772 "c.java",
773 ],
774 include_srcs: true,
775 }
776
777 java_library {
778 name: "bar",
779 srcs: [
780 "a.java",
781 "b.java",
782 "c.java",
783 ],
784 java_resource_dirs: ["java-res"],
785 include_srcs: true,
786 }
787 `)
788
789 // Test a library with include_srcs: true
790 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
791 fooSrcJar := ctx.ModuleForTests("foo", "android_common").Output("foo.srcjar")
792
793 if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) {
794 t.Errorf("foo combined jars %v does not contain %q", w, g)
795 }
796
797 if g, w := fooSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w {
798 t.Errorf("foo source jar args %q is not %q", w, g)
799 }
800
801 // Test a library with include_srcs: true and resources
802 bar := ctx.ModuleForTests("bar", "android_common").Output("withres/bar.jar")
803 barResCombined := ctx.ModuleForTests("bar", "android_common").Output("res-combined/bar.jar")
804 barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar")
805 barSrcJar := ctx.ModuleForTests("bar", "android_common").Output("bar.srcjar")
806
807 if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
808 t.Errorf("bar combined resource jars %v does not contain %q", w, g)
809 }
810
811 if g, w := barRes.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
812 t.Errorf("bar combined resource jars %v does not contain %q", w, g)
813 }
814
815 if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) {
816 t.Errorf("bar combined jars %v does not contain %q", w, g)
817 }
818
819 if g, w := barSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w {
820 t.Errorf("bar source jar args %q is not %q", w, g)
821 }
822
823 if g, w := barRes.Args["jarArgs"], "-C java-res -f java-res/a/a -f java-res/b/b"; g != w {
824 t.Errorf("bar resource jar args %q is not %q", w, g)
825 }
826}
827
Colin Cross54190b32017-10-09 15:34:10 -0700828func TestGeneratedSources(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700829 ctx, _ := testJava(t, `
Colin Cross54190b32017-10-09 15:34:10 -0700830 java_library {
831 name: "foo",
832 srcs: [
833 "a*.java",
834 ":gen",
835 "b*.java",
836 ],
837 }
838
839 genrule {
840 name: "gen",
Colin Cross824bee32017-11-22 17:27:51 -0800841 tool_files: ["java-res/a"],
Colin Cross54190b32017-10-09 15:34:10 -0700842 out: ["gen.java"],
843 }
844 `)
845
846 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
847 genrule := ctx.ModuleForTests("gen", "").Rule("generator")
848
Colin Cross15e86d92017-10-20 15:07:08 -0700849 if filepath.Base(genrule.Output.String()) != "gen.java" {
850 t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String())
Colin Cross54190b32017-10-09 15:34:10 -0700851 }
852
853 if len(javac.Inputs) != 3 ||
854 javac.Inputs[0].String() != "a.java" ||
Colin Cross15e86d92017-10-20 15:07:08 -0700855 javac.Inputs[1].String() != genrule.Output.String() ||
Colin Cross54190b32017-10-09 15:34:10 -0700856 javac.Inputs[2].String() != "b.java" {
857 t.Errorf(`foo inputs %v != ["a.java", ".../gen.java", "b.java"]`, javac.Inputs)
858 }
859}
860
Nan Zhang61eaedb2017-11-02 13:28:15 -0700861func TestTurbine(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700862 ctx, _ := testJava(t, `
Nan Zhang61eaedb2017-11-02 13:28:15 -0700863 java_library {
864 name: "foo",
865 srcs: ["a.java"],
Jiyong Park2d492942018-03-05 17:44:10 +0900866 sdk_version: "14",
Nan Zhang61eaedb2017-11-02 13:28:15 -0700867 }
868
869 java_library {
870 name: "bar",
Colin Cross9bc43432017-12-15 20:20:39 -0800871 srcs: ["b.java"],
Nan Zhang61eaedb2017-11-02 13:28:15 -0700872 static_libs: ["foo"],
Jiyong Park2d492942018-03-05 17:44:10 +0900873 sdk_version: "14",
Nan Zhang61eaedb2017-11-02 13:28:15 -0700874 }
875
876 java_library {
877 name: "baz",
878 srcs: ["c.java"],
879 libs: ["bar"],
880 sdk_version: "14",
881 }
882 `)
883
884 fooTurbine := ctx.ModuleForTests("foo", "android_common").Rule("turbine")
885 barTurbine := ctx.ModuleForTests("bar", "android_common").Rule("turbine")
886 barJavac := ctx.ModuleForTests("bar", "android_common").Rule("javac")
887 barTurbineCombined := ctx.ModuleForTests("bar", "android_common").Description("for turbine")
888 bazJavac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
889
890 if len(fooTurbine.Inputs) != 1 || fooTurbine.Inputs[0].String() != "a.java" {
891 t.Errorf(`foo inputs %v != ["a.java"]`, fooTurbine.Inputs)
892 }
893
894 fooHeaderJar := filepath.Join(buildDir, ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
895 if !strings.Contains(barTurbine.Args["classpath"], fooHeaderJar) {
896 t.Errorf("bar turbine classpath %v does not contain %q", barTurbine.Args["classpath"], fooHeaderJar)
897 }
898 if !strings.Contains(barJavac.Args["classpath"], fooHeaderJar) {
899 t.Errorf("bar javac classpath %v does not contain %q", barJavac.Args["classpath"], fooHeaderJar)
900 }
901 if len(barTurbineCombined.Inputs) != 2 || barTurbineCombined.Inputs[1].String() != fooHeaderJar {
902 t.Errorf("bar turbine combineJar inputs %v does not contain %q", barTurbineCombined.Inputs, fooHeaderJar)
903 }
Anton Hanssonf66efeb2018-04-11 13:57:30 +0100904 if !strings.Contains(bazJavac.Args["classpath"], "prebuilts/sdk/14/public/android.jar") {
Nan Zhang61eaedb2017-11-02 13:28:15 -0700905 t.Errorf("baz javac classpath %v does not contain %q", bazJavac.Args["classpath"],
Anton Hanssonf66efeb2018-04-11 13:57:30 +0100906 "prebuilts/sdk/14/public/android.jar")
Nan Zhang61eaedb2017-11-02 13:28:15 -0700907 }
908}
909
910func TestSharding(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700911 ctx, _ := testJava(t, `
Nan Zhang61eaedb2017-11-02 13:28:15 -0700912 java_library {
913 name: "bar",
914 srcs: ["a.java","b.java","c.java"],
915 javac_shard_size: 1
916 }
917 `)
918
919 barHeaderJar := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
920 for i := 0; i < 3; i++ {
921 barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i))
922 if !strings.Contains(barJavac.Args["classpath"], barHeaderJar) {
923 t.Errorf("bar javac classpath %v does not contain %q", barJavac.Args["classpath"], barHeaderJar)
924 }
925 }
926}
927
Nan Zhang581fd212018-01-10 16:06:12 -0800928func TestDroiddoc(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700929 ctx, _ := testJava(t, `
Paul Duffin884363e2019-12-19 10:21:09 +0000930 droiddoc_exported_dir {
Dan Willemsencc090972018-02-26 14:33:31 -0800931 name: "droiddoc-templates-sdk",
932 path: ".",
933 }
Jiyong Park29074592019-07-07 16:27:47 +0900934 filegroup {
935 name: "bar-doc-aidl-srcs",
936 srcs: ["bar-doc/IBar.aidl"],
937 path: "bar-doc",
938 }
Nan Zhang581fd212018-01-10 16:06:12 -0800939 droiddoc {
940 name: "bar-doc",
941 srcs: [
942 "bar-doc/*.java",
Jiyong Park1e440682018-05-23 18:42:04 +0900943 "bar-doc/IFoo.aidl",
Jiyong Park29074592019-07-07 16:27:47 +0900944 ":bar-doc-aidl-srcs",
Nan Zhang581fd212018-01-10 16:06:12 -0800945 ],
946 exclude_srcs: [
947 "bar-doc/b.java"
948 ],
Dan Willemsencc090972018-02-26 14:33:31 -0800949 custom_template: "droiddoc-templates-sdk",
Nan Zhang581fd212018-01-10 16:06:12 -0800950 hdf: [
951 "android.whichdoc offline",
952 ],
953 knowntags: [
954 "bar-doc/known_oj_tags.txt",
955 ],
956 proofread_file: "libcore-proofread.txt",
957 todo_file: "libcore-docs-todo.html",
958 args: "-offlinemode -title \"libcore\"",
959 }
960 `)
961
Colin Crossc0806172019-06-14 18:51:47 -0700962 barDoc := ctx.ModuleForTests("bar-doc", "android_common").Rule("javadoc")
Jiyong Park1e440682018-05-23 18:42:04 +0900963 var javaSrcs []string
Colin Crossc0806172019-06-14 18:51:47 -0700964 for _, i := range barDoc.Inputs {
Jiyong Park1e440682018-05-23 18:42:04 +0900965 javaSrcs = append(javaSrcs, i.Base())
966 }
Colin Crossc0806172019-06-14 18:51:47 -0700967 if len(javaSrcs) != 1 || javaSrcs[0] != "a.java" {
968 t.Errorf("inputs of bar-doc must be []string{\"a.java\"}, but was %#v.", javaSrcs)
Jiyong Park29074592019-07-07 16:27:47 +0900969 }
970
Colin Crossc0806172019-06-14 18:51:47 -0700971 aidl := ctx.ModuleForTests("bar-doc", "android_common").Rule("aidl")
972 if g, w := barDoc.Implicits.Strings(), aidl.Output.String(); !inList(w, g) {
973 t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
974 }
975
976 if g, w := aidl.Implicits.Strings(), []string{"bar-doc/IBar.aidl", "bar-doc/IFoo.aidl"}; !reflect.DeepEqual(w, g) {
977 t.Errorf("aidl inputs must be %q, but was %q", w, g)
Jiyong Park1e440682018-05-23 18:42:04 +0900978 }
Nan Zhang581fd212018-01-10 16:06:12 -0800979}
980
Colin Cross54250902017-12-05 09:28:08 -0800981func TestJarGenrules(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700982 ctx, _ := testJava(t, `
Colin Cross54250902017-12-05 09:28:08 -0800983 java_library {
984 name: "foo",
985 srcs: ["a.java"],
986 }
987
988 java_genrule {
989 name: "jargen",
990 tool_files: ["b.java"],
991 cmd: "$(location b.java) $(in) $(out)",
992 out: ["jargen.jar"],
993 srcs: [":foo"],
994 }
995
996 java_library {
997 name: "bar",
998 static_libs: ["jargen"],
999 srcs: ["c.java"],
1000 }
1001
1002 java_library {
1003 name: "baz",
1004 libs: ["jargen"],
1005 srcs: ["c.java"],
1006 }
1007 `)
1008
1009 foo := ctx.ModuleForTests("foo", "android_common").Output("javac/foo.jar")
1010 jargen := ctx.ModuleForTests("jargen", "android_common").Output("jargen.jar")
1011 bar := ctx.ModuleForTests("bar", "android_common").Output("javac/bar.jar")
1012 baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
1013 barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
1014
1015 if len(jargen.Inputs) != 1 || jargen.Inputs[0].String() != foo.Output.String() {
1016 t.Errorf("expected jargen inputs [%q], got %q", foo.Output.String(), jargen.Inputs.Strings())
1017 }
1018
1019 if !strings.Contains(bar.Args["classpath"], jargen.Output.String()) {
1020 t.Errorf("bar classpath %v does not contain %q", bar.Args["classpath"], jargen.Output.String())
1021 }
1022
1023 if !strings.Contains(baz.Args["classpath"], jargen.Output.String()) {
1024 t.Errorf("baz classpath %v does not contain %q", baz.Args["classpath"], jargen.Output.String())
1025 }
1026
1027 if len(barCombined.Inputs) != 2 ||
1028 barCombined.Inputs[0].String() != bar.Output.String() ||
1029 barCombined.Inputs[1].String() != jargen.Output.String() {
1030 t.Errorf("bar combined jar inputs %v is not [%q, %q]",
1031 barCombined.Inputs.Strings(), bar.Output.String(), jargen.Output.String())
1032 }
1033}
1034
Nan Zhang27e284d2018-02-09 21:03:53 +00001035func TestExcludeFileGroupInSrcs(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001036 ctx, _ := testJava(t, `
Nan Zhang27e284d2018-02-09 21:03:53 +00001037 java_library {
1038 name: "foo",
1039 srcs: ["a.java", ":foo-srcs"],
1040 exclude_srcs: ["a.java", ":foo-excludes"],
1041 }
1042
1043 filegroup {
1044 name: "foo-srcs",
1045 srcs: ["java-fg/a.java", "java-fg/b.java", "java-fg/c.java"],
1046 }
1047
1048 filegroup {
1049 name: "foo-excludes",
1050 srcs: ["java-fg/a.java", "java-fg/b.java"],
1051 }
1052 `)
1053
1054 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
1055
1056 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" {
1057 t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs)
1058 }
1059}
Jiyong Parkc678ad32018-04-10 13:07:10 +09001060
Paul Duffin52d398a2019-06-11 12:31:14 +01001061func TestJavaLibrary(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001062 config := testConfig(nil, "", map[string][]byte{
Paul Duffin52d398a2019-06-11 12:31:14 +01001063 "libcore/Android.bp": []byte(`
1064 java_library {
1065 name: "core",
1066 sdk_version: "none",
1067 system_modules: "none",
1068 }`),
1069 })
Colin Cross98be1bb2019-12-13 20:41:13 -08001070 ctx := testContext()
Paul Duffin52d398a2019-06-11 12:31:14 +01001071 run(t, ctx, config)
1072}
1073
Jiyong Parkc678ad32018-04-10 13:07:10 +09001074func TestJavaSdkLibrary(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001075 ctx, _ := testJava(t, `
Paul Duffin884363e2019-12-19 10:21:09 +00001076 droiddoc_exported_dir {
Jiyong Parkc678ad32018-04-10 13:07:10 +09001077 name: "droiddoc-templates-sdk",
1078 path: ".",
1079 }
Jiyong Parkc678ad32018-04-10 13:07:10 +09001080 java_sdk_library {
1081 name: "foo",
1082 srcs: ["a.java", "b.java"],
1083 api_packages: ["foo"],
1084 }
1085 java_sdk_library {
1086 name: "bar",
1087 srcs: ["a.java", "b.java"],
1088 api_packages: ["bar"],
1089 }
1090 java_library {
1091 name: "baz",
1092 srcs: ["c.java"],
1093 libs: ["foo", "bar"],
1094 sdk_version: "system_current",
1095 }
Jiyong Park1be96912018-05-28 18:02:19 +09001096 java_library {
1097 name: "qux",
1098 srcs: ["c.java"],
1099 libs: ["baz"],
1100 sdk_version: "system_current",
1101 }
Paul Duffin726d23c2020-01-22 16:30:37 +00001102 java_library {
1103 name: "baz-test",
1104 srcs: ["c.java"],
1105 libs: ["foo"],
1106 sdk_version: "test_current",
1107 }
Paul Duffina2db18f2020-01-22 17:11:15 +00001108 java_library {
1109 name: "baz-29",
1110 srcs: ["c.java"],
1111 libs: ["foo"],
1112 sdk_version: "system_29",
1113 }
Jiyong Parkc678ad32018-04-10 13:07:10 +09001114 `)
1115
1116 // check the existence of the internal modules
1117 ctx.ModuleForTests("foo", "android_common")
1118 ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix, "android_common")
1119 ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix+sdkSystemApiSuffix, "android_common")
Jiyong Park58c518b2018-05-12 22:29:12 +09001120 ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix+sdkTestApiSuffix, "android_common")
Paul Duffin91b883d2020-02-11 13:05:28 +00001121 ctx.ModuleForTests("foo"+sdkStubsSourceSuffix, "android_common")
1122 ctx.ModuleForTests("foo"+sdkStubsSourceSuffix+sdkSystemApiSuffix, "android_common")
1123 ctx.ModuleForTests("foo"+sdkStubsSourceSuffix+sdkTestApiSuffix, "android_common")
Colin Cross7113d202019-11-20 16:39:12 -08001124 ctx.ModuleForTests("foo"+sdkXmlFileSuffix, "android_arm64_armv8-a")
Jiyong Park58c518b2018-05-12 22:29:12 +09001125 ctx.ModuleForTests("foo.api.public.28", "")
1126 ctx.ModuleForTests("foo.api.system.28", "")
1127 ctx.ModuleForTests("foo.api.test.28", "")
Jiyong Parkc678ad32018-04-10 13:07:10 +09001128
1129 bazJavac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
1130 // tests if baz is actually linked to the stubs lib
1131 if !strings.Contains(bazJavac.Args["classpath"], "foo.stubs.system.jar") {
1132 t.Errorf("baz javac classpath %v does not contain %q", bazJavac.Args["classpath"],
1133 "foo.stubs.system.jar")
1134 }
1135 // ... and not to the impl lib
Sundong Ahn054b19a2018-10-19 13:46:09 +09001136 if strings.Contains(bazJavac.Args["classpath"], "foo.jar") {
Jiyong Parkc678ad32018-04-10 13:07:10 +09001137 t.Errorf("baz javac classpath %v should not contain %q", bazJavac.Args["classpath"],
Sundong Ahn054b19a2018-10-19 13:46:09 +09001138 "foo.jar")
Jiyong Parkc678ad32018-04-10 13:07:10 +09001139 }
1140 // test if baz is not linked to the system variant of foo
1141 if strings.Contains(bazJavac.Args["classpath"], "foo.stubs.jar") {
1142 t.Errorf("baz javac classpath %v should not contain %q", bazJavac.Args["classpath"],
1143 "foo.stubs.jar")
1144 }
Jiyong Park1be96912018-05-28 18:02:19 +09001145
Paul Duffin726d23c2020-01-22 16:30:37 +00001146 bazTestJavac := ctx.ModuleForTests("baz-test", "android_common").Rule("javac")
1147 // tests if baz-test is actually linked to the test stubs lib
1148 if !strings.Contains(bazTestJavac.Args["classpath"], "foo.stubs.test.jar") {
1149 t.Errorf("baz-test javac classpath %v does not contain %q", bazTestJavac.Args["classpath"],
1150 "foo.stubs.test.jar")
1151 }
1152
Paul Duffina2db18f2020-01-22 17:11:15 +00001153 baz29Javac := ctx.ModuleForTests("baz-29", "android_common").Rule("javac")
1154 // tests if baz-29 is actually linked to the system 29 stubs lib
1155 if !strings.Contains(baz29Javac.Args["classpath"], "prebuilts/sdk/29/system/foo.jar") {
1156 t.Errorf("baz-29 javac classpath %v does not contain %q", baz29Javac.Args["classpath"],
1157 "prebuilts/sdk/29/system/foo.jar")
1158 }
1159
Jiyong Park1be96912018-05-28 18:02:19 +09001160 // test if baz has exported SDK lib names foo and bar to qux
1161 qux := ctx.ModuleForTests("qux", "android_common")
1162 if quxLib, ok := qux.Module().(*Library); ok {
1163 sdkLibs := quxLib.ExportedSdkLibs()
1164 if len(sdkLibs) != 2 || !android.InList("foo", sdkLibs) || !android.InList("bar", sdkLibs) {
1165 t.Errorf("qux should export \"foo\" and \"bar\" but exports %v", sdkLibs)
1166 }
1167 }
Jiyong Parkc678ad32018-04-10 13:07:10 +09001168}
Zoran Jovanovic8736ce22018-08-21 17:10:29 +02001169
1170var compilerFlagsTestCases = []struct {
1171 in string
1172 out bool
1173}{
1174 {
1175 in: "a",
1176 out: false,
1177 },
1178 {
1179 in: "-a",
1180 out: true,
1181 },
1182 {
1183 in: "-no-jdk",
1184 out: false,
1185 },
1186 {
1187 in: "-no-stdlib",
1188 out: false,
1189 },
1190 {
1191 in: "-kotlin-home",
1192 out: false,
1193 },
1194 {
1195 in: "-kotlin-home /some/path",
1196 out: false,
1197 },
1198 {
1199 in: "-include-runtime",
1200 out: false,
1201 },
1202 {
1203 in: "-Xintellij-plugin-root",
1204 out: false,
1205 },
1206}
1207
1208type mockContext struct {
1209 android.ModuleContext
1210 result bool
1211}
1212
1213func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1214 // CheckBadCompilerFlags calls this function when the flag should be rejected
1215 ctx.result = false
1216}
1217
1218func TestCompilerFlags(t *testing.T) {
1219 for _, testCase := range compilerFlagsTestCases {
1220 ctx := &mockContext{result: true}
1221 CheckKotlincFlags(ctx, []string{testCase.in})
1222 if ctx.result != testCase.out {
1223 t.Errorf("incorrect output:")
1224 t.Errorf(" input: %#v", testCase.in)
1225 t.Errorf(" expected: %#v", testCase.out)
1226 t.Errorf(" got: %#v", ctx.result)
1227 }
1228 }
1229}
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001230
1231// TODO(jungjw): Consider making this more robust by ignoring path order.
1232func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) {
1233 variables := ctx.ModuleForTests(moduleName, "android_common").Module().VariablesForTests()
1234 flags := strings.Split(variables["javacFlags"], " ")
1235 got := ""
1236 for _, flag := range flags {
1237 keyEnd := strings.Index(flag, "=")
1238 if keyEnd > -1 && flag[:keyEnd] == "--patch-module" {
1239 got = flag[keyEnd+1:]
1240 break
1241 }
1242 }
1243 if expected != got {
1244 t.Errorf("Unexpected patch-module flag for module %q - expected %q, but got %q", moduleName, expected, got)
1245 }
1246}
1247
1248func TestPatchModule(t *testing.T) {
Pete Gillin0c2143e2019-05-02 15:32:11 +01001249 t.Run("Java language level 8", func(t *testing.T) {
Pete Gillin1b3370f2019-10-01 13:57:31 +01001250 // Test with legacy javac -source 1.8 -target 1.8
Pete Gillinbdf5d712019-10-21 14:29:58 +01001251 bp := `
1252 java_library {
1253 name: "foo",
1254 srcs: ["a.java"],
1255 java_version: "1.8",
1256 }
1257
1258 java_library {
1259 name: "bar",
1260 srcs: ["b.java"],
1261 sdk_version: "none",
1262 system_modules: "none",
1263 patch_module: "java.base",
1264 java_version: "1.8",
1265 }
1266
1267 java_library {
1268 name: "baz",
1269 srcs: ["c.java"],
1270 patch_module: "java.base",
1271 java_version: "1.8",
1272 }
1273 `
1274 ctx, _ := testJava(t, bp)
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001275
1276 checkPatchModuleFlag(t, ctx, "foo", "")
1277 checkPatchModuleFlag(t, ctx, "bar", "")
1278 checkPatchModuleFlag(t, ctx, "baz", "")
1279 })
1280
Pete Gillin0c2143e2019-05-02 15:32:11 +01001281 t.Run("Java language level 9", func(t *testing.T) {
Pete Gillin1b3370f2019-10-01 13:57:31 +01001282 // Test with default javac -source 9 -target 9
Pete Gillinbdf5d712019-10-21 14:29:58 +01001283 bp := `
1284 java_library {
1285 name: "foo",
1286 srcs: ["a.java"],
1287 }
1288
1289 java_library {
1290 name: "bar",
1291 srcs: ["b.java"],
1292 sdk_version: "none",
1293 system_modules: "none",
1294 patch_module: "java.base",
1295 }
1296
1297 java_library {
1298 name: "baz",
1299 srcs: ["c.java"],
1300 patch_module: "java.base",
1301 }
1302 `
Pete Gillin1b3370f2019-10-01 13:57:31 +01001303 ctx, _ := testJava(t, bp)
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001304
1305 checkPatchModuleFlag(t, ctx, "foo", "")
1306 expected := "java.base=.:" + buildDir
1307 checkPatchModuleFlag(t, ctx, "bar", expected)
Jiyong Park231d0562019-12-18 17:28:17 +09001308 expected = "java.base=" + strings.Join([]string{".", buildDir, moduleToPath("ext"), moduleToPath("framework")}, ":")
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001309 checkPatchModuleFlag(t, ctx, "baz", expected)
1310 })
1311}
Paul Duffina7b9f422020-01-10 17:12:18 +00001312
1313func TestJavaSystemModules(t *testing.T) {
1314 ctx, _ := testJava(t, `
1315 java_system_modules {
1316 name: "system-modules",
1317 libs: ["system-module1", "system-module2"],
1318 }
1319 java_library {
1320 name: "system-module1",
1321 srcs: ["a.java"],
1322 sdk_version: "none",
1323 system_modules: "none",
1324 }
1325 java_library {
1326 name: "system-module2",
1327 srcs: ["b.java"],
1328 sdk_version: "none",
1329 system_modules: "none",
1330 }
1331 `)
1332
1333 // check the existence of the module
1334 systemModules := ctx.ModuleForTests("system-modules", "android_common")
1335
1336 cmd := systemModules.Rule("jarsTosystemModules")
1337
1338 // make sure the command compiles against the supplied modules.
1339 for _, module := range []string{"system-module1.jar", "system-module2.jar"} {
1340 if !strings.Contains(cmd.Args["classpath"], module) {
1341 t.Errorf("system modules classpath %v does not contain %q", cmd.Args["classpath"],
1342 module)
1343 }
1344 }
1345}
Paul Duffin90169ba2020-01-10 17:16:44 +00001346
1347func TestJavaSystemModulesImport(t *testing.T) {
1348 ctx, _ := testJava(t, `
1349 java_system_modules_import {
1350 name: "system-modules",
1351 libs: ["system-module1", "system-module2"],
1352 }
1353 java_import {
1354 name: "system-module1",
1355 jars: ["a.jar"],
1356 }
1357 java_import {
1358 name: "system-module2",
1359 jars: ["b.jar"],
1360 }
1361 `)
1362
1363 // check the existence of the module
1364 systemModules := ctx.ModuleForTests("system-modules", "android_common")
1365
1366 cmd := systemModules.Rule("jarsTosystemModules")
1367
1368 // make sure the command compiles against the supplied modules.
1369 for _, module := range []string{"system-module1.jar", "system-module2.jar"} {
1370 if !strings.Contains(cmd.Args["classpath"], module) {
1371 t.Errorf("system modules classpath %v does not contain %q", cmd.Args["classpath"],
1372 module)
1373 }
1374 }
1375}