blob: 7969d97985ccc5d70609386275b483cd93a2c3da [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 (
Paul Duffin1a393322020-11-18 16:36:47 +000018 "fmt"
Colin Cross72bb3632017-07-13 16:23:21 -070019 "os"
20 "path/filepath"
Colin Crossc0806172019-06-14 18:51:47 -070021 "reflect"
Colin Crossf8d9c492021-01-26 11:01:43 -080022 "runtime"
Nan Zhang61eaedb2017-11-02 13:28:15 -070023 "strconv"
Colin Cross72bb3632017-07-13 16:23:21 -070024 "strings"
25 "testing"
Colin Cross86a60ae2018-05-29 14:44:55 -070026
Spandan Das3cf04632024-01-19 00:22:22 +000027 "github.com/google/blueprint"
Jeongik Cha28df2572019-11-11 10:46:36 +090028 "github.com/google/blueprint/proptools"
29
Jihoon Kang84b25892023-12-01 22:01:06 +000030 "android/soong/aconfig"
Colin Crossa4f08812018-10-02 22:03:40 -070031 "android/soong/android"
32 "android/soong/cc"
Colin Crossc28bb0b2019-02-25 14:20:47 -080033 "android/soong/dexpreopt"
Colin Cross1661aff2021-03-12 17:56:51 -080034 "android/soong/genrule"
Colin Cross72bb3632017-07-13 16:23:21 -070035)
36
Paul Duffin70d3bee2021-03-21 11:26:05 +000037// Legacy preparer used for running tests within the java package.
38//
39// This includes everything that was needed to run any test in the java package prior to the
40// introduction of the test fixtures. Tests that are being converted to use fixtures directly
41// rather than through the testJava...() methods should avoid using this and instead use the
42// various preparers directly, using android.GroupFixturePreparers(...) to group them when
43// necessary.
44//
45// deprecated
46var prepareForJavaTest = android.GroupFixturePreparers(
Paul Duffin95bdab42021-03-08 21:48:46 +000047 genrule.PrepareForTestWithGenRuleBuildComponents,
48 // Get the CC build components but not default modules.
49 cc.PrepareForTestWithCcBuildComponents,
50 // Include all the default java modules.
Jiakai Zhangb95998b2023-05-11 16:39:27 +010051 PrepareForTestWithDexpreopt,
Jihoon Kang84b25892023-12-01 22:01:06 +000052 // Include aconfig modules.
53 aconfig.PrepareForTestWithAconfigBuildComponents,
Paul Duffin95bdab42021-03-08 21:48:46 +000054)
55
Colin Cross72bb3632017-07-13 16:23:21 -070056func TestMain(m *testing.M) {
Paul Duffind6339af2021-03-22 18:05:04 +000057 os.Exit(m.Run())
Colin Cross527012a2017-11-30 22:56:16 -080058}
59
Paul Duffin95bdab42021-03-08 21:48:46 +000060// testJavaError is a legacy way of running tests of java modules that expect errors.
61//
62// See testJava for an explanation as to how to stop using this deprecated method.
63//
64// deprecated
Jeongik Cha2cc570d2019-10-29 15:44:45 +090065func testJavaError(t *testing.T, pattern string, bp string) (*android.TestContext, android.Config) {
Jeongik Cha538c0d02019-07-11 15:54:27 +090066 t.Helper()
Paul Duffin71ae5942021-03-22 15:36:52 +000067 result := android.GroupFixturePreparers(
Paul Duffin9fc9f532021-03-23 15:41:11 +000068 prepareForJavaTest, dexpreopt.PrepareForTestByEnablingDexpreopt).
Paul Duffin6bac49c2021-03-12 21:28:15 +000069 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
70 RunTestWithBp(t, bp)
71 return result.TestContext, result.Config
Jeongik Cha2cc570d2019-10-29 15:44:45 +090072}
73
Paul Duffin71ae5942021-03-22 15:36:52 +000074// testJavaWithFS runs tests using the prepareForJavaTest
Paul Duffin95bdab42021-03-08 21:48:46 +000075//
76// See testJava for an explanation as to how to stop using this deprecated method.
77//
78// deprecated
79func testJavaWithFS(t *testing.T, bp string, fs android.MockFS) (*android.TestContext, android.Config) {
Colin Cross238c1f32020-06-07 16:58:18 -070080 t.Helper()
Paul Duffin71ae5942021-03-22 15:36:52 +000081 result := android.GroupFixturePreparers(
82 prepareForJavaTest, fs.AddToFixture()).RunTestWithBp(t, bp)
Paul Duffin95bdab42021-03-08 21:48:46 +000083 return result.TestContext, result.Config
Colin Cross238c1f32020-06-07 16:58:18 -070084}
85
Paul Duffin71ae5942021-03-22 15:36:52 +000086// testJava runs tests using the prepareForJavaTest
Paul Duffin95bdab42021-03-08 21:48:46 +000087//
Paul Duffin71ae5942021-03-22 15:36:52 +000088// Do not add any new usages of this, instead use the prepareForJavaTest directly as it makes it
Paul Duffin95bdab42021-03-08 21:48:46 +000089// much easier to customize the test behavior.
90//
91// If it is necessary to customize the behavior of an existing test that uses this then please first
Paul Duffin71ae5942021-03-22 15:36:52 +000092// convert the test to using prepareForJavaTest first and then in a following change add the
Paul Duffin95bdab42021-03-08 21:48:46 +000093// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
94// that it did not change the test behavior unexpectedly.
95//
96// deprecated
Jaewoong Jungf9a04432019-07-17 11:15:09 -070097func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) {
Colin Cross6b4a32d2017-12-05 13:42:45 -080098 t.Helper()
Paul Duffin71ae5942021-03-22 15:36:52 +000099 result := prepareForJavaTest.RunTestWithBp(t, bp)
Paul Duffin95bdab42021-03-08 21:48:46 +0000100 return result.TestContext, result.Config
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900101}
102
Paul Duffin95bdab42021-03-08 21:48:46 +0000103// defaultModuleToPath constructs a path to the turbine generate jar for a default test module that
104// is defined in PrepareForIntegrationTestWithJava
105func defaultModuleToPath(name string) string {
Paul Duffin76101fa2021-03-13 09:55:25 +0000106 switch {
107 case name == `""`:
108 return name
109 case strings.HasSuffix(name, ".jar"):
110 return name
111 default:
Paul Duffin414ea5e2021-03-22 17:31:52 +0000112 return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine-combined", name+".jar")
Paul Duffin76101fa2021-03-13 09:55:25 +0000113 }
Paul Duffin95bdab42021-03-08 21:48:46 +0000114}
115
Paul Duffin76e5c8a2021-03-20 14:19:46 +0000116// Test that the PrepareForTestWithJavaDefaultModules provides all the files that it uses by
117// running it in a fixture that requires all source files to exist.
118func TestPrepareForTestWithJavaDefaultModules(t *testing.T) {
119 android.GroupFixturePreparers(
120 PrepareForTestWithJavaDefaultModules,
121 android.PrepareForTestDisallowNonExistentPaths,
122 ).RunTest(t)
123}
124
Jeongik Chae403e9e2019-12-07 00:16:24 +0900125func TestJavaLinkType(t *testing.T) {
126 testJava(t, `
127 java_library {
128 name: "foo",
129 srcs: ["a.java"],
130 libs: ["bar"],
131 static_libs: ["baz"],
132 }
133
134 java_library {
135 name: "bar",
136 sdk_version: "current",
137 srcs: ["b.java"],
138 }
139
140 java_library {
141 name: "baz",
142 sdk_version: "system_current",
143 srcs: ["c.java"],
144 }
145 `)
146
Steven Moreland00298982020-11-17 21:44:36 +0000147 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900148 java_library {
149 name: "foo",
150 srcs: ["a.java"],
151 libs: ["bar"],
152 sdk_version: "current",
153 static_libs: ["baz"],
154 }
155
156 java_library {
157 name: "bar",
158 sdk_version: "current",
159 srcs: ["b.java"],
160 }
161
162 java_library {
163 name: "baz",
164 sdk_version: "system_current",
165 srcs: ["c.java"],
166 }
167 `)
168
169 testJava(t, `
170 java_library {
171 name: "foo",
172 srcs: ["a.java"],
173 libs: ["bar"],
174 sdk_version: "system_current",
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
Steven Moreland00298982020-11-17 21:44:36 +0000191 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900192 java_library {
193 name: "foo",
194 srcs: ["a.java"],
195 libs: ["bar"],
196 sdk_version: "system_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 srcs: ["c.java"],
209 }
210 `)
211}
212
Colin Cross72bb3632017-07-13 16:23:21 -0700213func TestSimple(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700214 ctx, _ := testJava(t, `
Colin Cross72bb3632017-07-13 16:23:21 -0700215 java_library {
216 name: "foo",
217 srcs: ["a.java"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700218 libs: ["bar"],
219 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700220 }
221
222 java_library {
223 name: "bar",
224 srcs: ["b.java"],
225 }
226
227 java_library {
228 name: "baz",
229 srcs: ["c.java"],
230 }
Colin Crossd5934c82017-10-02 13:55:26 -0700231 `)
Colin Cross72bb3632017-07-13 16:23:21 -0700232
Paul Duffina71a67a2021-03-29 00:42:57 +0100233 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700234 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Colin Cross72bb3632017-07-13 16:23:21 -0700235
236 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
237 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
238 }
239
Colin Cross1ee23172017-10-18 14:44:18 -0700240 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
Paul Duffin414ea5e2021-03-22 17:31:52 +0000241 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
242 bazTurbine := filepath.Join("out", "soong", ".intermediates", "baz", "android_common", "turbine-combined", "baz.jar")
Colin Cross0a6e0072017-08-30 14:24:55 -0700243
Paul Duffin22b77cd2021-03-12 19:15:01 +0000244 android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barTurbine)
Colin Cross72bb3632017-07-13 16:23:21 -0700245
Paul Duffin22b77cd2021-03-12 19:15:01 +0000246 android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazTurbine)
Colin Cross0a6e0072017-08-30 14:24:55 -0700247
248 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
249 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross72bb3632017-07-13 16:23:21 -0700250 }
251}
252
Artur Satayev9cf46692019-11-26 18:08:34 +0000253func TestExportedPlugins(t *testing.T) {
254 type Result struct {
Colin Crossc9fe10f2020-11-19 18:06:03 -0800255 library string
256 processors string
257 disableTurbine bool
Artur Satayev9cf46692019-11-26 18:08:34 +0000258 }
259 var tests = []struct {
260 name string
261 extra string
262 results []Result
263 }{
264 {
265 name: "Exported plugin is not a direct plugin",
266 extra: `java_library { name: "exports", srcs: ["a.java"], exported_plugins: ["plugin"] }`,
267 results: []Result{{library: "exports", processors: "-proc:none"}},
268 },
269 {
270 name: "Exports plugin to dependee",
271 extra: `
272 java_library{name: "exports", exported_plugins: ["plugin"]}
273 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
274 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
275 `,
276 results: []Result{
277 {library: "foo", processors: "-processor com.android.TestPlugin"},
278 {library: "bar", processors: "-processor com.android.TestPlugin"},
279 },
280 },
281 {
282 name: "Exports plugin to android_library",
283 extra: `
284 java_library{name: "exports", exported_plugins: ["plugin"]}
285 android_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
286 android_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
287 `,
288 results: []Result{
289 {library: "foo", processors: "-processor com.android.TestPlugin"},
290 {library: "bar", processors: "-processor com.android.TestPlugin"},
291 },
292 },
293 {
294 name: "Exports plugin is not propagated via transitive deps",
295 extra: `
296 java_library{name: "exports", exported_plugins: ["plugin"]}
297 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
298 java_library{name: "bar", srcs: ["a.java"], static_libs: ["foo"]}
299 `,
300 results: []Result{
301 {library: "foo", processors: "-processor com.android.TestPlugin"},
302 {library: "bar", processors: "-proc:none"},
303 },
304 },
305 {
306 name: "Exports plugin appends to plugins",
307 extra: `
308 java_plugin{name: "plugin2", processor_class: "com.android.TestPlugin2"}
309 java_library{name: "exports", exported_plugins: ["plugin"]}
310 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"], plugins: ["plugin2"]}
311 `,
312 results: []Result{
313 {library: "foo", processors: "-processor com.android.TestPlugin,com.android.TestPlugin2"},
314 },
315 },
Colin Crossc9fe10f2020-11-19 18:06:03 -0800316 {
317 name: "Exports plugin to with generates_api to dependee",
318 extra: `
319 java_library{name: "exports", exported_plugins: ["plugin_generates_api"]}
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", disableTurbine: true},
325 {library: "bar", processors: "-processor com.android.TestPlugin", disableTurbine: true},
326 },
327 },
Artur Satayev9cf46692019-11-26 18:08:34 +0000328 }
329
330 for _, test := range tests {
331 t.Run(test.name, func(t *testing.T) {
332 ctx, _ := testJava(t, `
333 java_plugin {
334 name: "plugin",
335 processor_class: "com.android.TestPlugin",
336 }
Colin Crossc9fe10f2020-11-19 18:06:03 -0800337 java_plugin {
338 name: "plugin_generates_api",
339 generates_api: true,
340 processor_class: "com.android.TestPlugin",
341 }
Artur Satayev9cf46692019-11-26 18:08:34 +0000342 `+test.extra)
343
344 for _, want := range test.results {
345 javac := ctx.ModuleForTests(want.library, "android_common").Rule("javac")
346 if javac.Args["processor"] != want.processors {
347 t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"])
348 }
Colin Crossc9fe10f2020-11-19 18:06:03 -0800349 turbine := ctx.ModuleForTests(want.library, "android_common").MaybeRule("turbine")
350 disableTurbine := turbine.BuildParams.Rule == nil
351 if disableTurbine != want.disableTurbine {
352 t.Errorf("For library %v, expected disableTurbine %v, found %v", want.library, want.disableTurbine, disableTurbine)
353 }
Artur Satayev9cf46692019-11-26 18:08:34 +0000354 }
355 })
356 }
357}
358
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900359func TestSdkVersionByPartition(t *testing.T) {
360 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900361 java_library {
362 name: "foo",
363 srcs: ["a.java"],
364 vendor: true,
365 }
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900366 `)
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900367
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900368 testJava(t, `
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900369 java_library {
370 name: "bar",
371 srcs: ["b.java"],
372 }
373 `)
374
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900375 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900376 bp := `
377 java_library {
378 name: "foo",
379 srcs: ["a.java"],
380 product_specific: true,
381 }
382 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800383
Paul Duffin414ea5e2021-03-22 17:31:52 +0000384 errorHandler := android.FixtureExpectsNoErrors
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900385 if enforce {
Paul Duffin414ea5e2021-03-22 17:31:52 +0000386 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product")
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900387 }
Paul Duffin414ea5e2021-03-22 17:31:52 +0000388
389 android.GroupFixturePreparers(
390 PrepareForTestWithJavaDefaultModules,
391 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
392 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
393 }),
394 ).
395 ExtendWithErrorHandler(errorHandler).
396 RunTestWithBp(t, bp)
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900397 }
398}
399
Colin Crossd5934c82017-10-02 13:55:26 -0700400func TestArchSpecific(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700401 ctx, _ := testJava(t, `
Colin Crossd5934c82017-10-02 13:55:26 -0700402 java_library {
403 name: "foo",
404 srcs: ["a.java"],
405 target: {
406 android: {
407 srcs: ["b.java"],
408 },
409 },
410 }
411 `)
412
413 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
414 if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" {
415 t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs)
416 }
417}
418
Colin Cross6b4a32d2017-12-05 13:42:45 -0800419func TestBinary(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700420 ctx, _ := testJava(t, `
Colin Cross6b4a32d2017-12-05 13:42:45 -0800421 java_library_host {
422 name: "foo",
423 srcs: ["a.java"],
424 }
425
426 java_binary_host {
427 name: "bar",
428 srcs: ["b.java"],
429 static_libs: ["foo"],
Colin Cross89226d92020-10-09 19:00:54 -0700430 jni_libs: ["libjni"],
431 }
432
433 cc_library_shared {
434 name: "libjni",
435 host_supported: true,
436 device_supported: false,
437 stl: "none",
Colin Cross6b4a32d2017-12-05 13:42:45 -0800438 }
439 `)
440
Colin Cross0c66bc62021-07-20 09:47:41 -0700441 buildOS := ctx.Config().BuildOS.String()
Colin Cross6b4a32d2017-12-05 13:42:45 -0800442
443 bar := ctx.ModuleForTests("bar", buildOS+"_common")
444 barJar := bar.Output("bar.jar").Output.String()
445 barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64")
446 barWrapperDeps := barWrapper.Output("bar").Implicits.Strings()
447
Colin Cross89226d92020-10-09 19:00:54 -0700448 libjni := ctx.ModuleForTests("libjni", buildOS+"_x86_64_shared")
449 libjniSO := libjni.Rule("Cp").Output.String()
450
Colin Cross6b4a32d2017-12-05 13:42:45 -0800451 // Test that the install binary wrapper depends on the installed jar file
Colin Crossc179ea62020-10-09 10:54:15 -0700452 if g, w := barWrapperDeps, barJar; !android.InList(w, g) {
453 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g)
Colin Cross6b4a32d2017-12-05 13:42:45 -0800454 }
Colin Cross89226d92020-10-09 19:00:54 -0700455
456 // Test that the install binary wrapper depends on the installed JNI libraries
457 if g, w := barWrapperDeps, libjniSO; !android.InList(w, g) {
458 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g)
Colin Cross6b4a32d2017-12-05 13:42:45 -0800459 }
Alex Humesky2070e322020-06-09 20:23:08 -0400460}
Colin Cross6b4a32d2017-12-05 13:42:45 -0800461
Colin Crossf8d9c492021-01-26 11:01:43 -0800462func TestTest(t *testing.T) {
463 ctx, _ := testJava(t, `
464 java_test_host {
465 name: "foo",
466 srcs: ["a.java"],
467 jni_libs: ["libjni"],
468 }
469
470 cc_library_shared {
471 name: "libjni",
472 host_supported: true,
473 device_supported: false,
474 stl: "none",
475 }
476 `)
477
Colin Cross0c66bc62021-07-20 09:47:41 -0700478 buildOS := ctx.Config().BuildOS.String()
Colin Crossf8d9c492021-01-26 11:01:43 -0800479
480 foo := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
481
482 expected := "lib64/libjni.so"
483 if runtime.GOOS == "darwin" {
484 expected = "lib64/libjni.dylib"
485 }
486
487 fooTestData := foo.data
488 if len(fooTestData) != 1 || fooTestData[0].Rel() != expected {
489 t.Errorf(`expected foo test data relative path [%q], got %q`,
490 expected, fooTestData.Strings())
491 }
492}
493
Alex Humesky2070e322020-06-09 20:23:08 -0400494func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) {
495 bp := `
496 java_library {
497 name: "target_library",
498 srcs: ["a.java"],
499 }
500
501 java_binary_host {
502 name: "host_binary",
503 srcs: ["b.java"],
504 }
505 `
Alex Humesky2070e322020-06-09 20:23:08 -0400506
Paul Duffin414ea5e2021-03-22 17:31:52 +0000507 result := android.GroupFixturePreparers(
508 PrepareForTestWithJavaDefaultModules,
509 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
510 variables.MinimizeJavaDebugInfo = proptools.BoolPtr(true)
511 }),
512 ).RunTestWithBp(t, bp)
Alex Humesky2070e322020-06-09 20:23:08 -0400513
Liz Kammer7941b302020-07-28 13:27:34 -0700514 // first, check that the -g flag is added to target modules
Paul Duffin414ea5e2021-03-22 17:31:52 +0000515 targetLibrary := result.ModuleForTests("target_library", "android_common")
Alex Humesky2070e322020-06-09 20:23:08 -0400516 targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"]
517 if !strings.Contains(targetJavaFlags, "-g:source,lines") {
518 t.Errorf("target library javac flags %v should contain "+
519 "-g:source,lines override with MinimizeJavaDebugInfo", targetJavaFlags)
520 }
521
522 // check that -g is not overridden for host modules
Colin Cross0c66bc62021-07-20 09:47:41 -0700523 buildOS := result.Config.BuildOS.String()
Paul Duffin414ea5e2021-03-22 17:31:52 +0000524 hostBinary := result.ModuleForTests("host_binary", buildOS+"_common")
Alex Humesky2070e322020-06-09 20:23:08 -0400525 hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"]
526 if strings.Contains(hostJavaFlags, "-g:source,lines") {
527 t.Errorf("java_binary_host javac flags %v should not have "+
528 "-g:source,lines override with MinimizeJavaDebugInfo", hostJavaFlags)
529 }
Colin Cross6b4a32d2017-12-05 13:42:45 -0800530}
531
Spandan Das59a4a2b2024-01-09 21:35:56 +0000532// A minimal context object for use with DexJarBuildPath
533type moduleErrorfTestCtx struct {
534}
535
536func (ctx moduleErrorfTestCtx) ModuleErrorf(format string, args ...interface{}) {
537}
538
539var _ android.ModuleErrorfContext = (*moduleErrorfTestCtx)(nil)
540
Colin Cross72bb3632017-07-13 16:23:21 -0700541func TestPrebuilts(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700542 ctx, _ := testJava(t, `
Colin Cross72bb3632017-07-13 16:23:21 -0700543 java_library {
544 name: "foo",
Paul Duffin91547182019-11-12 19:39:36 +0000545 srcs: ["a.java", ":stubs-source"],
Paul Duffinfcfd7912020-01-31 17:54:30 +0000546 libs: ["bar", "sdklib"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700547 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700548 }
549
Colin Cross74d73e22017-08-02 11:05:49 -0700550 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700551 name: "bar",
Colin Cross74d73e22017-08-02 11:05:49 -0700552 jars: ["a.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700553 }
554
Colin Cross74d73e22017-08-02 11:05:49 -0700555 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700556 name: "baz",
Colin Cross74d73e22017-08-02 11:05:49 -0700557 jars: ["b.jar"],
Liz Kammerd6c31d22020-08-05 15:40:41 -0700558 sdk_version: "current",
559 compile_dex: true,
Colin Cross72bb3632017-07-13 16:23:21 -0700560 }
Colin Cross42be7612019-02-21 18:12:14 -0800561
562 dex_import {
563 name: "qux",
564 jars: ["b.jar"],
565 }
Colin Cross79c7c262019-04-17 11:11:46 -0700566
567 java_sdk_library_import {
Paul Duffin56d44902020-01-31 13:36:25 +0000568 name: "sdklib",
569 public: {
570 jars: ["c.jar"],
571 },
572 }
573
Paul Duffin91547182019-11-12 19:39:36 +0000574 prebuilt_stubs_sources {
575 name: "stubs-source",
Paul Duffin9b478b02019-12-10 13:41:51 +0000576 srcs: ["stubs/sources"],
Paul Duffin91547182019-11-12 19:39:36 +0000577 }
Paul Duffin1b82e6a2019-12-03 18:06:47 +0000578
579 java_test_import {
580 name: "test",
581 jars: ["a.jar"],
582 test_suites: ["cts"],
583 test_config: "AndroidTest.xml",
584 }
Colin Cross72bb3632017-07-13 16:23:21 -0700585 `)
586
Paul Duffin9b478b02019-12-10 13:41:51 +0000587 fooModule := ctx.ModuleForTests("foo", "android_common")
588 javac := fooModule.Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700589 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Liz Kammerd6c31d22020-08-05 15:40:41 -0700590 barModule := ctx.ModuleForTests("bar", "android_common")
Colin Crossdad2a362024-03-23 04:43:41 +0000591 barJar := barModule.Output("combined/bar.jar").Output
Liz Kammerd6c31d22020-08-05 15:40:41 -0700592 bazModule := ctx.ModuleForTests("baz", "android_common")
593 bazJar := bazModule.Rule("combineJar").Output
Colin Crossdad2a362024-03-23 04:43:41 +0000594 sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").
595 Output("combined/sdklib.stubs.jar").Output
Colin Cross72bb3632017-07-13 16:23:21 -0700596
Paul Duffin9b478b02019-12-10 13:41:51 +0000597 fooLibrary := fooModule.Module().(*Library)
Chaohui Wangdcbe33c2022-10-11 11:13:30 +0800598 assertDeepEquals(t, "foo unique sources incorrect",
599 []string{"a.java"}, fooLibrary.uniqueSrcFiles.Strings())
Paul Duffin91547182019-11-12 19:39:36 +0000600
Paul Duffin9b478b02019-12-10 13:41:51 +0000601 assertDeepEquals(t, "foo java source jars incorrect",
602 []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"},
603 android.NormalizePathsForTesting(fooLibrary.compiledSrcJars))
Paul Duffin91547182019-11-12 19:39:36 +0000604
Colin Cross37f6d792018-07-12 12:28:41 -0700605 if !strings.Contains(javac.Args["classpath"], barJar.String()) {
606 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String())
Colin Cross72bb3632017-07-13 16:23:21 -0700607 }
608
Spandan Das59a4a2b2024-01-09 21:35:56 +0000609 errCtx := moduleErrorfTestCtx{}
610 barDexJar := barModule.Module().(*Import).DexJarBuildPath(errCtx)
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +0100611 if barDexJar.IsSet() {
612 t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar)
Liz Kammerd6c31d22020-08-05 15:40:41 -0700613 }
614
Colin Cross79c7c262019-04-17 11:11:46 -0700615 if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
616 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String())
617 }
618
Colin Cross37f6d792018-07-12 12:28:41 -0700619 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() {
620 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
Colin Cross72bb3632017-07-13 16:23:21 -0700621 }
Colin Cross42be7612019-02-21 18:12:14 -0800622
Spandan Das59a4a2b2024-01-09 21:35:56 +0000623 bazDexJar := bazModule.Module().(*Import).DexJarBuildPath(errCtx).Path()
Paul Duffin414ea5e2021-03-22 17:31:52 +0000624 expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar"
625 android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar)
Liz Kammerd6c31d22020-08-05 15:40:41 -0700626
Colin Cross42be7612019-02-21 18:12:14 -0800627 ctx.ModuleForTests("qux", "android_common").Rule("Cp")
Wei Li598f92d2023-01-04 17:12:24 -0800628
629 entries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0]
630 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
631 entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0]
632 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
Colin Cross72bb3632017-07-13 16:23:21 -0700633}
634
Paul Duffin9b478b02019-12-10 13:41:51 +0000635func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) {
636 if !reflect.DeepEqual(expected, actual) {
637 t.Errorf("%s: expected %q, found %q", message, expected, actual)
638 }
639}
640
Paul Duffin1a393322020-11-18 16:36:47 +0000641func TestPrebuiltStubsSources(t *testing.T) {
642 test := func(t *testing.T, sourcesPath string, expectedInputs []string) {
643 ctx, _ := testJavaWithFS(t, fmt.Sprintf(`
644prebuilt_stubs_sources {
645 name: "stubs-source",
646 srcs: ["%s"],
647}`, sourcesPath), map[string][]byte{
648 "stubs/sources/pkg/A.java": nil,
649 "stubs/sources/pkg/B.java": nil,
650 })
651
652 zipSrc := ctx.ModuleForTests("stubs-source", "android_common").Rule("zip_src")
653 if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) {
654 t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual)
655 }
656 }
657
658 t.Run("empty/missing directory", func(t *testing.T) {
Colin Crossce3a51d2021-03-19 16:22:12 -0700659 test(t, "empty-directory", nil)
Paul Duffin1a393322020-11-18 16:36:47 +0000660 })
661
662 t.Run("non-empty set of sources", func(t *testing.T) {
663 test(t, "stubs/sources", []string{
664 "stubs/sources/pkg/A.java",
665 "stubs/sources/pkg/B.java",
666 })
667 })
668}
669
Colin Cross89536d42017-07-07 14:35:50 -0700670func TestDefaults(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700671 ctx, _ := testJava(t, `
Colin Cross89536d42017-07-07 14:35:50 -0700672 java_defaults {
673 name: "defaults",
674 srcs: ["a.java"],
675 libs: ["bar"],
676 static_libs: ["baz"],
Sasha Smundak2057f822019-04-16 17:16:58 -0700677 optimize: {enabled: false},
Colin Cross89536d42017-07-07 14:35:50 -0700678 }
679
680 java_library {
681 name: "foo",
682 defaults: ["defaults"],
683 }
684
685 java_library {
686 name: "bar",
687 srcs: ["b.java"],
688 }
689
690 java_library {
691 name: "baz",
692 srcs: ["c.java"],
693 }
Sasha Smundak2057f822019-04-16 17:16:58 -0700694
695 android_test {
696 name: "atestOptimize",
697 defaults: ["defaults"],
698 optimize: {enabled: true},
699 }
700
701 android_test {
702 name: "atestNoOptimize",
703 defaults: ["defaults"],
704 }
705
706 android_test {
707 name: "atestDefault",
708 srcs: ["a.java"],
709 }
Colin Cross89536d42017-07-07 14:35:50 -0700710 `)
711
Paul Duffina71a67a2021-03-29 00:42:57 +0100712 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
Nan Zhanged19fc32017-10-19 13:06:22 -0700713 combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
Colin Cross89536d42017-07-07 14:35:50 -0700714
715 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
716 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
717 }
718
Paul Duffin414ea5e2021-03-22 17:31:52 +0000719 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
Nan Zhanged19fc32017-10-19 13:06:22 -0700720 if !strings.Contains(javac.Args["classpath"], barTurbine) {
721 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
Colin Cross89536d42017-07-07 14:35:50 -0700722 }
723
Colin Cross1ee23172017-10-18 14:44:18 -0700724 baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
Colin Cross0a6e0072017-08-30 14:24:55 -0700725 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
726 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross89536d42017-07-07 14:35:50 -0700727 }
Sasha Smundak2057f822019-04-16 17:16:58 -0700728
729 atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8")
730 if atestOptimize.Output == nil {
731 t.Errorf("atestOptimize should optimize APK")
732 }
733
734 atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8")
735 if atestNoOptimize.Output == nil {
736 t.Errorf("atestNoOptimize should not optimize APK")
737 }
738
Jared Duke63a3da92022-06-02 19:11:14 +0000739 atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("d8")
Sasha Smundak2057f822019-04-16 17:16:58 -0700740 if atestDefault.Output == nil {
Jared Duke63a3da92022-06-02 19:11:14 +0000741 t.Errorf("atestDefault should not optimize APK")
Sasha Smundak2057f822019-04-16 17:16:58 -0700742 }
Colin Cross89536d42017-07-07 14:35:50 -0700743}
744
Colin Cross0f37af02017-09-27 17:42:05 -0700745func TestResources(t *testing.T) {
746 var table = []struct {
747 name string
748 prop string
749 extra string
750 args string
751 }{
752 {
Colin Crossaf9c55b2017-10-03 14:50:08 -0700753 // Test that a module with java_resource_dirs includes the files
Colin Cross0f37af02017-09-27 17:42:05 -0700754 name: "resource dirs",
Colin Cross824bee32017-11-22 17:27:51 -0800755 prop: `java_resource_dirs: ["java-res"]`,
Colin Cross0ead1d72018-04-10 13:07:42 -0700756 args: "-C java-res -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700757 },
758 {
759 // Test that a module with java_resources includes the files
760 name: "resource files",
Colin Cross0ead1d72018-04-10 13:07:42 -0700761 prop: `java_resources: ["java-res/a/a", "java-res/b/b"]`,
762 args: "-C . -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700763 },
764 {
765 // Test that a module with a filegroup in java_resources includes the files with the
766 // path prefix
767 name: "resource filegroup",
768 prop: `java_resources: [":foo-res"]`,
769 extra: `
770 filegroup {
771 name: "foo-res",
Colin Cross824bee32017-11-22 17:27:51 -0800772 path: "java-res",
Colin Cross0ead1d72018-04-10 13:07:42 -0700773 srcs: ["java-res/a/a", "java-res/b/b"],
Colin Cross0f37af02017-09-27 17:42:05 -0700774 }`,
Colin Cross0ead1d72018-04-10 13:07:42 -0700775 args: "-C java-res -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700776 },
777 {
Colin Cross0ead1d72018-04-10 13:07:42 -0700778 // Test that a module with wildcards in java_resource_dirs has the correct path prefixes
779 name: "wildcard dirs",
780 prop: `java_resource_dirs: ["java-res/*"]`,
781 args: "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b",
782 },
783 {
784 // Test that a module exclude_java_resource_dirs excludes the files
785 name: "wildcard dirs",
786 prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`,
787 args: "-C java-res/a -f java-res/a/a",
788 },
Colin Crosscedd4762018-09-13 11:26:19 -0700789 {
790 // Test wildcards in java_resources
791 name: "wildcard files",
792 prop: `java_resources: ["java-res/**/*"]`,
793 args: "-C . -f java-res/a/a -f java-res/b/b",
794 },
795 {
796 // Test exclude_java_resources with java_resources
797 name: "wildcard files with exclude",
798 prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`,
799 args: "-C . -f java-res/a/a",
800 },
801 {
802 // Test exclude_java_resources with java_resource_dirs
803 name: "resource dirs with exclude files",
804 prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`,
805 args: "-C java-res -f java-res/a/a",
806 },
807 {
808 // Test exclude_java_resource_dirs with java_resource_dirs
809 name: "resource dirs with exclude files",
810 prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`,
811 args: "-C java-res -f java-res/a/a -f java-res/b/b",
812 },
Colin Cross0f37af02017-09-27 17:42:05 -0700813 }
814
815 for _, test := range table {
816 t.Run(test.name, func(t *testing.T) {
Colin Cross238c1f32020-06-07 16:58:18 -0700817 ctx, _ := testJavaWithFS(t, `
Colin Cross0f37af02017-09-27 17:42:05 -0700818 java_library {
819 name: "foo",
820 srcs: [
821 "a.java",
822 "b.java",
823 "c.java",
824 ],
825 `+test.prop+`,
826 }
Colin Cross238c1f32020-06-07 16:58:18 -0700827 `+test.extra,
828 map[string][]byte{
829 "java-res/a/a": nil,
830 "java-res/b/b": nil,
831 "java-res2/a": nil,
832 },
833 )
Colin Cross0f37af02017-09-27 17:42:05 -0700834
Colin Cross331a1212018-08-15 20:40:52 -0700835 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
Colin Cross1ee23172017-10-18 14:44:18 -0700836 fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar")
Colin Cross0f37af02017-09-27 17:42:05 -0700837
838 if !inList(fooRes.Output.String(), foo.Inputs.Strings()) {
839 t.Errorf("foo combined jars %v does not contain %q",
840 foo.Inputs.Strings(), fooRes.Output.String())
841 }
842
Colin Crossaf9c55b2017-10-03 14:50:08 -0700843 if fooRes.Args["jarArgs"] != test.args {
844 t.Errorf("foo resource jar args %q is not %q",
Colin Cross0f37af02017-09-27 17:42:05 -0700845 fooRes.Args["jarArgs"], test.args)
846 }
847 })
848 }
849}
850
Colin Cross0c4ce212019-05-03 15:28:19 -0700851func TestIncludeSrcs(t *testing.T) {
Colin Cross238c1f32020-06-07 16:58:18 -0700852 ctx, _ := testJavaWithFS(t, `
Colin Cross0c4ce212019-05-03 15:28:19 -0700853 java_library {
854 name: "foo",
855 srcs: [
856 "a.java",
857 "b.java",
858 "c.java",
859 ],
860 include_srcs: true,
861 }
862
863 java_library {
864 name: "bar",
865 srcs: [
866 "a.java",
867 "b.java",
868 "c.java",
869 ],
870 java_resource_dirs: ["java-res"],
871 include_srcs: true,
872 }
Colin Cross238c1f32020-06-07 16:58:18 -0700873 `, map[string][]byte{
874 "java-res/a/a": nil,
875 "java-res/b/b": nil,
876 "java-res2/a": nil,
877 })
Colin Cross0c4ce212019-05-03 15:28:19 -0700878
879 // Test a library with include_srcs: true
880 foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
881 fooSrcJar := ctx.ModuleForTests("foo", "android_common").Output("foo.srcjar")
882
883 if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) {
884 t.Errorf("foo combined jars %v does not contain %q", w, g)
885 }
886
887 if g, w := fooSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w {
888 t.Errorf("foo source jar args %q is not %q", w, g)
889 }
890
891 // Test a library with include_srcs: true and resources
892 bar := ctx.ModuleForTests("bar", "android_common").Output("withres/bar.jar")
893 barResCombined := ctx.ModuleForTests("bar", "android_common").Output("res-combined/bar.jar")
894 barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar")
895 barSrcJar := ctx.ModuleForTests("bar", "android_common").Output("bar.srcjar")
896
897 if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
898 t.Errorf("bar combined resource jars %v does not contain %q", w, g)
899 }
900
901 if g, w := barRes.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
902 t.Errorf("bar combined resource jars %v does not contain %q", w, g)
903 }
904
905 if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) {
906 t.Errorf("bar combined jars %v does not contain %q", w, g)
907 }
908
909 if g, w := barSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w {
910 t.Errorf("bar source jar args %q is not %q", w, g)
911 }
912
913 if g, w := barRes.Args["jarArgs"], "-C java-res -f java-res/a/a -f java-res/b/b"; g != w {
914 t.Errorf("bar resource jar args %q is not %q", w, g)
915 }
916}
917
Colin Cross54190b32017-10-09 15:34:10 -0700918func TestGeneratedSources(t *testing.T) {
Colin Cross238c1f32020-06-07 16:58:18 -0700919 ctx, _ := testJavaWithFS(t, `
Colin Cross54190b32017-10-09 15:34:10 -0700920 java_library {
921 name: "foo",
922 srcs: [
923 "a*.java",
924 ":gen",
925 "b*.java",
926 ],
927 }
928
929 genrule {
930 name: "gen",
Colin Cross824bee32017-11-22 17:27:51 -0800931 tool_files: ["java-res/a"],
Colin Cross54190b32017-10-09 15:34:10 -0700932 out: ["gen.java"],
933 }
Colin Cross238c1f32020-06-07 16:58:18 -0700934 `, map[string][]byte{
935 "a.java": nil,
936 "b.java": nil,
937 })
Colin Cross54190b32017-10-09 15:34:10 -0700938
939 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
940 genrule := ctx.ModuleForTests("gen", "").Rule("generator")
941
Colin Cross15e86d92017-10-20 15:07:08 -0700942 if filepath.Base(genrule.Output.String()) != "gen.java" {
943 t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String())
Colin Cross54190b32017-10-09 15:34:10 -0700944 }
945
946 if len(javac.Inputs) != 3 ||
947 javac.Inputs[0].String() != "a.java" ||
Colin Cross15e86d92017-10-20 15:07:08 -0700948 javac.Inputs[1].String() != genrule.Output.String() ||
Colin Cross54190b32017-10-09 15:34:10 -0700949 javac.Inputs[2].String() != "b.java" {
950 t.Errorf(`foo inputs %v != ["a.java", ".../gen.java", "b.java"]`, javac.Inputs)
951 }
952}
953
Nan Zhang61eaedb2017-11-02 13:28:15 -0700954func TestTurbine(t *testing.T) {
Paul Duffin71ae5942021-03-22 15:36:52 +0000955 result := android.GroupFixturePreparers(
956 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})).
Paul Duffin3d9f2682021-03-13 09:47:16 +0000957 RunTestWithBp(t, `
Nan Zhang61eaedb2017-11-02 13:28:15 -0700958 java_library {
959 name: "foo",
960 srcs: ["a.java"],
Jiyong Park2d492942018-03-05 17:44:10 +0900961 sdk_version: "14",
Nan Zhang61eaedb2017-11-02 13:28:15 -0700962 }
963
964 java_library {
965 name: "bar",
Colin Cross9bc43432017-12-15 20:20:39 -0800966 srcs: ["b.java"],
Nan Zhang61eaedb2017-11-02 13:28:15 -0700967 static_libs: ["foo"],
Jiyong Park2d492942018-03-05 17:44:10 +0900968 sdk_version: "14",
Nan Zhang61eaedb2017-11-02 13:28:15 -0700969 }
970
971 java_library {
972 name: "baz",
973 srcs: ["c.java"],
974 libs: ["bar"],
975 sdk_version: "14",
976 }
977 `)
978
Paul Duffina71a67a2021-03-29 00:42:57 +0100979 fooTurbine := result.ModuleForTests("foo", "android_common").Rule("turbine")
980 barTurbine := result.ModuleForTests("bar", "android_common").Rule("turbine")
981 barJavac := result.ModuleForTests("bar", "android_common").Rule("javac")
982 barTurbineCombined := result.ModuleForTests("bar", "android_common").Description("for turbine")
983 bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac")
Nan Zhang61eaedb2017-11-02 13:28:15 -0700984
Paul Duffin414ea5e2021-03-22 17:31:52 +0000985 android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs)
Nan Zhang61eaedb2017-11-02 13:28:15 -0700986
Paul Duffin414ea5e2021-03-22 17:31:52 +0000987 fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
988 barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
Colin Crossf61766e2022-03-16 18:06:48 -0700989 android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar)
Paul Duffin3d9f2682021-03-13 09:47:16 +0000990 android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar)
Paul Duffin414ea5e2021-03-22 17:31:52 +0000991 android.AssertPathsRelativeToTopEquals(t, "bar turbine combineJar", []string{barTurbineJar, fooHeaderJar}, barTurbineCombined.Inputs)
Paul Duffin3d9f2682021-03-13 09:47:16 +0000992 android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "prebuilts/sdk/14/public/android.jar")
Nan Zhang61eaedb2017-11-02 13:28:15 -0700993}
994
995func TestSharding(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700996 ctx, _ := testJava(t, `
Nan Zhang61eaedb2017-11-02 13:28:15 -0700997 java_library {
998 name: "bar",
999 srcs: ["a.java","b.java","c.java"],
1000 javac_shard_size: 1
1001 }
1002 `)
1003
Colin Cross3d56ed52021-11-18 22:23:12 -08001004 barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
Nan Zhang61eaedb2017-11-02 13:28:15 -07001005 for i := 0; i < 3; i++ {
Paul Duffina71a67a2021-03-29 00:42:57 +01001006 barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i))
Colin Cross3d56ed52021-11-18 22:23:12 -08001007 if !strings.HasPrefix(barJavac.Args["classpath"], "-classpath "+barHeaderJar+":") {
1008 t.Errorf("bar javac classpath %v does start with %q", barJavac.Args["classpath"], barHeaderJar)
Nan Zhang61eaedb2017-11-02 13:28:15 -07001009 }
1010 }
1011}
1012
Nan Zhang27e284d2018-02-09 21:03:53 +00001013func TestExcludeFileGroupInSrcs(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001014 ctx, _ := testJava(t, `
Nan Zhang27e284d2018-02-09 21:03:53 +00001015 java_library {
1016 name: "foo",
1017 srcs: ["a.java", ":foo-srcs"],
1018 exclude_srcs: ["a.java", ":foo-excludes"],
1019 }
1020
1021 filegroup {
1022 name: "foo-srcs",
1023 srcs: ["java-fg/a.java", "java-fg/b.java", "java-fg/c.java"],
1024 }
1025
1026 filegroup {
1027 name: "foo-excludes",
1028 srcs: ["java-fg/a.java", "java-fg/b.java"],
1029 }
1030 `)
1031
1032 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
1033
1034 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" {
1035 t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs)
1036 }
1037}
Jiyong Parkc678ad32018-04-10 13:07:10 +09001038
Colin Crossdad2a362024-03-23 04:43:41 +00001039func TestJavaLibraryOutputFiles(t *testing.T) {
Paul Duffin414ea5e2021-03-22 17:31:52 +00001040 testJavaWithFS(t, "", map[string][]byte{
Paul Duffin52d398a2019-06-11 12:31:14 +01001041 "libcore/Android.bp": []byte(`
1042 java_library {
1043 name: "core",
1044 sdk_version: "none",
1045 system_modules: "none",
Paul Duffinaa55f742020-10-06 17:20:13 +01001046 }
1047
1048 filegroup {
1049 name: "core-jar",
1050 srcs: [":core{.jar}"],
1051 }
Paul Duffin414ea5e2021-03-22 17:31:52 +00001052 `),
Paul Duffinaa55f742020-10-06 17:20:13 +01001053 })
Paul Duffinaa55f742020-10-06 17:20:13 +01001054}
1055
Colin Crossdad2a362024-03-23 04:43:41 +00001056func TestJavaImportOutputFiles(t *testing.T) {
Paul Duffin414ea5e2021-03-22 17:31:52 +00001057 testJavaWithFS(t, "", map[string][]byte{
Paul Duffinaa55f742020-10-06 17:20:13 +01001058 "libcore/Android.bp": []byte(`
1059 java_import {
1060 name: "core",
1061 sdk_version: "none",
1062 }
1063
1064 filegroup {
1065 name: "core-jar",
1066 srcs: [":core{.jar}"],
1067 }
Paul Duffin414ea5e2021-03-22 17:31:52 +00001068 `),
Paul Duffin52d398a2019-06-11 12:31:14 +01001069 })
Paul Duffin52d398a2019-06-11 12:31:14 +01001070}
1071
Colin Crossdad2a362024-03-23 04:43:41 +00001072func TestJavaImport(t *testing.T) {
1073 bp := `
1074 java_library {
1075 name: "source_library",
1076 srcs: ["source.java"],
1077 }
1078
1079 java_import {
1080 name: "import_with_no_deps",
1081 jars: ["no_deps.jar"],
1082 }
1083
1084 java_import {
1085 name: "import_with_source_deps",
1086 jars: ["source_deps.jar"],
1087 static_libs: ["source_library"],
1088 }
1089
1090 java_import {
1091 name: "import_with_import_deps",
1092 jars: ["import_deps.jar"],
1093 static_libs: ["import_with_no_deps"],
1094 }
1095 `
1096 ctx := android.GroupFixturePreparers(
1097 PrepareForTestWithJavaDefaultModules,
1098 ).RunTestWithBp(t, bp)
1099
1100 source := ctx.ModuleForTests("source_library", "android_common")
1101 sourceJar := source.Output("javac/source_library.jar")
1102 sourceHeaderJar := source.Output("turbine-combined/source_library.jar")
1103 sourceJavaInfo, _ := android.SingletonModuleProvider(ctx, source.Module(), JavaInfoProvider)
1104
1105 // The source library produces separate implementation and header jars
1106 android.AssertPathsRelativeToTopEquals(t, "source library implementation jar",
1107 []string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars)
1108 android.AssertPathsRelativeToTopEquals(t, "source library header jar",
1109 []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars)
1110
1111 importWithNoDeps := ctx.ModuleForTests("import_with_no_deps", "android_common")
1112 importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar")
1113 importWithNoDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider)
1114
1115 // An import with no deps produces a single jar used as both the header and implementation jar.
1116 android.AssertPathsRelativeToTopEquals(t, "import with no deps implementation jar",
1117 []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.ImplementationAndResourcesJars)
1118 android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar",
1119 []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars)
1120 android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs",
1121 []string{"no_deps.jar"}, importWithNoDepsJar.Inputs)
1122
1123 importWithSourceDeps := ctx.ModuleForTests("import_with_source_deps", "android_common")
1124 importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar")
1125 importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar")
1126 importWithSourceDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider)
1127
1128 // An import with source deps produces separate header and implementation jars.
1129 android.AssertPathsRelativeToTopEquals(t, "import with source deps implementation jar",
1130 []string{importWithSourceDepsJar.Output.String()}, importWithSourceDepsJavaInfo.ImplementationAndResourcesJars)
1131 android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar",
1132 []string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars)
1133 android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs",
1134 []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs)
1135 android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs",
1136 []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs)
1137
1138 importWithImportDeps := ctx.ModuleForTests("import_with_import_deps", "android_common")
1139 importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar")
1140 importWithImportDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider)
1141
1142 // An import with only import deps produces a single jar used as both the header and implementation jar.
1143 android.AssertPathsRelativeToTopEquals(t, "import with import deps implementation jar",
1144 []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.ImplementationAndResourcesJars)
1145 android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar",
1146 []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars)
1147 android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs",
1148 []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs)
1149}
1150
Zoran Jovanovic8736ce22018-08-21 17:10:29 +02001151var compilerFlagsTestCases = []struct {
1152 in string
1153 out bool
1154}{
1155 {
1156 in: "a",
1157 out: false,
1158 },
1159 {
1160 in: "-a",
1161 out: true,
1162 },
1163 {
1164 in: "-no-jdk",
1165 out: false,
1166 },
1167 {
1168 in: "-no-stdlib",
1169 out: false,
1170 },
1171 {
1172 in: "-kotlin-home",
1173 out: false,
1174 },
1175 {
1176 in: "-kotlin-home /some/path",
1177 out: false,
1178 },
1179 {
1180 in: "-include-runtime",
1181 out: false,
1182 },
1183 {
1184 in: "-Xintellij-plugin-root",
1185 out: false,
1186 },
1187}
1188
1189type mockContext struct {
1190 android.ModuleContext
1191 result bool
1192}
1193
1194func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1195 // CheckBadCompilerFlags calls this function when the flag should be rejected
1196 ctx.result = false
1197}
1198
1199func TestCompilerFlags(t *testing.T) {
1200 for _, testCase := range compilerFlagsTestCases {
1201 ctx := &mockContext{result: true}
1202 CheckKotlincFlags(ctx, []string{testCase.in})
1203 if ctx.result != testCase.out {
1204 t.Errorf("incorrect output:")
1205 t.Errorf(" input: %#v", testCase.in)
1206 t.Errorf(" expected: %#v", testCase.out)
1207 t.Errorf(" got: %#v", ctx.result)
1208 }
1209 }
1210}
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001211
1212// TODO(jungjw): Consider making this more robust by ignoring path order.
1213func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) {
Paul Duffin414ea5e2021-03-22 17:31:52 +00001214 variables := ctx.ModuleForTests(moduleName, "android_common").VariablesForTestsRelativeToTop()
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001215 flags := strings.Split(variables["javacFlags"], " ")
1216 got := ""
1217 for _, flag := range flags {
1218 keyEnd := strings.Index(flag, "=")
1219 if keyEnd > -1 && flag[:keyEnd] == "--patch-module" {
1220 got = flag[keyEnd+1:]
1221 break
1222 }
1223 }
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +02001224 if expected != android.StringPathRelativeToTop(ctx.Config().SoongOutDir(), got) {
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001225 t.Errorf("Unexpected patch-module flag for module %q - expected %q, but got %q", moduleName, expected, got)
1226 }
1227}
1228
1229func TestPatchModule(t *testing.T) {
Pete Gillin0c2143e2019-05-02 15:32:11 +01001230 t.Run("Java language level 8", func(t *testing.T) {
Pete Gillin1b3370f2019-10-01 13:57:31 +01001231 // Test with legacy javac -source 1.8 -target 1.8
Pete Gillinbdf5d712019-10-21 14:29:58 +01001232 bp := `
1233 java_library {
1234 name: "foo",
1235 srcs: ["a.java"],
1236 java_version: "1.8",
1237 }
1238
1239 java_library {
1240 name: "bar",
1241 srcs: ["b.java"],
1242 sdk_version: "none",
1243 system_modules: "none",
1244 patch_module: "java.base",
1245 java_version: "1.8",
1246 }
1247
1248 java_library {
1249 name: "baz",
1250 srcs: ["c.java"],
1251 patch_module: "java.base",
1252 java_version: "1.8",
1253 }
1254 `
1255 ctx, _ := testJava(t, bp)
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001256
1257 checkPatchModuleFlag(t, ctx, "foo", "")
1258 checkPatchModuleFlag(t, ctx, "bar", "")
1259 checkPatchModuleFlag(t, ctx, "baz", "")
1260 })
1261
Pete Gillin0c2143e2019-05-02 15:32:11 +01001262 t.Run("Java language level 9", func(t *testing.T) {
Pete Gillin1b3370f2019-10-01 13:57:31 +01001263 // Test with default javac -source 9 -target 9
Pete Gillinbdf5d712019-10-21 14:29:58 +01001264 bp := `
1265 java_library {
1266 name: "foo",
1267 srcs: ["a.java"],
1268 }
1269
1270 java_library {
1271 name: "bar",
1272 srcs: ["b.java"],
1273 sdk_version: "none",
1274 system_modules: "none",
1275 patch_module: "java.base",
1276 }
1277
1278 java_library {
1279 name: "baz",
Jingwen Chen5136a6e2020-10-30 01:01:35 -04001280 srcs: [
1281 "c.java",
1282 // Tests for b/150878007
1283 "dir/d.java",
1284 "dir2/e.java",
1285 "dir2/f.java",
1286 "nested/dir/g.java"
1287 ],
Pete Gillinbdf5d712019-10-21 14:29:58 +01001288 patch_module: "java.base",
1289 }
1290 `
Pete Gillin1b3370f2019-10-01 13:57:31 +01001291 ctx, _ := testJava(t, bp)
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001292
1293 checkPatchModuleFlag(t, ctx, "foo", "")
Paul Duffin414ea5e2021-03-22 17:31:52 +00001294 expected := "java.base=.:out/soong"
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001295 checkPatchModuleFlag(t, ctx, "bar", expected)
Jingwen Chen5136a6e2020-10-30 01:01:35 -04001296 expected = "java.base=" + strings.Join([]string{
Colin Cross8ff10582023-12-07 13:10:56 -08001297 ".", "out/soong", defaultModuleToPath("ext"), defaultModuleToPath("framework")}, ":")
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001298 checkPatchModuleFlag(t, ctx, "baz", expected)
1299 })
1300}
Paul Duffina7b9f422020-01-10 17:12:18 +00001301
Paul Duffin83a2d962019-11-19 19:44:10 +00001302func TestJavaLibraryWithSystemModules(t *testing.T) {
1303 ctx, _ := testJava(t, `
1304 java_library {
1305 name: "lib-with-source-system-modules",
1306 srcs: [
1307 "a.java",
1308 ],
1309 sdk_version: "none",
1310 system_modules: "source-system-modules",
1311 }
1312
1313 java_library {
1314 name: "source-jar",
1315 srcs: [
1316 "a.java",
1317 ],
1318 }
1319
1320 java_system_modules {
1321 name: "source-system-modules",
1322 libs: ["source-jar"],
1323 }
1324
1325 java_library {
1326 name: "lib-with-prebuilt-system-modules",
1327 srcs: [
1328 "a.java",
1329 ],
1330 sdk_version: "none",
1331 system_modules: "prebuilt-system-modules",
1332 }
1333
1334 java_import {
1335 name: "prebuilt-jar",
1336 jars: ["a.jar"],
1337 }
1338
1339 java_system_modules_import {
1340 name: "prebuilt-system-modules",
1341 libs: ["prebuilt-jar"],
1342 }
1343 `)
1344
1345 checkBootClasspathForSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar")
1346
1347 checkBootClasspathForSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar")
1348}
1349
1350func checkBootClasspathForSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) {
1351 javacRule := ctx.ModuleForTests(moduleName, "android_common").Rule("javac")
1352 bootClasspath := javacRule.Args["bootClasspath"]
1353 if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) {
1354 t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath)
1355 }
1356}
Jiyong Park19604de2020-03-24 16:44:11 +09001357
1358func TestAidlExportIncludeDirsFromImports(t *testing.T) {
1359 ctx, _ := testJava(t, `
1360 java_library {
1361 name: "foo",
1362 srcs: ["aidl/foo/IFoo.aidl"],
1363 libs: ["bar"],
1364 }
1365
1366 java_import {
1367 name: "bar",
1368 jars: ["a.jar"],
1369 aidl: {
1370 export_include_dirs: ["aidl/bar"],
1371 },
1372 }
1373 `)
1374
1375 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
1376 expectedAidlFlag := "-Iaidl/bar"
1377 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1378 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1379 }
1380}
Liz Kammerdd849a82020-06-12 16:38:45 -07001381
Jooyung Hane197d8b2021-01-05 10:33:16 +09001382func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) {
1383 ctx, _ := testJava(t, `
1384 java_library {
1385 name: "foo",
1386 srcs: ["aidl/foo/IFoo.aidl"],
1387 aidl: { flags: ["-Werror"], },
1388 }
1389 `)
1390
1391 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
1392 expectedAidlFlag := "-Werror"
1393 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1394 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1395 }
1396}
1397
Jooyung Han07f70c02021-11-06 07:08:45 +09001398func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
1399 fixture := android.GroupFixturePreparers(
1400 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}}))
1401
1402 for _, tc := range []struct {
1403 name string
1404 sdkVersion string
1405 expected string
1406 }{
1407 {"default is current", "", "current"},
1408 {"use sdk_version", `sdk_version: "14"`, "14"},
1409 {"system_current", `sdk_version: "system_current"`, "current"},
1410 } {
1411 t.Run(tc.name, func(t *testing.T) {
1412 ctx := fixture.RunTestWithBp(t, `
1413 java_library {
1414 name: "foo",
1415 srcs: ["aidl/foo/IFoo.aidl"],
1416 `+tc.sdkVersion+`
1417 }
1418 `)
1419 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
1420 expectedAidlFlag := "--min_sdk_version=" + tc.expected
1421 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1422 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1423 }
1424 })
1425 }
1426}
1427
Spandan Das757b6662022-11-17 04:29:59 +00001428func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) {
1429 bpTemplate := `
1430 droidstubs {
1431 name: "foo-stubs",
1432 srcs: ["foo.aidl"],
1433 %s
1434 system_modules: "none",
1435 }
1436 `
1437 testCases := []struct {
1438 desc string
1439 sdkVersionBp string
1440 minSdkVersionExpected string
1441 }{
1442 {
1443 desc: "sdk_version not set, module compiles against private platform APIs",
1444 sdkVersionBp: ``,
1445 minSdkVersionExpected: "10000",
1446 },
1447 {
1448 desc: "sdk_version set to none, module does not build against an SDK",
1449 sdkVersionBp: `sdk_version: "none",`,
1450 minSdkVersionExpected: "10000",
1451 },
1452 }
1453 for _, tc := range testCases {
1454 ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp))
1455 aidlCmd := ctx.ModuleForTests("foo-stubs", "android_common").Rule("aidl").RuleParams.Command
1456 expected := "--min_sdk_version=" + tc.minSdkVersionExpected
1457 android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected)
1458 }
1459}
1460
Thiébaud Weksteende8417c2022-02-10 15:41:46 +11001461func TestAidlEnforcePermissions(t *testing.T) {
1462 ctx, _ := testJava(t, `
1463 java_library {
1464 name: "foo",
1465 srcs: ["aidl/foo/IFoo.aidl"],
1466 aidl: { enforce_permissions: true },
1467 }
1468 `)
1469
1470 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
1471 expectedAidlFlag := "-Wmissing-permission-annotation -Werror"
1472 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1473 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1474 }
1475}
1476
1477func TestAidlEnforcePermissionsException(t *testing.T) {
1478 ctx, _ := testJava(t, `
1479 java_library {
1480 name: "foo",
1481 srcs: ["aidl/foo/IFoo.aidl", "aidl/foo/IFoo2.aidl"],
1482 aidl: { enforce_permissions: true, enforce_permissions_exceptions: ["aidl/foo/IFoo2.aidl"] },
1483 }
1484 `)
1485
1486 aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
1487 expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl"
1488 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1489 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1490 }
1491 expectedAidlFlag = "$$FLAGS aidl/foo/IFoo2.aidl"
1492 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1493 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1494 }
1495}
1496
Liz Kammerdd849a82020-06-12 16:38:45 -07001497func TestDataNativeBinaries(t *testing.T) {
Cole Faust5c503d12023-01-24 11:48:08 -08001498 ctx := android.GroupFixturePreparers(
1499 prepareForJavaTest,
1500 android.PrepareForTestWithAllowMissingDependencies).RunTestWithBp(t, `
Liz Kammerdd849a82020-06-12 16:38:45 -07001501 java_test_host {
1502 name: "foo",
1503 srcs: ["a.java"],
1504 data_native_bins: ["bin"]
1505 }
1506
Cole Faust5c503d12023-01-24 11:48:08 -08001507 cc_binary_host {
Liz Kammerdd849a82020-06-12 16:38:45 -07001508 name: "bin",
Cole Faust5c503d12023-01-24 11:48:08 -08001509 srcs: ["bin.cpp"],
Liz Kammerdd849a82020-06-12 16:38:45 -07001510 }
Cole Faust5c503d12023-01-24 11:48:08 -08001511 `).TestContext
Liz Kammerdd849a82020-06-12 16:38:45 -07001512
Colin Cross0c66bc62021-07-20 09:47:41 -07001513 buildOS := ctx.Config().BuildOS.String()
Liz Kammerdd849a82020-06-12 16:38:45 -07001514
1515 test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
Colin Crossaa255532020-07-03 13:18:24 -07001516 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
Cole Faust5c503d12023-01-24 11:48:08 -08001517 expected := []string{"out/soong/.intermediates/bin/" + buildOS + "_x86_64/bin:bin"}
Liz Kammerdd849a82020-06-12 16:38:45 -07001518 actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
Paul Duffin414ea5e2021-03-22 17:31:52 +00001519 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_COMPATIBILITY_SUPPORT_FILES", ctx.Config(), expected, actual)
Liz Kammerdd849a82020-06-12 16:38:45 -07001520}
Yuexi Ma627263f2021-03-04 13:47:56 -08001521
1522func TestDefaultInstallable(t *testing.T) {
1523 ctx, _ := testJava(t, `
1524 java_test_host {
1525 name: "foo"
1526 }
1527 `)
1528
Colin Cross0c66bc62021-07-20 09:47:41 -07001529 buildOS := ctx.Config().BuildOS.String()
Yuexi Ma627263f2021-03-04 13:47:56 -08001530 module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
1531 assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true),
1532 module.properties.Installable)
1533}
Cole Faust75fffb12021-06-13 15:23:16 -07001534
1535func TestErrorproneEnabled(t *testing.T) {
1536 ctx, _ := testJava(t, `
1537 java_library {
1538 name: "foo",
1539 srcs: ["a.java"],
1540 errorprone: {
1541 enabled: true,
1542 },
1543 }
1544 `)
1545
1546 javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
1547
1548 // Test that the errorprone plugins are passed to javac
1549 expectedSubstring := "-Xplugin:ErrorProne"
1550 if !strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
Cole Faust2b1536e2021-06-18 12:25:54 -07001551 t.Errorf("expected javacFlags to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
Cole Faust75fffb12021-06-13 15:23:16 -07001552 }
1553
1554 // Modules with errorprone { enabled: true } will include errorprone checks
1555 // in the main javac build rule. Only when RUN_ERROR_PRONE is true will
1556 // the explicit errorprone build rule be created.
1557 errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
1558 if errorprone.RuleParams.Description != "" {
1559 t.Errorf("expected errorprone build rule to not exist, but it did")
1560 }
1561}
Cole Faust2b1536e2021-06-18 12:25:54 -07001562
1563func TestErrorproneDisabled(t *testing.T) {
1564 bp := `
1565 java_library {
1566 name: "foo",
1567 srcs: ["a.java"],
1568 errorprone: {
1569 enabled: false,
1570 },
1571 }
1572 `
1573 ctx := android.GroupFixturePreparers(
1574 PrepareForTestWithJavaDefaultModules,
1575 android.FixtureMergeEnv(map[string]string{
1576 "RUN_ERROR_PRONE": "true",
1577 }),
1578 ).RunTestWithBp(t, bp)
1579
1580 javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
1581
1582 // Test that the errorprone plugins are not passed to javac, like they would
1583 // be if enabled was true.
1584 expectedSubstring := "-Xplugin:ErrorProne"
1585 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
1586 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
1587 }
1588
1589 // Check that no errorprone build rule is created, like there would be
1590 // if enabled was unset and RUN_ERROR_PRONE was true.
1591 errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
1592 if errorprone.RuleParams.Description != "" {
1593 t.Errorf("expected errorprone build rule to not exist, but it did")
1594 }
1595}
1596
1597func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) {
1598 bp := `
1599 java_library {
1600 name: "foo",
1601 srcs: ["a.java"],
1602 }
1603 `
1604 ctx := android.GroupFixturePreparers(
1605 PrepareForTestWithJavaDefaultModules,
1606 android.FixtureMergeEnv(map[string]string{
1607 "RUN_ERROR_PRONE": "true",
1608 }),
1609 ).RunTestWithBp(t, bp)
1610
1611 javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
1612 errorprone := ctx.ModuleForTests("foo", "android_common").Description("errorprone")
1613
1614 // Check that the errorprone plugins are not passed to javac, because they
1615 // will instead be passed to the separate errorprone compilation
1616 expectedSubstring := "-Xplugin:ErrorProne"
1617 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
1618 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
1619 }
1620
1621 // Check that the errorprone plugin is enabled
1622 if !strings.Contains(errorprone.Args["javacFlags"], expectedSubstring) {
1623 t.Errorf("expected errorprone to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
1624 }
1625}
Sam Delmericob3342ce2022-01-20 21:10:28 +00001626
1627func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) {
Sam Delmericocc271e22022-06-01 15:45:02 +00001628 testCases := []struct {
1629 dataDeviceBinType string
1630 depCompileMultilib string
1631 variants []string
1632 expectedError string
1633 }{
1634 {
1635 dataDeviceBinType: "first",
1636 depCompileMultilib: "first",
1637 variants: []string{"android_arm64_armv8-a"},
1638 },
1639 {
1640 dataDeviceBinType: "first",
1641 depCompileMultilib: "both",
1642 variants: []string{"android_arm64_armv8-a"},
1643 },
1644 {
1645 // this is true because our testing framework is set up with
1646 // Targets ~ [<64bit target>, <32bit target>], where 64bit is "first"
1647 dataDeviceBinType: "first",
1648 depCompileMultilib: "32",
1649 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1650 },
1651 {
1652 dataDeviceBinType: "first",
1653 depCompileMultilib: "64",
1654 variants: []string{"android_arm64_armv8-a"},
1655 },
1656 {
1657 dataDeviceBinType: "both",
1658 depCompileMultilib: "both",
1659 variants: []string{
1660 "android_arm_armv7-a-neon",
1661 "android_arm64_armv8-a",
1662 },
1663 },
1664 {
1665 dataDeviceBinType: "both",
1666 depCompileMultilib: "32",
1667 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1668 },
1669 {
1670 dataDeviceBinType: "both",
1671 depCompileMultilib: "64",
1672 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1673 },
1674 {
1675 dataDeviceBinType: "both",
1676 depCompileMultilib: "first",
1677 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1678 },
1679 {
1680 dataDeviceBinType: "32",
1681 depCompileMultilib: "32",
1682 variants: []string{"android_arm_armv7-a-neon"},
1683 },
1684 {
1685 dataDeviceBinType: "32",
1686 depCompileMultilib: "first",
1687 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1688 },
1689 {
1690 dataDeviceBinType: "32",
1691 depCompileMultilib: "both",
1692 variants: []string{"android_arm_armv7-a-neon"},
1693 },
1694 {
1695 dataDeviceBinType: "32",
1696 depCompileMultilib: "64",
1697 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1698 },
1699 {
1700 dataDeviceBinType: "64",
1701 depCompileMultilib: "64",
1702 variants: []string{"android_arm64_armv8-a"},
1703 },
1704 {
1705 dataDeviceBinType: "64",
1706 depCompileMultilib: "both",
1707 variants: []string{"android_arm64_armv8-a"},
1708 },
1709 {
1710 dataDeviceBinType: "64",
1711 depCompileMultilib: "first",
1712 variants: []string{"android_arm64_armv8-a"},
1713 },
1714 {
1715 dataDeviceBinType: "64",
1716 depCompileMultilib: "32",
1717 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1718 },
1719 {
1720 dataDeviceBinType: "prefer32",
1721 depCompileMultilib: "32",
1722 variants: []string{"android_arm_armv7-a-neon"},
1723 },
1724 {
1725 dataDeviceBinType: "prefer32",
1726 depCompileMultilib: "both",
1727 variants: []string{"android_arm_armv7-a-neon"},
1728 },
1729 {
1730 dataDeviceBinType: "prefer32",
1731 depCompileMultilib: "first",
1732 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1733 },
1734 {
1735 dataDeviceBinType: "prefer32",
1736 depCompileMultilib: "64",
1737 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1738 },
Sam Delmericob3342ce2022-01-20 21:10:28 +00001739 }
Sam Delmericob3342ce2022-01-20 21:10:28 +00001740
Sam Delmericocc271e22022-06-01 15:45:02 +00001741 bpTemplate := `
Sam Delmericob3342ce2022-01-20 21:10:28 +00001742 java_test_host {
1743 name: "foo",
1744 srcs: ["test.java"],
Sam Delmericocc271e22022-06-01 15:45:02 +00001745 data_device_bins_%s: ["bar"],
Sam Delmericob3342ce2022-01-20 21:10:28 +00001746 }
1747
1748 cc_binary {
1749 name: "bar",
Sam Delmericocc271e22022-06-01 15:45:02 +00001750 compile_multilib: "%s",
Sam Delmericob3342ce2022-01-20 21:10:28 +00001751 }
1752 `
1753
Sam Delmericocc271e22022-06-01 15:45:02 +00001754 for _, tc := range testCases {
1755 bp := fmt.Sprintf(bpTemplate, tc.dataDeviceBinType, tc.depCompileMultilib)
Sam Delmericob3342ce2022-01-20 21:10:28 +00001756
Sam Delmericocc271e22022-06-01 15:45:02 +00001757 errorHandler := android.FixtureExpectsNoErrors
1758 if tc.expectedError != "" {
1759 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError)
1760 }
Sam Delmericob3342ce2022-01-20 21:10:28 +00001761
Sam Delmericocc271e22022-06-01 15:45:02 +00001762 testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib)
1763 t.Run(testName, func(t *testing.T) {
1764 ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava).
1765 ExtendWithErrorHandler(errorHandler).
1766 RunTestWithBp(t, bp)
1767 if tc.expectedError != "" {
1768 return
1769 }
1770
1771 buildOS := ctx.Config.BuildOS.String()
1772 fooVariant := ctx.ModuleForTests("foo", buildOS+"_common")
1773 fooMod := fooVariant.Module().(*TestHost)
1774 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0]
1775
1776 expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />`
1777 autogen := fooVariant.Rule("autogen")
1778 if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) {
1779 t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig)
1780 }
1781
1782 expectedData := []string{}
1783 for _, variant := range tc.variants {
1784 barVariant := ctx.ModuleForTests("bar", variant)
1785 relocated := barVariant.Output("bar")
1786 expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant)
1787 android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input)
1788
1789 expectedData = append(expectedData, fmt.Sprintf("out/soong/.intermediates/bar/%s/bar:bar", variant))
1790 }
1791
1792 actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
1793 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData)
1794 })
Sam Delmericob3342ce2022-01-20 21:10:28 +00001795 }
1796}
Sam Delmerico277795c2022-02-25 17:04:37 +00001797
Zi Wangca65b402022-10-10 13:45:06 -07001798func TestDeviceBinaryWrapperGeneration(t *testing.T) {
1799 // Scenario 1: java_binary has main_class property in its bp
1800 ctx, _ := testJava(t, `
1801 java_binary {
1802 name: "foo",
1803 srcs: ["foo.java"],
1804 main_class: "foo.bar.jb",
1805 }
1806 `)
1807 wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_arm64_armv8-a").AllOutputs())
1808 if !strings.Contains(wrapperPath, "foo.sh") {
1809 t.Errorf("wrapper file foo.sh is not generated")
1810 }
1811
1812 // Scenario 2: java_binary has neither wrapper nor main_class, its build
1813 // is expected to be failed.
1814 testJavaError(t, "main_class property is required for device binary if no default wrapper is assigned", `
1815 java_binary {
1816 name: "foo",
1817 srcs: ["foo.java"],
1818 }`)
1819}
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001820
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001821func TestJavaApiContributionEmptyApiFile(t *testing.T) {
Jihoon Kang063ec002023-06-28 01:16:23 +00001822 android.GroupFixturePreparers(
1823 prepareForJavaTest,
1824 android.FixtureMergeEnv(
1825 map[string]string{
1826 "DISABLE_STUB_VALIDATION": "true",
1827 },
1828 ),
1829 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001830 "Error: foo has an empty api file.",
Jihoon Kang063ec002023-06-28 01:16:23 +00001831 )).RunTestWithBp(t, `
1832 java_api_contribution {
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001833 name: "foo",
1834 }
1835 java_api_library {
1836 name: "bar",
1837 api_surface: "public",
1838 api_contributions: ["foo"],
Jihoon Kang5d701272024-02-15 21:53:49 +00001839 stubs_type: "everything",
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001840 }
1841 `)
1842}
1843
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001844func TestJavaApiLibraryAndProviderLink(t *testing.T) {
1845 provider_bp_a := `
1846 java_api_contribution {
1847 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00001848 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00001849 api_surface: "public",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001850 }
1851 `
1852 provider_bp_b := `java_api_contribution {
1853 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00001854 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00001855 api_surface: "public",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001856 }
1857 `
Jihoon Kang063ec002023-06-28 01:16:23 +00001858 ctx := android.GroupFixturePreparers(
1859 prepareForJavaTest,
1860 android.FixtureMergeMockFs(
1861 map[string][]byte{
1862 "a/Android.bp": []byte(provider_bp_a),
1863 "b/Android.bp": []byte(provider_bp_b),
1864 },
1865 ),
1866 android.FixtureMergeEnv(
1867 map[string]string{
1868 "DISABLE_STUB_VALIDATION": "true",
1869 },
1870 ),
1871 ).RunTestWithBp(t, `
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001872 java_api_library {
1873 name: "bar1",
1874 api_surface: "public",
Jihoon Kang60d4a092022-11-17 23:47:43 +00001875 api_contributions: ["foo1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00001876 stubs_type: "everything",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001877 }
1878
1879 java_api_library {
1880 name: "bar2",
1881 api_surface: "system",
Jihoon Kang60d4a092022-11-17 23:47:43 +00001882 api_contributions: ["foo1", "foo2"],
Jihoon Kang5d701272024-02-15 21:53:49 +00001883 stubs_type: "everything",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001884 }
Jihoon Kang063ec002023-06-28 01:16:23 +00001885 `)
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001886
1887 testcases := []struct {
1888 moduleName string
1889 sourceTextFileDirs []string
1890 }{
1891 {
1892 moduleName: "bar1",
Jihoon Kang84473f52023-08-11 22:36:33 +00001893 sourceTextFileDirs: []string{"a/current.txt"},
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001894 },
1895 {
1896 moduleName: "bar2",
Jihoon Kang6be0f002023-09-20 23:03:01 +00001897 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"},
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001898 },
1899 }
1900 for _, c := range testcases {
1901 m := ctx.ModuleForTests(c.moduleName, "android_common")
1902 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07001903 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
Jihoon Kang0ac87c22022-11-15 19:06:14 +00001904 manifestCommand := sboxProto.Commands[0].GetCommand()
1905 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ")
1906 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag)
1907 }
1908}
1909
Jihoon Kang1c51f502023-01-09 23:42:40 +00001910func TestJavaApiLibraryAndDefaultsLink(t *testing.T) {
Jihoon Kang362aa9d2023-01-20 19:44:07 +00001911 provider_bp_a := `
1912 java_api_contribution {
Jihoon Kang1c51f502023-01-09 23:42:40 +00001913 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00001914 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00001915 api_surface: "public",
Jihoon Kang1c51f502023-01-09 23:42:40 +00001916 }
1917 `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00001918 provider_bp_b := `
1919 java_api_contribution {
Jihoon Kang1c51f502023-01-09 23:42:40 +00001920 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00001921 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00001922 api_surface: "public",
Jihoon Kang1c51f502023-01-09 23:42:40 +00001923 }
1924 `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00001925 provider_bp_c := `
1926 java_api_contribution {
Jihoon Kang1c51f502023-01-09 23:42:40 +00001927 name: "foo3",
Jihoon Kang8fe19822023-09-14 06:27:36 +00001928 api_file: "system-current.txt",
1929 api_surface: "system",
Jihoon Kang1c51f502023-01-09 23:42:40 +00001930 }
1931 `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00001932 provider_bp_d := `
1933 java_api_contribution {
Jihoon Kang1c51f502023-01-09 23:42:40 +00001934 name: "foo4",
Jihoon Kang8fe19822023-09-14 06:27:36 +00001935 api_file: "system-current.txt",
1936 api_surface: "system",
Jihoon Kang1c51f502023-01-09 23:42:40 +00001937 }
1938 `
Jihoon Kang063ec002023-06-28 01:16:23 +00001939 ctx := android.GroupFixturePreparers(
1940 prepareForJavaTest,
1941 android.FixtureMergeMockFs(
1942 map[string][]byte{
1943 "a/Android.bp": []byte(provider_bp_a),
1944 "b/Android.bp": []byte(provider_bp_b),
1945 "c/Android.bp": []byte(provider_bp_c),
1946 "d/Android.bp": []byte(provider_bp_d),
1947 },
1948 ),
1949 android.FixtureMergeEnv(
1950 map[string]string{
1951 "DISABLE_STUB_VALIDATION": "true",
1952 },
1953 ),
1954 ).RunTestWithBp(t, `
Jihoon Kang1c51f502023-01-09 23:42:40 +00001955 java_defaults {
1956 name: "baz1",
1957 api_surface: "public",
1958 api_contributions: ["foo1", "foo2"],
1959 }
1960
1961 java_defaults {
1962 name: "baz2",
1963 api_surface: "system",
1964 api_contributions: ["foo3"],
1965 }
1966
1967 java_api_library {
1968 name: "bar1",
1969 api_surface: "public",
1970 api_contributions: ["foo1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00001971 stubs_type: "everything",
Jihoon Kang1c51f502023-01-09 23:42:40 +00001972 }
1973
1974 java_api_library {
1975 name: "bar2",
1976 api_surface: "public",
1977 defaults:["baz1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00001978 stubs_type: "everything",
Jihoon Kang1c51f502023-01-09 23:42:40 +00001979 }
1980
1981 java_api_library {
1982 name: "bar3",
1983 api_surface: "system",
1984 defaults:["baz1", "baz2"],
1985 api_contributions: ["foo4"],
Jihoon Kang5d701272024-02-15 21:53:49 +00001986 stubs_type: "everything",
Jihoon Kang1c51f502023-01-09 23:42:40 +00001987 }
Jihoon Kang063ec002023-06-28 01:16:23 +00001988 `)
Jihoon Kang1c51f502023-01-09 23:42:40 +00001989
1990 testcases := []struct {
1991 moduleName string
1992 sourceTextFileDirs []string
1993 }{
1994 {
1995 moduleName: "bar1",
Jihoon Kang84473f52023-08-11 22:36:33 +00001996 sourceTextFileDirs: []string{"a/current.txt"},
Jihoon Kang1c51f502023-01-09 23:42:40 +00001997 },
1998 {
1999 moduleName: "bar2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002000 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"},
Jihoon Kang1c51f502023-01-09 23:42:40 +00002001 },
2002 {
Jihoon Kang8fe19822023-09-14 06:27:36 +00002003 moduleName: "bar3",
2004 // API text files need to be sorted from the narrower api scope to the wider api scope
Jihoon Kang6be0f002023-09-20 23:03:01 +00002005 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "c/system-current.txt", "d/system-current.txt"},
Jihoon Kang1c51f502023-01-09 23:42:40 +00002006 },
2007 }
2008 for _, c := range testcases {
2009 m := ctx.ModuleForTests(c.moduleName, "android_common")
2010 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002011 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
Jihoon Kang1c51f502023-01-09 23:42:40 +00002012 manifestCommand := sboxProto.Commands[0].GetCommand()
2013 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ")
2014 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag)
2015 }
2016}
2017
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002018func TestJavaApiLibraryJarGeneration(t *testing.T) {
2019 provider_bp_a := `
2020 java_api_contribution {
2021 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002022 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002023 api_surface: "public",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002024 }
2025 `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002026 provider_bp_b := `
2027 java_api_contribution {
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002028 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002029 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002030 api_surface: "public",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002031 }
2032 `
Jihoon Kang063ec002023-06-28 01:16:23 +00002033 ctx := android.GroupFixturePreparers(
2034 prepareForJavaTest,
2035 android.FixtureMergeMockFs(
2036 map[string][]byte{
2037 "a/Android.bp": []byte(provider_bp_a),
2038 "b/Android.bp": []byte(provider_bp_b),
2039 },
2040 ),
2041 android.FixtureMergeEnv(
2042 map[string]string{
2043 "DISABLE_STUB_VALIDATION": "true",
2044 },
2045 ),
2046 ).RunTestWithBp(t, `
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002047 java_api_library {
2048 name: "bar1",
2049 api_surface: "public",
Jihoon Kang60d4a092022-11-17 23:47:43 +00002050 api_contributions: ["foo1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002051 stubs_type: "everything",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002052 }
2053
2054 java_api_library {
2055 name: "bar2",
2056 api_surface: "system",
Jihoon Kang60d4a092022-11-17 23:47:43 +00002057 api_contributions: ["foo1", "foo2"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002058 stubs_type: "everything",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002059 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002060 `)
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002061
2062 testcases := []struct {
2063 moduleName string
2064 outputJarName string
2065 }{
2066 {
2067 moduleName: "bar1",
Jihoon Kang25857f52023-03-01 00:27:32 +00002068 outputJarName: "bar1/bar1.jar",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002069 },
2070 {
2071 moduleName: "bar2",
Jihoon Kang25857f52023-03-01 00:27:32 +00002072 outputJarName: "bar2/bar2.jar",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002073 },
2074 }
2075 for _, c := range testcases {
2076 m := ctx.ModuleForTests(c.moduleName, "android_common")
2077 outputs := fmt.Sprint(m.AllOutputs())
2078 if !strings.Contains(outputs, c.outputJarName) {
2079 t.Errorf("Module output does not contain expected jar %s", c.outputJarName)
2080 }
2081 }
2082}
Cole Faust21680542022-12-07 18:18:37 -08002083
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002084func TestJavaApiLibraryLibsLink(t *testing.T) {
2085 provider_bp_a := `
2086 java_api_contribution {
2087 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002088 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002089 api_surface: "public",
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002090 }
2091 `
2092 provider_bp_b := `
2093 java_api_contribution {
2094 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002095 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002096 api_surface: "public",
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002097 }
2098 `
2099 lib_bp_a := `
2100 java_library {
2101 name: "lib1",
2102 srcs: ["Lib.java"],
2103 }
2104 `
2105 lib_bp_b := `
2106 java_library {
2107 name: "lib2",
2108 srcs: ["Lib.java"],
2109 }
2110 `
2111
Jihoon Kang063ec002023-06-28 01:16:23 +00002112 ctx := android.GroupFixturePreparers(
2113 prepareForJavaTest,
2114 android.FixtureMergeMockFs(
2115 map[string][]byte{
2116 "a/Android.bp": []byte(provider_bp_a),
2117 "b/Android.bp": []byte(provider_bp_b),
2118 "c/Android.bp": []byte(lib_bp_a),
2119 "c/Lib.java": {},
2120 "d/Android.bp": []byte(lib_bp_b),
2121 "d/Lib.java": {},
2122 },
2123 ),
2124 android.FixtureMergeEnv(
2125 map[string]string{
2126 "DISABLE_STUB_VALIDATION": "true",
2127 },
2128 ),
2129 ).RunTestWithBp(t, `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002130 java_api_library {
2131 name: "bar1",
2132 api_surface: "public",
2133 api_contributions: ["foo1"],
2134 libs: ["lib1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002135 stubs_type: "everything",
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002136 }
2137
2138 java_api_library {
2139 name: "bar2",
2140 api_surface: "system",
2141 api_contributions: ["foo1", "foo2"],
2142 libs: ["lib1", "lib2", "bar1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002143 stubs_type: "everything",
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002144 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002145 `)
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002146
2147 testcases := []struct {
2148 moduleName string
2149 classPathJarNames []string
2150 }{
2151 {
2152 moduleName: "bar1",
2153 classPathJarNames: []string{"lib1.jar"},
2154 },
2155 {
2156 moduleName: "bar2",
Jihoon Kang25857f52023-03-01 00:27:32 +00002157 classPathJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"},
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002158 },
2159 }
2160 for _, c := range testcases {
2161 m := ctx.ModuleForTests(c.moduleName, "android_common")
2162 javacRules := m.Rule("javac")
2163 classPathArgs := javacRules.Args["classpath"]
2164 for _, jarName := range c.classPathJarNames {
2165 if !strings.Contains(classPathArgs, jarName) {
2166 t.Errorf("Module output does not contain expected jar %s", jarName)
2167 }
2168 }
2169 }
2170}
2171
Jihoon Kange30fff02023-02-14 20:18:20 +00002172func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
2173 provider_bp_a := `
2174 java_api_contribution {
2175 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002176 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002177 api_surface: "public",
Jihoon Kange30fff02023-02-14 20:18:20 +00002178 }
2179 `
2180 provider_bp_b := `
2181 java_api_contribution {
2182 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002183 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002184 api_surface: "public",
Jihoon Kange30fff02023-02-14 20:18:20 +00002185 }
2186 `
2187 lib_bp_a := `
2188 java_library {
2189 name: "lib1",
2190 srcs: ["Lib.java"],
2191 }
2192 `
2193 lib_bp_b := `
2194 java_library {
2195 name: "lib2",
2196 srcs: ["Lib.java"],
2197 }
2198 `
2199
Jihoon Kang063ec002023-06-28 01:16:23 +00002200 ctx := android.GroupFixturePreparers(
2201 prepareForJavaTest,
2202 android.FixtureMergeMockFs(
2203 map[string][]byte{
2204 "a/Android.bp": []byte(provider_bp_a),
2205 "b/Android.bp": []byte(provider_bp_b),
2206 "c/Android.bp": []byte(lib_bp_a),
2207 "c/Lib.java": {},
2208 "d/Android.bp": []byte(lib_bp_b),
2209 "d/Lib.java": {},
2210 },
2211 ),
2212 android.FixtureMergeEnv(
2213 map[string]string{
2214 "DISABLE_STUB_VALIDATION": "true",
2215 },
2216 ),
2217 ).RunTestWithBp(t, `
Jihoon Kange30fff02023-02-14 20:18:20 +00002218 java_api_library {
2219 name: "bar1",
2220 api_surface: "public",
2221 api_contributions: ["foo1"],
2222 static_libs: ["lib1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002223 stubs_type: "everything",
Jihoon Kange30fff02023-02-14 20:18:20 +00002224 }
2225
2226 java_api_library {
2227 name: "bar2",
2228 api_surface: "system",
2229 api_contributions: ["foo1", "foo2"],
2230 static_libs: ["lib1", "lib2", "bar1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002231 stubs_type: "everything",
Jihoon Kange30fff02023-02-14 20:18:20 +00002232 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002233 `)
Jihoon Kange30fff02023-02-14 20:18:20 +00002234
2235 testcases := []struct {
2236 moduleName string
2237 staticLibJarNames []string
2238 }{
2239 {
2240 moduleName: "bar1",
2241 staticLibJarNames: []string{"lib1.jar"},
2242 },
2243 {
2244 moduleName: "bar2",
Jihoon Kang25857f52023-03-01 00:27:32 +00002245 staticLibJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"},
Jihoon Kange30fff02023-02-14 20:18:20 +00002246 },
2247 }
2248 for _, c := range testcases {
2249 m := ctx.ModuleForTests(c.moduleName, "android_common")
2250 mergeZipsCommand := m.Rule("merge_zips").RuleParams.Command
2251 for _, jarName := range c.staticLibJarNames {
2252 if !strings.Contains(mergeZipsCommand, jarName) {
2253 t.Errorf("merge_zips command does not contain expected jar %s", jarName)
2254 }
2255 }
2256 }
2257}
2258
Jihoon Kangca198c22023-06-22 23:13:51 +00002259func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) {
Jihoon Kang01e522c2023-03-14 01:09:34 +00002260 provider_bp_a := `
2261 java_api_contribution {
2262 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002263 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002264 api_surface: "public",
Jihoon Kang01e522c2023-03-14 01:09:34 +00002265 }
2266 `
2267 provider_bp_b := `
2268 java_api_contribution {
2269 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002270 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002271 api_surface: "public",
Jihoon Kang01e522c2023-03-14 01:09:34 +00002272 }
2273 `
2274 lib_bp_a := `
2275 java_api_library {
2276 name: "lib1",
2277 api_surface: "public",
2278 api_contributions: ["foo1", "foo2"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002279 stubs_type: "everything",
Jihoon Kang01e522c2023-03-14 01:09:34 +00002280 }
2281 `
2282
Jihoon Kang063ec002023-06-28 01:16:23 +00002283 ctx := android.GroupFixturePreparers(
2284 prepareForJavaTest,
2285 android.FixtureMergeMockFs(
2286 map[string][]byte{
2287 "a/Android.bp": []byte(provider_bp_a),
2288 "b/Android.bp": []byte(provider_bp_b),
2289 "c/Android.bp": []byte(lib_bp_a),
2290 },
2291 ),
2292 android.FixtureMergeEnv(
2293 map[string]string{
2294 "DISABLE_STUB_VALIDATION": "true",
2295 },
2296 ),
2297 ).RunTestWithBp(t, `
Jihoon Kang01e522c2023-03-14 01:09:34 +00002298 java_api_library {
2299 name: "bar1",
2300 api_surface: "public",
2301 api_contributions: ["foo1"],
Jihoon Kangca198c22023-06-22 23:13:51 +00002302 full_api_surface_stub: "lib1",
Jihoon Kang5d701272024-02-15 21:53:49 +00002303 stubs_type: "everything",
Jihoon Kang01e522c2023-03-14 01:09:34 +00002304 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002305 `)
Jihoon Kang01e522c2023-03-14 01:09:34 +00002306
2307 m := ctx.ModuleForTests("bar1", "android_common")
2308 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002309 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
Jihoon Kang01e522c2023-03-14 01:09:34 +00002310 manifestCommand := sboxProto.Commands[0].GetCommand()
Jihoon Kangca198c22023-06-22 23:13:51 +00002311 android.AssertStringDoesContain(t, "Command expected to contain full_api_surface_stub output jar", manifestCommand, "lib1.jar")
Jihoon Kang01e522c2023-03-14 01:09:34 +00002312}
2313
Anton Hansson0e73f9e2023-09-20 13:39:57 +00002314func TestTransitiveSrcFiles(t *testing.T) {
2315 ctx, _ := testJava(t, `
2316 java_library {
2317 name: "a",
2318 srcs: ["a.java"],
2319 }
2320 java_library {
2321 name: "b",
2322 srcs: ["b.java"],
2323 }
2324 java_library {
2325 name: "c",
2326 srcs: ["c.java"],
2327 libs: ["a"],
2328 static_libs: ["b"],
2329 }
2330 `)
2331 c := ctx.ModuleForTests("c", "android_common").Module()
Colin Cross5a377182023-12-14 14:46:23 -08002332 javaInfo, _ := android.SingletonModuleProvider(ctx, c, JavaInfoProvider)
2333 transitiveSrcFiles := android.Paths(javaInfo.TransitiveSrcFiles.ToList())
Anton Hansson0e73f9e2023-09-20 13:39:57 +00002334 android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings())
2335}
2336
Cole Faust21680542022-12-07 18:18:37 -08002337func TestTradefedOptions(t *testing.T) {
2338 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
2339java_test_host {
2340 name: "foo",
2341 test_options: {
2342 tradefed_options: [
2343 {
2344 name: "exclude-path",
2345 value: "org/apache"
2346 }
2347 ]
2348 }
2349}
2350`)
2351
2352 buildOS := result.Config.BuildOS.String()
2353 args := result.ModuleForTests("foo", buildOS+"_common").
2354 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
2355 expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />")
2356 if args["extraConfigs"] != expected {
2357 t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"])
2358 }
2359}
Dan Shiec731432023-05-26 04:21:44 +00002360
2361func TestTestRunnerOptions(t *testing.T) {
2362 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
2363java_test_host {
2364 name: "foo",
2365 test_options: {
2366 test_runner_options: [
2367 {
2368 name: "test-timeout",
2369 value: "10m"
2370 }
2371 ]
2372 }
2373}
2374`)
2375
2376 buildOS := result.Config.BuildOS.String()
2377 args := result.ModuleForTests("foo", buildOS+"_common").
2378 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
2379 expected := proptools.NinjaAndShellEscape("<option name=\"test-timeout\" value=\"10m\" />\\n ")
2380 if args["extraTestRunnerConfigs"] != expected {
2381 t.Errorf("Expected args[\"extraTestRunnerConfigs\"] to equal %q, was %q", expected, args["extraTestRunnerConfigs"])
2382 }
2383}
Jihoon Kang381c2fa2023-06-01 22:17:32 +00002384
2385func TestJavaExcludeStaticLib(t *testing.T) {
2386 ctx, _ := testJava(t, `
2387 java_library {
2388 name: "bar",
2389 }
2390 java_library {
2391 name: "foo",
2392 }
2393 java_library {
2394 name: "baz",
2395 static_libs: [
2396 "foo",
2397 "bar",
2398 ],
2399 exclude_static_libs: [
2400 "bar",
2401 ],
2402 }
2403 `)
2404
2405 // "bar" not included as dependency of "baz"
2406 CheckModuleDependencies(t, ctx, "baz", "android_common", []string{
2407 `core-lambda-stubs`,
2408 `ext`,
2409 `foo`,
2410 `framework`,
2411 `stable-core-platform-api-stubs-system-modules`,
2412 `stable.core.platform.api.stubs`,
2413 })
2414}
Jihoon Kang1bfb6f22023-07-01 00:13:47 +00002415
2416func TestJavaLibraryWithResourcesStem(t *testing.T) {
2417 ctx, _ := testJavaWithFS(t, `
2418 java_library {
2419 name: "foo",
2420 java_resource_dirs: ["test-jar"],
2421 stem: "test",
2422 }
2423 `,
2424 map[string][]byte{
2425 "test-jar/test/resource.txt": nil,
2426 })
2427
2428 m := ctx.ModuleForTests("foo", "android_common")
2429 outputs := fmt.Sprint(m.AllOutputs())
2430 if !strings.Contains(outputs, "test.jar") {
2431 t.Errorf("Module output does not contain expected jar %s", "test.jar")
2432 }
2433}
Mark Whitea15790a2023-08-22 21:28:11 +00002434
2435func TestHeadersOnly(t *testing.T) {
2436 ctx, _ := testJava(t, `
2437 java_library {
2438 name: "foo",
2439 srcs: ["a.java"],
2440 headers_only: true,
2441 }
2442 `)
2443
2444 turbine := ctx.ModuleForTests("foo", "android_common").Rule("turbine")
2445 if len(turbine.Inputs) != 1 || turbine.Inputs[0].String() != "a.java" {
2446 t.Errorf(`foo inputs %v != ["a.java"]`, turbine.Inputs)
2447 }
2448
2449 javac := ctx.ModuleForTests("foo", "android_common").MaybeRule("javac")
2450 android.AssertDeepEquals(t, "javac rule", nil, javac.Rule)
2451}
Jihoon Kangfdf32362023-09-12 00:36:43 +00002452
2453func TestJavaApiContributionImport(t *testing.T) {
Jihoon Kang063ec002023-06-28 01:16:23 +00002454 ctx := android.GroupFixturePreparers(
2455 prepareForJavaTest,
2456 android.FixtureMergeEnv(
2457 map[string]string{
2458 "DISABLE_STUB_VALIDATION": "true",
2459 },
2460 ),
2461 ).RunTestWithBp(t, `
Jihoon Kangfdf32362023-09-12 00:36:43 +00002462 java_api_library {
2463 name: "foo",
2464 api_contributions: ["bar"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002465 stubs_type: "everything",
Jihoon Kangfdf32362023-09-12 00:36:43 +00002466 }
2467 java_api_contribution_import {
2468 name: "bar",
2469 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002470 api_surface: "public",
Jihoon Kangfdf32362023-09-12 00:36:43 +00002471 }
2472 `)
2473 m := ctx.ModuleForTests("foo", "android_common")
2474 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002475 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
Jihoon Kangfdf32362023-09-12 00:36:43 +00002476 manifestCommand := sboxProto.Commands[0].GetCommand()
2477 sourceFilesFlag := "--source-files current.txt"
2478 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag)
2479}
Jihoon Kanga96a7b12023-09-20 23:43:32 +00002480
2481func TestJavaApiLibraryApiFilesSorting(t *testing.T) {
2482 ctx, _ := testJava(t, `
2483 java_api_library {
2484 name: "foo",
2485 api_contributions: [
2486 "system-server-api-stubs-docs-non-updatable.api.contribution",
2487 "test-api-stubs-docs-non-updatable.api.contribution",
2488 "system-api-stubs-docs-non-updatable.api.contribution",
2489 "module-lib-api-stubs-docs-non-updatable.api.contribution",
2490 "api-stubs-docs-non-updatable.api.contribution",
2491 ],
Jihoon Kang5d701272024-02-15 21:53:49 +00002492 stubs_type: "everything",
Jihoon Kanga96a7b12023-09-20 23:43:32 +00002493 }
2494 `)
2495 m := ctx.ModuleForTests("foo", "android_common")
2496 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002497 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest)
Jihoon Kanga96a7b12023-09-20 23:43:32 +00002498 manifestCommand := sboxProto.Commands[0].GetCommand()
2499
2500 // Api files are sorted from the narrowest api scope to the widest api scope.
2501 // test api and module lib api surface do not have subset/superset relationship,
2502 // but they will never be passed as inputs at the same time.
2503 sourceFilesFlag := "--source-files default/java/api/current.txt " +
2504 "default/java/api/system-current.txt default/java/api/test-current.txt " +
2505 "default/java/api/module-lib-current.txt default/java/api/system-server-current.txt"
2506 android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag)
2507}
Jihoon Kang4ec24872023-10-05 17:26:09 +00002508
2509func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) {
2510 result := android.GroupFixturePreparers(
2511 prepareForJavaTest,
2512 PrepareForTestWithJavaSdkLibraryFiles,
2513 FixtureWithLastReleaseApis("foo"),
2514 android.FixtureModifyConfig(func(config android.Config) {
2515 config.SetApiLibraries([]string{"foo"})
2516 }),
2517 android.FixtureMergeMockFs(
2518 map[string][]byte{
2519 "A.java": nil,
2520 },
2521 ),
2522 ).RunTestWithBp(t, `
2523 java_library {
2524 name: "bar",
2525 srcs: ["a.java"],
2526 }
2527 java_system_modules {
2528 name: "baz",
2529 libs: ["bar"],
2530 }
2531 java_sdk_library {
2532 name: "foo",
2533 srcs: ["A.java"],
2534 system_modules: "baz",
2535 }
2536 `)
2537 m := result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common")
2538 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002539 sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest)
Jihoon Kang4ec24872023-10-05 17:26:09 +00002540 manifestCommand := sboxProto.Commands[0].GetCommand()
Cole Fauste8561c62023-11-30 17:26:37 -08002541 classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar"
Jihoon Kang4ec24872023-10-05 17:26:09 +00002542 android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag)
2543}
Jihoon Kang063ec002023-06-28 01:16:23 +00002544
2545func TestApiLibraryDroidstubsDependency(t *testing.T) {
2546 result := android.GroupFixturePreparers(
2547 prepareForJavaTest,
2548 PrepareForTestWithJavaSdkLibraryFiles,
2549 FixtureWithLastReleaseApis("foo"),
2550 android.FixtureModifyConfig(func(config android.Config) {
2551 config.SetApiLibraries([]string{"foo"})
2552 }),
2553 android.FixtureMergeMockFs(
2554 map[string][]byte{
2555 "A.java": nil,
2556 },
2557 ),
2558 ).RunTestWithBp(t, `
2559 java_api_library {
2560 name: "foo",
2561 api_contributions: [
2562 "api-stubs-docs-non-updatable.api.contribution",
2563 ],
2564 enable_validation: true,
Jihoon Kang5d701272024-02-15 21:53:49 +00002565 stubs_type: "everything",
Jihoon Kang063ec002023-06-28 01:16:23 +00002566 }
2567 java_api_library {
2568 name: "bar",
2569 api_contributions: [
2570 "api-stubs-docs-non-updatable.api.contribution",
2571 ],
2572 enable_validation: false,
Jihoon Kang5d701272024-02-15 21:53:49 +00002573 stubs_type: "everything",
Jihoon Kang063ec002023-06-28 01:16:23 +00002574 }
2575 `)
2576
Jihoon Kang3c89f042023-12-19 02:40:22 +00002577 currentApiTimestampPath := "api-stubs-docs-non-updatable/android_common/everything/check_current_api.timestamp"
Jihoon Kang063ec002023-06-28 01:16:23 +00002578 foo := result.ModuleForTests("foo", "android_common").Module().(*ApiLibrary)
2579 fooValidationPathsString := strings.Join(foo.validationPaths.Strings(), " ")
2580 bar := result.ModuleForTests("bar", "android_common").Module().(*ApiLibrary)
2581 barValidationPathsString := strings.Join(bar.validationPaths.Strings(), " ")
2582 android.AssertStringDoesContain(t,
2583 "Module expected to have validation",
2584 fooValidationPathsString,
2585 currentApiTimestampPath,
2586 )
2587 android.AssertStringDoesNotContain(t,
2588 "Module expected to not have validation",
2589 barValidationPathsString,
2590 currentApiTimestampPath,
2591 )
2592}
Jihoon Kang1975d3e2023-10-16 23:24:11 +00002593
2594func TestDisableFromTextStubForCoverageBuild(t *testing.T) {
2595 result := android.GroupFixturePreparers(
2596 prepareForJavaTest,
2597 PrepareForTestWithJavaSdkLibraryFiles,
2598 PrepareForTestWithJacocoInstrumentation,
2599 FixtureWithLastReleaseApis("foo"),
2600 android.FixtureModifyConfig(func(config android.Config) {
2601 config.SetApiLibraries([]string{"foo"})
2602 config.SetBuildFromTextStub(true)
2603 }),
2604 android.FixtureModifyEnv(func(env map[string]string) {
2605 env["EMMA_INSTRUMENT"] = "true"
2606 }),
2607 ).RunTestWithBp(t, `
2608 java_sdk_library {
2609 name: "foo",
2610 srcs: ["A.java"],
2611 }
2612 `)
2613 android.AssertBoolEquals(t, "stub module expected to depend on from-source stub",
2614 true, CheckModuleHasDependency(t, result.TestContext,
2615 apiScopePublic.stubsLibraryModuleName("foo"), "android_common",
2616 apiScopePublic.sourceStubLibraryModuleName("foo")))
2617
2618 android.AssertBoolEquals(t, "stub module expected to not depend on from-text stub",
2619 false, CheckModuleHasDependency(t, result.TestContext,
2620 apiScopePublic.stubsLibraryModuleName("foo"), "android_common",
2621 apiScopePublic.apiLibraryModuleName("foo")))
2622}
Spandan Das3cf04632024-01-19 00:22:22 +00002623
2624func TestMultiplePrebuilts(t *testing.T) {
2625 bp := `
2626 // an rdep
2627 java_library {
2628 name: "foo",
2629 libs: ["bar"],
2630 }
2631
2632 // multiple variations of dep
2633 // source
2634 java_library {
2635 name: "bar",
2636 srcs: ["bar.java"],
2637 }
2638 // prebuilt "v1"
2639 java_import {
2640 name: "bar",
2641 jars: ["bar.jar"],
2642 }
2643 // prebuilt "v2"
2644 java_import {
2645 name: "bar.v2",
2646 source_module_name: "bar",
2647 jars: ["bar.v1.jar"],
2648 }
2649
2650 // selectors
2651 apex_contributions {
2652 name: "myapex_contributions",
2653 contents: ["%v"],
2654 }
2655 `
2656 hasDep := func(ctx *android.TestResult, m android.Module, wantDep android.Module) bool {
2657 t.Helper()
2658 var found bool
2659 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
2660 if dep == wantDep {
2661 found = true
2662 }
2663 })
2664 return found
2665 }
2666
2667 hasFileWithStem := func(m android.TestingModule, stem string) bool {
2668 t.Helper()
2669 for _, o := range m.AllOutputs() {
2670 _, file := filepath.Split(o)
2671 if file == stem+".jar" {
2672 return true
2673 }
2674 }
2675 return false
2676 }
2677
2678 testCases := []struct {
2679 desc string
2680 selectedDependencyName string
2681 expectedDependencyName string
2682 }{
2683 {
2684 desc: "Source library is selected using apex_contributions",
2685 selectedDependencyName: "bar",
2686 expectedDependencyName: "bar",
2687 },
2688 {
2689 desc: "Prebuilt library v1 is selected using apex_contributions",
2690 selectedDependencyName: "prebuilt_bar",
2691 expectedDependencyName: "prebuilt_bar",
2692 },
2693 {
2694 desc: "Prebuilt library v2 is selected using apex_contributions",
2695 selectedDependencyName: "prebuilt_bar.v2",
2696 expectedDependencyName: "prebuilt_bar.v2",
2697 },
2698 }
2699
2700 for _, tc := range testCases {
2701 ctx := android.GroupFixturePreparers(
2702 prepareForJavaTest,
2703 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2704 variables.BuildFlags = map[string]string{
2705 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions",
2706 }
2707 }),
2708 ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
2709
2710 // check that rdep gets the correct variation of dep
2711 foo := ctx.ModuleForTests("foo", "android_common")
2712 expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_common")
2713 android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module()))
2714
2715 // check that output file of dep is always bar.jar
2716 // The filename should be agnostic to source/prebuilt/prebuilt_version
2717 android.AssertBoolEquals(t, fmt.Sprintf("could not find bar.jar in outputs of %s. All Outputs %v\n", tc.expectedDependencyName, expectedDependency.AllOutputs()), true, hasFileWithStem(expectedDependency, "bar"))
2718
2719 // check LOCAL_MODULE of the selected module name
2720 // the prebuilt should have the same LOCAL_MODULE when exported to make
2721 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, expectedDependency.Module())[0]
2722 android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "bar", entries.EntryMap["LOCAL_MODULE"][0])
2723 }
2724}
Jihoon Kang5d701272024-02-15 21:53:49 +00002725
Spandan Dase4c911e2024-01-19 00:22:22 +00002726func TestMultiplePlatformCompatConfigPrebuilts(t *testing.T) {
2727 bp := `
2728 // multiple variations of platform_compat_config
2729 // source
2730 platform_compat_config {
2731 name: "myconfig",
2732 }
2733 // prebuilt "v1"
2734 prebuilt_platform_compat_config {
2735 name: "myconfig",
2736 metadata: "myconfig.xml",
2737 }
2738 // prebuilt "v2"
2739 prebuilt_platform_compat_config {
2740 name: "myconfig.v2",
2741 source_module_name: "myconfig", // without source_module_name, the singleton will merge two .xml files
2742 metadata: "myconfig.v2.xml",
2743 }
2744
2745 // selectors
2746 apex_contributions {
2747 name: "myapex_contributions",
2748 contents: ["%v"],
2749 }
2750 `
2751 testCases := []struct {
2752 desc string
2753 selectedDependencyName string
2754 expectedPlatformCompatConfigXml string
2755 }{
2756 {
2757 desc: "Source platform_compat_config is selected using apex_contributions",
2758 selectedDependencyName: "myconfig",
2759 expectedPlatformCompatConfigXml: "out/soong/.intermediates/myconfig/android_common/myconfig_meta.xml",
2760 },
2761 {
2762 desc: "Prebuilt platform_compat_config v1 is selected using apex_contributions",
2763 selectedDependencyName: "prebuilt_myconfig",
2764 expectedPlatformCompatConfigXml: "myconfig.xml",
2765 },
2766 {
2767 desc: "Prebuilt platform_compat_config v2 is selected using apex_contributions",
2768 selectedDependencyName: "prebuilt_myconfig.v2",
2769 expectedPlatformCompatConfigXml: "myconfig.v2.xml",
2770 },
2771 }
2772
2773 for _, tc := range testCases {
2774 ctx := android.GroupFixturePreparers(
2775 prepareForJavaTest,
2776 PrepareForTestWithPlatformCompatConfig,
2777 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2778 variables.BuildFlags = map[string]string{
2779 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions",
2780 }
2781 }),
2782 ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
2783
2784 mergedGlobalConfig := ctx.SingletonForTests("platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml")
2785 android.AssertIntEquals(t, "The merged compat config file should only have a single dependency", 1, len(mergedGlobalConfig.Implicits))
2786 android.AssertStringEquals(t, "The merged compat config file is missing the appropriate platform compat config", mergedGlobalConfig.Implicits[0].String(), tc.expectedPlatformCompatConfigXml)
2787 }
2788}
2789
Jihoon Kang5d701272024-02-15 21:53:49 +00002790func TestApiLibraryAconfigDeclarations(t *testing.T) {
2791 result := android.GroupFixturePreparers(
2792 prepareForJavaTest,
2793 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2794 }),
2795 android.FixtureMergeMockFs(map[string][]byte{
2796 "a/A.java": nil,
2797 "a/current.txt": nil,
2798 "a/removed.txt": nil,
2799 }),
2800 ).RunTestWithBp(t, `
2801 aconfig_declarations {
2802 name: "bar",
2803 package: "com.example.package",
2804 srcs: [
2805 "bar.aconfig",
2806 ],
2807 }
2808 java_api_contribution {
2809 name: "baz",
2810 api_file: "a/current.txt",
2811 api_surface: "public",
2812 }
2813 java_api_library {
2814 name: "foo",
2815 api_surface: "public",
2816 api_contributions: [
2817 "baz",
2818 ],
2819 aconfig_declarations: [
2820 "bar",
2821 ],
2822 stubs_type: "exportable",
2823 enable_validation: false,
2824 }
2825 `)
2826
2827 // Check if java_api_library depends on aconfig_declarations
2828 android.AssertBoolEquals(t, "foo expected to depend on bar",
2829 CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
2830
2831 m := result.ModuleForTests("foo", "android_common")
2832 android.AssertStringDoesContain(t, "foo generates revert annotations file",
2833 strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
2834
2835 // revert-annotations.txt passed to exportable stubs generation metalava command
2836 manifest := m.Output("metalava.sbox.textproto")
2837 cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
2838 android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
2839}
yangbill2af0b6e2024-03-15 09:29:29 +00002840
2841func TestJavaLibHostWithStem(t *testing.T) {
2842 ctx, _ := testJava(t, `
2843 java_library_host {
2844 name: "foo",
2845 srcs: ["a.java"],
2846 stem: "foo-new",
2847 }
2848 `)
2849
2850 buildOS := ctx.Config().BuildOS.String()
2851 foo := ctx.ModuleForTests("foo", buildOS+"_common")
2852
2853 outputs := fmt.Sprint(foo.AllOutputs())
2854 if !strings.Contains(outputs, "foo-new.jar") {
2855 t.Errorf("Module output does not contain expected jar %s", "foo-new.jar")
2856 }
2857}
2858
2859func TestJavaLibWithStem(t *testing.T) {
2860 ctx, _ := testJava(t, `
2861 java_library {
2862 name: "foo",
2863 srcs: ["a.java"],
2864 stem: "foo-new",
2865 }
2866 `)
2867
2868 foo := ctx.ModuleForTests("foo", "android_common")
2869
2870 outputs := fmt.Sprint(foo.AllOutputs())
2871 if !strings.Contains(outputs, "foo-new.jar") {
2872 t.Errorf("Module output does not contain expected jar %s", "foo-new.jar")
2873 }
2874}
Colin Cross5e87f342024-04-11 15:28:18 -07002875
2876func TestJavaLibraryOutputFilesRel(t *testing.T) {
2877 result := android.GroupFixturePreparers(
2878 PrepareForTestWithJavaDefaultModules,
2879 ).RunTestWithBp(t, `
2880 java_library {
2881 name: "foo",
2882 srcs: ["a.java"],
2883 }
2884
2885 java_import {
2886 name: "bar",
2887 jars: ["bar.aar"],
2888
2889 }
2890
2891 java_import {
2892 name: "baz",
2893 jars: ["baz.aar"],
2894 static_libs: ["bar"],
2895 }
2896 `)
2897
2898 foo := result.ModuleForTests("foo", "android_common")
2899 bar := result.ModuleForTests("bar", "android_common")
2900 baz := result.ModuleForTests("baz", "android_common")
2901
2902 fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "")
2903 barOutputPath := android.OutputFileForModule(android.PathContext(nil), bar.Module(), "")
2904 bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "")
2905
2906 android.AssertPathRelativeToTopEquals(t, "foo output path",
2907 "out/soong/.intermediates/foo/android_common/javac/foo.jar", fooOutputPath)
2908 android.AssertPathRelativeToTopEquals(t, "bar output path",
2909 "out/soong/.intermediates/bar/android_common/combined/bar.jar", barOutputPath)
2910 android.AssertPathRelativeToTopEquals(t, "baz output path",
2911 "out/soong/.intermediates/baz/android_common/combined/baz.jar", bazOutputPath)
2912
2913 android.AssertStringEquals(t, "foo relative output path",
2914 "foo.jar", fooOutputPath.Rel())
2915 android.AssertStringEquals(t, "bar relative output path",
2916 "bar.jar", barOutputPath.Rel())
2917 android.AssertStringEquals(t, "baz relative output path",
2918 "baz.jar", bazOutputPath.Rel())
2919}