• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 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	"path/filepath"
19	"reflect"
20	"strings"
21	"testing"
22
23	"github.com/google/blueprint/proptools"
24
25	"android/soong/android"
26	"android/soong/java/config"
27)
28
29func TestClasspath(t *testing.T) {
30	var classpathTestcases = []struct {
31		name          string
32		unbundled     bool
33		pdk           bool
34		moduleType    string
35		host          android.OsClass
36		properties    string
37		bootclasspath []string
38		system        string
39		classpath     []string
40		aidl          string
41	}{
42		{
43			name:          "default",
44			bootclasspath: config.DefaultBootclasspathLibraries,
45			system:        config.DefaultSystemModules,
46			classpath:     config.DefaultLibraries,
47			aidl:          "-Iframework/aidl",
48		},
49		{
50			name:          "blank sdk version",
51			properties:    `sdk_version: "",`,
52			bootclasspath: config.DefaultBootclasspathLibraries,
53			system:        config.DefaultSystemModules,
54			classpath:     config.DefaultLibraries,
55			aidl:          "-Iframework/aidl",
56		},
57		{
58
59			name:          "sdk v25",
60			properties:    `sdk_version: "25",`,
61			bootclasspath: []string{`""`},
62			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
63			classpath:     []string{"prebuilts/sdk/25/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
64			aidl:          "-pprebuilts/sdk/25/public/framework.aidl",
65		},
66		{
67
68			name:          "current",
69			properties:    `sdk_version: "current",`,
70			bootclasspath: []string{"android_stubs_current", "core-lambda-stubs"},
71			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
72			aidl:          "-p" + buildDir + "/framework.aidl",
73		},
74		{
75
76			name:          "system_current",
77			properties:    `sdk_version: "system_current",`,
78			bootclasspath: []string{"android_system_stubs_current", "core-lambda-stubs"},
79			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
80			aidl:          "-p" + buildDir + "/framework.aidl",
81		},
82		{
83
84			name:          "system_25",
85			properties:    `sdk_version: "system_25",`,
86			bootclasspath: []string{`""`},
87			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
88			classpath:     []string{"prebuilts/sdk/25/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
89			aidl:          "-pprebuilts/sdk/25/public/framework.aidl",
90		},
91		{
92
93			name:          "test_current",
94			properties:    `sdk_version: "test_current",`,
95			bootclasspath: []string{"android_test_stubs_current", "core-lambda-stubs"},
96			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
97			aidl:          "-p" + buildDir + "/framework.aidl",
98		},
99		{
100
101			name:          "core_current",
102			properties:    `sdk_version: "core_current",`,
103			bootclasspath: []string{"core.current.stubs", "core-lambda-stubs"},
104			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
105		},
106		{
107
108			name:          "nostdlib",
109			properties:    `no_standard_libs: true, system_modules: "none"`,
110			system:        "none",
111			bootclasspath: []string{`""`},
112			classpath:     []string{},
113		},
114		{
115
116			name:          "nostdlib system_modules",
117			properties:    `no_standard_libs: true, system_modules: "core-platform-api-stubs-system-modules"`,
118			system:        "core-platform-api-stubs-system-modules",
119			bootclasspath: []string{`""`},
120			classpath:     []string{},
121		},
122		{
123
124			name:          "host default",
125			moduleType:    "java_library_host",
126			properties:    ``,
127			host:          android.Host,
128			bootclasspath: []string{"jdk8/jre/lib/jce.jar", "jdk8/jre/lib/rt.jar"},
129			classpath:     []string{},
130		},
131		{
132			name:       "host nostdlib",
133			moduleType: "java_library_host",
134			host:       android.Host,
135			properties: `no_standard_libs: true`,
136			classpath:  []string{},
137		},
138		{
139
140			name:          "host supported default",
141			host:          android.Host,
142			properties:    `host_supported: true,`,
143			classpath:     []string{},
144			bootclasspath: []string{"jdk8/jre/lib/jce.jar", "jdk8/jre/lib/rt.jar"},
145		},
146		{
147			name:       "host supported nostdlib",
148			host:       android.Host,
149			properties: `host_supported: true, no_standard_libs: true, system_modules: "none"`,
150			classpath:  []string{},
151		},
152		{
153
154			name:          "unbundled sdk v25",
155			unbundled:     true,
156			properties:    `sdk_version: "25",`,
157			bootclasspath: []string{`""`},
158			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
159			classpath:     []string{"prebuilts/sdk/25/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
160			aidl:          "-pprebuilts/sdk/25/public/framework.aidl",
161		},
162		{
163
164			name:          "unbundled current",
165			unbundled:     true,
166			properties:    `sdk_version: "current",`,
167			bootclasspath: []string{`""`},
168			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
169			classpath:     []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
170			aidl:          "-pprebuilts/sdk/current/public/framework.aidl",
171		},
172
173		{
174			name:          "pdk default",
175			pdk:           true,
176			bootclasspath: []string{`""`},
177			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
178			classpath:     []string{"prebuilts/sdk/25/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
179			aidl:          "-pprebuilts/sdk/25/public/framework.aidl",
180		},
181		{
182			name:          "pdk current",
183			pdk:           true,
184			properties:    `sdk_version: "current",`,
185			bootclasspath: []string{`""`},
186			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
187			classpath:     []string{"prebuilts/sdk/25/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
188			aidl:          "-pprebuilts/sdk/25/public/framework.aidl",
189		},
190		{
191			name:          "pdk 25",
192			pdk:           true,
193			properties:    `sdk_version: "25",`,
194			bootclasspath: []string{`""`},
195			system:        "bootclasspath", // special value to tell 1.9 test to expect bootclasspath
196			classpath:     []string{"prebuilts/sdk/25/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
197			aidl:          "-pprebuilts/sdk/25/public/framework.aidl",
198		},
199	}
200
201	for _, testcase := range classpathTestcases {
202		t.Run(testcase.name, func(t *testing.T) {
203			moduleType := "java_library"
204			if testcase.moduleType != "" {
205				moduleType = testcase.moduleType
206			}
207
208			bp := moduleType + ` {
209				name: "foo",
210				srcs: ["a.java"],
211				target: {
212					android: {
213						srcs: ["bar-doc/IFoo.aidl"],
214					},
215				},
216				` + testcase.properties + `
217			}`
218
219			variant := "android_common"
220			if testcase.host == android.Host {
221				variant = android.BuildOs.String() + "_common"
222			}
223
224			convertModulesToPaths := func(cp []string) []string {
225				ret := make([]string, len(cp))
226				for i, e := range cp {
227					ret[i] = moduleToPath(e)
228				}
229				return ret
230			}
231
232			bootclasspath := convertModulesToPaths(testcase.bootclasspath)
233			classpath := convertModulesToPaths(testcase.classpath)
234
235			bc := strings.Join(bootclasspath, ":")
236			if bc != "" {
237				bc = "-bootclasspath " + bc
238			}
239
240			c := strings.Join(classpath, ":")
241			if c != "" {
242				c = "-classpath " + c
243			}
244			system := ""
245			if testcase.system == "none" {
246				system = "--system=none"
247			} else if testcase.system != "" {
248				system = "--system=" + filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system") + "/"
249			}
250
251			checkClasspath := func(t *testing.T, ctx *android.TestContext) {
252				javac := ctx.ModuleForTests("foo", variant).Rule("javac")
253
254				got := javac.Args["bootClasspath"]
255				if got != bc {
256					t.Errorf("bootclasspath expected %q != got %q", bc, got)
257				}
258
259				got = javac.Args["classpath"]
260				if got != c {
261					t.Errorf("classpath expected %q != got %q", c, got)
262				}
263
264				var deps []string
265				if len(bootclasspath) > 0 && bootclasspath[0] != `""` {
266					deps = append(deps, bootclasspath...)
267				}
268				deps = append(deps, classpath...)
269
270				if !reflect.DeepEqual(javac.Implicits.Strings(), deps) {
271					t.Errorf("implicits expected %q != got %q", deps, javac.Implicits.Strings())
272				}
273			}
274
275			t.Run("1.8", func(t *testing.T) {
276				// Test default javac 1.8
277				config := testConfig(nil)
278				if testcase.unbundled {
279					config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
280				}
281				if testcase.pdk {
282					config.TestProductVariables.Pdk = proptools.BoolPtr(true)
283				}
284				ctx := testContext(config, bp, nil)
285				run(t, ctx, config)
286
287				checkClasspath(t, ctx)
288
289				if testcase.host != android.Host {
290					aidl := ctx.ModuleForTests("foo", variant).Rule("aidl")
291
292					aidlFlags := aidl.Args["aidlFlags"]
293					// Trim trailing "-I." to avoid having to specify it in every test
294					aidlFlags = strings.TrimSpace(strings.TrimSuffix(aidlFlags, "-I."))
295
296					if g, w := aidlFlags, testcase.aidl; g != w {
297						t.Errorf("want aidl flags %q, got %q", w, g)
298					}
299				}
300			})
301
302			// Test again with javac 1.9
303			t.Run("1.9", func(t *testing.T) {
304				config := testConfig(map[string]string{"EXPERIMENTAL_USE_OPENJDK9": "true"})
305				if testcase.unbundled {
306					config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
307				}
308				if testcase.pdk {
309					config.TestProductVariables.Pdk = proptools.BoolPtr(true)
310				}
311				ctx := testContext(config, bp, nil)
312				run(t, ctx, config)
313
314				javac := ctx.ModuleForTests("foo", variant).Rule("javac")
315				got := javac.Args["bootClasspath"]
316				expected := system
317				if testcase.system == "bootclasspath" {
318					expected = bc
319				}
320				if got != expected {
321					t.Errorf("bootclasspath expected %q != got %q", expected, got)
322				}
323			})
324
325			// Test again with PLATFORM_VERSION_CODENAME=REL
326			t.Run("REL", func(t *testing.T) {
327				config := testConfig(nil)
328				config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("REL")
329				config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(true)
330
331				if testcase.unbundled {
332					config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
333				}
334				if testcase.pdk {
335					config.TestProductVariables.Pdk = proptools.BoolPtr(true)
336				}
337				ctx := testContext(config, bp, nil)
338				run(t, ctx, config)
339
340				checkClasspath(t, ctx)
341			})
342		})
343	}
344
345}
346