• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 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	"strings"
19	"testing"
20
21	"android/soong/android"
22)
23
24func TestJavaLint(t *testing.T) {
25	ctx, _ := testJavaWithFS(t, `
26		java_library {
27			name: "foo",
28			srcs: [
29				"a.java",
30				"b.java",
31				"c.java",
32			],
33			min_sdk_version: "29",
34			sdk_version: "system_current",
35		}
36       `, map[string][]byte{
37		"lint-baseline.xml": nil,
38	})
39
40	foo := ctx.ModuleForTests("foo", "android_common")
41
42	sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
43	if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
44		t.Error("did not pass --baseline flag")
45	}
46}
47
48func TestJavaLintWithoutBaseline(t *testing.T) {
49	ctx, _ := testJavaWithFS(t, `
50		java_library {
51			name: "foo",
52			srcs: [
53				"a.java",
54				"b.java",
55				"c.java",
56			],
57			min_sdk_version: "29",
58			sdk_version: "system_current",
59		}
60       `, map[string][]byte{})
61
62	foo := ctx.ModuleForTests("foo", "android_common")
63
64	sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
65	if strings.Contains(*sboxProto.Commands[0].Command, "--baseline") {
66		t.Error("passed --baseline flag for non existent file")
67	}
68}
69
70func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
71	android.GroupFixturePreparers(
72		PrepareForTestWithJavaDefaultModules,
73		android.PrepareForTestDisallowNonExistentPaths,
74	).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{`source path "mybaseline.xml" does not exist`})).
75		RunTestWithBp(t, `
76			java_library {
77				name: "foo",
78				srcs: [
79				],
80				min_sdk_version: "29",
81				sdk_version: "system_current",
82				lint: {
83					baseline_filename: "mybaseline.xml",
84				},
85			}
86	 `)
87}
88
89func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
90	ctx, _ := testJavaWithFS(t, `
91		java_library {
92			name: "foo",
93			srcs: [
94				"a.java",
95				"b.java",
96				"c.java",
97			],
98			min_sdk_version: "29",
99			sdk_version: "system_current",
100			lint: {
101				error_checks: ["SomeCheck"],
102				baseline_filename: "mybaseline.xml",
103			},
104		}
105       `, map[string][]byte{
106		"mybaseline.xml": nil,
107	})
108
109	foo := ctx.ModuleForTests("foo", "android_common")
110
111	sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
112	if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
113		t.Error("did not use the correct file for baseline")
114	}
115
116	if !strings.Contains(*sboxProto.Commands[0].Command, "--warning_check NewApi") {
117		// TODO(b/268261262): Change this to check for --error_check
118		t.Error("should check NewApi warnings")
119	}
120
121	if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
122		t.Error("should combine NewApi errors with SomeCheck errors")
123	}
124}
125
126func TestJavaLintBypassUpdatableChecks(t *testing.T) {
127	testCases := []struct {
128		name  string
129		bp    string
130		error string
131	}{
132		{
133			name: "warning_checks",
134			bp: `
135				java_library {
136					name: "foo",
137					srcs: [
138						"a.java",
139					],
140					min_sdk_version: "29",
141					sdk_version: "current",
142					lint: {
143						warning_checks: ["NewApi"],
144					},
145				}
146			`,
147			error: "lint.warning_checks: Can't treat \\[NewApi\\] checks as warnings if min_sdk_version is different from sdk_version.",
148		},
149		{
150			name: "disable_checks",
151			bp: `
152				java_library {
153					name: "foo",
154					srcs: [
155						"a.java",
156					],
157					min_sdk_version: "29",
158					sdk_version: "current",
159					lint: {
160						disabled_checks: ["NewApi"],
161					},
162				}
163			`,
164			error: "lint.disabled_checks: Can't disable \\[NewApi\\] checks if min_sdk_version is different from sdk_version.",
165		},
166	}
167
168	for _, testCase := range testCases {
169		t.Run(testCase.name, func(t *testing.T) {
170			errorHandler := android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.error)
171			android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
172				ExtendWithErrorHandler(errorHandler).
173				RunTestWithBp(t, testCase.bp)
174		})
175	}
176}
177
178// TODO(b/193460475): Re-enable this test
179//func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
180//	bp := `
181//		java_library {
182//			name: "foo",
183//			srcs: [
184//				"a.java",
185//			],
186//			static_libs: ["bar"],
187//			min_sdk_version: "29",
188//			sdk_version: "current",
189//			lint: {
190//				strict_updatability_linting: true,
191//			},
192//		}
193//
194//		java_library {
195//			name: "bar",
196//			srcs: [
197//				"a.java",
198//			],
199//			min_sdk_version: "29",
200//			sdk_version: "current",
201//		}
202//	`
203//	fs := android.MockFS{
204//		"lint-baseline.xml": nil,
205//	}
206//
207//	result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
208//		RunTestWithBp(t, bp)
209//
210//	foo := result.ModuleForTests("foo", "android_common")
211//	sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
212//	if !strings.Contains(*sboxProto.Commands[0].Command,
213//		"--baseline lint-baseline.xml --disallowed_issues NewApi") {
214//		t.Error("did not restrict baselining NewApi")
215//	}
216//
217//	bar := result.ModuleForTests("bar", "android_common")
218//	sboxProto = android.RuleBuilderSboxProtoForTests(t, bar.Output("lint.sbox.textproto"))
219//	if !strings.Contains(*sboxProto.Commands[0].Command,
220//		"--baseline lint-baseline.xml --disallowed_issues NewApi") {
221//		t.Error("did not restrict baselining NewApi")
222//	}
223//}
224
225func TestJavaLintDatabaseSelectionFull(t *testing.T) {
226	testCases := []struct {
227		sdk_version   string
228		expected_file string
229	}{
230		{
231			"current",
232			"api_versions_public.xml",
233		}, {
234			"core_platform",
235			"api_versions_public.xml",
236		}, {
237			"system_current",
238			"api_versions_system.xml",
239		}, {
240			"module_current",
241			"api_versions_module_lib.xml",
242		}, {
243			"system_server_current",
244			"api_versions_system_server.xml",
245		}, {
246			"S",
247			"api_versions_public.xml",
248		}, {
249			"30",
250			"api_versions_public.xml",
251		}, {
252			"10000",
253			"api_versions_public.xml",
254		},
255	}
256	bp := `
257		java_library {
258			name: "foo",
259			srcs: [
260				"a.java",
261			],
262			min_sdk_version: "29",
263			sdk_version: "XXX",
264			lint: {
265				strict_updatability_linting: true,
266			},
267		}
268`
269	for _, testCase := range testCases {
270		thisBp := strings.Replace(bp, "XXX", testCase.sdk_version, 1)
271
272		result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, FixtureWithPrebuiltApis(map[string][]string{
273			"30":    {"foo"},
274			"10000": {"foo"},
275		})).
276			RunTestWithBp(t, thisBp)
277
278		foo := result.ModuleForTests("foo", "android_common")
279		sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
280		if !strings.Contains(*sboxProto.Commands[0].Command, "/"+testCase.expected_file) {
281			t.Error("did not use full api database for case", testCase)
282		}
283	}
284}
285