blob: 7159e3f4f5cf0011225ebac5b31dc50deac336c5 [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 Cross5ea9bcc2017-07-27 15:41:32 -070062 ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
63 ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
Colin Cross89536d42017-07-07 14:35:50 -070064 ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
Colin Cross72bb3632017-07-13 16:23:21 -070065 ctx.Register()
66
Colin Cross4c428df2017-09-15 17:36:05 -070067 extraModules := []string{
68 "core-oj",
69 "core-libart",
70 "framework",
71 "ext",
72 "okhttp",
Colin Cross2acdae82017-09-15 19:44:24 -070073 "android_stubs_current",
74 "android_system_stubs_current",
75 "android_test_stubs_current",
Colin Cross4c428df2017-09-15 17:36:05 -070076 }
Colin Cross72bb3632017-07-13 16:23:21 -070077
78 for _, extra := range extraModules {
79 bp += fmt.Sprintf(`
80 java_library {
81 name: "%s",
Colin Cross0a6e0072017-08-30 14:24:55 -070082 srcs: ["a.java"],
Colin Cross76b5f0c2017-08-29 16:02:06 -070083 no_standard_libs: true,
Colin Cross72bb3632017-07-13 16:23:21 -070084 }
85 `, extra)
86 }
87
88 ctx.MockFileSystem(map[string][]byte{
Colin Crossfc3674a2017-09-18 17:41:52 -070089 "Android.bp": []byte(bp),
90 "a.java": nil,
91 "b.java": nil,
92 "c.java": nil,
93 "a.jar": nil,
94 "b.jar": nil,
95 "prebuilts/sdk/14/android.jar": nil,
96 "prebuilts/sdk/14/framework.aidl": nil,
Colin Cross72bb3632017-07-13 16:23:21 -070097 })
98
99 _, errs := ctx.ParseBlueprintsFiles("Android.bp")
100 fail(t, errs)
101 _, errs = ctx.PrepareBuildActions(config)
102 fail(t, errs)
103
104 return ctx
105}
106
Colin Cross2acdae82017-09-15 19:44:24 -0700107func moduleToPath(name string) string {
108 switch {
109 case name == `""`:
110 return name
Colin Crossfc3674a2017-09-18 17:41:52 -0700111 case strings.HasSuffix(name, ".jar"):
112 return name
Colin Cross2acdae82017-09-15 19:44:24 -0700113 default:
114 return filepath.Join(buildDir, ".intermediates", name, "android_common", "classes-desugar.jar")
115 }
116}
117
Colin Cross72bb3632017-07-13 16:23:21 -0700118func TestSimple(t *testing.T) {
119 ctx := testJava(t, `
120 java_library {
121 name: "foo",
122 srcs: ["a.java"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700123 libs: ["bar"],
124 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700125 }
126
127 java_library {
128 name: "bar",
129 srcs: ["b.java"],
130 }
131
132 java_library {
133 name: "baz",
134 srcs: ["c.java"],
135 }
136 `)
137
Colin Cross4c428df2017-09-15 17:36:05 -0700138 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
139 combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
Colin Cross72bb3632017-07-13 16:23:21 -0700140
141 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
142 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
143 }
144
Colin Cross4c428df2017-09-15 17:36:05 -0700145 bar := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "classes-desugar.jar")
146 baz := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "classes-desugar.jar")
Colin Cross0a6e0072017-08-30 14:24:55 -0700147
Colin Cross72bb3632017-07-13 16:23:21 -0700148 if !strings.Contains(javac.Args["classpath"], bar) {
149 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
150 }
151
Colin Cross0a6e0072017-08-30 14:24:55 -0700152 if !strings.Contains(javac.Args["classpath"], baz) {
153 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], baz)
154 }
155
156 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
157 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross72bb3632017-07-13 16:23:21 -0700158 }
159}
160
Colin Cross2acdae82017-09-15 19:44:24 -0700161var classpathTestcases = []struct {
162 name string
163 host android.OsClass
164 properties string
165 bootclasspath []string
166 classpath []string
167}{
168 {
169 name: "default",
170 bootclasspath: []string{"core-oj", "core-libart"},
171 classpath: []string{"ext", "framework", "okhttp"},
172 },
173 {
174 name: "blank sdk version",
175 properties: `sdk_version: "",`,
176 bootclasspath: []string{"core-oj", "core-libart"},
177 classpath: []string{"ext", "framework", "okhttp"},
178 },
179 {
Colin Cross4c428df2017-09-15 17:36:05 -0700180
Colin Cross2acdae82017-09-15 19:44:24 -0700181 name: "sdk v14",
182 properties: `sdk_version: "14",`,
Colin Crossfc3674a2017-09-18 17:41:52 -0700183 bootclasspath: []string{`""`},
184 classpath: []string{"prebuilts/sdk/14/android.jar"},
Colin Cross2acdae82017-09-15 19:44:24 -0700185 },
186 {
Colin Cross72bb3632017-07-13 16:23:21 -0700187
Colin Cross2acdae82017-09-15 19:44:24 -0700188 name: "current",
189 properties: `sdk_version: "current",`,
190 bootclasspath: []string{"android_stubs_current"},
191 classpath: []string{},
192 },
193 {
Colin Cross72bb3632017-07-13 16:23:21 -0700194
Colin Cross2acdae82017-09-15 19:44:24 -0700195 name: "system_current",
196 properties: `sdk_version: "system_current",`,
197 bootclasspath: []string{"android_system_stubs_current"},
198 classpath: []string{},
199 },
200 {
Colin Cross72bb3632017-07-13 16:23:21 -0700201
Colin Cross2acdae82017-09-15 19:44:24 -0700202 name: "test_current",
203 properties: `sdk_version: "test_current",`,
204 bootclasspath: []string{"android_test_stubs_current"},
205 classpath: []string{},
206 },
207 {
Colin Cross72bb3632017-07-13 16:23:21 -0700208
Colin Cross2acdae82017-09-15 19:44:24 -0700209 name: "nostdlib",
210 properties: `no_standard_libs: true`,
211 bootclasspath: []string{`""`},
212 classpath: []string{},
213 },
214 {
Colin Cross72bb3632017-07-13 16:23:21 -0700215
Colin Cross2acdae82017-09-15 19:44:24 -0700216 name: "host default",
217 host: android.Host,
218 properties: ``,
219 classpath: []string{},
220 },
221 {
222 name: "host nostdlib",
223 host: android.Host,
224 properties: `no_standard_libs: true`,
225 classpath: []string{},
226 },
227}
Colin Cross72bb3632017-07-13 16:23:21 -0700228
Colin Cross2acdae82017-09-15 19:44:24 -0700229func TestClasspath(t *testing.T) {
230 for _, testcase := range classpathTestcases {
231 t.Run(testcase.name, func(t *testing.T) {
232 hostExtra := ""
233 if testcase.host == android.Host {
234 hostExtra = "_host"
235 }
236 ctx := testJava(t, `
237 java_library`+hostExtra+` {
238 name: "foo",
239 srcs: ["a.java"],
240 `+testcase.properties+`
241 }
242 `)
Colin Cross72bb3632017-07-13 16:23:21 -0700243
Colin Cross2acdae82017-09-15 19:44:24 -0700244 convertModulesToPaths := func(cp []string) []string {
245 ret := make([]string, len(cp))
246 for i, e := range cp {
247 ret[i] = moduleToPath(e)
248 }
249 return ret
250 }
Colin Cross72bb3632017-07-13 16:23:21 -0700251
Colin Cross2acdae82017-09-15 19:44:24 -0700252 bootclasspath := convertModulesToPaths(testcase.bootclasspath)
253 classpath := convertModulesToPaths(testcase.classpath)
Colin Cross72bb3632017-07-13 16:23:21 -0700254
Colin Cross2acdae82017-09-15 19:44:24 -0700255 variant := "android_common"
256 if testcase.host == android.Host {
257 variant = android.BuildOs.String() + "_common"
258 }
259 javac := ctx.ModuleForTests("foo", variant).Rule("javac")
260
Colin Cross72bb3632017-07-13 16:23:21 -0700261 got := strings.TrimPrefix(javac.Args["bootClasspath"], "-bootclasspath ")
Colin Cross2acdae82017-09-15 19:44:24 -0700262 bc := strings.Join(bootclasspath, ":")
263 if got != bc {
264 t.Errorf("bootclasspath expected %q != got %q", bc, got)
Colin Cross72bb3632017-07-13 16:23:21 -0700265 }
Colin Cross72bb3632017-07-13 16:23:21 -0700266
Colin Cross2acdae82017-09-15 19:44:24 -0700267 got = strings.TrimPrefix(javac.Args["classpath"], "-classpath ")
268 c := strings.Join(classpath, ":")
269 if got != c {
270 t.Errorf("classpath expected %q != got %q", c, got)
271 }
272
273 var deps []string
274 if len(bootclasspath) > 0 && bootclasspath[0] != `""` {
275 deps = append(deps, bootclasspath...)
276 }
277 deps = append(deps, classpath...)
278
279 if !reflect.DeepEqual(javac.Implicits.Strings(), deps) {
280 t.Errorf("implicits expected %q != got %q", deps, javac.Implicits.Strings())
281 }
282 })
Colin Cross72bb3632017-07-13 16:23:21 -0700283 }
284
Colin Cross72bb3632017-07-13 16:23:21 -0700285}
286
287func TestPrebuilts(t *testing.T) {
288 ctx := testJava(t, `
289 java_library {
290 name: "foo",
291 srcs: ["a.java"],
Colin Crosse8dc34a2017-07-19 11:22:16 -0700292 libs: ["bar"],
293 static_libs: ["baz"],
Colin Cross72bb3632017-07-13 16:23:21 -0700294 }
295
Colin Cross74d73e22017-08-02 11:05:49 -0700296 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700297 name: "bar",
Colin Cross74d73e22017-08-02 11:05:49 -0700298 jars: ["a.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700299 }
300
Colin Cross74d73e22017-08-02 11:05:49 -0700301 java_import {
Colin Cross72bb3632017-07-13 16:23:21 -0700302 name: "baz",
Colin Cross74d73e22017-08-02 11:05:49 -0700303 jars: ["b.jar"],
Colin Cross72bb3632017-07-13 16:23:21 -0700304 }
305 `)
306
Colin Cross4c428df2017-09-15 17:36:05 -0700307 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
308 combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
Colin Cross72bb3632017-07-13 16:23:21 -0700309
310 bar := "a.jar"
311 if !strings.Contains(javac.Args["classpath"], bar) {
312 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
313 }
314
Colin Cross0a6e0072017-08-30 14:24:55 -0700315 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != "b.jar" {
316 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, "b.jar")
Colin Cross72bb3632017-07-13 16:23:21 -0700317 }
318}
319
Colin Cross89536d42017-07-07 14:35:50 -0700320func TestDefaults(t *testing.T) {
321 ctx := testJava(t, `
322 java_defaults {
323 name: "defaults",
324 srcs: ["a.java"],
325 libs: ["bar"],
326 static_libs: ["baz"],
327 }
328
329 java_library {
330 name: "foo",
331 defaults: ["defaults"],
332 }
333
334 java_library {
335 name: "bar",
336 srcs: ["b.java"],
337 }
338
339 java_library {
340 name: "baz",
341 srcs: ["c.java"],
342 }
343 `)
344
Colin Cross4c428df2017-09-15 17:36:05 -0700345 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
346 combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
Colin Cross89536d42017-07-07 14:35:50 -0700347
348 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
349 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
350 }
351
Colin Cross4c428df2017-09-15 17:36:05 -0700352 bar := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "classes-desugar.jar")
Colin Cross89536d42017-07-07 14:35:50 -0700353 if !strings.Contains(javac.Args["classpath"], bar) {
354 t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
355 }
356
Colin Cross4c428df2017-09-15 17:36:05 -0700357 baz := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "classes-desugar.jar")
Colin Cross0a6e0072017-08-30 14:24:55 -0700358 if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
359 t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
Colin Cross89536d42017-07-07 14:35:50 -0700360 }
361}
362
Colin Cross72bb3632017-07-13 16:23:21 -0700363func fail(t *testing.T, errs []error) {
364 if len(errs) > 0 {
365 for _, err := range errs {
366 t.Error(err)
367 }
368 t.FailNow()
369 }
370}