blob: d9a43f5933d8238d5edce4b97e7029a58cad06b7 [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 {
60 return TestConfig(buildDir, env, bp, fs)
Colin Cross1369cdb2017-09-29 17:58:17 -070061}
62
Colin Cross98be1bb2019-12-13 20:41:13 -080063func testContext() *android.TestContext {
Colin Cross72bb3632017-07-13 16:23:21 -070064
Colin Cross4c428df2017-09-15 17:36:05 -070065 ctx := android.NewTestArchContext()
Paul Duffinf9b1da02019-12-18 19:51:55 +000066 RegisterJavaBuildComponents(ctx)
67 RegisterAppBuildComponents(ctx)
68 RegisterAARBuildComponents(ctx)
Paul Duffinb0f85072019-12-19 10:28:56 +000069 RegisterGenRuleBuildComponents(ctx)
Colin Cross4b49b762019-11-22 15:25:03 -080070 ctx.RegisterModuleType("java_system_modules", SystemModulesFactory)
Colin Cross4b49b762019-11-22 15:25:03 -080071 ctx.RegisterModuleType("java_plugin", PluginFactory)
Colin Cross4b49b762019-11-22 15:25:03 -080072 ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
73 ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
Paul Duffin884363e2019-12-19 10:21:09 +000074 RegisterDocsBuildComponents(ctx)
75 RegisterStubsBuildComponents(ctx)
Colin Cross4b49b762019-11-22 15:25:03 -080076 ctx.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
77 ctx.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
Colin Cross4b49b762019-11-22 15:25:03 -080078 ctx.RegisterModuleType("prebuilt_apis", PrebuiltApisFactory)
Colin Cross5ea9bcc2017-07-27 15:41:32 -070079 ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
80 ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
Colin Cross89536d42017-07-07 14:35:50 -070081 ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
Jiyong Parkc678ad32018-04-10 13:07:10 +090082 ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
Inseob Kimc0907f12019-02-08 21:00:45 +090083 ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
Jiyong Parkc678ad32018-04-10 13:07:10 +090084 })
Jaewoong Jungb639a6a2019-05-10 15:16:29 -070085 ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080086 ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
Colin Cross3047fa22019-04-18 10:56:44 -070087 ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory))
Colin Crossa4f08812018-10-02 22:03:40 -070088
89 // Register module types and mutators from cc needed for JNI testing
Colin Cross4b49b762019-11-22 15:25:03 -080090 ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
91 ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
92 ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
93 ctx.RegisterModuleType("llndk_library", cc.LlndkLibraryFactory)
94 ctx.RegisterModuleType("ndk_prebuilt_shared_stl", cc.NdkPrebuiltSharedStlFactory)
Colin Crossa4f08812018-10-02 22:03:40 -070095 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
96 ctx.BottomUp("link", cc.LinkageMutator).Parallel()
97 ctx.BottomUp("begin", cc.BeginMutator).Parallel()
98 })
99
Colin Cross527012a2017-11-30 22:56:16 -0800100 return ctx
101}
102
103func run(t *testing.T, ctx *android.TestContext, config android.Config) {
Colin Cross6b4a32d2017-12-05 13:42:45 -0800104 t.Helper()
Colin Crossc28bb0b2019-02-25 14:20:47 -0800105
Colin Cross98be1bb2019-12-13 20:41:13 -0800106 pathCtx := android.PathContextForTesting(config)
Colin Crossc28bb0b2019-02-25 14:20:47 -0800107 setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
108
Colin Cross98be1bb2019-12-13 20:41:13 -0800109 ctx.Register(config)
Paul Duffinbaccf7e2019-06-11 11:58:30 +0100110 _, errs := ctx.ParseBlueprintsFiles("Android.bp")
Logan Chien42039712018-03-12 16:29:17 +0800111 android.FailIfErrored(t, errs)
Colin Cross72bb3632017-07-13 16:23:21 -0700112 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800113 android.FailIfErrored(t, errs)
Colin Cross527012a2017-11-30 22:56:16 -0800114}
115
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900116func testJavaError(t *testing.T, pattern string, bp string) (*android.TestContext, android.Config) {
Jeongik Cha538c0d02019-07-11 15:54:27 +0900117 t.Helper()
Colin Cross98be1bb2019-12-13 20:41:13 -0800118 return testJavaErrorWithConfig(t, pattern, testConfig(nil, bp, nil))
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900119}
120
Colin Cross98be1bb2019-12-13 20:41:13 -0800121func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config) (*android.TestContext, android.Config) {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900122 t.Helper()
Colin Cross98be1bb2019-12-13 20:41:13 -0800123 ctx := testContext()
Jeongik Cha538c0d02019-07-11 15:54:27 +0900124
Colin Cross98be1bb2019-12-13 20:41:13 -0800125 pathCtx := android.PathContextForTesting(config)
Jeongik Cha538c0d02019-07-11 15:54:27 +0900126 setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
127
Colin Cross98be1bb2019-12-13 20:41:13 -0800128 ctx.Register(config)
Jeongik Cha538c0d02019-07-11 15:54:27 +0900129 _, errs := ctx.ParseBlueprintsFiles("Android.bp")
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 _, errs = ctx.PrepareBuildActions(config)
135 if len(errs) > 0 {
136 android.FailIfNoMatchingErrors(t, pattern, errs)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900137 return ctx, config
Jeongik Cha538c0d02019-07-11 15:54:27 +0900138 }
139
140 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900141
142 return ctx, config
Jeongik Cha538c0d02019-07-11 15:54:27 +0900143}
144
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700145func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) {
Colin Cross6b4a32d2017-12-05 13:42:45 -0800146 t.Helper()
Colin Cross98be1bb2019-12-13 20:41:13 -0800147 return testJavaWithConfig(t, testConfig(nil, bp, nil))
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900148}
149
Colin Cross98be1bb2019-12-13 20:41:13 -0800150func testJavaWithConfig(t *testing.T, config android.Config) (*android.TestContext, android.Config) {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900151 t.Helper()
Colin Cross98be1bb2019-12-13 20:41:13 -0800152 ctx := testContext()
Colin Cross527012a2017-11-30 22:56:16 -0800153 run(t, ctx, config)
Colin Cross72bb3632017-07-13 16:23:21 -0700154
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700155 return ctx, config
Colin Cross72bb3632017-07-13 16:23:21 -0700156}
157
Colin Cross2acdae82017-09-15 19:44:24 -0700158func moduleToPath(name string) string {
159 switch {
160 case name == `""`:
161 return name
Colin Crossfc3674a2017-09-18 17:41:52 -0700162 case strings.HasSuffix(name, ".jar"):
163 return name
Nan Zhanged19fc32017-10-19 13:06:22 -0700164 default:
165 return filepath.Join(buildDir, ".intermediates", name, "android_common", "turbine-combined", name+".jar")
Colin Cross2acdae82017-09-15 19:44:24 -0700166 }
167}
168
Jeongik Chae403e9e2019-12-07 00:16:24 +0900169func TestJavaLinkType(t *testing.T) {
170 testJava(t, `
171 java_library {
172 name: "foo",
173 srcs: ["a.java"],
174 libs: ["bar"],
175 static_libs: ["baz"],
176 }
177
178 java_library {
179 name: "bar",
180 sdk_version: "current",
181 srcs: ["b.java"],
182 }
183
184 java_library {
185 name: "baz",
186 sdk_version: "system_current",
187 srcs: ["c.java"],
188 }
189 `)
190
191 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.", `
192 java_library {
193 name: "foo",
194 srcs: ["a.java"],
195 libs: ["bar"],
196 sdk_version: "current",
197 static_libs: ["baz"],
198 }
199
200 java_library {
201 name: "bar",
202 sdk_version: "current",
203 srcs: ["b.java"],
204 }
205
206 java_library {
207 name: "baz",
208 sdk_version: "system_current",
209 srcs: ["c.java"],
210 }
211 `)
212
213 testJava(t, `
214 java_library {
215 name: "foo",
216 srcs: ["a.java"],
217 libs: ["bar"],
218 sdk_version: "system_current",
219 static_libs: ["baz"],
220 }
221
222 java_library {
223 name: "bar",
224 sdk_version: "current",
225 srcs: ["b.java"],
226 }
227
228 java_library {
229 name: "baz",
230 sdk_version: "system_current",
231 srcs: ["c.java"],
232 }
233 `)
234
235 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.", `
236 java_library {
237 name: "foo",
238 srcs: ["a.java"],
239 libs: ["bar"],
240 sdk_version: "system_current",
241 static_libs: ["baz"],
242 }
243
244 java_library {
245 name: "bar",
246 sdk_version: "current",
247 srcs: ["b.java"],
248 }
249
250 java_library {
251 name: "baz",
252 srcs: ["c.java"],
253 }
254 `)
255}
256
Colin Cross72bb3632017-07-13 16:23:21 -0700257func TestSimple(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700258 ctx, _ := testJava(t, `
Colin Cross72bb3632017-07-13 16:23:21 -0700259 java_library {
260 name: "foo",
261 srcs: ["a.java"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700262 libs: ["bar"],
263 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700264 }
265
266 java_library {
267 name: "bar",
268 srcs: ["b.java"],
269 }
270
271 java_library {
272 name: "baz",
273 srcs: ["c.java"],
274 }
Colin Crossd5934c82017-10-02 13:55:26 -0700275 `)
Colin Cross72bb3632017-07-13 16:23:21 -0700276
Colin Cross4c428df2017-09-15 17:36:05 -0700277 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700278 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Colin Cross72bb3632017-07-13 16:23:21 -0700279
280 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
281 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
282 }
283
Colin Cross1ee23172017-10-18 14:44:18 -0700284 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
Nan Zhanged19fc32017-10-19 13:06:22 -0700285 barTurbine := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
286 bazTurbine := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "turbine-combined", "baz.jar")
Colin Cross0a6e0072017-08-30 14:24:55 -0700287
Nan Zhanged19fc32017-10-19 13:06:22 -0700288 if !strings.Contains(javac.Args["classpath"], barTurbine) {
289 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
Colin Cross72bb3632017-07-13 16:23:21 -0700290 }
291
Nan Zhanged19fc32017-10-19 13:06:22 -0700292 if !strings.Contains(javac.Args["classpath"], bazTurbine) {
293 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bazTurbine)
Colin Cross0a6e0072017-08-30 14:24:55 -0700294 }
295
296 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
297 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross72bb3632017-07-13 16:23:21 -0700298 }
299}
300
Artur Satayev9cf46692019-11-26 18:08:34 +0000301func TestExportedPlugins(t *testing.T) {
302 type Result struct {
303 library string
304 processors string
305 }
306 var tests = []struct {
307 name string
308 extra string
309 results []Result
310 }{
311 {
312 name: "Exported plugin is not a direct plugin",
313 extra: `java_library { name: "exports", srcs: ["a.java"], exported_plugins: ["plugin"] }`,
314 results: []Result{{library: "exports", processors: "-proc:none"}},
315 },
316 {
317 name: "Exports plugin to dependee",
318 extra: `
319 java_library{name: "exports", exported_plugins: ["plugin"]}
320 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
321 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
322 `,
323 results: []Result{
324 {library: "foo", processors: "-processor com.android.TestPlugin"},
325 {library: "bar", processors: "-processor com.android.TestPlugin"},
326 },
327 },
328 {
329 name: "Exports plugin to android_library",
330 extra: `
331 java_library{name: "exports", exported_plugins: ["plugin"]}
332 android_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
333 android_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
334 `,
335 results: []Result{
336 {library: "foo", processors: "-processor com.android.TestPlugin"},
337 {library: "bar", processors: "-processor com.android.TestPlugin"},
338 },
339 },
340 {
341 name: "Exports plugin is not propagated via transitive deps",
342 extra: `
343 java_library{name: "exports", exported_plugins: ["plugin"]}
344 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
345 java_library{name: "bar", srcs: ["a.java"], static_libs: ["foo"]}
346 `,
347 results: []Result{
348 {library: "foo", processors: "-processor com.android.TestPlugin"},
349 {library: "bar", processors: "-proc:none"},
350 },
351 },
352 {
353 name: "Exports plugin appends to plugins",
354 extra: `
355 java_plugin{name: "plugin2", processor_class: "com.android.TestPlugin2"}
356 java_library{name: "exports", exported_plugins: ["plugin"]}
357 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"], plugins: ["plugin2"]}
358 `,
359 results: []Result{
360 {library: "foo", processors: "-processor com.android.TestPlugin,com.android.TestPlugin2"},
361 },
362 },
363 }
364
365 for _, test := range tests {
366 t.Run(test.name, func(t *testing.T) {
367 ctx, _ := testJava(t, `
368 java_plugin {
369 name: "plugin",
370 processor_class: "com.android.TestPlugin",
371 }
372 `+test.extra)
373
374 for _, want := range test.results {
375 javac := ctx.ModuleForTests(want.library, "android_common").Rule("javac")
376 if javac.Args["processor"] != want.processors {
377 t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"])
378 }
379 }
380 })
381 }
382}
383
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900384func TestSdkVersionByPartition(t *testing.T) {
385 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900386 java_library {
387 name: "foo",
388 srcs: ["a.java"],
389 vendor: true,
390 }
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900391 `)
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900392
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900393 testJava(t, `
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900394 java_library {
395 name: "bar",
396 srcs: ["b.java"],
397 }
398 `)
399
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900400 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900401 bp := `
402 java_library {
403 name: "foo",
404 srcs: ["a.java"],
405 product_specific: true,
406 }
407 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800408
409 config := testConfig(nil, bp, nil)
410 config.TestProductVariables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900411 if enforce {
Colin Cross98be1bb2019-12-13 20:41:13 -0800412 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 +0900413 } else {
Colin Cross98be1bb2019-12-13 20:41:13 -0800414 testJavaWithConfig(t, config)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900415 }
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900416 }
417}
418
Colin Crossd5934c82017-10-02 13:55:26 -0700419func TestArchSpecific(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700420 ctx, _ := testJava(t, `
Colin Crossd5934c82017-10-02 13:55:26 -0700421 java_library {
422 name: "foo",
423 srcs: ["a.java"],
424 target: {
425 android: {
426 srcs: ["b.java"],
427 },
428 },
429 }
430 `)
431
432 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
433 if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" {
434 t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs)
435 }
436}
437
Colin Cross6b4a32d2017-12-05 13:42:45 -0800438func TestBinary(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700439 ctx, _ := testJava(t, `
Colin Cross6b4a32d2017-12-05 13:42:45 -0800440 java_library_host {
441 name: "foo",
442 srcs: ["a.java"],
443 }
444
445 java_binary_host {
446 name: "bar",
447 srcs: ["b.java"],
448 static_libs: ["foo"],
449 }
450 `)
451
452 buildOS := android.BuildOs.String()
453
454 bar := ctx.ModuleForTests("bar", buildOS+"_common")
455 barJar := bar.Output("bar.jar").Output.String()
456 barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64")
457 barWrapperDeps := barWrapper.Output("bar").Implicits.Strings()
458
459 // Test that the install binary wrapper depends on the installed jar file
460 if len(barWrapperDeps) != 1 || barWrapperDeps[0] != barJar {
461 t.Errorf("expected binary wrapper implicits [%q], got %v",
462 barJar, barWrapperDeps)
463 }
464
465}
466
Colin Cross72bb3632017-07-13 16:23:21 -0700467func TestPrebuilts(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700468 ctx, _ := testJava(t, `
Colin Cross72bb3632017-07-13 16:23:21 -0700469 java_library {
470 name: "foo",
Paul Duffin91547182019-11-12 19:39:36 +0000471 srcs: ["a.java", ":stubs-source"],
Colin Cross79c7c262019-04-17 11:11:46 -0700472 libs: ["bar", "sdklib"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700473 static_libs: ["baz"],
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: "bar",
Colin Cross74d73e22017-08-02 11:05:49 -0700478 jars: ["a.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700479 }
480
Colin Cross74d73e22017-08-02 11:05:49 -0700481 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700482 name: "baz",
Colin Cross74d73e22017-08-02 11:05:49 -0700483 jars: ["b.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700484 }
Colin Cross42be7612019-02-21 18:12:14 -0800485
486 dex_import {
487 name: "qux",
488 jars: ["b.jar"],
489 }
Colin Cross79c7c262019-04-17 11:11:46 -0700490
491 java_sdk_library_import {
492 name: "sdklib",
493 jars: ["b.jar"],
494 }
Paul Duffin91547182019-11-12 19:39:36 +0000495
496 prebuilt_stubs_sources {
497 name: "stubs-source",
498 srcs: ["stubs/sources/**/*.java"],
499 }
Colin Cross72bb3632017-07-13 16:23:21 -0700500 `)
501
Colin Cross4c428df2017-09-15 17:36:05 -0700502 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700503 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Colin Cross37f6d792018-07-12 12:28:41 -0700504 barJar := ctx.ModuleForTests("bar", "android_common").Rule("combineJar").Output
505 bazJar := ctx.ModuleForTests("baz", "android_common").Rule("combineJar").Output
Colin Cross79c7c262019-04-17 11:11:46 -0700506 sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
Colin Cross72bb3632017-07-13 16:23:21 -0700507
Paul Duffin91547182019-11-12 19:39:36 +0000508 inputs := []string{}
509 for _, p := range javac.BuildParams.Inputs {
510 inputs = append(inputs, p.String())
511 }
512
513 expected := []string{
514 "a.java",
515 "stubs/sources/foo/Foo.java",
516 }
517 if !reflect.DeepEqual(expected, inputs) {
518 t.Errorf("foo inputs incorrect: expected %q, found %q", expected, inputs)
519 }
520
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
Colin Cross89536d42017-07-07 14:35:50 -0700536func TestDefaults(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700537 ctx, _ := testJava(t, `
Colin Cross89536d42017-07-07 14:35:50 -0700538 java_defaults {
539 name: "defaults",
540 srcs: ["a.java"],
541 libs: ["bar"],
542 static_libs: ["baz"],
Sasha Smundak2057f822019-04-16 17:16:58 -0700543 optimize: {enabled: false},
Colin Cross89536d42017-07-07 14:35:50 -0700544 }
545
546 java_library {
547 name: "foo",
548 defaults: ["defaults"],
549 }
550
551 java_library {
552 name: "bar",
553 srcs: ["b.java"],
554 }
555
556 java_library {
557 name: "baz",
558 srcs: ["c.java"],
559 }
Sasha Smundak2057f822019-04-16 17:16:58 -0700560
561 android_test {
562 name: "atestOptimize",
563 defaults: ["defaults"],
564 optimize: {enabled: true},
565 }
566
567 android_test {
568 name: "atestNoOptimize",
569 defaults: ["defaults"],
570 }
571
572 android_test {
573 name: "atestDefault",
574 srcs: ["a.java"],
575 }
Colin Cross89536d42017-07-07 14:35:50 -0700576 `)
577
Colin Cross4c428df2017-09-15 17:36:05 -0700578 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700579 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Colin Cross89536d42017-07-07 14:35:50 -0700580
581 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
582 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
583 }
584
Nan Zhanged19fc32017-10-19 13:06:22 -0700585 barTurbine := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
586 if !strings.Contains(javac.Args["classpath"], barTurbine) {
587 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
Colin Cross89536d42017-07-07 14:35:50 -0700588 }
589
Colin Cross1ee23172017-10-18 14:44:18 -0700590 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
Colin Cross0a6e0072017-08-30 14:24:55 -0700591 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
592 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross89536d42017-07-07 14:35:50 -0700593 }
Sasha Smundak2057f822019-04-16 17:16:58 -0700594
595 atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8")
596 if atestOptimize.Output == nil {
597 t.Errorf("atestOptimize should optimize APK")
598 }
599
600 atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8")
601 if atestNoOptimize.Output == nil {
602 t.Errorf("atestNoOptimize should not optimize APK")
603 }
604
605 atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("r8")
606 if atestDefault.Output == nil {
607 t.Errorf("atestDefault should optimize APK")
608 }
Colin Cross89536d42017-07-07 14:35:50 -0700609}
610
Colin Cross0f37af02017-09-27 17:42:05 -0700611func TestResources(t *testing.T) {
612 var table = []struct {
613 name string
614 prop string
615 extra string
616 args string
617 }{
618 {
Colin Crossaf9c55b2017-10-03 14:50:08 -0700619 // Test that a module with java_resource_dirs includes the files
Colin Cross0f37af02017-09-27 17:42:05 -0700620 name: "resource dirs",
Colin Cross824bee32017-11-22 17:27:51 -0800621 prop: `java_resource_dirs: ["java-res"]`,
Colin Cross0ead1d72018-04-10 13:07:42 -0700622 args: "-C java-res -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700623 },
624 {
625 // Test that a module with java_resources includes the files
626 name: "resource files",
Colin Cross0ead1d72018-04-10 13:07:42 -0700627 prop: `java_resources: ["java-res/a/a", "java-res/b/b"]`,
628 args: "-C . -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700629 },
630 {
631 // Test that a module with a filegroup in java_resources includes the files with the
632 // path prefix
633 name: "resource filegroup",
634 prop: `java_resources: [":foo-res"]`,
635 extra: `
636 filegroup {
637 name: "foo-res",
Colin Cross824bee32017-11-22 17:27:51 -0800638 path: "java-res",
Colin Cross0ead1d72018-04-10 13:07:42 -0700639 srcs: ["java-res/a/a", "java-res/b/b"],
Colin Cross0f37af02017-09-27 17:42:05 -0700640 }`,
Colin Cross0ead1d72018-04-10 13:07:42 -0700641 args: "-C java-res -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700642 },
643 {
Colin Cross0ead1d72018-04-10 13:07:42 -0700644 // Test that a module with wildcards in java_resource_dirs has the correct path prefixes
645 name: "wildcard dirs",
646 prop: `java_resource_dirs: ["java-res/*"]`,
647 args: "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b",
648 },
649 {
650 // Test that a module exclude_java_resource_dirs excludes the files
651 name: "wildcard dirs",
652 prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`,
653 args: "-C java-res/a -f java-res/a/a",
654 },
Colin Crosscedd4762018-09-13 11:26:19 -0700655 {
656 // Test wildcards in java_resources
657 name: "wildcard files",
658 prop: `java_resources: ["java-res/**/*"]`,
659 args: "-C . -f java-res/a/a -f java-res/b/b",
660 },
661 {
662 // Test exclude_java_resources with java_resources
663 name: "wildcard files with exclude",
664 prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`,
665 args: "-C . -f java-res/a/a",
666 },
667 {
668 // Test exclude_java_resources with java_resource_dirs
669 name: "resource dirs with exclude files",
670 prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`,
671 args: "-C java-res -f java-res/a/a",
672 },
673 {
674 // Test exclude_java_resource_dirs with java_resource_dirs
675 name: "resource dirs with exclude files",
676 prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`,
677 args: "-C java-res -f java-res/a/a -f java-res/b/b",
678 },
Colin Cross0f37af02017-09-27 17:42:05 -0700679 }
680
681 for _, test := range table {
682 t.Run(test.name, func(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700683 ctx, _ := testJava(t, `
Colin Cross0f37af02017-09-27 17:42:05 -0700684 java_library {
685 name: "foo",
686 srcs: [
687 "a.java",
688 "b.java",
689 "c.java",
690 ],
691 `+test.prop+`,
692 }
693 `+test.extra)
694
Colin Cross331a1212018-08-15 20:40:52 -0700695 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
Colin Cross1ee23172017-10-18 14:44:18 -0700696 fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar")
Colin Cross0f37af02017-09-27 17:42:05 -0700697
698 if !inList(fooRes.Output.String(), foo.Inputs.Strings()) {
699 t.Errorf("foo combined jars %v does not contain %q",
700 foo.Inputs.Strings(), fooRes.Output.String())
701 }
702
Colin Crossaf9c55b2017-10-03 14:50:08 -0700703 if fooRes.Args["jarArgs"] != test.args {
704 t.Errorf("foo resource jar args %q is not %q",
Colin Cross0f37af02017-09-27 17:42:05 -0700705 fooRes.Args["jarArgs"], test.args)
706 }
707 })
708 }
709}
710
Colin Cross0c4ce212019-05-03 15:28:19 -0700711func TestIncludeSrcs(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700712 ctx, _ := testJava(t, `
Colin Cross0c4ce212019-05-03 15:28:19 -0700713 java_library {
714 name: "foo",
715 srcs: [
716 "a.java",
717 "b.java",
718 "c.java",
719 ],
720 include_srcs: true,
721 }
722
723 java_library {
724 name: "bar",
725 srcs: [
726 "a.java",
727 "b.java",
728 "c.java",
729 ],
730 java_resource_dirs: ["java-res"],
731 include_srcs: true,
732 }
733 `)
734
735 // Test a library with include_srcs: true
736 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
737 fooSrcJar := ctx.ModuleForTests("foo", "android_common").Output("foo.srcjar")
738
739 if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) {
740 t.Errorf("foo combined jars %v does not contain %q", w, g)
741 }
742
743 if g, w := fooSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w {
744 t.Errorf("foo source jar args %q is not %q", w, g)
745 }
746
747 // Test a library with include_srcs: true and resources
748 bar := ctx.ModuleForTests("bar", "android_common").Output("withres/bar.jar")
749 barResCombined := ctx.ModuleForTests("bar", "android_common").Output("res-combined/bar.jar")
750 barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar")
751 barSrcJar := ctx.ModuleForTests("bar", "android_common").Output("bar.srcjar")
752
753 if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
754 t.Errorf("bar combined resource jars %v does not contain %q", w, g)
755 }
756
757 if g, w := barRes.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
758 t.Errorf("bar combined resource jars %v does not contain %q", w, g)
759 }
760
761 if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) {
762 t.Errorf("bar combined jars %v does not contain %q", w, g)
763 }
764
765 if g, w := barSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w {
766 t.Errorf("bar source jar args %q is not %q", w, g)
767 }
768
769 if g, w := barRes.Args["jarArgs"], "-C java-res -f java-res/a/a -f java-res/b/b"; g != w {
770 t.Errorf("bar resource jar args %q is not %q", w, g)
771 }
772}
773
Colin Cross54190b32017-10-09 15:34:10 -0700774func TestGeneratedSources(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700775 ctx, _ := testJava(t, `
Colin Cross54190b32017-10-09 15:34:10 -0700776 java_library {
777 name: "foo",
778 srcs: [
779 "a*.java",
780 ":gen",
781 "b*.java",
782 ],
783 }
784
785 genrule {
786 name: "gen",
Colin Cross824bee32017-11-22 17:27:51 -0800787 tool_files: ["java-res/a"],
Colin Cross54190b32017-10-09 15:34:10 -0700788 out: ["gen.java"],
789 }
790 `)
791
792 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
793 genrule := ctx.ModuleForTests("gen", "").Rule("generator")
794
Colin Cross15e86d92017-10-20 15:07:08 -0700795 if filepath.Base(genrule.Output.String()) != "gen.java" {
796 t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String())
Colin Cross54190b32017-10-09 15:34:10 -0700797 }
798
799 if len(javac.Inputs) != 3 ||
800 javac.Inputs[0].String() != "a.java" ||
Colin Cross15e86d92017-10-20 15:07:08 -0700801 javac.Inputs[1].String() != genrule.Output.String() ||
Colin Cross54190b32017-10-09 15:34:10 -0700802 javac.Inputs[2].String() != "b.java" {
803 t.Errorf(`foo inputs %v != ["a.java", ".../gen.java", "b.java"]`, javac.Inputs)
804 }
805}
806
Nan Zhang61eaedb2017-11-02 13:28:15 -0700807func TestTurbine(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700808 ctx, _ := testJava(t, `
Nan Zhang61eaedb2017-11-02 13:28:15 -0700809 java_library {
810 name: "foo",
811 srcs: ["a.java"],
Jiyong Park2d492942018-03-05 17:44:10 +0900812 sdk_version: "14",
Nan Zhang61eaedb2017-11-02 13:28:15 -0700813 }
814
815 java_library {
816 name: "bar",
Colin Cross9bc43432017-12-15 20:20:39 -0800817 srcs: ["b.java"],
Nan Zhang61eaedb2017-11-02 13:28:15 -0700818 static_libs: ["foo"],
Jiyong Park2d492942018-03-05 17:44:10 +0900819 sdk_version: "14",
Nan Zhang61eaedb2017-11-02 13:28:15 -0700820 }
821
822 java_library {
823 name: "baz",
824 srcs: ["c.java"],
825 libs: ["bar"],
826 sdk_version: "14",
827 }
828 `)
829
830 fooTurbine := ctx.ModuleForTests("foo", "android_common").Rule("turbine")
831 barTurbine := ctx.ModuleForTests("bar", "android_common").Rule("turbine")
832 barJavac := ctx.ModuleForTests("bar", "android_common").Rule("javac")
833 barTurbineCombined := ctx.ModuleForTests("bar", "android_common").Description("for turbine")
834 bazJavac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
835
836 if len(fooTurbine.Inputs) != 1 || fooTurbine.Inputs[0].String() != "a.java" {
837 t.Errorf(`foo inputs %v != ["a.java"]`, fooTurbine.Inputs)
838 }
839
840 fooHeaderJar := filepath.Join(buildDir, ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
841 if !strings.Contains(barTurbine.Args["classpath"], fooHeaderJar) {
842 t.Errorf("bar turbine classpath %v does not contain %q", barTurbine.Args["classpath"], fooHeaderJar)
843 }
844 if !strings.Contains(barJavac.Args["classpath"], fooHeaderJar) {
845 t.Errorf("bar javac classpath %v does not contain %q", barJavac.Args["classpath"], fooHeaderJar)
846 }
847 if len(barTurbineCombined.Inputs) != 2 || barTurbineCombined.Inputs[1].String() != fooHeaderJar {
848 t.Errorf("bar turbine combineJar inputs %v does not contain %q", barTurbineCombined.Inputs, fooHeaderJar)
849 }
Anton Hanssonf66efeb2018-04-11 13:57:30 +0100850 if !strings.Contains(bazJavac.Args["classpath"], "prebuilts/sdk/14/public/android.jar") {
Nan Zhang61eaedb2017-11-02 13:28:15 -0700851 t.Errorf("baz javac classpath %v does not contain %q", bazJavac.Args["classpath"],
Anton Hanssonf66efeb2018-04-11 13:57:30 +0100852 "prebuilts/sdk/14/public/android.jar")
Nan Zhang61eaedb2017-11-02 13:28:15 -0700853 }
854}
855
856func TestSharding(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700857 ctx, _ := testJava(t, `
Nan Zhang61eaedb2017-11-02 13:28:15 -0700858 java_library {
859 name: "bar",
860 srcs: ["a.java","b.java","c.java"],
861 javac_shard_size: 1
862 }
863 `)
864
865 barHeaderJar := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
866 for i := 0; i < 3; i++ {
867 barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i))
868 if !strings.Contains(barJavac.Args["classpath"], barHeaderJar) {
869 t.Errorf("bar javac classpath %v does not contain %q", barJavac.Args["classpath"], barHeaderJar)
870 }
871 }
872}
873
Nan Zhang581fd212018-01-10 16:06:12 -0800874func TestDroiddoc(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700875 ctx, _ := testJava(t, `
Paul Duffin884363e2019-12-19 10:21:09 +0000876 droiddoc_exported_dir {
Dan Willemsencc090972018-02-26 14:33:31 -0800877 name: "droiddoc-templates-sdk",
878 path: ".",
879 }
Jiyong Park29074592019-07-07 16:27:47 +0900880 filegroup {
881 name: "bar-doc-aidl-srcs",
882 srcs: ["bar-doc/IBar.aidl"],
883 path: "bar-doc",
884 }
Nan Zhang581fd212018-01-10 16:06:12 -0800885 droiddoc {
886 name: "bar-doc",
887 srcs: [
888 "bar-doc/*.java",
Jiyong Park1e440682018-05-23 18:42:04 +0900889 "bar-doc/IFoo.aidl",
Jiyong Park29074592019-07-07 16:27:47 +0900890 ":bar-doc-aidl-srcs",
Nan Zhang581fd212018-01-10 16:06:12 -0800891 ],
892 exclude_srcs: [
893 "bar-doc/b.java"
894 ],
Dan Willemsencc090972018-02-26 14:33:31 -0800895 custom_template: "droiddoc-templates-sdk",
Nan Zhang581fd212018-01-10 16:06:12 -0800896 hdf: [
897 "android.whichdoc offline",
898 ],
899 knowntags: [
900 "bar-doc/known_oj_tags.txt",
901 ],
902 proofread_file: "libcore-proofread.txt",
903 todo_file: "libcore-docs-todo.html",
904 args: "-offlinemode -title \"libcore\"",
905 }
906 `)
907
Colin Crossc0806172019-06-14 18:51:47 -0700908 barDoc := ctx.ModuleForTests("bar-doc", "android_common").Rule("javadoc")
Jiyong Park1e440682018-05-23 18:42:04 +0900909 var javaSrcs []string
Colin Crossc0806172019-06-14 18:51:47 -0700910 for _, i := range barDoc.Inputs {
Jiyong Park1e440682018-05-23 18:42:04 +0900911 javaSrcs = append(javaSrcs, i.Base())
912 }
Colin Crossc0806172019-06-14 18:51:47 -0700913 if len(javaSrcs) != 1 || javaSrcs[0] != "a.java" {
914 t.Errorf("inputs of bar-doc must be []string{\"a.java\"}, but was %#v.", javaSrcs)
Jiyong Park29074592019-07-07 16:27:47 +0900915 }
916
Colin Crossc0806172019-06-14 18:51:47 -0700917 aidl := ctx.ModuleForTests("bar-doc", "android_common").Rule("aidl")
918 if g, w := barDoc.Implicits.Strings(), aidl.Output.String(); !inList(w, g) {
919 t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
920 }
921
922 if g, w := aidl.Implicits.Strings(), []string{"bar-doc/IBar.aidl", "bar-doc/IFoo.aidl"}; !reflect.DeepEqual(w, g) {
923 t.Errorf("aidl inputs must be %q, but was %q", w, g)
Jiyong Park1e440682018-05-23 18:42:04 +0900924 }
Nan Zhang581fd212018-01-10 16:06:12 -0800925}
926
Colin Cross54250902017-12-05 09:28:08 -0800927func TestJarGenrules(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700928 ctx, _ := testJava(t, `
Colin Cross54250902017-12-05 09:28:08 -0800929 java_library {
930 name: "foo",
931 srcs: ["a.java"],
932 }
933
934 java_genrule {
935 name: "jargen",
936 tool_files: ["b.java"],
937 cmd: "$(location b.java) $(in) $(out)",
938 out: ["jargen.jar"],
939 srcs: [":foo"],
940 }
941
942 java_library {
943 name: "bar",
944 static_libs: ["jargen"],
945 srcs: ["c.java"],
946 }
947
948 java_library {
949 name: "baz",
950 libs: ["jargen"],
951 srcs: ["c.java"],
952 }
953 `)
954
955 foo := ctx.ModuleForTests("foo", "android_common").Output("javac/foo.jar")
956 jargen := ctx.ModuleForTests("jargen", "android_common").Output("jargen.jar")
957 bar := ctx.ModuleForTests("bar", "android_common").Output("javac/bar.jar")
958 baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
959 barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
960
961 if len(jargen.Inputs) != 1 || jargen.Inputs[0].String() != foo.Output.String() {
962 t.Errorf("expected jargen inputs [%q], got %q", foo.Output.String(), jargen.Inputs.Strings())
963 }
964
965 if !strings.Contains(bar.Args["classpath"], jargen.Output.String()) {
966 t.Errorf("bar classpath %v does not contain %q", bar.Args["classpath"], jargen.Output.String())
967 }
968
969 if !strings.Contains(baz.Args["classpath"], jargen.Output.String()) {
970 t.Errorf("baz classpath %v does not contain %q", baz.Args["classpath"], jargen.Output.String())
971 }
972
973 if len(barCombined.Inputs) != 2 ||
974 barCombined.Inputs[0].String() != bar.Output.String() ||
975 barCombined.Inputs[1].String() != jargen.Output.String() {
976 t.Errorf("bar combined jar inputs %v is not [%q, %q]",
977 barCombined.Inputs.Strings(), bar.Output.String(), jargen.Output.String())
978 }
979}
980
Nan Zhang27e284d2018-02-09 21:03:53 +0000981func TestExcludeFileGroupInSrcs(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700982 ctx, _ := testJava(t, `
Nan Zhang27e284d2018-02-09 21:03:53 +0000983 java_library {
984 name: "foo",
985 srcs: ["a.java", ":foo-srcs"],
986 exclude_srcs: ["a.java", ":foo-excludes"],
987 }
988
989 filegroup {
990 name: "foo-srcs",
991 srcs: ["java-fg/a.java", "java-fg/b.java", "java-fg/c.java"],
992 }
993
994 filegroup {
995 name: "foo-excludes",
996 srcs: ["java-fg/a.java", "java-fg/b.java"],
997 }
998 `)
999
1000 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
1001
1002 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" {
1003 t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs)
1004 }
1005}
Jiyong Parkc678ad32018-04-10 13:07:10 +09001006
Paul Duffin52d398a2019-06-11 12:31:14 +01001007func TestJavaLibrary(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001008 config := testConfig(nil, "", map[string][]byte{
Paul Duffin52d398a2019-06-11 12:31:14 +01001009 "libcore/Android.bp": []byte(`
1010 java_library {
1011 name: "core",
1012 sdk_version: "none",
1013 system_modules: "none",
1014 }`),
1015 })
Colin Cross98be1bb2019-12-13 20:41:13 -08001016 ctx := testContext()
Paul Duffin52d398a2019-06-11 12:31:14 +01001017 run(t, ctx, config)
1018}
1019
Jiyong Parkc678ad32018-04-10 13:07:10 +09001020func TestJavaSdkLibrary(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001021 ctx, _ := testJava(t, `
Paul Duffin884363e2019-12-19 10:21:09 +00001022 droiddoc_exported_dir {
Jiyong Parkc678ad32018-04-10 13:07:10 +09001023 name: "droiddoc-templates-sdk",
1024 path: ".",
1025 }
Jiyong Parkc678ad32018-04-10 13:07:10 +09001026 java_sdk_library {
1027 name: "foo",
1028 srcs: ["a.java", "b.java"],
1029 api_packages: ["foo"],
1030 }
1031 java_sdk_library {
1032 name: "bar",
1033 srcs: ["a.java", "b.java"],
1034 api_packages: ["bar"],
1035 }
1036 java_library {
1037 name: "baz",
1038 srcs: ["c.java"],
1039 libs: ["foo", "bar"],
1040 sdk_version: "system_current",
1041 }
Jiyong Park1be96912018-05-28 18:02:19 +09001042 java_library {
1043 name: "qux",
1044 srcs: ["c.java"],
1045 libs: ["baz"],
1046 sdk_version: "system_current",
1047 }
Jiyong Parkc678ad32018-04-10 13:07:10 +09001048 `)
1049
1050 // check the existence of the internal modules
1051 ctx.ModuleForTests("foo", "android_common")
1052 ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix, "android_common")
1053 ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix+sdkSystemApiSuffix, "android_common")
Jiyong Park58c518b2018-05-12 22:29:12 +09001054 ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix+sdkTestApiSuffix, "android_common")
Jiyong Parkc678ad32018-04-10 13:07:10 +09001055 ctx.ModuleForTests("foo"+sdkDocsSuffix, "android_common")
1056 ctx.ModuleForTests("foo"+sdkDocsSuffix+sdkSystemApiSuffix, "android_common")
Jiyong Park58c518b2018-05-12 22:29:12 +09001057 ctx.ModuleForTests("foo"+sdkDocsSuffix+sdkTestApiSuffix, "android_common")
Colin Cross7113d202019-11-20 16:39:12 -08001058 ctx.ModuleForTests("foo"+sdkXmlFileSuffix, "android_arm64_armv8-a")
Jiyong Park58c518b2018-05-12 22:29:12 +09001059 ctx.ModuleForTests("foo.api.public.28", "")
1060 ctx.ModuleForTests("foo.api.system.28", "")
1061 ctx.ModuleForTests("foo.api.test.28", "")
Jiyong Parkc678ad32018-04-10 13:07:10 +09001062
1063 bazJavac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
1064 // tests if baz is actually linked to the stubs lib
1065 if !strings.Contains(bazJavac.Args["classpath"], "foo.stubs.system.jar") {
1066 t.Errorf("baz javac classpath %v does not contain %q", bazJavac.Args["classpath"],
1067 "foo.stubs.system.jar")
1068 }
1069 // ... and not to the impl lib
Sundong Ahn054b19a2018-10-19 13:46:09 +09001070 if strings.Contains(bazJavac.Args["classpath"], "foo.jar") {
Jiyong Parkc678ad32018-04-10 13:07:10 +09001071 t.Errorf("baz javac classpath %v should not contain %q", bazJavac.Args["classpath"],
Sundong Ahn054b19a2018-10-19 13:46:09 +09001072 "foo.jar")
Jiyong Parkc678ad32018-04-10 13:07:10 +09001073 }
1074 // test if baz is not linked to the system variant of foo
1075 if strings.Contains(bazJavac.Args["classpath"], "foo.stubs.jar") {
1076 t.Errorf("baz javac classpath %v should not contain %q", bazJavac.Args["classpath"],
1077 "foo.stubs.jar")
1078 }
Jiyong Park1be96912018-05-28 18:02:19 +09001079
1080 // test if baz has exported SDK lib names foo and bar to qux
1081 qux := ctx.ModuleForTests("qux", "android_common")
1082 if quxLib, ok := qux.Module().(*Library); ok {
1083 sdkLibs := quxLib.ExportedSdkLibs()
1084 if len(sdkLibs) != 2 || !android.InList("foo", sdkLibs) || !android.InList("bar", sdkLibs) {
1085 t.Errorf("qux should export \"foo\" and \"bar\" but exports %v", sdkLibs)
1086 }
1087 }
Jiyong Parkc678ad32018-04-10 13:07:10 +09001088}
Zoran Jovanovic8736ce22018-08-21 17:10:29 +02001089
1090var compilerFlagsTestCases = []struct {
1091 in string
1092 out bool
1093}{
1094 {
1095 in: "a",
1096 out: false,
1097 },
1098 {
1099 in: "-a",
1100 out: true,
1101 },
1102 {
1103 in: "-no-jdk",
1104 out: false,
1105 },
1106 {
1107 in: "-no-stdlib",
1108 out: false,
1109 },
1110 {
1111 in: "-kotlin-home",
1112 out: false,
1113 },
1114 {
1115 in: "-kotlin-home /some/path",
1116 out: false,
1117 },
1118 {
1119 in: "-include-runtime",
1120 out: false,
1121 },
1122 {
1123 in: "-Xintellij-plugin-root",
1124 out: false,
1125 },
1126}
1127
1128type mockContext struct {
1129 android.ModuleContext
1130 result bool
1131}
1132
1133func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1134 // CheckBadCompilerFlags calls this function when the flag should be rejected
1135 ctx.result = false
1136}
1137
1138func TestCompilerFlags(t *testing.T) {
1139 for _, testCase := range compilerFlagsTestCases {
1140 ctx := &mockContext{result: true}
1141 CheckKotlincFlags(ctx, []string{testCase.in})
1142 if ctx.result != testCase.out {
1143 t.Errorf("incorrect output:")
1144 t.Errorf(" input: %#v", testCase.in)
1145 t.Errorf(" expected: %#v", testCase.out)
1146 t.Errorf(" got: %#v", ctx.result)
1147 }
1148 }
1149}
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001150
1151// TODO(jungjw): Consider making this more robust by ignoring path order.
1152func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) {
1153 variables := ctx.ModuleForTests(moduleName, "android_common").Module().VariablesForTests()
1154 flags := strings.Split(variables["javacFlags"], " ")
1155 got := ""
1156 for _, flag := range flags {
1157 keyEnd := strings.Index(flag, "=")
1158 if keyEnd > -1 && flag[:keyEnd] == "--patch-module" {
1159 got = flag[keyEnd+1:]
1160 break
1161 }
1162 }
1163 if expected != got {
1164 t.Errorf("Unexpected patch-module flag for module %q - expected %q, but got %q", moduleName, expected, got)
1165 }
1166}
1167
1168func TestPatchModule(t *testing.T) {
Pete Gillin0c2143e2019-05-02 15:32:11 +01001169 t.Run("Java language level 8", func(t *testing.T) {
Pete Gillin1b3370f2019-10-01 13:57:31 +01001170 // Test with legacy javac -source 1.8 -target 1.8
Pete Gillinbdf5d712019-10-21 14:29:58 +01001171 bp := `
1172 java_library {
1173 name: "foo",
1174 srcs: ["a.java"],
1175 java_version: "1.8",
1176 }
1177
1178 java_library {
1179 name: "bar",
1180 srcs: ["b.java"],
1181 sdk_version: "none",
1182 system_modules: "none",
1183 patch_module: "java.base",
1184 java_version: "1.8",
1185 }
1186
1187 java_library {
1188 name: "baz",
1189 srcs: ["c.java"],
1190 patch_module: "java.base",
1191 java_version: "1.8",
1192 }
1193 `
1194 ctx, _ := testJava(t, bp)
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001195
1196 checkPatchModuleFlag(t, ctx, "foo", "")
1197 checkPatchModuleFlag(t, ctx, "bar", "")
1198 checkPatchModuleFlag(t, ctx, "baz", "")
1199 })
1200
Pete Gillin0c2143e2019-05-02 15:32:11 +01001201 t.Run("Java language level 9", func(t *testing.T) {
Pete Gillin1b3370f2019-10-01 13:57:31 +01001202 // Test with default javac -source 9 -target 9
Pete Gillinbdf5d712019-10-21 14:29:58 +01001203 bp := `
1204 java_library {
1205 name: "foo",
1206 srcs: ["a.java"],
1207 }
1208
1209 java_library {
1210 name: "bar",
1211 srcs: ["b.java"],
1212 sdk_version: "none",
1213 system_modules: "none",
1214 patch_module: "java.base",
1215 }
1216
1217 java_library {
1218 name: "baz",
1219 srcs: ["c.java"],
1220 patch_module: "java.base",
1221 }
1222 `
Pete Gillin1b3370f2019-10-01 13:57:31 +01001223 ctx, _ := testJava(t, bp)
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001224
1225 checkPatchModuleFlag(t, ctx, "foo", "")
1226 expected := "java.base=.:" + buildDir
1227 checkPatchModuleFlag(t, ctx, "bar", expected)
Jiyong Park231d0562019-12-18 17:28:17 +09001228 expected = "java.base=" + strings.Join([]string{".", buildDir, moduleToPath("ext"), moduleToPath("framework")}, ":")
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001229 checkPatchModuleFlag(t, ctx, "baz", expected)
1230 })
1231}