• 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 TestJavaLintDoesntUseBaselineImplicitly(t *testing.T) {
25	t.Parallel()
26	ctx, _ := testJavaWithFS(t, `
27		java_library {
28			name: "foo",
29			srcs: [
30				"a.java",
31				"b.java",
32				"c.java",
33			],
34			min_sdk_version: "29",
35			sdk_version: "system_current",
36		}
37       `, map[string][]byte{
38		"lint-baseline.xml": nil,
39	})
40
41	foo := ctx.ModuleForTests(t, "foo", "android_common")
42
43	sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
44	if strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
45		t.Error("Passed --baseline flag when baseline_filename was not set")
46	}
47}
48
49func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
50	t.Parallel()
51	android.GroupFixturePreparers(
52		PrepareForTestWithJavaDefaultModules,
53		android.PrepareForTestDisallowNonExistentPaths,
54	).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{`source path "mybaseline.xml" does not exist`})).
55		RunTestWithBp(t, `
56			java_library {
57				name: "foo",
58				srcs: [
59				],
60				min_sdk_version: "29",
61				sdk_version: "system_current",
62				lint: {
63					baseline_filename: "mybaseline.xml",
64				},
65			}
66	 `)
67}
68
69func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
70	t.Parallel()
71	ctx, _ := testJavaWithFS(t, `
72		java_library {
73			name: "foo",
74			srcs: [
75				"a.java",
76				"b.java",
77				"c.java",
78			],
79			min_sdk_version: "29",
80			sdk_version: "system_current",
81			lint: {
82				error_checks: ["SomeCheck"],
83				baseline_filename: "mybaseline.xml",
84			},
85		}
86       `, map[string][]byte{
87		"mybaseline.xml": nil,
88	})
89
90	foo := ctx.ModuleForTests(t, "foo", "android_common")
91
92	sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
93	if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
94		t.Error("did not use the correct file for baseline")
95	}
96
97	if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check NewApi") {
98		t.Error("should check NewApi errors")
99	}
100
101	if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
102		t.Error("should combine NewApi errors with SomeCheck errors")
103	}
104}
105
106func TestJavaLintBypassUpdatableChecks(t *testing.T) {
107	t.Parallel()
108	testCases := []struct {
109		name  string
110		bp    string
111		error string
112	}{
113		{
114			name: "warning_checks",
115			bp: `
116				java_library {
117					name: "foo",
118					srcs: [
119						"a.java",
120					],
121					min_sdk_version: "29",
122					sdk_version: "current",
123					lint: {
124						warning_checks: ["NewApi"],
125					},
126				}
127			`,
128			error: "lint.warning_checks: Can't treat \\[NewApi\\] checks as warnings if min_sdk_version is different from sdk_version.",
129		},
130		{
131			name: "disable_checks",
132			bp: `
133				java_library {
134					name: "foo",
135					srcs: [
136						"a.java",
137					],
138					min_sdk_version: "29",
139					sdk_version: "current",
140					lint: {
141						disabled_checks: ["NewApi"],
142					},
143				}
144			`,
145			error: "lint.disabled_checks: Can't disable \\[NewApi\\] checks if min_sdk_version is different from sdk_version.",
146		},
147	}
148
149	for _, testCase := range testCases {
150		t.Run(testCase.name, func(t *testing.T) {
151			t.Parallel()
152			errorHandler := android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.error)
153			android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
154				ExtendWithErrorHandler(errorHandler).
155				RunTestWithBp(t, testCase.bp)
156		})
157	}
158}
159
160func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
161	t.Parallel()
162	bp := `
163		java_library {
164			name: "foo",
165			srcs: [
166				"a.java",
167			],
168			static_libs: ["bar"],
169			min_sdk_version: "29",
170			sdk_version: "current",
171			lint: {
172				strict_updatability_linting: true,
173				baseline_filename: "foo_lint_baseline.xml",
174			},
175		}
176
177		java_library {
178			name: "bar",
179			srcs: [
180				"a.java",
181			],
182			min_sdk_version: "29",
183			sdk_version: "current",
184			lint: {
185				baseline_filename: "bar_lint_baseline.xml",
186			}
187		}
188	`
189	fs := android.MockFS{
190		"lint-baseline.xml": nil,
191	}
192
193	result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
194		RunTestWithBp(t, bp)
195
196	foo := result.ModuleForTests(t, "foo", "android_common")
197	strictUpdatabilityCheck := foo.Output("lint_strict_updatability_check.stamp")
198	if !strings.Contains(strictUpdatabilityCheck.RuleParams.Command,
199		"--disallowed_issues NewApi") {
200		t.Error("did not restrict baselining NewApi")
201	}
202	android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "foo_lint_baseline.xml")
203	android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "bar_lint_baseline.xml")
204}
205
206func TestJavaLintDatabaseSelectionFull(t *testing.T) {
207	testCases := []struct {
208		sdk_version   string
209		expected_file string
210	}{
211		{
212			"current",
213			"api_versions_public.xml",
214		}, {
215			"core_platform",
216			"api_versions_public.xml",
217		}, {
218			"system_current",
219			"api_versions_system.xml",
220		}, {
221			"module_current",
222			"api_versions_module_lib.xml",
223		}, {
224			"system_server_current",
225			"api_versions_system_server.xml",
226		}, {
227			"S",
228			"api_versions_public.xml",
229		}, {
230			"30",
231			"api_versions_public.xml",
232		}, {
233			"10000",
234			"api_versions_public.xml",
235		},
236	}
237	bp := `
238		java_library {
239			name: "foo",
240			srcs: [
241				"a.java",
242			],
243			min_sdk_version: "29",
244			sdk_version: "XXX",
245			lint: {
246				strict_updatability_linting: true,
247			},
248		}
249`
250	for _, testCase := range testCases {
251		thisBp := strings.Replace(bp, "XXX", testCase.sdk_version, 1)
252
253		result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, FixtureWithPrebuiltApis(map[string][]string{
254			"30":    {"foo"},
255			"10000": {"foo"},
256		})).
257			RunTestWithBp(t, thisBp)
258
259		foo := result.ModuleForTests(t, "foo", "android_common")
260		sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto"))
261		if !strings.Contains(*sboxProto.Commands[0].Command, "/"+testCase.expected_file) {
262			t.Error("did not use full api database for case", testCase)
263		}
264	}
265}
266
267func TestCantControlCheckSeverityWithFlags(t *testing.T) {
268	bp := `
269		java_library {
270			name: "foo",
271			srcs: [
272				"a.java",
273			],
274			min_sdk_version: "29",
275			sdk_version: "current",
276			lint: {
277				flags: ["--disabled", "NewApi"],
278			},
279		}
280	`
281	PrepareForTestWithJavaDefaultModules.
282		ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Don't use --disable, --enable, or --check in the flags field, instead use the dedicated disabled_checks, warning_checks, error_checks, or fatal_checks fields")).
283		RunTestWithBp(t, bp)
284}
285
286// b/358643466
287func TestNotTestViaDefault(t *testing.T) {
288	bp := `
289		java_defaults {
290			name: "mydefaults",
291			lint: {
292				test: false,
293			},
294		}
295		android_test {
296			name: "foo",
297			srcs: [
298				"a.java",
299			],
300			min_sdk_version: "29",
301			sdk_version: "current",
302			defaults: ["mydefaults"],
303		}
304		android_test {
305			name: "foo2",
306			srcs: [
307				"a.java",
308			],
309			min_sdk_version: "29",
310			sdk_version: "current",
311		}
312	`
313	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, bp)
314	ctx := result.TestContext
315
316	foo := ctx.ModuleForTests(t, "foo", "android_common")
317	sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
318	command := *sboxProto.Commands[0].Command
319
320	if strings.Contains(command, "--test") {
321		t.Fatalf("Expected command to not contain --test")
322	}
323
324	foo2 := ctx.ModuleForTests(t, "foo2", "android_common")
325	sboxProto2 := android.RuleBuilderSboxProtoForTests(t, ctx, foo2.Output("lint.sbox.textproto"))
326	command2 := *sboxProto2.Commands[0].Command
327
328	if !strings.Contains(command2, "--test") {
329		t.Fatalf("Expected command to contain --test")
330	}
331}
332