blob: 040adb440dfb6004573bf14c90481999353105f7 [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 (
18 "android/soong/android"
19 "fmt"
20 "io/ioutil"
21 "os"
22 "path/filepath"
Colin Cross227d4362017-08-30 14:14:52 -070023 "reflect"
Colin Cross72bb3632017-07-13 16:23:21 -070024 "strings"
25 "testing"
26)
27
28var buildDir string
29
30func setUp() {
31 var err error
32 buildDir, err = ioutil.TempDir("", "soong_java_test")
33 if err != nil {
34 panic(err)
35 }
36}
37
38func tearDown() {
39 os.RemoveAll(buildDir)
40}
41
42func TestMain(m *testing.M) {
43 run := func() int {
44 setUp()
45 defer tearDown()
46
47 return m.Run()
48 }
49
50 os.Exit(run())
51}
52
53func testJava(t *testing.T, bp string) *android.TestContext {
Colin Cross4c428df2017-09-15 17:36:05 -070054 config := android.TestArchConfig(buildDir)
Colin Cross72bb3632017-07-13 16:23:21 -070055
Colin Cross4c428df2017-09-15 17:36:05 -070056 ctx := android.NewTestArchContext()
Colin Cross72bb3632017-07-13 16:23:21 -070057 ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory))
Colin Crossf506d872017-07-19 15:53:04 -070058 ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(LibraryFactory))
Colin Cross2acdae82017-09-15 19:44:24 -070059 ctx.RegisterModuleType("java_library_host", android.ModuleFactoryAdaptor(LibraryHostFactory))
Colin Cross74d73e22017-08-02 11:05:49 -070060 ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(ImportFactory))
Colin Cross89536d42017-07-07 14:35:50 -070061 ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
Colin Cross2acdae82017-09-15 19:44:24 -070062 ctx.RegisterModuleType("android_prebuilt_sdk", android.ModuleFactoryAdaptor(SdkPrebuiltFactory))
Colin Cross5ea9bcc2017-07-27 15:41:32 -070063 ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
64 ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
Colin Cross89536d42017-07-07 14:35:50 -070065 ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
Colin Cross72bb3632017-07-13 16:23:21 -070066 ctx.Register()
67
Colin Cross4c428df2017-09-15 17:36:05 -070068 extraModules := []string{
69 "core-oj",
70 "core-libart",
71 "framework",
72 "ext",
73 "okhttp",
Colin Cross2acdae82017-09-15 19:44:24 -070074 "android_stubs_current",
75 "android_system_stubs_current",
76 "android_test_stubs_current",
Colin Cross4c428df2017-09-15 17:36:05 -070077 }
Colin Cross72bb3632017-07-13 16:23:21 -070078
79 for _, extra := range extraModules {
80 bp += fmt.Sprintf(`
81 java_library {
82 name: "%s",
Colin Cross0a6e0072017-08-30 14:24:55 -070083 srcs: ["a.java"],
Colin Cross76b5f0c2017-08-29 16:02:06 -070084 no_standard_libs: true,
Colin Cross72bb3632017-07-13 16:23:21 -070085 }
86 `, extra)
87 }
88
Colin Cross2acdae82017-09-15 19:44:24 -070089 bp += `
90 android_prebuilt_sdk {
91 name: "sdk_v14",
92 jars: ["sdk_v14.jar"],
93 }
94 `
95
Colin Cross72bb3632017-07-13 16:23:21 -070096 ctx.MockFileSystem(map[string][]byte{
Colin Cross2acdae82017-09-15 19:44:24 -070097 "Android.bp": []byte(bp),
98 "a.java": nil,
99 "b.java": nil,
100 "c.java": nil,
101 "a.jar": nil,
102 "b.jar": nil,
103 "sdk_v14.jar": nil,
Colin Cross72bb3632017-07-13 16:23:21 -0700104 })
105
106 _, errs := ctx.ParseBlueprintsFiles("Android.bp")
107 fail(t, errs)
108 _, errs = ctx.PrepareBuildActions(config)
109 fail(t, errs)
110
111 return ctx
112}
113
Colin Cross2acdae82017-09-15 19:44:24 -0700114func moduleToPath(name string) string {
115 switch {
116 case name == `""`:
117 return name
118 case strings.HasPrefix(name, "sdk_v"):
119 return name + ".jar"
120 default:
121 return filepath.Join(buildDir, ".intermediates", name, "android_common", "classes-desugar.jar")
122 }
123}
124
Colin Cross72bb3632017-07-13 16:23:21 -0700125func TestSimple(t *testing.T) {
126 ctx := testJava(t, `
127 java_library {
128 name: "foo",
129 srcs: ["a.java"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700130 libs: ["bar"],
131 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700132 }
133
134 java_library {
135 name: "bar",
136 srcs: ["b.java"],
137 }
138
139 java_library {
140 name: "baz",
141 srcs: ["c.java"],
142 }
143 `)
144
Colin Cross4c428df2017-09-15 17:36:05 -0700145 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
146 combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
Colin Cross72bb3632017-07-13 16:23:21 -0700147
148 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
149 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
150 }
151
Colin Cross4c428df2017-09-15 17:36:05 -0700152 bar := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "classes-desugar.jar")
153 baz := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "classes-desugar.jar")
Colin Cross0a6e0072017-08-30 14:24:55 -0700154
Colin Cross72bb3632017-07-13 16:23:21 -0700155 if !strings.Contains(javac.Args["classpath"], bar) {
156 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
157 }
158
Colin Cross0a6e0072017-08-30 14:24:55 -0700159 if !strings.Contains(javac.Args["classpath"], baz) {
160 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], baz)
161 }
162
163 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
164 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross72bb3632017-07-13 16:23:21 -0700165 }
166}
167
Colin Cross2acdae82017-09-15 19:44:24 -0700168var classpathTestcases = []struct {
169 name string
170 host android.OsClass
171 properties string
172 bootclasspath []string
173 classpath []string
174}{
175 {
176 name: "default",
177 bootclasspath: []string{"core-oj", "core-libart"},
178 classpath: []string{"ext", "framework", "okhttp"},
179 },
180 {
181 name: "blank sdk version",
182 properties: `sdk_version: "",`,
183 bootclasspath: []string{"core-oj", "core-libart"},
184 classpath: []string{"ext", "framework", "okhttp"},
185 },
186 {
Colin Cross4c428df2017-09-15 17:36:05 -0700187
Colin Cross2acdae82017-09-15 19:44:24 -0700188 name: "sdk v14",
189 properties: `sdk_version: "14",`,
190 bootclasspath: []string{"sdk_v14"},
191 classpath: []string{},
192 },
193 {
Colin Cross72bb3632017-07-13 16:23:21 -0700194
Colin Cross2acdae82017-09-15 19:44:24 -0700195 name: "current",
196 properties: `sdk_version: "current",`,
197 bootclasspath: []string{"android_stubs_current"},
198 classpath: []string{},
199 },
200 {
Colin Cross72bb3632017-07-13 16:23:21 -0700201
Colin Cross2acdae82017-09-15 19:44:24 -0700202 name: "system_current",
203 properties: `sdk_version: "system_current",`,
204 bootclasspath: []string{"android_system_stubs_current"},
205 classpath: []string{},
206 },
207 {
Colin Cross72bb3632017-07-13 16:23:21 -0700208
Colin Cross2acdae82017-09-15 19:44:24 -0700209 name: "test_current",
210 properties: `sdk_version: "test_current",`,
211 bootclasspath: []string{"android_test_stubs_current"},
212 classpath: []string{},
213 },
214 {
Colin Cross72bb3632017-07-13 16:23:21 -0700215
Colin Cross2acdae82017-09-15 19:44:24 -0700216 name: "nostdlib",
217 properties: `no_standard_libs: true`,
218 bootclasspath: []string{`""`},
219 classpath: []string{},
220 },
221 {
Colin Cross72bb3632017-07-13 16:23:21 -0700222
Colin Cross2acdae82017-09-15 19:44:24 -0700223 name: "host default",
224 host: android.Host,
225 properties: ``,
226 classpath: []string{},
227 },
228 {
229 name: "host nostdlib",
230 host: android.Host,
231 properties: `no_standard_libs: true`,
232 classpath: []string{},
233 },
234}
Colin Cross72bb3632017-07-13 16:23:21 -0700235
Colin Cross2acdae82017-09-15 19:44:24 -0700236func TestClasspath(t *testing.T) {
237 for _, testcase := range classpathTestcases {
238 t.Run(testcase.name, func(t *testing.T) {
239 hostExtra := ""
240 if testcase.host == android.Host {
241 hostExtra = "_host"
242 }
243 ctx := testJava(t, `
244 java_library`+hostExtra+` {
245 name: "foo",
246 srcs: ["a.java"],
247 `+testcase.properties+`
248 }
249 `)
Colin Cross72bb3632017-07-13 16:23:21 -0700250
Colin Cross2acdae82017-09-15 19:44:24 -0700251 convertModulesToPaths := func(cp []string) []string {
252 ret := make([]string, len(cp))
253 for i, e := range cp {
254 ret[i] = moduleToPath(e)
255 }
256 return ret
257 }
Colin Cross72bb3632017-07-13 16:23:21 -0700258
Colin Cross2acdae82017-09-15 19:44:24 -0700259 bootclasspath := convertModulesToPaths(testcase.bootclasspath)
260 classpath := convertModulesToPaths(testcase.classpath)
Colin Cross72bb3632017-07-13 16:23:21 -0700261
Colin Cross2acdae82017-09-15 19:44:24 -0700262 variant := "android_common"
263 if testcase.host == android.Host {
264 variant = android.BuildOs.String() + "_common"
265 }
266 javac := ctx.ModuleForTests("foo", variant).Rule("javac")
267
Colin Cross72bb3632017-07-13 16:23:21 -0700268 got := strings.TrimPrefix(javac.Args["bootClasspath"], "-bootclasspath ")
Colin Cross2acdae82017-09-15 19:44:24 -0700269 bc := strings.Join(bootclasspath, ":")
270 if got != bc {
271 t.Errorf("bootclasspath expected %q != got %q", bc, got)
Colin Cross72bb3632017-07-13 16:23:21 -0700272 }
Colin Cross72bb3632017-07-13 16:23:21 -0700273
Colin Cross2acdae82017-09-15 19:44:24 -0700274 got = strings.TrimPrefix(javac.Args["classpath"], "-classpath ")
275 c := strings.Join(classpath, ":")
276 if got != c {
277 t.Errorf("classpath expected %q != got %q", c, got)
278 }
279
280 var deps []string
281 if len(bootclasspath) > 0 && bootclasspath[0] != `""` {
282 deps = append(deps, bootclasspath...)
283 }
284 deps = append(deps, classpath...)
285
286 if !reflect.DeepEqual(javac.Implicits.Strings(), deps) {
287 t.Errorf("implicits expected %q != got %q", deps, javac.Implicits.Strings())
288 }
289 })
Colin Cross72bb3632017-07-13 16:23:21 -0700290 }
291
Colin Cross72bb3632017-07-13 16:23:21 -0700292}
293
294func TestPrebuilts(t *testing.T) {
295 ctx := testJava(t, `
296 java_library {
297 name: "foo",
298 srcs: ["a.java"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700299 libs: ["bar"],
300 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700301 }
302
Colin Cross74d73e22017-08-02 11:05:49 -0700303 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700304 name: "bar",
Colin Cross74d73e22017-08-02 11:05:49 -0700305 jars: ["a.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700306 }
307
Colin Cross74d73e22017-08-02 11:05:49 -0700308 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700309 name: "baz",
Colin Cross74d73e22017-08-02 11:05:49 -0700310 jars: ["b.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700311 }
312 `)
313
Colin Cross4c428df2017-09-15 17:36:05 -0700314 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
315 combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
Colin Cross72bb3632017-07-13 16:23:21 -0700316
317 bar := "a.jar"
318 if !strings.Contains(javac.Args["classpath"], bar) {
319 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
320 }
321
Colin Cross0a6e0072017-08-30 14:24:55 -0700322 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != "b.jar" {
323 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, "b.jar")
Colin Cross72bb3632017-07-13 16:23:21 -0700324 }
325}
326
Colin Cross89536d42017-07-07 14:35:50 -0700327func TestDefaults(t *testing.T) {
328 ctx := testJava(t, `
329 java_defaults {
330 name: "defaults",
331 srcs: ["a.java"],
332 libs: ["bar"],
333 static_libs: ["baz"],
334 }
335
336 java_library {
337 name: "foo",
338 defaults: ["defaults"],
339 }
340
341 java_library {
342 name: "bar",
343 srcs: ["b.java"],
344 }
345
346 java_library {
347 name: "baz",
348 srcs: ["c.java"],
349 }
350 `)
351
Colin Cross4c428df2017-09-15 17:36:05 -0700352 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
353 combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
Colin Cross89536d42017-07-07 14:35:50 -0700354
355 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
356 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
357 }
358
Colin Cross4c428df2017-09-15 17:36:05 -0700359 bar := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "classes-desugar.jar")
Colin Cross89536d42017-07-07 14:35:50 -0700360 if !strings.Contains(javac.Args["classpath"], bar) {
361 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
362 }
363
Colin Cross4c428df2017-09-15 17:36:05 -0700364 baz := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "classes-desugar.jar")
Colin Cross0a6e0072017-08-30 14:24:55 -0700365 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
366 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross89536d42017-07-07 14:35:50 -0700367 }
368}
369
Colin Cross72bb3632017-07-13 16:23:21 -0700370func fail(t *testing.T, errs []error) {
371 if len(errs) > 0 {
372 for _, err := range errs {
373 t.Error(err)
374 }
375 t.FailNow()
376 }
377}