blob: b04ab1780db5068efd7e1b511b7af7554189d54f [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"
Colin Crossc9b4f6b2024-07-26 15:25:46 -070023 "slices"
Nan Zhang61eaedb2017-11-02 13:28:15 -070024 "strconv"
Colin Cross72bb3632017-07-13 16:23:21 -070025 "strings"
26 "testing"
Colin Cross86a60ae2018-05-29 14:44:55 -070027
Spandan Das3cf04632024-01-19 00:22:22 +000028 "github.com/google/blueprint"
Jeongik Cha28df2572019-11-11 10:46:36 +090029 "github.com/google/blueprint/proptools"
30
Jihoon Kang84b25892023-12-01 22:01:06 +000031 "android/soong/aconfig"
Colin Crossa4f08812018-10-02 22:03:40 -070032 "android/soong/android"
33 "android/soong/cc"
Colin Crossc28bb0b2019-02-25 14:20:47 -080034 "android/soong/dexpreopt"
Colin Cross1661aff2021-03-12 17:56:51 -080035 "android/soong/genrule"
Colin Cross72bb3632017-07-13 16:23:21 -070036)
37
Paul Duffin70d3bee2021-03-21 11:26:05 +000038// Legacy preparer used for running tests within the java package.
39//
40// This includes everything that was needed to run any test in the java package prior to the
41// introduction of the test fixtures. Tests that are being converted to use fixtures directly
42// rather than through the testJava...() methods should avoid using this and instead use the
43// various preparers directly, using android.GroupFixturePreparers(...) to group them when
44// necessary.
45//
46// deprecated
47var prepareForJavaTest = android.GroupFixturePreparers(
Paul Duffin95bdab42021-03-08 21:48:46 +000048 genrule.PrepareForTestWithGenRuleBuildComponents,
49 // Get the CC build components but not default modules.
50 cc.PrepareForTestWithCcBuildComponents,
51 // Include all the default java modules.
Jiakai Zhangb95998b2023-05-11 16:39:27 +010052 PrepareForTestWithDexpreopt,
Jihoon Kang84b25892023-12-01 22:01:06 +000053 // Include aconfig modules.
54 aconfig.PrepareForTestWithAconfigBuildComponents,
Paul Duffin95bdab42021-03-08 21:48:46 +000055)
56
Colin Cross72bb3632017-07-13 16:23:21 -070057func TestMain(m *testing.M) {
Paul Duffind6339af2021-03-22 18:05:04 +000058 os.Exit(m.Run())
Colin Cross527012a2017-11-30 22:56:16 -080059}
60
Paul Duffin95bdab42021-03-08 21:48:46 +000061// testJavaError is a legacy way of running tests of java modules that expect errors.
62//
63// See testJava for an explanation as to how to stop using this deprecated method.
64//
65// deprecated
Jeongik Cha2cc570d2019-10-29 15:44:45 +090066func testJavaError(t *testing.T, pattern string, bp string) (*android.TestContext, android.Config) {
Jeongik Cha538c0d02019-07-11 15:54:27 +090067 t.Helper()
Paul Duffin71ae5942021-03-22 15:36:52 +000068 result := android.GroupFixturePreparers(
Paul Duffin9fc9f532021-03-23 15:41:11 +000069 prepareForJavaTest, dexpreopt.PrepareForTestByEnablingDexpreopt).
Paul Duffin6bac49c2021-03-12 21:28:15 +000070 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
71 RunTestWithBp(t, bp)
72 return result.TestContext, result.Config
Jeongik Cha2cc570d2019-10-29 15:44:45 +090073}
74
Paul Duffin71ae5942021-03-22 15:36:52 +000075// testJavaWithFS runs tests using the prepareForJavaTest
Paul Duffin95bdab42021-03-08 21:48:46 +000076//
77// See testJava for an explanation as to how to stop using this deprecated method.
78//
79// deprecated
80func testJavaWithFS(t *testing.T, bp string, fs android.MockFS) (*android.TestContext, android.Config) {
Colin Cross238c1f32020-06-07 16:58:18 -070081 t.Helper()
Paul Duffin71ae5942021-03-22 15:36:52 +000082 result := android.GroupFixturePreparers(
83 prepareForJavaTest, fs.AddToFixture()).RunTestWithBp(t, bp)
Paul Duffin95bdab42021-03-08 21:48:46 +000084 return result.TestContext, result.Config
Colin Cross238c1f32020-06-07 16:58:18 -070085}
86
Paul Duffin71ae5942021-03-22 15:36:52 +000087// testJava runs tests using the prepareForJavaTest
Paul Duffin95bdab42021-03-08 21:48:46 +000088//
Paul Duffin71ae5942021-03-22 15:36:52 +000089// Do not add any new usages of this, instead use the prepareForJavaTest directly as it makes it
Paul Duffin95bdab42021-03-08 21:48:46 +000090// much easier to customize the test behavior.
91//
92// 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 +000093// convert the test to using prepareForJavaTest first and then in a following change add the
Paul Duffin95bdab42021-03-08 21:48:46 +000094// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
95// that it did not change the test behavior unexpectedly.
96//
97// deprecated
Jaewoong Jungf9a04432019-07-17 11:15:09 -070098func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) {
Colin Cross6b4a32d2017-12-05 13:42:45 -080099 t.Helper()
Paul Duffin71ae5942021-03-22 15:36:52 +0000100 result := prepareForJavaTest.RunTestWithBp(t, bp)
Paul Duffin95bdab42021-03-08 21:48:46 +0000101 return result.TestContext, result.Config
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900102}
103
Paul Duffin95bdab42021-03-08 21:48:46 +0000104// defaultModuleToPath constructs a path to the turbine generate jar for a default test module that
105// is defined in PrepareForIntegrationTestWithJava
106func defaultModuleToPath(name string) string {
Paul Duffin76101fa2021-03-13 09:55:25 +0000107 switch {
108 case name == `""`:
109 return name
110 case strings.HasSuffix(name, ".jar"):
111 return name
112 default:
Paul Duffin414ea5e2021-03-22 17:31:52 +0000113 return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine-combined", name+".jar")
Paul Duffin76101fa2021-03-13 09:55:25 +0000114 }
Paul Duffin95bdab42021-03-08 21:48:46 +0000115}
116
Paul Duffin76e5c8a2021-03-20 14:19:46 +0000117// Test that the PrepareForTestWithJavaDefaultModules provides all the files that it uses by
118// running it in a fixture that requires all source files to exist.
119func TestPrepareForTestWithJavaDefaultModules(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800120 t.Parallel()
Paul Duffin76e5c8a2021-03-20 14:19:46 +0000121 android.GroupFixturePreparers(
122 PrepareForTestWithJavaDefaultModules,
123 android.PrepareForTestDisallowNonExistentPaths,
124 ).RunTest(t)
125}
126
Jeongik Chae403e9e2019-12-07 00:16:24 +0900127func TestJavaLinkType(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800128 t.Parallel()
Jeongik Chae403e9e2019-12-07 00:16:24 +0900129 testJava(t, `
130 java_library {
131 name: "foo",
132 srcs: ["a.java"],
133 libs: ["bar"],
134 static_libs: ["baz"],
135 }
136
137 java_library {
138 name: "bar",
139 sdk_version: "current",
140 srcs: ["b.java"],
141 }
142
143 java_library {
144 name: "baz",
145 sdk_version: "system_current",
146 srcs: ["c.java"],
147 }
148 `)
149
Steven Moreland00298982020-11-17 21:44:36 +0000150 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900151 java_library {
152 name: "foo",
153 srcs: ["a.java"],
154 libs: ["bar"],
155 sdk_version: "current",
156 static_libs: ["baz"],
157 }
158
159 java_library {
160 name: "bar",
161 sdk_version: "current",
162 srcs: ["b.java"],
163 }
164
165 java_library {
166 name: "baz",
167 sdk_version: "system_current",
168 srcs: ["c.java"],
169 }
170 `)
171
172 testJava(t, `
173 java_library {
174 name: "foo",
175 srcs: ["a.java"],
176 libs: ["bar"],
177 sdk_version: "system_current",
178 static_libs: ["baz"],
179 }
180
181 java_library {
182 name: "bar",
183 sdk_version: "current",
184 srcs: ["b.java"],
185 }
186
187 java_library {
188 name: "baz",
189 sdk_version: "system_current",
190 srcs: ["c.java"],
191 }
192 `)
193
Steven Moreland00298982020-11-17 21:44:36 +0000194 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900195 java_library {
196 name: "foo",
197 srcs: ["a.java"],
198 libs: ["bar"],
199 sdk_version: "system_current",
200 static_libs: ["baz"],
201 }
202
203 java_library {
204 name: "bar",
205 sdk_version: "current",
206 srcs: ["b.java"],
207 }
208
209 java_library {
210 name: "baz",
211 srcs: ["c.java"],
212 }
213 `)
214}
215
Colin Cross72bb3632017-07-13 16:23:21 -0700216func TestSimple(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800217 t.Parallel()
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700218 bp := `
Colin Cross72bb3632017-07-13 16:23:21 -0700219 java_library {
220 name: "foo",
221 srcs: ["a.java"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700222 libs: ["bar"],
223 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700224 }
225
226 java_library {
227 name: "bar",
228 srcs: ["b.java"],
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700229 static_libs: ["quz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700230 }
231
232 java_library {
233 name: "baz",
234 srcs: ["c.java"],
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700235 static_libs: ["quz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700236 }
Colin Cross72bb3632017-07-13 16:23:21 -0700237
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700238 java_library {
239 name: "quz",
240 srcs: ["d.java"],
241 }`
Colin Cross72bb3632017-07-13 16:23:21 -0700242
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700243 frameworkTurbineCombinedJars := []string{
244 "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar",
245 "out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar",
Colin Cross72bb3632017-07-13 16:23:21 -0700246 }
247
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700248 frameworkTurbineJars := []string{
249 "out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
250 "out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
251 }
Colin Cross0a6e0072017-08-30 14:24:55 -0700252
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700253 testCases := []struct {
254 name string
Colin Cross72bb3632017-07-13 16:23:21 -0700255
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700256 preparer android.FixturePreparer
Colin Cross0a6e0072017-08-30 14:24:55 -0700257
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700258 fooJavacInputs []string
259 fooJavacClasspath []string
260 fooCombinedInputs []string
261 fooHeaderCombinedInputs []string
262
263 barJavacInputs []string
264 barJavacClasspath []string
265 barCombinedInputs []string
266 barHeaderCombinedInputs []string
267 }{
268 {
269 name: "normal",
270 preparer: android.NullFixturePreparer,
271 fooJavacInputs: []string{"a.java"},
272 fooJavacClasspath: slices.Concat(
273 frameworkTurbineCombinedJars,
274 []string{
275 "out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar",
276 "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
277 },
278 ),
279 fooCombinedInputs: []string{
280 "out/soong/.intermediates/foo/android_common/javac/foo.jar",
281 "out/soong/.intermediates/baz/android_common/combined/baz.jar",
282 },
283
284 fooHeaderCombinedInputs: []string{
285 "out/soong/.intermediates/foo/android_common/turbine/foo.jar",
286 "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
287 },
288
289 barJavacInputs: []string{"b.java"},
290 barJavacClasspath: slices.Concat(
291 frameworkTurbineCombinedJars,
292 []string{
293 "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
294 },
295 ),
296 barCombinedInputs: []string{
297 "out/soong/.intermediates/bar/android_common/javac/bar.jar",
298 "out/soong/.intermediates/quz/android_common/javac/quz.jar",
299 },
300 barHeaderCombinedInputs: []string{
301 "out/soong/.intermediates/bar/android_common/turbine/bar.jar",
302 "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
303 },
304 },
305 {
306 name: "transitive classpath",
307 preparer: PrepareForTestWithTransitiveClasspathEnabled,
308 fooJavacInputs: []string{"a.java"},
309 fooJavacClasspath: slices.Concat(
310 frameworkTurbineJars,
311 []string{
312 "out/soong/.intermediates/bar/android_common/turbine/bar.jar",
313 "out/soong/.intermediates/quz/android_common/turbine/quz.jar",
314 "out/soong/.intermediates/baz/android_common/turbine/baz.jar",
315 },
316 ),
317 fooCombinedInputs: []string{
318 "out/soong/.intermediates/foo/android_common/javac/foo.jar",
319 "out/soong/.intermediates/baz/android_common/javac/baz.jar",
320 "out/soong/.intermediates/quz/android_common/javac/quz.jar",
321 },
322
323 fooHeaderCombinedInputs: []string{
324 "out/soong/.intermediates/foo/android_common/turbine/foo.jar",
325 "out/soong/.intermediates/baz/android_common/turbine/baz.jar",
326 "out/soong/.intermediates/quz/android_common/turbine/quz.jar",
327 },
328
329 barJavacInputs: []string{"b.java"},
330 barJavacClasspath: slices.Concat(
331 frameworkTurbineJars,
332 []string{"out/soong/.intermediates/quz/android_common/turbine/quz.jar"},
333 ),
334 barCombinedInputs: []string{
335 "out/soong/.intermediates/bar/android_common/javac/bar.jar",
336 "out/soong/.intermediates/quz/android_common/javac/quz.jar",
337 },
338 barHeaderCombinedInputs: []string{
339 "out/soong/.intermediates/bar/android_common/turbine/bar.jar",
340 "out/soong/.intermediates/quz/android_common/turbine/quz.jar",
341 },
342 },
343 }
344
345 for _, tt := range testCases {
346 t.Run(tt.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800347 t.Parallel()
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700348 result := android.GroupFixturePreparers(
349 PrepareForTestWithJavaDefaultModules,
350 tt.preparer,
351 ).RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -0800352 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700353
354 fooJavac := foo.Rule("javac")
355 android.AssertPathsRelativeToTopEquals(t, "foo javac inputs", tt.fooJavacInputs, fooJavac.Inputs)
356
357 fooJavacClasspath := fooJavac.Args["classpath"]
358 android.AssertStringPathsRelativeToTopEquals(t, "foo javac classpath", result.Config, tt.fooJavacClasspath,
359 strings.Split(strings.TrimPrefix(fooJavacClasspath, "-classpath "), ":"))
360
361 fooCombinedJar := foo.Output("combined/foo.jar")
362 android.AssertPathsRelativeToTopEquals(t, "foo combined inputs", tt.fooCombinedInputs, fooCombinedJar.Inputs)
363
364 fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar")
365 android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs)
366
Colin Cross90607e92025-02-11 14:58:07 -0800367 bar := result.ModuleForTests(t, "bar", "android_common")
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700368 barJavac := bar.Rule("javac")
369 android.AssertPathsRelativeToTopEquals(t, "bar javac inputs", tt.barJavacInputs, barJavac.Inputs)
370
371 barJavacClasspath := barJavac.Args["classpath"]
372 android.AssertStringPathsRelativeToTopEquals(t, "bar javac classpath", result.Config, tt.barJavacClasspath,
373 strings.Split(strings.TrimPrefix(barJavacClasspath, "-classpath "), ":"))
374
375 barCombinedJar := bar.Output("combined/bar.jar")
376 android.AssertPathsRelativeToTopEquals(t, "bar combined inputs", tt.barCombinedInputs, barCombinedJar.Inputs)
377
378 barCombinedHeaderJar := bar.Output("turbine-combined/bar.jar")
379 android.AssertPathsRelativeToTopEquals(t, "bar header combined inputs", tt.barHeaderCombinedInputs, barCombinedHeaderJar.Inputs)
380 })
Colin Cross72bb3632017-07-13 16:23:21 -0700381 }
382}
383
Artur Satayev9cf46692019-11-26 18:08:34 +0000384func TestExportedPlugins(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800385 t.Parallel()
Artur Satayev9cf46692019-11-26 18:08:34 +0000386 type Result struct {
Colin Crossc9fe10f2020-11-19 18:06:03 -0800387 library string
388 processors string
389 disableTurbine bool
Artur Satayev9cf46692019-11-26 18:08:34 +0000390 }
391 var tests = []struct {
392 name string
393 extra string
394 results []Result
395 }{
396 {
397 name: "Exported plugin is not a direct plugin",
398 extra: `java_library { name: "exports", srcs: ["a.java"], exported_plugins: ["plugin"] }`,
399 results: []Result{{library: "exports", processors: "-proc:none"}},
400 },
401 {
402 name: "Exports plugin to dependee",
403 extra: `
404 java_library{name: "exports", exported_plugins: ["plugin"]}
405 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
406 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
407 `,
408 results: []Result{
409 {library: "foo", processors: "-processor com.android.TestPlugin"},
410 {library: "bar", processors: "-processor com.android.TestPlugin"},
411 },
412 },
413 {
414 name: "Exports plugin to android_library",
415 extra: `
416 java_library{name: "exports", exported_plugins: ["plugin"]}
417 android_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
418 android_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
419 `,
420 results: []Result{
421 {library: "foo", processors: "-processor com.android.TestPlugin"},
422 {library: "bar", processors: "-processor com.android.TestPlugin"},
423 },
424 },
425 {
426 name: "Exports plugin is not propagated via transitive deps",
427 extra: `
428 java_library{name: "exports", exported_plugins: ["plugin"]}
429 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
430 java_library{name: "bar", srcs: ["a.java"], static_libs: ["foo"]}
431 `,
432 results: []Result{
433 {library: "foo", processors: "-processor com.android.TestPlugin"},
434 {library: "bar", processors: "-proc:none"},
435 },
436 },
437 {
438 name: "Exports plugin appends to plugins",
439 extra: `
440 java_plugin{name: "plugin2", processor_class: "com.android.TestPlugin2"}
441 java_library{name: "exports", exported_plugins: ["plugin"]}
442 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"], plugins: ["plugin2"]}
443 `,
444 results: []Result{
445 {library: "foo", processors: "-processor com.android.TestPlugin,com.android.TestPlugin2"},
446 },
447 },
Colin Crossc9fe10f2020-11-19 18:06:03 -0800448 {
449 name: "Exports plugin to with generates_api to dependee",
450 extra: `
451 java_library{name: "exports", exported_plugins: ["plugin_generates_api"]}
452 java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
453 java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
454 `,
455 results: []Result{
456 {library: "foo", processors: "-processor com.android.TestPlugin", disableTurbine: true},
457 {library: "bar", processors: "-processor com.android.TestPlugin", disableTurbine: true},
458 },
459 },
Artur Satayev9cf46692019-11-26 18:08:34 +0000460 }
461
462 for _, test := range tests {
463 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800464 t.Parallel()
Artur Satayev9cf46692019-11-26 18:08:34 +0000465 ctx, _ := testJava(t, `
466 java_plugin {
467 name: "plugin",
468 processor_class: "com.android.TestPlugin",
469 }
Colin Crossc9fe10f2020-11-19 18:06:03 -0800470 java_plugin {
471 name: "plugin_generates_api",
472 generates_api: true,
473 processor_class: "com.android.TestPlugin",
474 }
Artur Satayev9cf46692019-11-26 18:08:34 +0000475 `+test.extra)
476
477 for _, want := range test.results {
Colin Cross90607e92025-02-11 14:58:07 -0800478 javac := ctx.ModuleForTests(t, want.library, "android_common").Rule("javac")
Artur Satayev9cf46692019-11-26 18:08:34 +0000479 if javac.Args["processor"] != want.processors {
480 t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"])
481 }
Colin Cross90607e92025-02-11 14:58:07 -0800482 turbine := ctx.ModuleForTests(t, want.library, "android_common").MaybeRule("turbine")
Colin Crossc9fe10f2020-11-19 18:06:03 -0800483 disableTurbine := turbine.BuildParams.Rule == nil
484 if disableTurbine != want.disableTurbine {
485 t.Errorf("For library %v, expected disableTurbine %v, found %v", want.library, want.disableTurbine, disableTurbine)
486 }
Artur Satayev9cf46692019-11-26 18:08:34 +0000487 }
488 })
489 }
490}
491
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900492func TestSdkVersionByPartition(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800493 t.Parallel()
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900494 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900495 java_library {
496 name: "foo",
497 srcs: ["a.java"],
498 vendor: true,
499 }
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900500 `)
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900501
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900502 testJava(t, `
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900503 java_library {
504 name: "bar",
505 srcs: ["b.java"],
506 }
507 `)
508
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900509 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900510 bp := `
511 java_library {
512 name: "foo",
513 srcs: ["a.java"],
514 product_specific: true,
515 }
516 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800517
Paul Duffin414ea5e2021-03-22 17:31:52 +0000518 errorHandler := android.FixtureExpectsNoErrors
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900519 if enforce {
Paul Duffin414ea5e2021-03-22 17:31:52 +0000520 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 +0900521 }
Paul Duffin414ea5e2021-03-22 17:31:52 +0000522
523 android.GroupFixturePreparers(
524 PrepareForTestWithJavaDefaultModules,
525 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
526 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
527 }),
528 ).
529 ExtendWithErrorHandler(errorHandler).
530 RunTestWithBp(t, bp)
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900531 }
532}
533
Colin Crossd5934c82017-10-02 13:55:26 -0700534func TestArchSpecific(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800535 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700536 ctx, _ := testJava(t, `
Colin Crossd5934c82017-10-02 13:55:26 -0700537 java_library {
538 name: "foo",
539 srcs: ["a.java"],
540 target: {
541 android: {
542 srcs: ["b.java"],
543 },
544 },
545 }
546 `)
547
Colin Cross90607e92025-02-11 14:58:07 -0800548 javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
Colin Crossd5934c82017-10-02 13:55:26 -0700549 if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" {
550 t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs)
551 }
552}
553
Colin Cross6b4a32d2017-12-05 13:42:45 -0800554func TestBinary(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800555 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700556 ctx, _ := testJava(t, `
Colin Cross6b4a32d2017-12-05 13:42:45 -0800557 java_library_host {
558 name: "foo",
559 srcs: ["a.java"],
560 }
561
562 java_binary_host {
563 name: "bar",
564 srcs: ["b.java"],
565 static_libs: ["foo"],
Colin Cross89226d92020-10-09 19:00:54 -0700566 jni_libs: ["libjni"],
567 }
568
569 cc_library_shared {
570 name: "libjni",
571 host_supported: true,
572 device_supported: false,
573 stl: "none",
Colin Cross6b4a32d2017-12-05 13:42:45 -0800574 }
575 `)
576
Colin Cross0c66bc62021-07-20 09:47:41 -0700577 buildOS := ctx.Config().BuildOS.String()
Colin Cross6b4a32d2017-12-05 13:42:45 -0800578
Colin Cross90607e92025-02-11 14:58:07 -0800579 bar := ctx.ModuleForTests(t, "bar", buildOS+"_common")
Colin Cross6b4a32d2017-12-05 13:42:45 -0800580 barJar := bar.Output("bar.jar").Output.String()
Cole Faustb9c67e22024-10-08 16:39:56 -0700581 barWrapperDeps := bar.Output("bar").Implicits.Strings()
Colin Cross6b4a32d2017-12-05 13:42:45 -0800582
Colin Cross90607e92025-02-11 14:58:07 -0800583 libjni := ctx.ModuleForTests(t, "libjni", buildOS+"_x86_64_shared")
Colin Cross89226d92020-10-09 19:00:54 -0700584 libjniSO := libjni.Rule("Cp").Output.String()
585
Colin Cross6b4a32d2017-12-05 13:42:45 -0800586 // Test that the install binary wrapper depends on the installed jar file
Colin Crossc179ea62020-10-09 10:54:15 -0700587 if g, w := barWrapperDeps, barJar; !android.InList(w, g) {
588 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g)
Colin Cross6b4a32d2017-12-05 13:42:45 -0800589 }
Colin Cross89226d92020-10-09 19:00:54 -0700590
591 // Test that the install binary wrapper depends on the installed JNI libraries
592 if g, w := barWrapperDeps, libjniSO; !android.InList(w, g) {
593 t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g)
Colin Cross6b4a32d2017-12-05 13:42:45 -0800594 }
Alex Humesky2070e322020-06-09 20:23:08 -0400595}
Colin Cross6b4a32d2017-12-05 13:42:45 -0800596
Colin Crossf8d9c492021-01-26 11:01:43 -0800597func TestTest(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800598 t.Parallel()
Colin Crossf8d9c492021-01-26 11:01:43 -0800599 ctx, _ := testJava(t, `
600 java_test_host {
601 name: "foo",
602 srcs: ["a.java"],
603 jni_libs: ["libjni"],
604 }
605
606 cc_library_shared {
607 name: "libjni",
608 host_supported: true,
609 device_supported: false,
610 stl: "none",
611 }
612 `)
613
Colin Cross0c66bc62021-07-20 09:47:41 -0700614 buildOS := ctx.Config().BuildOS.String()
Colin Crossf8d9c492021-01-26 11:01:43 -0800615
Colin Cross90607e92025-02-11 14:58:07 -0800616 foo := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
Colin Crossf8d9c492021-01-26 11:01:43 -0800617
618 expected := "lib64/libjni.so"
619 if runtime.GOOS == "darwin" {
620 expected = "lib64/libjni.dylib"
621 }
622
623 fooTestData := foo.data
624 if len(fooTestData) != 1 || fooTestData[0].Rel() != expected {
625 t.Errorf(`expected foo test data relative path [%q], got %q`,
626 expected, fooTestData.Strings())
627 }
628}
629
Colin Crossb3614422025-02-18 15:18:18 -0800630func TestHostCommonData(t *testing.T) {
631 t.Parallel()
632 ctx, _ := testJava(t, `
633 java_library_host {
634 name: "host",
635 srcs: ["a.java"],
636 }
637
638 java_test {
639 name: "foo",
640 srcs: ["a.java"],
641 host_common_data: [":host"],
642 }
643 `)
644
645 foo := ctx.ModuleForTests(t, "foo", "android_common").Module().(*Test)
646 host := ctx.ModuleForTests(t, "host", ctx.Config().BuildOSCommonTarget.String()).Module().(*Library)
647
648 if g, w := foo.data.RelativeToTop().Strings(), []string{host.outputFile.RelativeToTop().String()}; !slices.Equal(g, w) {
649 t.Errorf("expected test data %q, got %q\n", w, g)
650 }
651}
652
Alex Humesky2070e322020-06-09 20:23:08 -0400653func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800654 t.Parallel()
Alex Humesky2070e322020-06-09 20:23:08 -0400655 bp := `
656 java_library {
657 name: "target_library",
658 srcs: ["a.java"],
659 }
660
661 java_binary_host {
662 name: "host_binary",
663 srcs: ["b.java"],
664 }
665 `
Alex Humesky2070e322020-06-09 20:23:08 -0400666
Paul Duffin414ea5e2021-03-22 17:31:52 +0000667 result := android.GroupFixturePreparers(
668 PrepareForTestWithJavaDefaultModules,
669 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
670 variables.MinimizeJavaDebugInfo = proptools.BoolPtr(true)
671 }),
672 ).RunTestWithBp(t, bp)
Alex Humesky2070e322020-06-09 20:23:08 -0400673
Liz Kammer7941b302020-07-28 13:27:34 -0700674 // first, check that the -g flag is added to target modules
Colin Cross90607e92025-02-11 14:58:07 -0800675 targetLibrary := result.ModuleForTests(t, "target_library", "android_common")
Alex Humesky2070e322020-06-09 20:23:08 -0400676 targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"]
677 if !strings.Contains(targetJavaFlags, "-g:source,lines") {
678 t.Errorf("target library javac flags %v should contain "+
679 "-g:source,lines override with MinimizeJavaDebugInfo", targetJavaFlags)
680 }
681
682 // check that -g is not overridden for host modules
Colin Cross0c66bc62021-07-20 09:47:41 -0700683 buildOS := result.Config.BuildOS.String()
Colin Cross90607e92025-02-11 14:58:07 -0800684 hostBinary := result.ModuleForTests(t, "host_binary", buildOS+"_common")
Alex Humesky2070e322020-06-09 20:23:08 -0400685 hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"]
686 if strings.Contains(hostJavaFlags, "-g:source,lines") {
687 t.Errorf("java_binary_host javac flags %v should not have "+
688 "-g:source,lines override with MinimizeJavaDebugInfo", hostJavaFlags)
689 }
Colin Cross6b4a32d2017-12-05 13:42:45 -0800690}
691
Spandan Das59a4a2b2024-01-09 21:35:56 +0000692// A minimal context object for use with DexJarBuildPath
693type moduleErrorfTestCtx struct {
694}
695
696func (ctx moduleErrorfTestCtx) ModuleErrorf(format string, args ...interface{}) {
697}
698
699var _ android.ModuleErrorfContext = (*moduleErrorfTestCtx)(nil)
700
Colin Cross72bb3632017-07-13 16:23:21 -0700701func TestPrebuilts(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800702 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700703 ctx, _ := testJava(t, `
Colin Cross72bb3632017-07-13 16:23:21 -0700704 java_library {
705 name: "foo",
Paul Duffin91547182019-11-12 19:39:36 +0000706 srcs: ["a.java", ":stubs-source"],
Jihoon Kang28c96572024-09-11 23:44:44 +0000707 libs: ["bar", "sdklib.stubs"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700708 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700709 }
710
Colin Cross74d73e22017-08-02 11:05:49 -0700711 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700712 name: "bar",
Colin Cross74d73e22017-08-02 11:05:49 -0700713 jars: ["a.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700714 }
715
Colin Cross74d73e22017-08-02 11:05:49 -0700716 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700717 name: "baz",
Colin Cross74d73e22017-08-02 11:05:49 -0700718 jars: ["b.jar"],
Liz Kammerd6c31d22020-08-05 15:40:41 -0700719 sdk_version: "current",
720 compile_dex: true,
Colin Cross72bb3632017-07-13 16:23:21 -0700721 }
Colin Cross42be7612019-02-21 18:12:14 -0800722
723 dex_import {
724 name: "qux",
725 jars: ["b.jar"],
726 }
Colin Cross79c7c262019-04-17 11:11:46 -0700727
728 java_sdk_library_import {
Paul Duffin56d44902020-01-31 13:36:25 +0000729 name: "sdklib",
730 public: {
731 jars: ["c.jar"],
732 },
733 }
734
Paul Duffin91547182019-11-12 19:39:36 +0000735 prebuilt_stubs_sources {
736 name: "stubs-source",
Paul Duffin9b478b02019-12-10 13:41:51 +0000737 srcs: ["stubs/sources"],
Paul Duffin91547182019-11-12 19:39:36 +0000738 }
Paul Duffin1b82e6a2019-12-03 18:06:47 +0000739
740 java_test_import {
741 name: "test",
742 jars: ["a.jar"],
743 test_suites: ["cts"],
744 test_config: "AndroidTest.xml",
745 }
Colin Cross72bb3632017-07-13 16:23:21 -0700746 `)
747
Colin Cross90607e92025-02-11 14:58:07 -0800748 fooModule := ctx.ModuleForTests(t, "foo", "android_common")
Paul Duffin9b478b02019-12-10 13:41:51 +0000749 javac := fooModule.Rule("javac")
Colin Cross90607e92025-02-11 14:58:07 -0800750 combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac")
751 barModule := ctx.ModuleForTests(t, "bar", "android_common")
Colin Crossdad2a362024-03-23 04:43:41 +0000752 barJar := barModule.Output("combined/bar.jar").Output
Colin Cross90607e92025-02-11 14:58:07 -0800753 bazModule := ctx.ModuleForTests(t, "baz", "android_common")
Colin Crossc9b4f6b2024-07-26 15:25:46 -0700754 bazJar := bazModule.Output("combined/baz.jar").Output
Colin Cross90607e92025-02-11 14:58:07 -0800755 sdklibStubsJar := ctx.ModuleForTests(t, "sdklib.stubs", "android_common").
Colin Crossdad2a362024-03-23 04:43:41 +0000756 Output("combined/sdklib.stubs.jar").Output
Colin Cross72bb3632017-07-13 16:23:21 -0700757
Paul Duffin9b478b02019-12-10 13:41:51 +0000758 fooLibrary := fooModule.Module().(*Library)
Chaohui Wangdcbe33c2022-10-11 11:13:30 +0800759 assertDeepEquals(t, "foo unique sources incorrect",
760 []string{"a.java"}, fooLibrary.uniqueSrcFiles.Strings())
Paul Duffin91547182019-11-12 19:39:36 +0000761
Paul Duffin9b478b02019-12-10 13:41:51 +0000762 assertDeepEquals(t, "foo java source jars incorrect",
763 []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"},
764 android.NormalizePathsForTesting(fooLibrary.compiledSrcJars))
Paul Duffin91547182019-11-12 19:39:36 +0000765
Colin Cross37f6d792018-07-12 12:28:41 -0700766 if !strings.Contains(javac.Args["classpath"], barJar.String()) {
767 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String())
Colin Cross72bb3632017-07-13 16:23:21 -0700768 }
769
Spandan Das59a4a2b2024-01-09 21:35:56 +0000770 errCtx := moduleErrorfTestCtx{}
771 barDexJar := barModule.Module().(*Import).DexJarBuildPath(errCtx)
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +0100772 if barDexJar.IsSet() {
773 t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar)
Liz Kammerd6c31d22020-08-05 15:40:41 -0700774 }
775
Colin Cross79c7c262019-04-17 11:11:46 -0700776 if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
777 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String())
778 }
779
Colin Cross37f6d792018-07-12 12:28:41 -0700780 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() {
781 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
Colin Cross72bb3632017-07-13 16:23:21 -0700782 }
Colin Cross42be7612019-02-21 18:12:14 -0800783
Spandan Das59a4a2b2024-01-09 21:35:56 +0000784 bazDexJar := bazModule.Module().(*Import).DexJarBuildPath(errCtx).Path()
Paul Duffin414ea5e2021-03-22 17:31:52 +0000785 expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar"
786 android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar)
Liz Kammerd6c31d22020-08-05 15:40:41 -0700787
Colin Cross90607e92025-02-11 14:58:07 -0800788 ctx.ModuleForTests(t, "qux", "android_common").Rule("Cp")
Wei Li598f92d2023-01-04 17:12:24 -0800789
790 entries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0]
791 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
792 entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0]
793 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
Colin Cross72bb3632017-07-13 16:23:21 -0700794}
795
Paul Duffin9b478b02019-12-10 13:41:51 +0000796func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) {
797 if !reflect.DeepEqual(expected, actual) {
798 t.Errorf("%s: expected %q, found %q", message, expected, actual)
799 }
800}
801
Paul Duffin1a393322020-11-18 16:36:47 +0000802func TestPrebuiltStubsSources(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800803 t.Parallel()
Paul Duffin1a393322020-11-18 16:36:47 +0000804 test := func(t *testing.T, sourcesPath string, expectedInputs []string) {
805 ctx, _ := testJavaWithFS(t, fmt.Sprintf(`
806prebuilt_stubs_sources {
807 name: "stubs-source",
808 srcs: ["%s"],
809}`, sourcesPath), map[string][]byte{
810 "stubs/sources/pkg/A.java": nil,
811 "stubs/sources/pkg/B.java": nil,
812 })
813
Colin Cross90607e92025-02-11 14:58:07 -0800814 zipSrc := ctx.ModuleForTests(t, "stubs-source", "android_common").Rule("zip_src")
Paul Duffin1a393322020-11-18 16:36:47 +0000815 if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) {
816 t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual)
817 }
818 }
819
820 t.Run("empty/missing directory", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800821 t.Parallel()
Colin Crossce3a51d2021-03-19 16:22:12 -0700822 test(t, "empty-directory", nil)
Paul Duffin1a393322020-11-18 16:36:47 +0000823 })
824
825 t.Run("non-empty set of sources", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800826 t.Parallel()
Paul Duffin1a393322020-11-18 16:36:47 +0000827 test(t, "stubs/sources", []string{
828 "stubs/sources/pkg/A.java",
829 "stubs/sources/pkg/B.java",
830 })
831 })
832}
833
Colin Cross89536d42017-07-07 14:35:50 -0700834func TestDefaults(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800835 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700836 ctx, _ := testJava(t, `
Colin Cross89536d42017-07-07 14:35:50 -0700837 java_defaults {
838 name: "defaults",
839 srcs: ["a.java"],
840 libs: ["bar"],
841 static_libs: ["baz"],
Sasha Smundak2057f822019-04-16 17:16:58 -0700842 optimize: {enabled: false},
Colin Cross89536d42017-07-07 14:35:50 -0700843 }
844
845 java_library {
846 name: "foo",
847 defaults: ["defaults"],
848 }
849
850 java_library {
851 name: "bar",
852 srcs: ["b.java"],
853 }
854
855 java_library {
856 name: "baz",
857 srcs: ["c.java"],
858 }
Sasha Smundak2057f822019-04-16 17:16:58 -0700859
860 android_test {
861 name: "atestOptimize",
862 defaults: ["defaults"],
863 optimize: {enabled: true},
864 }
865
866 android_test {
867 name: "atestNoOptimize",
868 defaults: ["defaults"],
869 }
870
871 android_test {
872 name: "atestDefault",
873 srcs: ["a.java"],
874 }
Colin Cross89536d42017-07-07 14:35:50 -0700875 `)
876
Colin Cross90607e92025-02-11 14:58:07 -0800877 javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
878 combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac")
Colin Cross89536d42017-07-07 14:35:50 -0700879
880 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
881 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
882 }
883
Paul Duffin414ea5e2021-03-22 17:31:52 +0000884 barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
Nan Zhanged19fc32017-10-19 13:06:22 -0700885 if !strings.Contains(javac.Args["classpath"], barTurbine) {
886 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
Colin Cross89536d42017-07-07 14:35:50 -0700887 }
888
Colin Cross90607e92025-02-11 14:58:07 -0800889 baz := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac").Output.String()
Colin Cross0a6e0072017-08-30 14:24:55 -0700890 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
891 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross89536d42017-07-07 14:35:50 -0700892 }
Sasha Smundak2057f822019-04-16 17:16:58 -0700893
Colin Cross90607e92025-02-11 14:58:07 -0800894 atestOptimize := ctx.ModuleForTests(t, "atestOptimize", "android_common").MaybeRule("r8")
Sasha Smundak2057f822019-04-16 17:16:58 -0700895 if atestOptimize.Output == nil {
896 t.Errorf("atestOptimize should optimize APK")
897 }
898
Colin Cross90607e92025-02-11 14:58:07 -0800899 atestNoOptimize := ctx.ModuleForTests(t, "atestNoOptimize", "android_common").MaybeRule("d8")
Sasha Smundak2057f822019-04-16 17:16:58 -0700900 if atestNoOptimize.Output == nil {
901 t.Errorf("atestNoOptimize should not optimize APK")
902 }
903
Colin Cross90607e92025-02-11 14:58:07 -0800904 atestDefault := ctx.ModuleForTests(t, "atestDefault", "android_common").MaybeRule("d8")
Sasha Smundak2057f822019-04-16 17:16:58 -0700905 if atestDefault.Output == nil {
Jared Duke63a3da92022-06-02 19:11:14 +0000906 t.Errorf("atestDefault should not optimize APK")
Sasha Smundak2057f822019-04-16 17:16:58 -0700907 }
Colin Cross89536d42017-07-07 14:35:50 -0700908}
909
Colin Cross0f37af02017-09-27 17:42:05 -0700910func TestResources(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800911 t.Parallel()
Colin Cross0f37af02017-09-27 17:42:05 -0700912 var table = []struct {
913 name string
914 prop string
915 extra string
916 args string
917 }{
918 {
Colin Crossaf9c55b2017-10-03 14:50:08 -0700919 // Test that a module with java_resource_dirs includes the files
Colin Cross0f37af02017-09-27 17:42:05 -0700920 name: "resource dirs",
Colin Cross824bee32017-11-22 17:27:51 -0800921 prop: `java_resource_dirs: ["java-res"]`,
Colin Cross0ead1d72018-04-10 13:07:42 -0700922 args: "-C java-res -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700923 },
924 {
925 // Test that a module with java_resources includes the files
926 name: "resource files",
Colin Cross0ead1d72018-04-10 13:07:42 -0700927 prop: `java_resources: ["java-res/a/a", "java-res/b/b"]`,
928 args: "-C . -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700929 },
930 {
931 // Test that a module with a filegroup in java_resources includes the files with the
932 // path prefix
933 name: "resource filegroup",
934 prop: `java_resources: [":foo-res"]`,
935 extra: `
936 filegroup {
937 name: "foo-res",
Colin Cross824bee32017-11-22 17:27:51 -0800938 path: "java-res",
Colin Cross0ead1d72018-04-10 13:07:42 -0700939 srcs: ["java-res/a/a", "java-res/b/b"],
Colin Cross0f37af02017-09-27 17:42:05 -0700940 }`,
Colin Cross0ead1d72018-04-10 13:07:42 -0700941 args: "-C java-res -f java-res/a/a -f java-res/b/b",
Colin Cross0f37af02017-09-27 17:42:05 -0700942 },
943 {
Colin Cross0ead1d72018-04-10 13:07:42 -0700944 // Test that a module with wildcards in java_resource_dirs has the correct path prefixes
945 name: "wildcard dirs",
946 prop: `java_resource_dirs: ["java-res/*"]`,
947 args: "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b",
948 },
949 {
950 // Test that a module exclude_java_resource_dirs excludes the files
951 name: "wildcard dirs",
952 prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`,
953 args: "-C java-res/a -f java-res/a/a",
954 },
Colin Crosscedd4762018-09-13 11:26:19 -0700955 {
956 // Test wildcards in java_resources
957 name: "wildcard files",
958 prop: `java_resources: ["java-res/**/*"]`,
959 args: "-C . -f java-res/a/a -f java-res/b/b",
960 },
961 {
962 // Test exclude_java_resources with java_resources
963 name: "wildcard files with exclude",
964 prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`,
965 args: "-C . -f java-res/a/a",
966 },
967 {
968 // Test exclude_java_resources with java_resource_dirs
969 name: "resource dirs with exclude files",
970 prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`,
971 args: "-C java-res -f java-res/a/a",
972 },
973 {
974 // Test exclude_java_resource_dirs with java_resource_dirs
975 name: "resource dirs with exclude files",
976 prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`,
977 args: "-C java-res -f java-res/a/a -f java-res/b/b",
978 },
Colin Cross0f37af02017-09-27 17:42:05 -0700979 }
980
981 for _, test := range table {
982 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800983 t.Parallel()
Colin Cross238c1f32020-06-07 16:58:18 -0700984 ctx, _ := testJavaWithFS(t, `
Colin Cross0f37af02017-09-27 17:42:05 -0700985 java_library {
986 name: "foo",
987 srcs: [
988 "a.java",
989 "b.java",
990 "c.java",
991 ],
992 `+test.prop+`,
993 }
Colin Cross238c1f32020-06-07 16:58:18 -0700994 `+test.extra,
995 map[string][]byte{
996 "java-res/a/a": nil,
997 "java-res/b/b": nil,
998 "java-res2/a": nil,
999 },
1000 )
Colin Cross0f37af02017-09-27 17:42:05 -07001001
Colin Cross90607e92025-02-11 14:58:07 -08001002 foo := ctx.ModuleForTests(t, "foo", "android_common").Output("withres/foo.jar")
1003 fooRes := ctx.ModuleForTests(t, "foo", "android_common").Output("res/foo.jar")
Colin Cross0f37af02017-09-27 17:42:05 -07001004
1005 if !inList(fooRes.Output.String(), foo.Inputs.Strings()) {
1006 t.Errorf("foo combined jars %v does not contain %q",
1007 foo.Inputs.Strings(), fooRes.Output.String())
1008 }
1009
Colin Crossaf9c55b2017-10-03 14:50:08 -07001010 if fooRes.Args["jarArgs"] != test.args {
1011 t.Errorf("foo resource jar args %q is not %q",
Colin Cross0f37af02017-09-27 17:42:05 -07001012 fooRes.Args["jarArgs"], test.args)
1013 }
1014 })
1015 }
1016}
1017
Colin Cross0c4ce212019-05-03 15:28:19 -07001018func TestIncludeSrcs(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001019 t.Parallel()
Colin Cross238c1f32020-06-07 16:58:18 -07001020 ctx, _ := testJavaWithFS(t, `
Colin Cross0c4ce212019-05-03 15:28:19 -07001021 java_library {
1022 name: "foo",
1023 srcs: [
1024 "a.java",
1025 "b.java",
1026 "c.java",
1027 ],
1028 include_srcs: true,
1029 }
1030
1031 java_library {
1032 name: "bar",
1033 srcs: [
1034 "a.java",
1035 "b.java",
1036 "c.java",
1037 ],
1038 java_resource_dirs: ["java-res"],
1039 include_srcs: true,
1040 }
Colin Cross238c1f32020-06-07 16:58:18 -07001041 `, map[string][]byte{
1042 "java-res/a/a": nil,
1043 "java-res/b/b": nil,
1044 "java-res2/a": nil,
1045 })
Colin Cross0c4ce212019-05-03 15:28:19 -07001046
1047 // Test a library with include_srcs: true
Colin Cross90607e92025-02-11 14:58:07 -08001048 foo := ctx.ModuleForTests(t, "foo", "android_common").Output("withres/foo.jar")
1049 fooSrcJar := ctx.ModuleForTests(t, "foo", "android_common").Output("foo.srcjar")
Colin Cross0c4ce212019-05-03 15:28:19 -07001050
1051 if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) {
1052 t.Errorf("foo combined jars %v does not contain %q", w, g)
1053 }
1054
1055 if g, w := fooSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w {
1056 t.Errorf("foo source jar args %q is not %q", w, g)
1057 }
1058
1059 // Test a library with include_srcs: true and resources
Colin Cross90607e92025-02-11 14:58:07 -08001060 bar := ctx.ModuleForTests(t, "bar", "android_common").Output("withres/bar.jar")
1061 barResCombined := ctx.ModuleForTests(t, "bar", "android_common").Output("res-combined/bar.jar")
1062 barRes := ctx.ModuleForTests(t, "bar", "android_common").Output("res/bar.jar")
1063 barSrcJar := ctx.ModuleForTests(t, "bar", "android_common").Output("bar.srcjar")
Colin Cross0c4ce212019-05-03 15:28:19 -07001064
1065 if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
1066 t.Errorf("bar combined resource jars %v does not contain %q", w, g)
1067 }
1068
1069 if g, w := barRes.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
1070 t.Errorf("bar combined resource jars %v does not contain %q", w, g)
1071 }
1072
1073 if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) {
1074 t.Errorf("bar combined jars %v does not contain %q", w, g)
1075 }
1076
1077 if g, w := barSrcJar.Args["jarArgs"], "-C . -f a.java -f b.java -f c.java"; g != w {
1078 t.Errorf("bar source jar args %q is not %q", w, g)
1079 }
1080
1081 if g, w := barRes.Args["jarArgs"], "-C java-res -f java-res/a/a -f java-res/b/b"; g != w {
1082 t.Errorf("bar resource jar args %q is not %q", w, g)
1083 }
1084}
1085
Colin Cross54190b32017-10-09 15:34:10 -07001086func TestGeneratedSources(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001087 t.Parallel()
Colin Cross238c1f32020-06-07 16:58:18 -07001088 ctx, _ := testJavaWithFS(t, `
Colin Cross54190b32017-10-09 15:34:10 -07001089 java_library {
1090 name: "foo",
1091 srcs: [
1092 "a*.java",
1093 ":gen",
1094 "b*.java",
1095 ],
1096 }
1097
1098 genrule {
1099 name: "gen",
Colin Cross824bee32017-11-22 17:27:51 -08001100 tool_files: ["java-res/a"],
Colin Cross54190b32017-10-09 15:34:10 -07001101 out: ["gen.java"],
1102 }
Colin Cross238c1f32020-06-07 16:58:18 -07001103 `, map[string][]byte{
1104 "a.java": nil,
1105 "b.java": nil,
1106 })
Colin Cross54190b32017-10-09 15:34:10 -07001107
Colin Cross90607e92025-02-11 14:58:07 -08001108 javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
1109 genrule := ctx.ModuleForTests(t, "gen", "").Rule("generator")
Colin Cross54190b32017-10-09 15:34:10 -07001110
Colin Cross15e86d92017-10-20 15:07:08 -07001111 if filepath.Base(genrule.Output.String()) != "gen.java" {
1112 t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String())
Colin Cross54190b32017-10-09 15:34:10 -07001113 }
1114
1115 if len(javac.Inputs) != 3 ||
1116 javac.Inputs[0].String() != "a.java" ||
Colin Cross15e86d92017-10-20 15:07:08 -07001117 javac.Inputs[1].String() != genrule.Output.String() ||
Colin Cross54190b32017-10-09 15:34:10 -07001118 javac.Inputs[2].String() != "b.java" {
1119 t.Errorf(`foo inputs %v != ["a.java", ".../gen.java", "b.java"]`, javac.Inputs)
1120 }
1121}
1122
Nan Zhang61eaedb2017-11-02 13:28:15 -07001123func TestTurbine(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001124 t.Parallel()
Paul Duffin71ae5942021-03-22 15:36:52 +00001125 result := android.GroupFixturePreparers(
1126 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})).
Paul Duffin3d9f2682021-03-13 09:47:16 +00001127 RunTestWithBp(t, `
Nan Zhang61eaedb2017-11-02 13:28:15 -07001128 java_library {
1129 name: "foo",
1130 srcs: ["a.java"],
Jiyong Park2d492942018-03-05 17:44:10 +09001131 sdk_version: "14",
Nan Zhang61eaedb2017-11-02 13:28:15 -07001132 }
1133
1134 java_library {
1135 name: "bar",
Colin Cross9bc43432017-12-15 20:20:39 -08001136 srcs: ["b.java"],
Nan Zhang61eaedb2017-11-02 13:28:15 -07001137 static_libs: ["foo"],
Jiyong Park2d492942018-03-05 17:44:10 +09001138 sdk_version: "14",
Nan Zhang61eaedb2017-11-02 13:28:15 -07001139 }
1140
1141 java_library {
1142 name: "baz",
1143 srcs: ["c.java"],
1144 libs: ["bar"],
1145 sdk_version: "14",
1146 }
1147 `)
1148
Colin Cross90607e92025-02-11 14:58:07 -08001149 fooTurbine := result.ModuleForTests(t, "foo", "android_common").Rule("turbine")
1150 barTurbine := result.ModuleForTests(t, "bar", "android_common").Rule("turbine")
1151 barJavac := result.ModuleForTests(t, "bar", "android_common").Rule("javac")
1152 barTurbineCombined := result.ModuleForTests(t, "bar", "android_common").Description("for turbine")
1153 bazJavac := result.ModuleForTests(t, "baz", "android_common").Rule("javac")
Nan Zhang61eaedb2017-11-02 13:28:15 -07001154
Paul Duffin414ea5e2021-03-22 17:31:52 +00001155 android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs)
Nan Zhang61eaedb2017-11-02 13:28:15 -07001156
Paul Duffin414ea5e2021-03-22 17:31:52 +00001157 fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
1158 barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
Colin Crossf61766e2022-03-16 18:06:48 -07001159 android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar)
Paul Duffin3d9f2682021-03-13 09:47:16 +00001160 android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar)
Paul Duffin414ea5e2021-03-22 17:31:52 +00001161 android.AssertPathsRelativeToTopEquals(t, "bar turbine combineJar", []string{barTurbineJar, fooHeaderJar}, barTurbineCombined.Inputs)
Paul Duffin3d9f2682021-03-13 09:47:16 +00001162 android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "prebuilts/sdk/14/public/android.jar")
Nan Zhang61eaedb2017-11-02 13:28:15 -07001163}
1164
1165func TestSharding(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001166 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001167 ctx, _ := testJava(t, `
Nan Zhang61eaedb2017-11-02 13:28:15 -07001168 java_library {
1169 name: "bar",
1170 srcs: ["a.java","b.java","c.java"],
1171 javac_shard_size: 1
1172 }
1173 `)
1174
Colin Cross3d56ed52021-11-18 22:23:12 -08001175 barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
Nan Zhang61eaedb2017-11-02 13:28:15 -07001176 for i := 0; i < 3; i++ {
Colin Cross90607e92025-02-11 14:58:07 -08001177 barJavac := ctx.ModuleForTests(t, "bar", "android_common").Description("javac" + strconv.Itoa(i))
Colin Cross3d56ed52021-11-18 22:23:12 -08001178 if !strings.HasPrefix(barJavac.Args["classpath"], "-classpath "+barHeaderJar+":") {
1179 t.Errorf("bar javac classpath %v does start with %q", barJavac.Args["classpath"], barHeaderJar)
Nan Zhang61eaedb2017-11-02 13:28:15 -07001180 }
1181 }
1182}
1183
Nan Zhang27e284d2018-02-09 21:03:53 +00001184func TestExcludeFileGroupInSrcs(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001185 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001186 ctx, _ := testJava(t, `
Nan Zhang27e284d2018-02-09 21:03:53 +00001187 java_library {
1188 name: "foo",
1189 srcs: ["a.java", ":foo-srcs"],
1190 exclude_srcs: ["a.java", ":foo-excludes"],
1191 }
1192
1193 filegroup {
1194 name: "foo-srcs",
1195 srcs: ["java-fg/a.java", "java-fg/b.java", "java-fg/c.java"],
1196 }
1197
1198 filegroup {
1199 name: "foo-excludes",
1200 srcs: ["java-fg/a.java", "java-fg/b.java"],
1201 }
1202 `)
1203
Colin Cross90607e92025-02-11 14:58:07 -08001204 javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
Nan Zhang27e284d2018-02-09 21:03:53 +00001205
1206 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" {
1207 t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs)
1208 }
1209}
Jiyong Parkc678ad32018-04-10 13:07:10 +09001210
Colin Crossdad2a362024-03-23 04:43:41 +00001211func TestJavaLibraryOutputFiles(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001212 t.Parallel()
Paul Duffin414ea5e2021-03-22 17:31:52 +00001213 testJavaWithFS(t, "", map[string][]byte{
Paul Duffin52d398a2019-06-11 12:31:14 +01001214 "libcore/Android.bp": []byte(`
1215 java_library {
1216 name: "core",
1217 sdk_version: "none",
1218 system_modules: "none",
Paul Duffinaa55f742020-10-06 17:20:13 +01001219 }
1220
1221 filegroup {
1222 name: "core-jar",
Cole Faust65cb40a2024-10-21 15:41:42 -07001223 device_common_srcs: [":core{.jar}"],
Paul Duffinaa55f742020-10-06 17:20:13 +01001224 }
Paul Duffin414ea5e2021-03-22 17:31:52 +00001225 `),
Paul Duffinaa55f742020-10-06 17:20:13 +01001226 })
Paul Duffinaa55f742020-10-06 17:20:13 +01001227}
1228
Colin Crossdad2a362024-03-23 04:43:41 +00001229func TestJavaImportOutputFiles(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001230 t.Parallel()
Paul Duffin414ea5e2021-03-22 17:31:52 +00001231 testJavaWithFS(t, "", map[string][]byte{
Paul Duffinaa55f742020-10-06 17:20:13 +01001232 "libcore/Android.bp": []byte(`
1233 java_import {
1234 name: "core",
1235 sdk_version: "none",
1236 }
1237
1238 filegroup {
1239 name: "core-jar",
Cole Faust65cb40a2024-10-21 15:41:42 -07001240 device_common_srcs: [":core{.jar}"],
Paul Duffinaa55f742020-10-06 17:20:13 +01001241 }
Paul Duffin414ea5e2021-03-22 17:31:52 +00001242 `),
Paul Duffin52d398a2019-06-11 12:31:14 +01001243 })
Paul Duffin52d398a2019-06-11 12:31:14 +01001244}
1245
Colin Crossdad2a362024-03-23 04:43:41 +00001246func TestJavaImport(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001247 t.Parallel()
Colin Crossdad2a362024-03-23 04:43:41 +00001248 bp := `
1249 java_library {
1250 name: "source_library",
1251 srcs: ["source.java"],
1252 }
1253
1254 java_import {
1255 name: "import_with_no_deps",
1256 jars: ["no_deps.jar"],
1257 }
1258
1259 java_import {
1260 name: "import_with_source_deps",
1261 jars: ["source_deps.jar"],
1262 static_libs: ["source_library"],
1263 }
1264
1265 java_import {
1266 name: "import_with_import_deps",
1267 jars: ["import_deps.jar"],
1268 static_libs: ["import_with_no_deps"],
1269 }
1270 `
1271 ctx := android.GroupFixturePreparers(
1272 PrepareForTestWithJavaDefaultModules,
1273 ).RunTestWithBp(t, bp)
1274
Colin Cross90607e92025-02-11 14:58:07 -08001275 source := ctx.ModuleForTests(t, "source_library", "android_common")
Colin Crossdad2a362024-03-23 04:43:41 +00001276 sourceJar := source.Output("javac/source_library.jar")
1277 sourceHeaderJar := source.Output("turbine-combined/source_library.jar")
Yu Liu663e4502024-08-12 18:23:59 +00001278 sourceJavaInfo, _ := android.OtherModuleProvider(ctx, source.Module(), JavaInfoProvider)
Colin Crossdad2a362024-03-23 04:43:41 +00001279
1280 // The source library produces separate implementation and header jars
1281 android.AssertPathsRelativeToTopEquals(t, "source library implementation jar",
1282 []string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars)
1283 android.AssertPathsRelativeToTopEquals(t, "source library header jar",
1284 []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars)
1285
Colin Cross90607e92025-02-11 14:58:07 -08001286 importWithNoDeps := ctx.ModuleForTests(t, "import_with_no_deps", "android_common")
Colin Crossdad2a362024-03-23 04:43:41 +00001287 importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar")
Yu Liu663e4502024-08-12 18:23:59 +00001288 importWithNoDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider)
Colin Crossdad2a362024-03-23 04:43:41 +00001289
1290 // An import with no deps produces a single jar used as both the header and implementation jar.
1291 android.AssertPathsRelativeToTopEquals(t, "import with no deps implementation jar",
1292 []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.ImplementationAndResourcesJars)
1293 android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar",
1294 []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars)
1295 android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs",
1296 []string{"no_deps.jar"}, importWithNoDepsJar.Inputs)
1297
Colin Cross90607e92025-02-11 14:58:07 -08001298 importWithSourceDeps := ctx.ModuleForTests(t, "import_with_source_deps", "android_common")
Colin Crossdad2a362024-03-23 04:43:41 +00001299 importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar")
1300 importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar")
Yu Liu663e4502024-08-12 18:23:59 +00001301 importWithSourceDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider)
Colin Crossdad2a362024-03-23 04:43:41 +00001302
1303 // An import with source deps produces separate header and implementation jars.
1304 android.AssertPathsRelativeToTopEquals(t, "import with source deps implementation jar",
1305 []string{importWithSourceDepsJar.Output.String()}, importWithSourceDepsJavaInfo.ImplementationAndResourcesJars)
1306 android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar",
1307 []string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars)
1308 android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs",
1309 []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs)
1310 android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs",
1311 []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs)
1312
Colin Cross90607e92025-02-11 14:58:07 -08001313 importWithImportDeps := ctx.ModuleForTests(t, "import_with_import_deps", "android_common")
Colin Crossdad2a362024-03-23 04:43:41 +00001314 importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar")
Yu Liu663e4502024-08-12 18:23:59 +00001315 importWithImportDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider)
Colin Crossdad2a362024-03-23 04:43:41 +00001316
1317 // An import with only import deps produces a single jar used as both the header and implementation jar.
1318 android.AssertPathsRelativeToTopEquals(t, "import with import deps implementation jar",
1319 []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.ImplementationAndResourcesJars)
1320 android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar",
1321 []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars)
1322 android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs",
1323 []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs)
1324}
1325
Zoran Jovanovic8736ce22018-08-21 17:10:29 +02001326var compilerFlagsTestCases = []struct {
1327 in string
1328 out bool
1329}{
1330 {
1331 in: "a",
1332 out: false,
1333 },
1334 {
1335 in: "-a",
1336 out: true,
1337 },
1338 {
1339 in: "-no-jdk",
1340 out: false,
1341 },
1342 {
1343 in: "-no-stdlib",
1344 out: false,
1345 },
1346 {
1347 in: "-kotlin-home",
1348 out: false,
1349 },
1350 {
1351 in: "-kotlin-home /some/path",
1352 out: false,
1353 },
1354 {
1355 in: "-include-runtime",
1356 out: false,
1357 },
1358 {
1359 in: "-Xintellij-plugin-root",
1360 out: false,
1361 },
1362}
1363
1364type mockContext struct {
1365 android.ModuleContext
1366 result bool
1367}
1368
1369func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1370 // CheckBadCompilerFlags calls this function when the flag should be rejected
1371 ctx.result = false
1372}
1373
1374func TestCompilerFlags(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001375 t.Parallel()
Zoran Jovanovic8736ce22018-08-21 17:10:29 +02001376 for _, testCase := range compilerFlagsTestCases {
1377 ctx := &mockContext{result: true}
1378 CheckKotlincFlags(ctx, []string{testCase.in})
1379 if ctx.result != testCase.out {
1380 t.Errorf("incorrect output:")
1381 t.Errorf(" input: %#v", testCase.in)
1382 t.Errorf(" expected: %#v", testCase.out)
1383 t.Errorf(" got: %#v", ctx.result)
1384 }
1385 }
1386}
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001387
1388// TODO(jungjw): Consider making this more robust by ignoring path order.
1389func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) {
Colin Cross90607e92025-02-11 14:58:07 -08001390 variables := ctx.ModuleForTests(t, moduleName, "android_common").VariablesForTestsRelativeToTop()
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001391 flags := strings.Split(variables["javacFlags"], " ")
1392 got := ""
1393 for _, flag := range flags {
1394 keyEnd := strings.Index(flag, "=")
1395 if keyEnd > -1 && flag[:keyEnd] == "--patch-module" {
1396 got = flag[keyEnd+1:]
1397 break
1398 }
1399 }
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +02001400 if expected != android.StringPathRelativeToTop(ctx.Config().SoongOutDir(), got) {
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001401 t.Errorf("Unexpected patch-module flag for module %q - expected %q, but got %q", moduleName, expected, got)
1402 }
1403}
1404
1405func TestPatchModule(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001406 t.Parallel()
Pete Gillin0c2143e2019-05-02 15:32:11 +01001407 t.Run("Java language level 8", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001408 t.Parallel()
Pete Gillin1b3370f2019-10-01 13:57:31 +01001409 // Test with legacy javac -source 1.8 -target 1.8
Pete Gillinbdf5d712019-10-21 14:29:58 +01001410 bp := `
1411 java_library {
1412 name: "foo",
1413 srcs: ["a.java"],
1414 java_version: "1.8",
1415 }
1416
1417 java_library {
1418 name: "bar",
1419 srcs: ["b.java"],
1420 sdk_version: "none",
1421 system_modules: "none",
1422 patch_module: "java.base",
1423 java_version: "1.8",
1424 }
1425
1426 java_library {
1427 name: "baz",
1428 srcs: ["c.java"],
1429 patch_module: "java.base",
1430 java_version: "1.8",
1431 }
1432 `
1433 ctx, _ := testJava(t, bp)
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001434
1435 checkPatchModuleFlag(t, ctx, "foo", "")
1436 checkPatchModuleFlag(t, ctx, "bar", "")
1437 checkPatchModuleFlag(t, ctx, "baz", "")
1438 })
1439
Pete Gillin0c2143e2019-05-02 15:32:11 +01001440 t.Run("Java language level 9", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001441 t.Parallel()
Pete Gillin1b3370f2019-10-01 13:57:31 +01001442 // Test with default javac -source 9 -target 9
Pete Gillinbdf5d712019-10-21 14:29:58 +01001443 bp := `
1444 java_library {
1445 name: "foo",
1446 srcs: ["a.java"],
1447 }
1448
1449 java_library {
1450 name: "bar",
1451 srcs: ["b.java"],
1452 sdk_version: "none",
1453 system_modules: "none",
1454 patch_module: "java.base",
1455 }
1456
1457 java_library {
1458 name: "baz",
Jingwen Chen5136a6e2020-10-30 01:01:35 -04001459 srcs: [
1460 "c.java",
1461 // Tests for b/150878007
1462 "dir/d.java",
1463 "dir2/e.java",
1464 "dir2/f.java",
1465 "nested/dir/g.java"
1466 ],
Pete Gillinbdf5d712019-10-21 14:29:58 +01001467 patch_module: "java.base",
1468 }
1469 `
Pete Gillin1b3370f2019-10-01 13:57:31 +01001470 ctx, _ := testJava(t, bp)
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001471
1472 checkPatchModuleFlag(t, ctx, "foo", "")
Paul Duffin414ea5e2021-03-22 17:31:52 +00001473 expected := "java.base=.:out/soong"
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001474 checkPatchModuleFlag(t, ctx, "bar", expected)
Jingwen Chen5136a6e2020-10-30 01:01:35 -04001475 expected = "java.base=" + strings.Join([]string{
Colin Cross8ff10582023-12-07 13:10:56 -08001476 ".", "out/soong", defaultModuleToPath("ext"), defaultModuleToPath("framework")}, ":")
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001477 checkPatchModuleFlag(t, ctx, "baz", expected)
1478 })
1479}
Paul Duffina7b9f422020-01-10 17:12:18 +00001480
Paul Duffin83a2d962019-11-19 19:44:10 +00001481func TestJavaLibraryWithSystemModules(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001482 t.Parallel()
Paul Duffin83a2d962019-11-19 19:44:10 +00001483 ctx, _ := testJava(t, `
1484 java_library {
1485 name: "lib-with-source-system-modules",
1486 srcs: [
1487 "a.java",
1488 ],
1489 sdk_version: "none",
1490 system_modules: "source-system-modules",
1491 }
1492
1493 java_library {
1494 name: "source-jar",
1495 srcs: [
1496 "a.java",
1497 ],
1498 }
1499
1500 java_system_modules {
1501 name: "source-system-modules",
1502 libs: ["source-jar"],
1503 }
1504
1505 java_library {
1506 name: "lib-with-prebuilt-system-modules",
1507 srcs: [
1508 "a.java",
1509 ],
1510 sdk_version: "none",
1511 system_modules: "prebuilt-system-modules",
1512 }
1513
1514 java_import {
1515 name: "prebuilt-jar",
1516 jars: ["a.jar"],
1517 }
1518
1519 java_system_modules_import {
1520 name: "prebuilt-system-modules",
1521 libs: ["prebuilt-jar"],
1522 }
1523 `)
1524
Jihoon Kangb0f4c022024-08-06 00:15:25 +00001525 checkBootClasspathForLibWithSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar")
Paul Duffin83a2d962019-11-19 19:44:10 +00001526
Jihoon Kangb0f4c022024-08-06 00:15:25 +00001527 checkBootClasspathForLibWithSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar")
Paul Duffin83a2d962019-11-19 19:44:10 +00001528}
1529
Jihoon Kangb0f4c022024-08-06 00:15:25 +00001530func checkBootClasspathForLibWithSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) {
Colin Cross90607e92025-02-11 14:58:07 -08001531 javacRule := ctx.ModuleForTests(t, moduleName, "android_common").Rule("javac")
Paul Duffin83a2d962019-11-19 19:44:10 +00001532 bootClasspath := javacRule.Args["bootClasspath"]
1533 if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) {
1534 t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath)
1535 }
1536}
Jiyong Park19604de2020-03-24 16:44:11 +09001537
1538func TestAidlExportIncludeDirsFromImports(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001539 t.Parallel()
Jiyong Park19604de2020-03-24 16:44:11 +09001540 ctx, _ := testJava(t, `
1541 java_library {
1542 name: "foo",
1543 srcs: ["aidl/foo/IFoo.aidl"],
1544 libs: ["bar"],
1545 }
1546
1547 java_import {
1548 name: "bar",
1549 jars: ["a.jar"],
1550 aidl: {
1551 export_include_dirs: ["aidl/bar"],
1552 },
1553 }
1554 `)
1555
Colin Cross90607e92025-02-11 14:58:07 -08001556 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
Jiyong Park19604de2020-03-24 16:44:11 +09001557 expectedAidlFlag := "-Iaidl/bar"
1558 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1559 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1560 }
1561}
Liz Kammerdd849a82020-06-12 16:38:45 -07001562
Jooyung Hane197d8b2021-01-05 10:33:16 +09001563func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001564 t.Parallel()
Jooyung Hane197d8b2021-01-05 10:33:16 +09001565 ctx, _ := testJava(t, `
1566 java_library {
1567 name: "foo",
1568 srcs: ["aidl/foo/IFoo.aidl"],
1569 aidl: { flags: ["-Werror"], },
1570 }
1571 `)
1572
Colin Cross90607e92025-02-11 14:58:07 -08001573 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
Jooyung Hane197d8b2021-01-05 10:33:16 +09001574 expectedAidlFlag := "-Werror"
1575 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1576 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1577 }
1578}
1579
Jooyung Han07f70c02021-11-06 07:08:45 +09001580func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001581 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09001582 fixture := android.GroupFixturePreparers(
1583 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}}))
1584
1585 for _, tc := range []struct {
1586 name string
1587 sdkVersion string
1588 expected string
1589 }{
1590 {"default is current", "", "current"},
1591 {"use sdk_version", `sdk_version: "14"`, "14"},
1592 {"system_current", `sdk_version: "system_current"`, "current"},
1593 } {
1594 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001595 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09001596 ctx := fixture.RunTestWithBp(t, `
1597 java_library {
1598 name: "foo",
1599 srcs: ["aidl/foo/IFoo.aidl"],
1600 `+tc.sdkVersion+`
1601 }
1602 `)
Colin Cross90607e92025-02-11 14:58:07 -08001603 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
Jooyung Han07f70c02021-11-06 07:08:45 +09001604 expectedAidlFlag := "--min_sdk_version=" + tc.expected
1605 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1606 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1607 }
1608 })
1609 }
1610}
1611
Spandan Das757b6662022-11-17 04:29:59 +00001612func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001613 t.Parallel()
Spandan Das757b6662022-11-17 04:29:59 +00001614 bpTemplate := `
1615 droidstubs {
1616 name: "foo-stubs",
1617 srcs: ["foo.aidl"],
1618 %s
1619 system_modules: "none",
1620 }
1621 `
1622 testCases := []struct {
1623 desc string
1624 sdkVersionBp string
1625 minSdkVersionExpected string
1626 }{
1627 {
1628 desc: "sdk_version not set, module compiles against private platform APIs",
1629 sdkVersionBp: ``,
1630 minSdkVersionExpected: "10000",
1631 },
1632 {
1633 desc: "sdk_version set to none, module does not build against an SDK",
1634 sdkVersionBp: `sdk_version: "none",`,
1635 minSdkVersionExpected: "10000",
1636 },
1637 }
1638 for _, tc := range testCases {
1639 ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp))
Colin Cross90607e92025-02-11 14:58:07 -08001640 aidlCmd := ctx.ModuleForTests(t, "foo-stubs", "android_common").Rule("aidl").RuleParams.Command
Spandan Das757b6662022-11-17 04:29:59 +00001641 expected := "--min_sdk_version=" + tc.minSdkVersionExpected
1642 android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected)
1643 }
1644}
1645
Thiébaud Weksteende8417c2022-02-10 15:41:46 +11001646func TestAidlEnforcePermissions(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001647 t.Parallel()
Thiébaud Weksteende8417c2022-02-10 15:41:46 +11001648 ctx, _ := testJava(t, `
1649 java_library {
1650 name: "foo",
1651 srcs: ["aidl/foo/IFoo.aidl"],
1652 aidl: { enforce_permissions: true },
1653 }
1654 `)
1655
Colin Cross90607e92025-02-11 14:58:07 -08001656 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
Thiébaud Weksteende8417c2022-02-10 15:41:46 +11001657 expectedAidlFlag := "-Wmissing-permission-annotation -Werror"
1658 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1659 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1660 }
1661}
1662
1663func TestAidlEnforcePermissionsException(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001664 t.Parallel()
Thiébaud Weksteende8417c2022-02-10 15:41:46 +11001665 ctx, _ := testJava(t, `
1666 java_library {
1667 name: "foo",
1668 srcs: ["aidl/foo/IFoo.aidl", "aidl/foo/IFoo2.aidl"],
1669 aidl: { enforce_permissions: true, enforce_permissions_exceptions: ["aidl/foo/IFoo2.aidl"] },
1670 }
1671 `)
1672
Colin Cross90607e92025-02-11 14:58:07 -08001673 aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
Thiébaud Weksteende8417c2022-02-10 15:41:46 +11001674 expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl"
1675 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1676 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1677 }
1678 expectedAidlFlag = "$$FLAGS aidl/foo/IFoo2.aidl"
1679 if !strings.Contains(aidlCommand, expectedAidlFlag) {
1680 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
1681 }
1682}
1683
Liz Kammerdd849a82020-06-12 16:38:45 -07001684func TestDataNativeBinaries(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001685 t.Parallel()
Cole Faust5c503d12023-01-24 11:48:08 -08001686 ctx := android.GroupFixturePreparers(
1687 prepareForJavaTest,
1688 android.PrepareForTestWithAllowMissingDependencies).RunTestWithBp(t, `
Liz Kammerdd849a82020-06-12 16:38:45 -07001689 java_test_host {
1690 name: "foo",
1691 srcs: ["a.java"],
1692 data_native_bins: ["bin"]
1693 }
1694
Cole Faust5c503d12023-01-24 11:48:08 -08001695 cc_binary_host {
Liz Kammerdd849a82020-06-12 16:38:45 -07001696 name: "bin",
Cole Faust5c503d12023-01-24 11:48:08 -08001697 srcs: ["bin.cpp"],
Liz Kammerdd849a82020-06-12 16:38:45 -07001698 }
Cole Faust5c503d12023-01-24 11:48:08 -08001699 `).TestContext
Liz Kammerdd849a82020-06-12 16:38:45 -07001700
Colin Cross0c66bc62021-07-20 09:47:41 -07001701 buildOS := ctx.Config().BuildOS.String()
Liz Kammerdd849a82020-06-12 16:38:45 -07001702
Colin Cross90607e92025-02-11 14:58:07 -08001703 test := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
Colin Crossaa255532020-07-03 13:18:24 -07001704 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
Cole Faust5c503d12023-01-24 11:48:08 -08001705 expected := []string{"out/soong/.intermediates/bin/" + buildOS + "_x86_64/bin:bin"}
Liz Kammerdd849a82020-06-12 16:38:45 -07001706 actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
Paul Duffin414ea5e2021-03-22 17:31:52 +00001707 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_COMPATIBILITY_SUPPORT_FILES", ctx.Config(), expected, actual)
Liz Kammerdd849a82020-06-12 16:38:45 -07001708}
Yuexi Ma627263f2021-03-04 13:47:56 -08001709
1710func TestDefaultInstallable(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001711 t.Parallel()
Yuexi Ma627263f2021-03-04 13:47:56 -08001712 ctx, _ := testJava(t, `
1713 java_test_host {
1714 name: "foo"
1715 }
1716 `)
1717
Colin Cross0c66bc62021-07-20 09:47:41 -07001718 buildOS := ctx.Config().BuildOS.String()
Colin Cross90607e92025-02-11 14:58:07 -08001719 module := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
Yuexi Ma627263f2021-03-04 13:47:56 -08001720 assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true),
1721 module.properties.Installable)
1722}
Cole Faust75fffb12021-06-13 15:23:16 -07001723
1724func TestErrorproneEnabled(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001725 t.Parallel()
Cole Faust75fffb12021-06-13 15:23:16 -07001726 ctx, _ := testJava(t, `
1727 java_library {
1728 name: "foo",
1729 srcs: ["a.java"],
1730 errorprone: {
1731 enabled: true,
1732 },
1733 }
1734 `)
1735
Colin Cross90607e92025-02-11 14:58:07 -08001736 javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
Cole Faust75fffb12021-06-13 15:23:16 -07001737
1738 // Test that the errorprone plugins are passed to javac
1739 expectedSubstring := "-Xplugin:ErrorProne"
1740 if !strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
Cole Faust2b1536e2021-06-18 12:25:54 -07001741 t.Errorf("expected javacFlags to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
Cole Faust75fffb12021-06-13 15:23:16 -07001742 }
1743
1744 // Modules with errorprone { enabled: true } will include errorprone checks
1745 // in the main javac build rule. Only when RUN_ERROR_PRONE is true will
1746 // the explicit errorprone build rule be created.
Colin Cross90607e92025-02-11 14:58:07 -08001747 errorprone := ctx.ModuleForTests(t, "foo", "android_common").MaybeDescription("errorprone")
Cole Faust75fffb12021-06-13 15:23:16 -07001748 if errorprone.RuleParams.Description != "" {
1749 t.Errorf("expected errorprone build rule to not exist, but it did")
1750 }
1751}
Cole Faust2b1536e2021-06-18 12:25:54 -07001752
1753func TestErrorproneDisabled(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001754 t.Parallel()
Cole Faust2b1536e2021-06-18 12:25:54 -07001755 bp := `
1756 java_library {
1757 name: "foo",
1758 srcs: ["a.java"],
1759 errorprone: {
1760 enabled: false,
1761 },
1762 }
1763 `
1764 ctx := android.GroupFixturePreparers(
1765 PrepareForTestWithJavaDefaultModules,
1766 android.FixtureMergeEnv(map[string]string{
1767 "RUN_ERROR_PRONE": "true",
1768 }),
1769 ).RunTestWithBp(t, bp)
1770
Colin Cross90607e92025-02-11 14:58:07 -08001771 javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
Cole Faust2b1536e2021-06-18 12:25:54 -07001772
1773 // Test that the errorprone plugins are not passed to javac, like they would
1774 // be if enabled was true.
1775 expectedSubstring := "-Xplugin:ErrorProne"
1776 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
1777 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
1778 }
1779
1780 // Check that no errorprone build rule is created, like there would be
1781 // if enabled was unset and RUN_ERROR_PRONE was true.
Colin Cross90607e92025-02-11 14:58:07 -08001782 errorprone := ctx.ModuleForTests(t, "foo", "android_common").MaybeDescription("errorprone")
Cole Faust2b1536e2021-06-18 12:25:54 -07001783 if errorprone.RuleParams.Description != "" {
1784 t.Errorf("expected errorprone build rule to not exist, but it did")
1785 }
1786}
1787
1788func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001789 t.Parallel()
Cole Faust2b1536e2021-06-18 12:25:54 -07001790 bp := `
1791 java_library {
1792 name: "foo",
1793 srcs: ["a.java"],
1794 }
1795 `
1796 ctx := android.GroupFixturePreparers(
1797 PrepareForTestWithJavaDefaultModules,
1798 android.FixtureMergeEnv(map[string]string{
1799 "RUN_ERROR_PRONE": "true",
1800 }),
1801 ).RunTestWithBp(t, bp)
1802
Colin Cross90607e92025-02-11 14:58:07 -08001803 javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
1804 errorprone := ctx.ModuleForTests(t, "foo", "android_common").Description("errorprone")
Cole Faust2b1536e2021-06-18 12:25:54 -07001805
1806 // Check that the errorprone plugins are not passed to javac, because they
1807 // will instead be passed to the separate errorprone compilation
1808 expectedSubstring := "-Xplugin:ErrorProne"
1809 if strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
1810 t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
1811 }
1812
1813 // Check that the errorprone plugin is enabled
1814 if !strings.Contains(errorprone.Args["javacFlags"], expectedSubstring) {
1815 t.Errorf("expected errorprone to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
1816 }
1817}
Sam Delmericob3342ce2022-01-20 21:10:28 +00001818
1819func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001820 t.Parallel()
Sam Delmericocc271e22022-06-01 15:45:02 +00001821 testCases := []struct {
1822 dataDeviceBinType string
1823 depCompileMultilib string
1824 variants []string
1825 expectedError string
1826 }{
1827 {
1828 dataDeviceBinType: "first",
1829 depCompileMultilib: "first",
1830 variants: []string{"android_arm64_armv8-a"},
1831 },
1832 {
1833 dataDeviceBinType: "first",
1834 depCompileMultilib: "both",
1835 variants: []string{"android_arm64_armv8-a"},
1836 },
1837 {
1838 // this is true because our testing framework is set up with
1839 // Targets ~ [<64bit target>, <32bit target>], where 64bit is "first"
1840 dataDeviceBinType: "first",
1841 depCompileMultilib: "32",
1842 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1843 },
1844 {
1845 dataDeviceBinType: "first",
1846 depCompileMultilib: "64",
1847 variants: []string{"android_arm64_armv8-a"},
1848 },
1849 {
1850 dataDeviceBinType: "both",
1851 depCompileMultilib: "both",
1852 variants: []string{
1853 "android_arm_armv7-a-neon",
1854 "android_arm64_armv8-a",
1855 },
1856 },
1857 {
1858 dataDeviceBinType: "both",
1859 depCompileMultilib: "32",
1860 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1861 },
1862 {
1863 dataDeviceBinType: "both",
1864 depCompileMultilib: "64",
1865 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1866 },
1867 {
1868 dataDeviceBinType: "both",
1869 depCompileMultilib: "first",
1870 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1871 },
1872 {
1873 dataDeviceBinType: "32",
1874 depCompileMultilib: "32",
1875 variants: []string{"android_arm_armv7-a-neon"},
1876 },
1877 {
1878 dataDeviceBinType: "32",
1879 depCompileMultilib: "first",
1880 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1881 },
1882 {
1883 dataDeviceBinType: "32",
1884 depCompileMultilib: "both",
1885 variants: []string{"android_arm_armv7-a-neon"},
1886 },
1887 {
1888 dataDeviceBinType: "32",
1889 depCompileMultilib: "64",
1890 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1891 },
1892 {
1893 dataDeviceBinType: "64",
1894 depCompileMultilib: "64",
1895 variants: []string{"android_arm64_armv8-a"},
1896 },
1897 {
1898 dataDeviceBinType: "64",
1899 depCompileMultilib: "both",
1900 variants: []string{"android_arm64_armv8-a"},
1901 },
1902 {
1903 dataDeviceBinType: "64",
1904 depCompileMultilib: "first",
1905 variants: []string{"android_arm64_armv8-a"},
1906 },
1907 {
1908 dataDeviceBinType: "64",
1909 depCompileMultilib: "32",
1910 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1911 },
1912 {
1913 dataDeviceBinType: "prefer32",
1914 depCompileMultilib: "32",
1915 variants: []string{"android_arm_armv7-a-neon"},
1916 },
1917 {
1918 dataDeviceBinType: "prefer32",
1919 depCompileMultilib: "both",
1920 variants: []string{"android_arm_armv7-a-neon"},
1921 },
1922 {
1923 dataDeviceBinType: "prefer32",
1924 depCompileMultilib: "first",
1925 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1926 },
1927 {
1928 dataDeviceBinType: "prefer32",
1929 depCompileMultilib: "64",
1930 expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
1931 },
Sam Delmericob3342ce2022-01-20 21:10:28 +00001932 }
Sam Delmericob3342ce2022-01-20 21:10:28 +00001933
Sam Delmericocc271e22022-06-01 15:45:02 +00001934 bpTemplate := `
Sam Delmericob3342ce2022-01-20 21:10:28 +00001935 java_test_host {
1936 name: "foo",
1937 srcs: ["test.java"],
Sam Delmericocc271e22022-06-01 15:45:02 +00001938 data_device_bins_%s: ["bar"],
Sam Delmericob3342ce2022-01-20 21:10:28 +00001939 }
1940
1941 cc_binary {
1942 name: "bar",
Sam Delmericocc271e22022-06-01 15:45:02 +00001943 compile_multilib: "%s",
Sam Delmericob3342ce2022-01-20 21:10:28 +00001944 }
1945 `
1946
Sam Delmericocc271e22022-06-01 15:45:02 +00001947 for _, tc := range testCases {
1948 bp := fmt.Sprintf(bpTemplate, tc.dataDeviceBinType, tc.depCompileMultilib)
Sam Delmericob3342ce2022-01-20 21:10:28 +00001949
Sam Delmericocc271e22022-06-01 15:45:02 +00001950 errorHandler := android.FixtureExpectsNoErrors
1951 if tc.expectedError != "" {
1952 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError)
1953 }
Sam Delmericob3342ce2022-01-20 21:10:28 +00001954
Sam Delmericocc271e22022-06-01 15:45:02 +00001955 testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib)
1956 t.Run(testName, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001957 t.Parallel()
Sam Delmericocc271e22022-06-01 15:45:02 +00001958 ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava).
1959 ExtendWithErrorHandler(errorHandler).
1960 RunTestWithBp(t, bp)
1961 if tc.expectedError != "" {
1962 return
1963 }
1964
1965 buildOS := ctx.Config.BuildOS.String()
Colin Cross90607e92025-02-11 14:58:07 -08001966 fooVariant := ctx.ModuleForTests(t, "foo", buildOS+"_common")
Sam Delmericocc271e22022-06-01 15:45:02 +00001967 fooMod := fooVariant.Module().(*TestHost)
1968 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0]
1969
1970 expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />`
1971 autogen := fooVariant.Rule("autogen")
1972 if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) {
1973 t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig)
1974 }
1975
1976 expectedData := []string{}
1977 for _, variant := range tc.variants {
Colin Cross90607e92025-02-11 14:58:07 -08001978 barVariant := ctx.ModuleForTests(t, "bar", variant)
Sam Delmericocc271e22022-06-01 15:45:02 +00001979 relocated := barVariant.Output("bar")
1980 expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant)
1981 android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input)
1982
1983 expectedData = append(expectedData, fmt.Sprintf("out/soong/.intermediates/bar/%s/bar:bar", variant))
1984 }
1985
1986 actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
Jihoon Kang82197492025-01-29 19:30:31 +00001987 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, android.SortedUniqueStrings(expectedData), android.SortedUniqueStrings(actualData))
Sam Delmericocc271e22022-06-01 15:45:02 +00001988 })
Sam Delmericob3342ce2022-01-20 21:10:28 +00001989 }
1990}
Sam Delmerico277795c2022-02-25 17:04:37 +00001991
Zi Wangca65b402022-10-10 13:45:06 -07001992func TestDeviceBinaryWrapperGeneration(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001993 t.Parallel()
Zi Wangca65b402022-10-10 13:45:06 -07001994 // Scenario 1: java_binary has main_class property in its bp
1995 ctx, _ := testJava(t, `
1996 java_binary {
1997 name: "foo",
1998 srcs: ["foo.java"],
1999 main_class: "foo.bar.jb",
2000 }
2001 `)
Colin Cross90607e92025-02-11 14:58:07 -08002002 wrapperPath := fmt.Sprint(ctx.ModuleForTests(t, "foo", "android_common").AllOutputs())
Zi Wangca65b402022-10-10 13:45:06 -07002003 if !strings.Contains(wrapperPath, "foo.sh") {
2004 t.Errorf("wrapper file foo.sh is not generated")
2005 }
2006
2007 // Scenario 2: java_binary has neither wrapper nor main_class, its build
2008 // is expected to be failed.
2009 testJavaError(t, "main_class property is required for device binary if no default wrapper is assigned", `
2010 java_binary {
2011 name: "foo",
2012 srcs: ["foo.java"],
2013 }`)
2014}
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002015
Jihoon Kang3198f3c2023-01-26 08:08:52 +00002016func TestJavaApiContributionEmptyApiFile(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002017 t.Parallel()
Jihoon Kang063ec002023-06-28 01:16:23 +00002018 android.GroupFixturePreparers(
2019 prepareForJavaTest,
2020 android.FixtureMergeEnv(
2021 map[string]string{
2022 "DISABLE_STUB_VALIDATION": "true",
2023 },
2024 ),
2025 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
Jihoon Kang3198f3c2023-01-26 08:08:52 +00002026 "Error: foo has an empty api file.",
Jihoon Kang063ec002023-06-28 01:16:23 +00002027 )).RunTestWithBp(t, `
2028 java_api_contribution {
Jihoon Kang3198f3c2023-01-26 08:08:52 +00002029 name: "foo",
2030 }
2031 java_api_library {
2032 name: "bar",
2033 api_surface: "public",
2034 api_contributions: ["foo"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002035 stubs_type: "everything",
Jihoon Kang3198f3c2023-01-26 08:08:52 +00002036 }
2037 `)
2038}
2039
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002040func TestJavaApiLibraryAndProviderLink(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002041 t.Parallel()
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002042 provider_bp_a := `
2043 java_api_contribution {
2044 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002045 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002046 api_surface: "public",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002047 }
2048 `
2049 provider_bp_b := `java_api_contribution {
2050 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002051 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002052 api_surface: "public",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002053 }
2054 `
Jihoon Kang063ec002023-06-28 01:16:23 +00002055 ctx := android.GroupFixturePreparers(
2056 prepareForJavaTest,
2057 android.FixtureMergeMockFs(
2058 map[string][]byte{
2059 "a/Android.bp": []byte(provider_bp_a),
2060 "b/Android.bp": []byte(provider_bp_b),
2061 },
2062 ),
2063 android.FixtureMergeEnv(
2064 map[string]string{
2065 "DISABLE_STUB_VALIDATION": "true",
2066 },
2067 ),
2068 ).RunTestWithBp(t, `
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002069 java_api_library {
2070 name: "bar1",
2071 api_surface: "public",
Jihoon Kang60d4a092022-11-17 23:47:43 +00002072 api_contributions: ["foo1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002073 stubs_type: "everything",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002074 }
2075
2076 java_api_library {
2077 name: "bar2",
2078 api_surface: "system",
Jihoon Kang60d4a092022-11-17 23:47:43 +00002079 api_contributions: ["foo1", "foo2"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002080 stubs_type: "everything",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002081 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002082 `)
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002083
2084 testcases := []struct {
2085 moduleName string
2086 sourceTextFileDirs []string
2087 }{
2088 {
2089 moduleName: "bar1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002090 sourceTextFileDirs: []string{"a/current.txt"},
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002091 },
2092 {
2093 moduleName: "bar2",
Jihoon Kang6be0f002023-09-20 23:03:01 +00002094 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"},
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002095 },
2096 }
2097 for _, c := range testcases {
Colin Cross90607e92025-02-11 14:58:07 -08002098 m := ctx.ModuleForTests(t, c.moduleName, "android_common")
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002099 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002100 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002101 manifestCommand := sboxProto.Commands[0].GetCommand()
2102 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ")
2103 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag)
2104 }
2105}
2106
Jihoon Kang1c51f502023-01-09 23:42:40 +00002107func TestJavaApiLibraryAndDefaultsLink(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002108 t.Parallel()
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002109 provider_bp_a := `
2110 java_api_contribution {
Jihoon Kang1c51f502023-01-09 23:42:40 +00002111 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002112 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002113 api_surface: "public",
Jihoon Kang1c51f502023-01-09 23:42:40 +00002114 }
2115 `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002116 provider_bp_b := `
2117 java_api_contribution {
Jihoon Kang1c51f502023-01-09 23:42:40 +00002118 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002119 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002120 api_surface: "public",
Jihoon Kang1c51f502023-01-09 23:42:40 +00002121 }
2122 `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002123 provider_bp_c := `
2124 java_api_contribution {
Jihoon Kang1c51f502023-01-09 23:42:40 +00002125 name: "foo3",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002126 api_file: "system-current.txt",
2127 api_surface: "system",
Jihoon Kang1c51f502023-01-09 23:42:40 +00002128 }
2129 `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002130 provider_bp_d := `
2131 java_api_contribution {
Jihoon Kang1c51f502023-01-09 23:42:40 +00002132 name: "foo4",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002133 api_file: "system-current.txt",
2134 api_surface: "system",
Jihoon Kang1c51f502023-01-09 23:42:40 +00002135 }
2136 `
Jihoon Kang063ec002023-06-28 01:16:23 +00002137 ctx := android.GroupFixturePreparers(
2138 prepareForJavaTest,
2139 android.FixtureMergeMockFs(
2140 map[string][]byte{
2141 "a/Android.bp": []byte(provider_bp_a),
2142 "b/Android.bp": []byte(provider_bp_b),
2143 "c/Android.bp": []byte(provider_bp_c),
2144 "d/Android.bp": []byte(provider_bp_d),
2145 },
2146 ),
2147 android.FixtureMergeEnv(
2148 map[string]string{
2149 "DISABLE_STUB_VALIDATION": "true",
2150 },
2151 ),
2152 ).RunTestWithBp(t, `
Jihoon Kang1c51f502023-01-09 23:42:40 +00002153 java_defaults {
2154 name: "baz1",
2155 api_surface: "public",
2156 api_contributions: ["foo1", "foo2"],
2157 }
2158
2159 java_defaults {
2160 name: "baz2",
2161 api_surface: "system",
2162 api_contributions: ["foo3"],
2163 }
2164
2165 java_api_library {
2166 name: "bar1",
2167 api_surface: "public",
2168 api_contributions: ["foo1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002169 stubs_type: "everything",
Jihoon Kang1c51f502023-01-09 23:42:40 +00002170 }
2171
2172 java_api_library {
2173 name: "bar2",
2174 api_surface: "public",
2175 defaults:["baz1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002176 stubs_type: "everything",
Jihoon Kang1c51f502023-01-09 23:42:40 +00002177 }
2178
2179 java_api_library {
2180 name: "bar3",
2181 api_surface: "system",
2182 defaults:["baz1", "baz2"],
2183 api_contributions: ["foo4"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002184 stubs_type: "everything",
Jihoon Kang1c51f502023-01-09 23:42:40 +00002185 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002186 `)
Jihoon Kang1c51f502023-01-09 23:42:40 +00002187
2188 testcases := []struct {
2189 moduleName string
2190 sourceTextFileDirs []string
2191 }{
2192 {
2193 moduleName: "bar1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002194 sourceTextFileDirs: []string{"a/current.txt"},
Jihoon Kang1c51f502023-01-09 23:42:40 +00002195 },
2196 {
2197 moduleName: "bar2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002198 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"},
Jihoon Kang1c51f502023-01-09 23:42:40 +00002199 },
2200 {
Jihoon Kang8fe19822023-09-14 06:27:36 +00002201 moduleName: "bar3",
2202 // API text files need to be sorted from the narrower api scope to the wider api scope
Jihoon Kang6be0f002023-09-20 23:03:01 +00002203 sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "c/system-current.txt", "d/system-current.txt"},
Jihoon Kang1c51f502023-01-09 23:42:40 +00002204 },
2205 }
2206 for _, c := range testcases {
Colin Cross90607e92025-02-11 14:58:07 -08002207 m := ctx.ModuleForTests(t, c.moduleName, "android_common")
Jihoon Kang1c51f502023-01-09 23:42:40 +00002208 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002209 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
Jihoon Kang1c51f502023-01-09 23:42:40 +00002210 manifestCommand := sboxProto.Commands[0].GetCommand()
2211 sourceFilesFlag := "--source-files " + strings.Join(c.sourceTextFileDirs, " ")
2212 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag)
2213 }
2214}
2215
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002216func TestJavaApiLibraryJarGeneration(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002217 t.Parallel()
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002218 provider_bp_a := `
2219 java_api_contribution {
2220 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002221 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002222 api_surface: "public",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002223 }
2224 `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002225 provider_bp_b := `
2226 java_api_contribution {
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002227 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002228 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002229 api_surface: "public",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002230 }
2231 `
Jihoon Kang063ec002023-06-28 01:16:23 +00002232 ctx := android.GroupFixturePreparers(
2233 prepareForJavaTest,
2234 android.FixtureMergeMockFs(
2235 map[string][]byte{
2236 "a/Android.bp": []byte(provider_bp_a),
2237 "b/Android.bp": []byte(provider_bp_b),
2238 },
2239 ),
2240 android.FixtureMergeEnv(
2241 map[string]string{
2242 "DISABLE_STUB_VALIDATION": "true",
2243 },
2244 ),
2245 ).RunTestWithBp(t, `
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002246 java_api_library {
2247 name: "bar1",
2248 api_surface: "public",
Jihoon Kang60d4a092022-11-17 23:47:43 +00002249 api_contributions: ["foo1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002250 stubs_type: "everything",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002251 }
2252
2253 java_api_library {
2254 name: "bar2",
2255 api_surface: "system",
Jihoon Kang60d4a092022-11-17 23:47:43 +00002256 api_contributions: ["foo1", "foo2"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002257 stubs_type: "everything",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002258 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002259 `)
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002260
2261 testcases := []struct {
2262 moduleName string
2263 outputJarName string
2264 }{
2265 {
2266 moduleName: "bar1",
Jihoon Kang25857f52023-03-01 00:27:32 +00002267 outputJarName: "bar1/bar1.jar",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002268 },
2269 {
2270 moduleName: "bar2",
Jihoon Kang25857f52023-03-01 00:27:32 +00002271 outputJarName: "bar2/bar2.jar",
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002272 },
2273 }
2274 for _, c := range testcases {
Colin Cross90607e92025-02-11 14:58:07 -08002275 m := ctx.ModuleForTests(t, c.moduleName, "android_common")
Jihoon Kang0ac87c22022-11-15 19:06:14 +00002276 outputs := fmt.Sprint(m.AllOutputs())
2277 if !strings.Contains(outputs, c.outputJarName) {
2278 t.Errorf("Module output does not contain expected jar %s", c.outputJarName)
2279 }
2280 }
2281}
Cole Faust21680542022-12-07 18:18:37 -08002282
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002283func TestJavaApiLibraryLibsLink(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002284 t.Parallel()
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002285 provider_bp_a := `
2286 java_api_contribution {
2287 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002288 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002289 api_surface: "public",
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002290 }
2291 `
2292 provider_bp_b := `
2293 java_api_contribution {
2294 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002295 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002296 api_surface: "public",
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002297 }
2298 `
2299 lib_bp_a := `
2300 java_library {
2301 name: "lib1",
2302 srcs: ["Lib.java"],
2303 }
2304 `
2305 lib_bp_b := `
2306 java_library {
2307 name: "lib2",
2308 srcs: ["Lib.java"],
2309 }
2310 `
2311
Jihoon Kang063ec002023-06-28 01:16:23 +00002312 ctx := android.GroupFixturePreparers(
2313 prepareForJavaTest,
2314 android.FixtureMergeMockFs(
2315 map[string][]byte{
2316 "a/Android.bp": []byte(provider_bp_a),
2317 "b/Android.bp": []byte(provider_bp_b),
2318 "c/Android.bp": []byte(lib_bp_a),
2319 "c/Lib.java": {},
2320 "d/Android.bp": []byte(lib_bp_b),
2321 "d/Lib.java": {},
2322 },
2323 ),
2324 android.FixtureMergeEnv(
2325 map[string]string{
2326 "DISABLE_STUB_VALIDATION": "true",
2327 },
2328 ),
2329 ).RunTestWithBp(t, `
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002330 java_api_library {
2331 name: "bar1",
2332 api_surface: "public",
2333 api_contributions: ["foo1"],
2334 libs: ["lib1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002335 stubs_type: "everything",
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002336 }
2337
2338 java_api_library {
2339 name: "bar2",
2340 api_surface: "system",
2341 api_contributions: ["foo1", "foo2"],
2342 libs: ["lib1", "lib2", "bar1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002343 stubs_type: "everything",
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002344 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002345 `)
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002346
2347 testcases := []struct {
2348 moduleName string
2349 classPathJarNames []string
2350 }{
2351 {
2352 moduleName: "bar1",
2353 classPathJarNames: []string{"lib1.jar"},
2354 },
2355 {
2356 moduleName: "bar2",
Jihoon Kang25857f52023-03-01 00:27:32 +00002357 classPathJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"},
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002358 },
2359 }
2360 for _, c := range testcases {
Colin Cross90607e92025-02-11 14:58:07 -08002361 m := ctx.ModuleForTests(t, c.moduleName, "android_common")
Jihoon Kang362aa9d2023-01-20 19:44:07 +00002362 javacRules := m.Rule("javac")
2363 classPathArgs := javacRules.Args["classpath"]
2364 for _, jarName := range c.classPathJarNames {
2365 if !strings.Contains(classPathArgs, jarName) {
2366 t.Errorf("Module output does not contain expected jar %s", jarName)
2367 }
2368 }
2369 }
2370}
2371
Jihoon Kange30fff02023-02-14 20:18:20 +00002372func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002373 t.Parallel()
Jihoon Kange30fff02023-02-14 20:18:20 +00002374 provider_bp_a := `
2375 java_api_contribution {
2376 name: "foo1",
Jihoon Kang84473f52023-08-11 22:36:33 +00002377 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002378 api_surface: "public",
Jihoon Kange30fff02023-02-14 20:18:20 +00002379 }
2380 `
2381 provider_bp_b := `
2382 java_api_contribution {
2383 name: "foo2",
Jihoon Kang84473f52023-08-11 22:36:33 +00002384 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002385 api_surface: "public",
Jihoon Kange30fff02023-02-14 20:18:20 +00002386 }
2387 `
2388 lib_bp_a := `
2389 java_library {
2390 name: "lib1",
2391 srcs: ["Lib.java"],
2392 }
2393 `
2394 lib_bp_b := `
2395 java_library {
2396 name: "lib2",
2397 srcs: ["Lib.java"],
2398 }
2399 `
2400
Jihoon Kang063ec002023-06-28 01:16:23 +00002401 ctx := android.GroupFixturePreparers(
2402 prepareForJavaTest,
2403 android.FixtureMergeMockFs(
2404 map[string][]byte{
2405 "a/Android.bp": []byte(provider_bp_a),
2406 "b/Android.bp": []byte(provider_bp_b),
2407 "c/Android.bp": []byte(lib_bp_a),
2408 "c/Lib.java": {},
2409 "d/Android.bp": []byte(lib_bp_b),
2410 "d/Lib.java": {},
2411 },
2412 ),
2413 android.FixtureMergeEnv(
2414 map[string]string{
2415 "DISABLE_STUB_VALIDATION": "true",
2416 },
2417 ),
2418 ).RunTestWithBp(t, `
Jihoon Kange30fff02023-02-14 20:18:20 +00002419 java_api_library {
2420 name: "bar1",
2421 api_surface: "public",
2422 api_contributions: ["foo1"],
2423 static_libs: ["lib1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002424 stubs_type: "everything",
Jihoon Kange30fff02023-02-14 20:18:20 +00002425 }
2426
2427 java_api_library {
2428 name: "bar2",
2429 api_surface: "system",
2430 api_contributions: ["foo1", "foo2"],
2431 static_libs: ["lib1", "lib2", "bar1"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002432 stubs_type: "everything",
Jihoon Kange30fff02023-02-14 20:18:20 +00002433 }
Jihoon Kang063ec002023-06-28 01:16:23 +00002434 `)
Jihoon Kange30fff02023-02-14 20:18:20 +00002435
2436 testcases := []struct {
2437 moduleName string
2438 staticLibJarNames []string
2439 }{
2440 {
2441 moduleName: "bar1",
2442 staticLibJarNames: []string{"lib1.jar"},
2443 },
2444 {
2445 moduleName: "bar2",
Jihoon Kang25857f52023-03-01 00:27:32 +00002446 staticLibJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"},
Jihoon Kange30fff02023-02-14 20:18:20 +00002447 },
2448 }
2449 for _, c := range testcases {
Colin Cross90607e92025-02-11 14:58:07 -08002450 m := ctx.ModuleForTests(t, c.moduleName, "android_common")
Jihoon Kange30fff02023-02-14 20:18:20 +00002451 mergeZipsCommand := m.Rule("merge_zips").RuleParams.Command
2452 for _, jarName := range c.staticLibJarNames {
2453 if !strings.Contains(mergeZipsCommand, jarName) {
2454 t.Errorf("merge_zips command does not contain expected jar %s", jarName)
2455 }
2456 }
2457 }
2458}
2459
Anton Hansson0e73f9e2023-09-20 13:39:57 +00002460func TestTransitiveSrcFiles(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002461 t.Parallel()
Anton Hansson0e73f9e2023-09-20 13:39:57 +00002462 ctx, _ := testJava(t, `
2463 java_library {
2464 name: "a",
2465 srcs: ["a.java"],
2466 }
2467 java_library {
2468 name: "b",
2469 srcs: ["b.java"],
2470 }
2471 java_library {
2472 name: "c",
2473 srcs: ["c.java"],
2474 libs: ["a"],
2475 static_libs: ["b"],
2476 }
2477 `)
Colin Cross90607e92025-02-11 14:58:07 -08002478 c := ctx.ModuleForTests(t, "c", "android_common").Module()
Yu Liu663e4502024-08-12 18:23:59 +00002479 javaInfo, _ := android.OtherModuleProvider(ctx, c, JavaInfoProvider)
Colin Cross5a377182023-12-14 14:46:23 -08002480 transitiveSrcFiles := android.Paths(javaInfo.TransitiveSrcFiles.ToList())
Anton Hansson0e73f9e2023-09-20 13:39:57 +00002481 android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings())
2482}
2483
Cole Faust21680542022-12-07 18:18:37 -08002484func TestTradefedOptions(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002485 t.Parallel()
Cole Faust21680542022-12-07 18:18:37 -08002486 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
2487java_test_host {
2488 name: "foo",
2489 test_options: {
2490 tradefed_options: [
2491 {
2492 name: "exclude-path",
2493 value: "org/apache"
2494 }
2495 ]
2496 }
2497}
2498`)
2499
2500 buildOS := result.Config.BuildOS.String()
Colin Cross90607e92025-02-11 14:58:07 -08002501 args := result.ModuleForTests(t, "foo", buildOS+"_common").
Cole Faust21680542022-12-07 18:18:37 -08002502 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
2503 expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />")
2504 if args["extraConfigs"] != expected {
2505 t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"])
2506 }
2507}
Dan Shiec731432023-05-26 04:21:44 +00002508
2509func TestTestRunnerOptions(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002510 t.Parallel()
Dan Shiec731432023-05-26 04:21:44 +00002511 result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
2512java_test_host {
2513 name: "foo",
2514 test_options: {
2515 test_runner_options: [
2516 {
2517 name: "test-timeout",
2518 value: "10m"
2519 }
2520 ]
2521 }
2522}
2523`)
2524
2525 buildOS := result.Config.BuildOS.String()
Colin Cross90607e92025-02-11 14:58:07 -08002526 args := result.ModuleForTests(t, "foo", buildOS+"_common").
Dan Shiec731432023-05-26 04:21:44 +00002527 Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
2528 expected := proptools.NinjaAndShellEscape("<option name=\"test-timeout\" value=\"10m\" />\\n ")
2529 if args["extraTestRunnerConfigs"] != expected {
2530 t.Errorf("Expected args[\"extraTestRunnerConfigs\"] to equal %q, was %q", expected, args["extraTestRunnerConfigs"])
2531 }
2532}
Jihoon Kang381c2fa2023-06-01 22:17:32 +00002533
Jihoon Kang1bfb6f22023-07-01 00:13:47 +00002534func TestJavaLibraryWithResourcesStem(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002535 t.Parallel()
Jihoon Kang1bfb6f22023-07-01 00:13:47 +00002536 ctx, _ := testJavaWithFS(t, `
2537 java_library {
2538 name: "foo",
2539 java_resource_dirs: ["test-jar"],
2540 stem: "test",
2541 }
2542 `,
2543 map[string][]byte{
2544 "test-jar/test/resource.txt": nil,
2545 })
2546
Colin Cross90607e92025-02-11 14:58:07 -08002547 m := ctx.ModuleForTests(t, "foo", "android_common")
Jihoon Kang1bfb6f22023-07-01 00:13:47 +00002548 outputs := fmt.Sprint(m.AllOutputs())
2549 if !strings.Contains(outputs, "test.jar") {
2550 t.Errorf("Module output does not contain expected jar %s", "test.jar")
2551 }
2552}
Mark Whitea15790a2023-08-22 21:28:11 +00002553
2554func TestHeadersOnly(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002555 t.Parallel()
Mark Whitea15790a2023-08-22 21:28:11 +00002556 ctx, _ := testJava(t, `
2557 java_library {
2558 name: "foo",
2559 srcs: ["a.java"],
2560 headers_only: true,
2561 }
2562 `)
2563
Colin Cross90607e92025-02-11 14:58:07 -08002564 turbine := ctx.ModuleForTests(t, "foo", "android_common").Rule("turbine")
Mark Whitea15790a2023-08-22 21:28:11 +00002565 if len(turbine.Inputs) != 1 || turbine.Inputs[0].String() != "a.java" {
2566 t.Errorf(`foo inputs %v != ["a.java"]`, turbine.Inputs)
2567 }
2568
Colin Cross90607e92025-02-11 14:58:07 -08002569 javac := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("javac")
Mark Whitea15790a2023-08-22 21:28:11 +00002570 android.AssertDeepEquals(t, "javac rule", nil, javac.Rule)
2571}
Jihoon Kangfdf32362023-09-12 00:36:43 +00002572
2573func TestJavaApiContributionImport(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002574 t.Parallel()
Jihoon Kang063ec002023-06-28 01:16:23 +00002575 ctx := android.GroupFixturePreparers(
2576 prepareForJavaTest,
2577 android.FixtureMergeEnv(
2578 map[string]string{
2579 "DISABLE_STUB_VALIDATION": "true",
2580 },
2581 ),
2582 ).RunTestWithBp(t, `
Jihoon Kangfdf32362023-09-12 00:36:43 +00002583 java_api_library {
2584 name: "foo",
2585 api_contributions: ["bar"],
Jihoon Kang5d701272024-02-15 21:53:49 +00002586 stubs_type: "everything",
Jihoon Kangfdf32362023-09-12 00:36:43 +00002587 }
2588 java_api_contribution_import {
2589 name: "bar",
2590 api_file: "current.txt",
Jihoon Kang8fe19822023-09-14 06:27:36 +00002591 api_surface: "public",
Jihoon Kangfdf32362023-09-12 00:36:43 +00002592 }
2593 `)
Colin Cross90607e92025-02-11 14:58:07 -08002594 m := ctx.ModuleForTests(t, "foo", "android_common")
Jihoon Kangfdf32362023-09-12 00:36:43 +00002595 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002596 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
Jihoon Kangfdf32362023-09-12 00:36:43 +00002597 manifestCommand := sboxProto.Commands[0].GetCommand()
2598 sourceFilesFlag := "--source-files current.txt"
2599 android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag)
2600}
Jihoon Kanga96a7b12023-09-20 23:43:32 +00002601
2602func TestJavaApiLibraryApiFilesSorting(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002603 t.Parallel()
Jihoon Kanga96a7b12023-09-20 23:43:32 +00002604 ctx, _ := testJava(t, `
2605 java_api_library {
2606 name: "foo",
2607 api_contributions: [
2608 "system-server-api-stubs-docs-non-updatable.api.contribution",
2609 "test-api-stubs-docs-non-updatable.api.contribution",
2610 "system-api-stubs-docs-non-updatable.api.contribution",
2611 "module-lib-api-stubs-docs-non-updatable.api.contribution",
2612 "api-stubs-docs-non-updatable.api.contribution",
2613 ],
Jihoon Kang5d701272024-02-15 21:53:49 +00002614 stubs_type: "everything",
Jihoon Kanga96a7b12023-09-20 23:43:32 +00002615 }
2616 `)
Colin Cross90607e92025-02-11 14:58:07 -08002617 m := ctx.ModuleForTests(t, "foo", "android_common")
Jihoon Kanga96a7b12023-09-20 23:43:32 +00002618 manifest := m.Output("metalava.sbox.textproto")
Colin Crossf61d03d2023-11-02 16:56:39 -07002619 sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest)
Jihoon Kanga96a7b12023-09-20 23:43:32 +00002620 manifestCommand := sboxProto.Commands[0].GetCommand()
2621
2622 // Api files are sorted from the narrowest api scope to the widest api scope.
2623 // test api and module lib api surface do not have subset/superset relationship,
2624 // but they will never be passed as inputs at the same time.
2625 sourceFilesFlag := "--source-files default/java/api/current.txt " +
2626 "default/java/api/system-current.txt default/java/api/test-current.txt " +
2627 "default/java/api/module-lib-current.txt default/java/api/system-server-current.txt"
2628 android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag)
2629}
Jihoon Kang4ec24872023-10-05 17:26:09 +00002630
2631func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002632 t.Parallel()
Jihoon Kang4ec24872023-10-05 17:26:09 +00002633 result := android.GroupFixturePreparers(
2634 prepareForJavaTest,
2635 PrepareForTestWithJavaSdkLibraryFiles,
2636 FixtureWithLastReleaseApis("foo"),
Jihoon Kang4ec24872023-10-05 17:26:09 +00002637 android.FixtureMergeMockFs(
2638 map[string][]byte{
2639 "A.java": nil,
2640 },
2641 ),
2642 ).RunTestWithBp(t, `
2643 java_library {
2644 name: "bar",
2645 srcs: ["a.java"],
2646 }
2647 java_system_modules {
2648 name: "baz",
2649 libs: ["bar"],
2650 }
2651 java_sdk_library {
2652 name: "foo",
2653 srcs: ["A.java"],
2654 system_modules: "baz",
2655 }
2656 `)
Jihoon Kangb0f4c022024-08-06 00:15:25 +00002657
2658 checkBootClasspathForLibWithSystemModule(t, result.TestContext, apiScopePublic.apiLibraryModuleName("foo"), "/bar.jar")
Jihoon Kang4ec24872023-10-05 17:26:09 +00002659}
Jihoon Kang063ec002023-06-28 01:16:23 +00002660
2661func TestApiLibraryDroidstubsDependency(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002662 t.Parallel()
Jihoon Kang063ec002023-06-28 01:16:23 +00002663 result := android.GroupFixturePreparers(
2664 prepareForJavaTest,
2665 PrepareForTestWithJavaSdkLibraryFiles,
2666 FixtureWithLastReleaseApis("foo"),
Jihoon Kang063ec002023-06-28 01:16:23 +00002667 android.FixtureMergeMockFs(
2668 map[string][]byte{
2669 "A.java": nil,
2670 },
2671 ),
2672 ).RunTestWithBp(t, `
2673 java_api_library {
2674 name: "foo",
2675 api_contributions: [
2676 "api-stubs-docs-non-updatable.api.contribution",
2677 ],
2678 enable_validation: true,
Jihoon Kang5d701272024-02-15 21:53:49 +00002679 stubs_type: "everything",
Jihoon Kang063ec002023-06-28 01:16:23 +00002680 }
2681 java_api_library {
2682 name: "bar",
2683 api_contributions: [
2684 "api-stubs-docs-non-updatable.api.contribution",
2685 ],
2686 enable_validation: false,
Jihoon Kang5d701272024-02-15 21:53:49 +00002687 stubs_type: "everything",
Jihoon Kang063ec002023-06-28 01:16:23 +00002688 }
2689 `)
2690
Jihoon Kang3c89f042023-12-19 02:40:22 +00002691 currentApiTimestampPath := "api-stubs-docs-non-updatable/android_common/everything/check_current_api.timestamp"
Colin Cross90607e92025-02-11 14:58:07 -08002692 foo := result.ModuleForTests(t, "foo", "android_common").Module().(*ApiLibrary)
Jihoon Kang063ec002023-06-28 01:16:23 +00002693 fooValidationPathsString := strings.Join(foo.validationPaths.Strings(), " ")
Colin Cross90607e92025-02-11 14:58:07 -08002694 bar := result.ModuleForTests(t, "bar", "android_common").Module().(*ApiLibrary)
Jihoon Kang063ec002023-06-28 01:16:23 +00002695 barValidationPathsString := strings.Join(bar.validationPaths.Strings(), " ")
2696 android.AssertStringDoesContain(t,
2697 "Module expected to have validation",
2698 fooValidationPathsString,
2699 currentApiTimestampPath,
2700 )
2701 android.AssertStringDoesNotContain(t,
2702 "Module expected to not have validation",
2703 barValidationPathsString,
2704 currentApiTimestampPath,
2705 )
2706}
Jihoon Kang1975d3e2023-10-16 23:24:11 +00002707
2708func TestDisableFromTextStubForCoverageBuild(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002709 t.Parallel()
Jihoon Kang1975d3e2023-10-16 23:24:11 +00002710 result := android.GroupFixturePreparers(
2711 prepareForJavaTest,
2712 PrepareForTestWithJavaSdkLibraryFiles,
2713 PrepareForTestWithJacocoInstrumentation,
2714 FixtureWithLastReleaseApis("foo"),
2715 android.FixtureModifyConfig(func(config android.Config) {
Jihoon Kang1975d3e2023-10-16 23:24:11 +00002716 config.SetBuildFromTextStub(true)
2717 }),
2718 android.FixtureModifyEnv(func(env map[string]string) {
2719 env["EMMA_INSTRUMENT"] = "true"
2720 }),
2721 ).RunTestWithBp(t, `
2722 java_sdk_library {
2723 name: "foo",
2724 srcs: ["A.java"],
2725 }
2726 `)
2727 android.AssertBoolEquals(t, "stub module expected to depend on from-source stub",
2728 true, CheckModuleHasDependency(t, result.TestContext,
2729 apiScopePublic.stubsLibraryModuleName("foo"), "android_common",
Jihoon Kang2261a822024-09-12 00:01:54 +00002730 apiScopePublic.sourceStubsLibraryModuleName("foo")))
Jihoon Kang1975d3e2023-10-16 23:24:11 +00002731
2732 android.AssertBoolEquals(t, "stub module expected to not depend on from-text stub",
2733 false, CheckModuleHasDependency(t, result.TestContext,
2734 apiScopePublic.stubsLibraryModuleName("foo"), "android_common",
2735 apiScopePublic.apiLibraryModuleName("foo")))
2736}
Spandan Das3cf04632024-01-19 00:22:22 +00002737
2738func TestMultiplePrebuilts(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002739 t.Parallel()
Spandan Das3cf04632024-01-19 00:22:22 +00002740 bp := `
2741 // an rdep
2742 java_library {
2743 name: "foo",
2744 libs: ["bar"],
2745 }
2746
2747 // multiple variations of dep
2748 // source
2749 java_library {
2750 name: "bar",
2751 srcs: ["bar.java"],
2752 }
2753 // prebuilt "v1"
2754 java_import {
2755 name: "bar",
2756 jars: ["bar.jar"],
2757 }
2758 // prebuilt "v2"
2759 java_import {
2760 name: "bar.v2",
2761 source_module_name: "bar",
2762 jars: ["bar.v1.jar"],
2763 }
2764
2765 // selectors
2766 apex_contributions {
2767 name: "myapex_contributions",
2768 contents: ["%v"],
2769 }
2770 `
2771 hasDep := func(ctx *android.TestResult, m android.Module, wantDep android.Module) bool {
2772 t.Helper()
2773 var found bool
2774 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
2775 if dep == wantDep {
2776 found = true
2777 }
2778 })
2779 return found
2780 }
2781
2782 hasFileWithStem := func(m android.TestingModule, stem string) bool {
2783 t.Helper()
2784 for _, o := range m.AllOutputs() {
2785 _, file := filepath.Split(o)
2786 if file == stem+".jar" {
2787 return true
2788 }
2789 }
2790 return false
2791 }
2792
2793 testCases := []struct {
2794 desc string
2795 selectedDependencyName string
2796 expectedDependencyName string
2797 }{
2798 {
2799 desc: "Source library is selected using apex_contributions",
2800 selectedDependencyName: "bar",
2801 expectedDependencyName: "bar",
2802 },
2803 {
2804 desc: "Prebuilt library v1 is selected using apex_contributions",
2805 selectedDependencyName: "prebuilt_bar",
2806 expectedDependencyName: "prebuilt_bar",
2807 },
2808 {
2809 desc: "Prebuilt library v2 is selected using apex_contributions",
2810 selectedDependencyName: "prebuilt_bar.v2",
2811 expectedDependencyName: "prebuilt_bar.v2",
2812 },
2813 }
2814
2815 for _, tc := range testCases {
2816 ctx := android.GroupFixturePreparers(
2817 prepareForJavaTest,
Colin Crossa66b4632024-08-08 15:50:47 -07002818 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"),
Spandan Das3cf04632024-01-19 00:22:22 +00002819 ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
2820
2821 // check that rdep gets the correct variation of dep
Colin Cross90607e92025-02-11 14:58:07 -08002822 foo := ctx.ModuleForTests(t, "foo", "android_common")
2823 expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_common")
Spandan Das3cf04632024-01-19 00:22:22 +00002824 android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module()))
2825
2826 // check that output file of dep is always bar.jar
2827 // The filename should be agnostic to source/prebuilt/prebuilt_version
2828 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"))
2829
2830 // check LOCAL_MODULE of the selected module name
2831 // the prebuilt should have the same LOCAL_MODULE when exported to make
2832 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, expectedDependency.Module())[0]
2833 android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "bar", entries.EntryMap["LOCAL_MODULE"][0])
2834 }
2835}
Jihoon Kang5d701272024-02-15 21:53:49 +00002836
Spandan Dase4c911e2024-01-19 00:22:22 +00002837func TestMultiplePlatformCompatConfigPrebuilts(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002838 t.Parallel()
Spandan Dase4c911e2024-01-19 00:22:22 +00002839 bp := `
2840 // multiple variations of platform_compat_config
2841 // source
2842 platform_compat_config {
2843 name: "myconfig",
2844 }
2845 // prebuilt "v1"
2846 prebuilt_platform_compat_config {
2847 name: "myconfig",
2848 metadata: "myconfig.xml",
2849 }
2850 // prebuilt "v2"
2851 prebuilt_platform_compat_config {
2852 name: "myconfig.v2",
2853 source_module_name: "myconfig", // without source_module_name, the singleton will merge two .xml files
2854 metadata: "myconfig.v2.xml",
2855 }
2856
2857 // selectors
2858 apex_contributions {
2859 name: "myapex_contributions",
2860 contents: ["%v"],
2861 }
2862 `
2863 testCases := []struct {
2864 desc string
2865 selectedDependencyName string
2866 expectedPlatformCompatConfigXml string
2867 }{
2868 {
2869 desc: "Source platform_compat_config is selected using apex_contributions",
2870 selectedDependencyName: "myconfig",
2871 expectedPlatformCompatConfigXml: "out/soong/.intermediates/myconfig/android_common/myconfig_meta.xml",
2872 },
2873 {
2874 desc: "Prebuilt platform_compat_config v1 is selected using apex_contributions",
2875 selectedDependencyName: "prebuilt_myconfig",
2876 expectedPlatformCompatConfigXml: "myconfig.xml",
2877 },
2878 {
2879 desc: "Prebuilt platform_compat_config v2 is selected using apex_contributions",
2880 selectedDependencyName: "prebuilt_myconfig.v2",
2881 expectedPlatformCompatConfigXml: "myconfig.v2.xml",
2882 },
2883 }
2884
2885 for _, tc := range testCases {
2886 ctx := android.GroupFixturePreparers(
2887 prepareForJavaTest,
2888 PrepareForTestWithPlatformCompatConfig,
Colin Crossa66b4632024-08-08 15:50:47 -07002889 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"),
Spandan Dase4c911e2024-01-19 00:22:22 +00002890 ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
2891
Colin Cross90607e92025-02-11 14:58:07 -08002892 mergedGlobalConfig := ctx.SingletonForTests(t, "platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml")
Spandan Dase4c911e2024-01-19 00:22:22 +00002893 android.AssertIntEquals(t, "The merged compat config file should only have a single dependency", 1, len(mergedGlobalConfig.Implicits))
2894 android.AssertStringEquals(t, "The merged compat config file is missing the appropriate platform compat config", mergedGlobalConfig.Implicits[0].String(), tc.expectedPlatformCompatConfigXml)
2895 }
2896}
2897
Jihoon Kang5d701272024-02-15 21:53:49 +00002898func TestApiLibraryAconfigDeclarations(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002899 t.Parallel()
Jihoon Kang5d701272024-02-15 21:53:49 +00002900 result := android.GroupFixturePreparers(
2901 prepareForJavaTest,
2902 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2903 }),
2904 android.FixtureMergeMockFs(map[string][]byte{
2905 "a/A.java": nil,
2906 "a/current.txt": nil,
2907 "a/removed.txt": nil,
2908 }),
2909 ).RunTestWithBp(t, `
2910 aconfig_declarations {
2911 name: "bar",
2912 package: "com.example.package",
Yu Liu315a53c2024-04-24 16:41:57 +00002913 container: "com.android.foo",
Jihoon Kang5d701272024-02-15 21:53:49 +00002914 srcs: [
2915 "bar.aconfig",
2916 ],
2917 }
2918 java_api_contribution {
2919 name: "baz",
2920 api_file: "a/current.txt",
2921 api_surface: "public",
2922 }
2923 java_api_library {
2924 name: "foo",
2925 api_surface: "public",
2926 api_contributions: [
2927 "baz",
2928 ],
2929 aconfig_declarations: [
2930 "bar",
2931 ],
2932 stubs_type: "exportable",
2933 enable_validation: false,
2934 }
2935 `)
2936
2937 // Check if java_api_library depends on aconfig_declarations
2938 android.AssertBoolEquals(t, "foo expected to depend on bar",
2939 CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
2940
Colin Cross90607e92025-02-11 14:58:07 -08002941 m := result.ModuleForTests(t, "foo", "android_common")
Jihoon Kang5d701272024-02-15 21:53:49 +00002942 android.AssertStringDoesContain(t, "foo generates revert annotations file",
2943 strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
2944
2945 // revert-annotations.txt passed to exportable stubs generation metalava command
2946 manifest := m.Output("metalava.sbox.textproto")
2947 cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
2948 android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
2949}
yangbill2af0b6e2024-03-15 09:29:29 +00002950
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07002951func TestTestOnly(t *testing.T) {
2952 t.Parallel()
2953 ctx := android.GroupFixturePreparers(
2954 prepareForJavaTest,
2955 ).RunTestWithBp(t, `
2956 // These should be test-only
2957 java_library {
2958 name: "lib1-test-only",
2959 srcs: ["a.java"],
2960 test_only: true,
2961 }
2962 java_test {
2963 name: "java-test",
2964 }
2965 java_test_host {
2966 name: "java-test-host",
2967 }
2968 java_test_helper_library {
2969 name: "helper-library",
2970 }
2971 java_binary {
2972 name: "java-data-binary",
2973 srcs: ["foo.java"],
2974 main_class: "foo.bar.jb",
2975 test_only: true,
2976 }
2977
2978 // These are NOT
2979 java_library {
2980 name: "lib2-app",
2981 srcs: ["b.java"],
2982 }
2983 java_import {
2984 name: "bar",
2985 jars: ["bar.jar"],
2986 }
2987 java_binary {
2988 name: "java-binary",
2989 srcs: ["foo.java"],
2990 main_class: "foo.bar.jb",
2991 }
2992 `)
2993
2994 expectedTestOnlyModules := []string{
2995 "lib1-test-only",
2996 "java-test",
2997 "java-test-host",
2998 "helper-library",
2999 "java-data-binary",
3000 }
3001 expectedTopLevelTests := []string{
3002 "java-test",
3003 "java-test-host",
3004 }
3005 assertTestOnlyAndTopLevel(t, ctx, expectedTestOnlyModules, expectedTopLevelTests)
3006}
3007
3008// Don't allow setting test-only on things that are always tests or never tests.
3009func TestInvalidTestOnlyTargets(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003010 t.Parallel()
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07003011 testCases := []string{
3012 ` java_test { name: "java-test", test_only: true, srcs: ["foo.java"], } `,
3013 ` java_test_host { name: "java-test-host", test_only: true, srcs: ["foo.java"], } `,
3014 ` java_test_import { name: "java-test-import", test_only: true, } `,
3015 ` java_api_library { name: "java-api-library", test_only: true, } `,
3016 ` java_test_helper_library { name: "test-help-lib", test_only: true, } `,
3017 ` java_defaults { name: "java-defaults", test_only: true, } `,
3018 }
3019
3020 for i, bp := range testCases {
3021 android.GroupFixturePreparers(prepareForJavaTest).
3022 ExtendWithErrorHandler(
3023 expectOneError("unrecognized property \"test_only\"",
3024 fmt.Sprintf("testcase: %d", i))).
3025 RunTestWithBp(t, bp)
3026 }
3027}
3028
3029// Expect exactly one that matches 'expected'.
3030// Append 'msg' to the Errorf that printed.
3031func expectOneError(expected string, msg string) android.FixtureErrorHandler {
3032 return android.FixtureCustomErrorHandler(func(t *testing.T, result *android.TestResult) {
3033 t.Helper()
3034 if len(result.Errs) != 1 {
3035 t.Errorf("Expected exactly one error, but found: %d when setting test_only on: %s", len(result.Errs), msg)
3036 return
3037 }
3038 actualErrMsg := result.Errs[0].Error()
3039 if !strings.Contains(actualErrMsg, expected) {
3040 t.Errorf("Different error than expected. Received: [%v] on %s expected: %s", actualErrMsg, msg, expected)
3041 }
3042 })
3043}
3044
yangbill2af0b6e2024-03-15 09:29:29 +00003045func TestJavaLibHostWithStem(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003046 t.Parallel()
yangbill2af0b6e2024-03-15 09:29:29 +00003047 ctx, _ := testJava(t, `
3048 java_library_host {
3049 name: "foo",
3050 srcs: ["a.java"],
3051 stem: "foo-new",
3052 }
3053 `)
3054
3055 buildOS := ctx.Config().BuildOS.String()
Colin Cross90607e92025-02-11 14:58:07 -08003056 foo := ctx.ModuleForTests(t, "foo", buildOS+"_common")
yangbill2af0b6e2024-03-15 09:29:29 +00003057
3058 outputs := fmt.Sprint(foo.AllOutputs())
3059 if !strings.Contains(outputs, "foo-new.jar") {
3060 t.Errorf("Module output does not contain expected jar %s", "foo-new.jar")
3061 }
3062}
3063
3064func TestJavaLibWithStem(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003065 t.Parallel()
yangbill2af0b6e2024-03-15 09:29:29 +00003066 ctx, _ := testJava(t, `
3067 java_library {
3068 name: "foo",
3069 srcs: ["a.java"],
3070 stem: "foo-new",
3071 }
3072 `)
3073
Colin Cross90607e92025-02-11 14:58:07 -08003074 foo := ctx.ModuleForTests(t, "foo", "android_common")
yangbill2af0b6e2024-03-15 09:29:29 +00003075
3076 outputs := fmt.Sprint(foo.AllOutputs())
3077 if !strings.Contains(outputs, "foo-new.jar") {
3078 t.Errorf("Module output does not contain expected jar %s", "foo-new.jar")
3079 }
3080}
Colin Cross5e87f342024-04-11 15:28:18 -07003081
3082func TestJavaLibraryOutputFilesRel(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003083 t.Parallel()
Colin Cross5e87f342024-04-11 15:28:18 -07003084 result := android.GroupFixturePreparers(
3085 PrepareForTestWithJavaDefaultModules,
3086 ).RunTestWithBp(t, `
3087 java_library {
3088 name: "foo",
3089 srcs: ["a.java"],
3090 }
3091
3092 java_import {
3093 name: "bar",
3094 jars: ["bar.aar"],
3095
3096 }
3097
3098 java_import {
3099 name: "baz",
3100 jars: ["baz.aar"],
3101 static_libs: ["bar"],
3102 }
3103 `)
3104
Colin Cross90607e92025-02-11 14:58:07 -08003105 foo := result.ModuleForTests(t, "foo", "android_common")
3106 bar := result.ModuleForTests(t, "bar", "android_common")
3107 baz := result.ModuleForTests(t, "baz", "android_common")
Colin Cross5e87f342024-04-11 15:28:18 -07003108
Yu Liu51c22312024-08-20 23:56:15 +00003109 fooOutputPaths := foo.OutputFiles(result.TestContext, t, "")
3110 barOutputPaths := bar.OutputFiles(result.TestContext, t, "")
3111 bazOutputPaths := baz.OutputFiles(result.TestContext, t, "")
Colin Cross5e87f342024-04-11 15:28:18 -07003112
mrziwang9f7b9f42024-07-10 12:18:06 -07003113 android.AssertPathsRelativeToTopEquals(t, "foo output path",
3114 []string{"out/soong/.intermediates/foo/android_common/javac/foo.jar"}, fooOutputPaths)
mrziwang68786d82024-07-09 10:41:55 -07003115 android.AssertPathsRelativeToTopEquals(t, "bar output path",
3116 []string{"out/soong/.intermediates/bar/android_common/combined/bar.jar"}, barOutputPaths)
3117 android.AssertPathsRelativeToTopEquals(t, "baz output path",
3118 []string{"out/soong/.intermediates/baz/android_common/combined/baz.jar"}, bazOutputPaths)
Colin Cross5e87f342024-04-11 15:28:18 -07003119
3120 android.AssertStringEquals(t, "foo relative output path",
mrziwang9f7b9f42024-07-10 12:18:06 -07003121 "foo.jar", fooOutputPaths[0].Rel())
Colin Cross5e87f342024-04-11 15:28:18 -07003122 android.AssertStringEquals(t, "bar relative output path",
mrziwang68786d82024-07-09 10:41:55 -07003123 "bar.jar", barOutputPaths[0].Rel())
Colin Cross5e87f342024-04-11 15:28:18 -07003124 android.AssertStringEquals(t, "baz relative output path",
mrziwang68786d82024-07-09 10:41:55 -07003125 "baz.jar", bazOutputPaths[0].Rel())
Colin Cross5e87f342024-04-11 15:28:18 -07003126}
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07003127
Colin Crossb323c912024-09-24 15:21:00 -07003128func TestCoverage(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003129 t.Parallel()
Colin Crossb323c912024-09-24 15:21:00 -07003130 result := android.GroupFixturePreparers(
3131 PrepareForTestWithJavaDefaultModules,
3132 prepareForTestWithFrameworkJacocoInstrumentation,
3133 PrepareForTestWithTransitiveClasspathEnabled,
3134 ).RunTestWithBp(t, `
3135 android_app {
3136 name: "foo",
3137 srcs: ["foo.java"],
3138 static_libs: ["android.car"],
3139 platform_apis: true,
3140 }
3141
3142 // A library in InstrumentFrameworkModules
3143 java_library {
3144 name: "android.car",
3145 srcs: ["android.car.java"],
Colin Cross41698982024-11-13 11:31:31 -08003146 installable: true,
Colin Crossb323c912024-09-24 15:21:00 -07003147 }
3148 `)
3149
Colin Cross90607e92025-02-11 14:58:07 -08003150 foo := result.ModuleForTests(t, "foo", "android_common")
3151 androidCar := result.ModuleForTests(t, "android.car", "android_common")
Colin Crossb323c912024-09-24 15:21:00 -07003152
3153 fooJacoco := foo.Rule("jacoco")
3154 fooCombine := foo.Description("for javac")
3155
3156 androidCarJacoco := androidCar.Rule("jacoco")
3157 androidCarJavac := androidCar.Rule("javac")
3158
3159 android.AssertStringEquals(t, "foo instrumentation rule inputs", fooJacoco.Input.String(), fooCombine.Output.String())
3160 android.AssertStringEquals(t, "android.car instrumentation rule inputs", androidCarJacoco.Input.String(), androidCarJavac.Output.String())
3161
3162 // The input to instrumentation for the `foo` app contains the non-instrumented android.car classes.
3163 android.AssertStringListContains(t, "foo combined inputs", fooCombine.Inputs.Strings(), androidCarJavac.Output.String())
3164 android.AssertStringListDoesNotContain(t, "foo combined inputs", fooCombine.Inputs.Strings(), androidCarJacoco.Output.String())
3165}
3166
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07003167func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) {
3168 t.Helper()
3169 actualTrueModules := []string{}
3170 actualTopLevelTests := []string{}
3171 addActuals := func(m blueprint.Module, key blueprint.ProviderKey[android.TestModuleInformation]) {
3172 if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, key); ok {
3173 if provider.TestOnly {
3174 actualTrueModules = append(actualTrueModules, m.Name())
3175 }
3176 if provider.TopLevelTarget {
3177 actualTopLevelTests = append(actualTopLevelTests, m.Name())
3178 }
3179 }
3180 }
3181
3182 ctx.VisitAllModules(func(m blueprint.Module) {
3183 addActuals(m, android.TestOnlyProviderKey)
3184
3185 })
3186
3187 notEqual, left, right := android.ListSetDifference(expectedTestOnly, actualTrueModules)
3188 if notEqual {
3189 t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
3190 }
3191
3192 notEqual, left, right = android.ListSetDifference(expectedTopLevel, actualTopLevelTests)
3193 if notEqual {
3194 t.Errorf("top-level: Expected but not found: %v, Found but not expected: %v", left, right)
3195 }
3196}
Spandan Das77e27d42024-09-26 23:53:58 +00003197
Spandan Dase42c5d92024-10-03 22:39:52 +00003198// Test that a dependency edge is created to the matching variant of a native library listed in `jni_libs` of java_binary
Spandan Das77e27d42024-09-26 23:53:58 +00003199func TestNativeRequiredDepOfJavaBinary(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003200 t.Parallel()
Spandan Das77e27d42024-09-26 23:53:58 +00003201 findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module {
3202 var ret []blueprint.Module
3203 ctx.VisitDirectDeps(module, func(dep blueprint.Module) {
3204 if dep.Name() == depName {
3205 ret = append(ret, dep)
3206 }
3207 })
3208 return ret
3209 }
3210
3211 bp := cc.GatherRequiredDepsForTest(android.Android) + `
3212java_binary {
3213 name: "myjavabin",
3214 main_class: "com.android.MyJava",
Spandan Dase42c5d92024-10-03 22:39:52 +00003215 jni_libs: ["mynativelib"],
Spandan Das77e27d42024-09-26 23:53:58 +00003216}
3217cc_library_shared {
3218 name: "mynativelib",
3219}
3220`
3221 res, _ := testJava(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08003222 deps := findDepsOfModule(res, res.ModuleForTests(t, "myjavabin", "android_common").Module(), "mynativelib")
Cole Faustb9c67e22024-10-08 16:39:56 -07003223 android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(deps))
Spandan Das77e27d42024-09-26 23:53:58 +00003224}