xref: /aosp_15_r20/build/soong/java/lint_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2021 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage java
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"strings"
19*333d2b36SAndroid Build Coastguard Worker	"testing"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
22*333d2b36SAndroid Build Coastguard Worker)
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Workerfunc TestJavaLintDoesntUseBaselineImplicitly(t *testing.T) {
25*333d2b36SAndroid Build Coastguard Worker	ctx, _ := testJavaWithFS(t, `
26*333d2b36SAndroid Build Coastguard Worker		java_library {
27*333d2b36SAndroid Build Coastguard Worker			name: "foo",
28*333d2b36SAndroid Build Coastguard Worker			srcs: [
29*333d2b36SAndroid Build Coastguard Worker				"a.java",
30*333d2b36SAndroid Build Coastguard Worker				"b.java",
31*333d2b36SAndroid Build Coastguard Worker				"c.java",
32*333d2b36SAndroid Build Coastguard Worker			],
33*333d2b36SAndroid Build Coastguard Worker			min_sdk_version: "29",
34*333d2b36SAndroid Build Coastguard Worker			sdk_version: "system_current",
35*333d2b36SAndroid Build Coastguard Worker		}
36*333d2b36SAndroid Build Coastguard Worker       `, map[string][]byte{
37*333d2b36SAndroid Build Coastguard Worker		"lint-baseline.xml": nil,
38*333d2b36SAndroid Build Coastguard Worker	})
39*333d2b36SAndroid Build Coastguard Worker
40*333d2b36SAndroid Build Coastguard Worker	foo := ctx.ModuleForTests("foo", "android_common")
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Worker	sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
43*333d2b36SAndroid Build Coastguard Worker	if strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
44*333d2b36SAndroid Build Coastguard Worker		t.Error("Passed --baseline flag when baseline_filename was not set")
45*333d2b36SAndroid Build Coastguard Worker	}
46*333d2b36SAndroid Build Coastguard Worker}
47*333d2b36SAndroid Build Coastguard Worker
48*333d2b36SAndroid Build Coastguard Workerfunc TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
49*333d2b36SAndroid Build Coastguard Worker	android.GroupFixturePreparers(
50*333d2b36SAndroid Build Coastguard Worker		PrepareForTestWithJavaDefaultModules,
51*333d2b36SAndroid Build Coastguard Worker		android.PrepareForTestDisallowNonExistentPaths,
52*333d2b36SAndroid Build Coastguard Worker	).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{`source path "mybaseline.xml" does not exist`})).
53*333d2b36SAndroid Build Coastguard Worker		RunTestWithBp(t, `
54*333d2b36SAndroid Build Coastguard Worker			java_library {
55*333d2b36SAndroid Build Coastguard Worker				name: "foo",
56*333d2b36SAndroid Build Coastguard Worker				srcs: [
57*333d2b36SAndroid Build Coastguard Worker				],
58*333d2b36SAndroid Build Coastguard Worker				min_sdk_version: "29",
59*333d2b36SAndroid Build Coastguard Worker				sdk_version: "system_current",
60*333d2b36SAndroid Build Coastguard Worker				lint: {
61*333d2b36SAndroid Build Coastguard Worker					baseline_filename: "mybaseline.xml",
62*333d2b36SAndroid Build Coastguard Worker				},
63*333d2b36SAndroid Build Coastguard Worker			}
64*333d2b36SAndroid Build Coastguard Worker	 `)
65*333d2b36SAndroid Build Coastguard Worker}
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Workerfunc TestJavaLintUsesCorrectBpConfig(t *testing.T) {
68*333d2b36SAndroid Build Coastguard Worker	ctx, _ := testJavaWithFS(t, `
69*333d2b36SAndroid Build Coastguard Worker		java_library {
70*333d2b36SAndroid Build Coastguard Worker			name: "foo",
71*333d2b36SAndroid Build Coastguard Worker			srcs: [
72*333d2b36SAndroid Build Coastguard Worker				"a.java",
73*333d2b36SAndroid Build Coastguard Worker				"b.java",
74*333d2b36SAndroid Build Coastguard Worker				"c.java",
75*333d2b36SAndroid Build Coastguard Worker			],
76*333d2b36SAndroid Build Coastguard Worker			min_sdk_version: "29",
77*333d2b36SAndroid Build Coastguard Worker			sdk_version: "system_current",
78*333d2b36SAndroid Build Coastguard Worker			lint: {
79*333d2b36SAndroid Build Coastguard Worker				error_checks: ["SomeCheck"],
80*333d2b36SAndroid Build Coastguard Worker				baseline_filename: "mybaseline.xml",
81*333d2b36SAndroid Build Coastguard Worker			},
82*333d2b36SAndroid Build Coastguard Worker		}
83*333d2b36SAndroid Build Coastguard Worker       `, map[string][]byte{
84*333d2b36SAndroid Build Coastguard Worker		"mybaseline.xml": nil,
85*333d2b36SAndroid Build Coastguard Worker	})
86*333d2b36SAndroid Build Coastguard Worker
87*333d2b36SAndroid Build Coastguard Worker	foo := ctx.ModuleForTests("foo", "android_common")
88*333d2b36SAndroid Build Coastguard Worker
89*333d2b36SAndroid Build Coastguard Worker	sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
90*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
91*333d2b36SAndroid Build Coastguard Worker		t.Error("did not use the correct file for baseline")
92*333d2b36SAndroid Build Coastguard Worker	}
93*333d2b36SAndroid Build Coastguard Worker
94*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check NewApi") {
95*333d2b36SAndroid Build Coastguard Worker		t.Error("should check NewApi errors")
96*333d2b36SAndroid Build Coastguard Worker	}
97*333d2b36SAndroid Build Coastguard Worker
98*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
99*333d2b36SAndroid Build Coastguard Worker		t.Error("should combine NewApi errors with SomeCheck errors")
100*333d2b36SAndroid Build Coastguard Worker	}
101*333d2b36SAndroid Build Coastguard Worker}
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Workerfunc TestJavaLintBypassUpdatableChecks(t *testing.T) {
104*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
105*333d2b36SAndroid Build Coastguard Worker		name  string
106*333d2b36SAndroid Build Coastguard Worker		bp    string
107*333d2b36SAndroid Build Coastguard Worker		error string
108*333d2b36SAndroid Build Coastguard Worker	}{
109*333d2b36SAndroid Build Coastguard Worker		{
110*333d2b36SAndroid Build Coastguard Worker			name: "warning_checks",
111*333d2b36SAndroid Build Coastguard Worker			bp: `
112*333d2b36SAndroid Build Coastguard Worker				java_library {
113*333d2b36SAndroid Build Coastguard Worker					name: "foo",
114*333d2b36SAndroid Build Coastguard Worker					srcs: [
115*333d2b36SAndroid Build Coastguard Worker						"a.java",
116*333d2b36SAndroid Build Coastguard Worker					],
117*333d2b36SAndroid Build Coastguard Worker					min_sdk_version: "29",
118*333d2b36SAndroid Build Coastguard Worker					sdk_version: "current",
119*333d2b36SAndroid Build Coastguard Worker					lint: {
120*333d2b36SAndroid Build Coastguard Worker						warning_checks: ["NewApi"],
121*333d2b36SAndroid Build Coastguard Worker					},
122*333d2b36SAndroid Build Coastguard Worker				}
123*333d2b36SAndroid Build Coastguard Worker			`,
124*333d2b36SAndroid Build Coastguard Worker			error: "lint.warning_checks: Can't treat \\[NewApi\\] checks as warnings if min_sdk_version is different from sdk_version.",
125*333d2b36SAndroid Build Coastguard Worker		},
126*333d2b36SAndroid Build Coastguard Worker		{
127*333d2b36SAndroid Build Coastguard Worker			name: "disable_checks",
128*333d2b36SAndroid Build Coastguard Worker			bp: `
129*333d2b36SAndroid Build Coastguard Worker				java_library {
130*333d2b36SAndroid Build Coastguard Worker					name: "foo",
131*333d2b36SAndroid Build Coastguard Worker					srcs: [
132*333d2b36SAndroid Build Coastguard Worker						"a.java",
133*333d2b36SAndroid Build Coastguard Worker					],
134*333d2b36SAndroid Build Coastguard Worker					min_sdk_version: "29",
135*333d2b36SAndroid Build Coastguard Worker					sdk_version: "current",
136*333d2b36SAndroid Build Coastguard Worker					lint: {
137*333d2b36SAndroid Build Coastguard Worker						disabled_checks: ["NewApi"],
138*333d2b36SAndroid Build Coastguard Worker					},
139*333d2b36SAndroid Build Coastguard Worker				}
140*333d2b36SAndroid Build Coastguard Worker			`,
141*333d2b36SAndroid Build Coastguard Worker			error: "lint.disabled_checks: Can't disable \\[NewApi\\] checks if min_sdk_version is different from sdk_version.",
142*333d2b36SAndroid Build Coastguard Worker		},
143*333d2b36SAndroid Build Coastguard Worker	}
144*333d2b36SAndroid Build Coastguard Worker
145*333d2b36SAndroid Build Coastguard Worker	for _, testCase := range testCases {
146*333d2b36SAndroid Build Coastguard Worker		t.Run(testCase.name, func(t *testing.T) {
147*333d2b36SAndroid Build Coastguard Worker			errorHandler := android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.error)
148*333d2b36SAndroid Build Coastguard Worker			android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
149*333d2b36SAndroid Build Coastguard Worker				ExtendWithErrorHandler(errorHandler).
150*333d2b36SAndroid Build Coastguard Worker				RunTestWithBp(t, testCase.bp)
151*333d2b36SAndroid Build Coastguard Worker		})
152*333d2b36SAndroid Build Coastguard Worker	}
153*333d2b36SAndroid Build Coastguard Worker}
154*333d2b36SAndroid Build Coastguard Worker
155*333d2b36SAndroid Build Coastguard Workerfunc TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
156*333d2b36SAndroid Build Coastguard Worker	bp := `
157*333d2b36SAndroid Build Coastguard Worker		java_library {
158*333d2b36SAndroid Build Coastguard Worker			name: "foo",
159*333d2b36SAndroid Build Coastguard Worker			srcs: [
160*333d2b36SAndroid Build Coastguard Worker				"a.java",
161*333d2b36SAndroid Build Coastguard Worker			],
162*333d2b36SAndroid Build Coastguard Worker			static_libs: ["bar"],
163*333d2b36SAndroid Build Coastguard Worker			min_sdk_version: "29",
164*333d2b36SAndroid Build Coastguard Worker			sdk_version: "current",
165*333d2b36SAndroid Build Coastguard Worker			lint: {
166*333d2b36SAndroid Build Coastguard Worker				strict_updatability_linting: true,
167*333d2b36SAndroid Build Coastguard Worker				baseline_filename: "foo_lint_baseline.xml",
168*333d2b36SAndroid Build Coastguard Worker			},
169*333d2b36SAndroid Build Coastguard Worker		}
170*333d2b36SAndroid Build Coastguard Worker
171*333d2b36SAndroid Build Coastguard Worker		java_library {
172*333d2b36SAndroid Build Coastguard Worker			name: "bar",
173*333d2b36SAndroid Build Coastguard Worker			srcs: [
174*333d2b36SAndroid Build Coastguard Worker				"a.java",
175*333d2b36SAndroid Build Coastguard Worker			],
176*333d2b36SAndroid Build Coastguard Worker			min_sdk_version: "29",
177*333d2b36SAndroid Build Coastguard Worker			sdk_version: "current",
178*333d2b36SAndroid Build Coastguard Worker			lint: {
179*333d2b36SAndroid Build Coastguard Worker				baseline_filename: "bar_lint_baseline.xml",
180*333d2b36SAndroid Build Coastguard Worker			}
181*333d2b36SAndroid Build Coastguard Worker		}
182*333d2b36SAndroid Build Coastguard Worker	`
183*333d2b36SAndroid Build Coastguard Worker	fs := android.MockFS{
184*333d2b36SAndroid Build Coastguard Worker		"lint-baseline.xml": nil,
185*333d2b36SAndroid Build Coastguard Worker	}
186*333d2b36SAndroid Build Coastguard Worker
187*333d2b36SAndroid Build Coastguard Worker	result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
188*333d2b36SAndroid Build Coastguard Worker		RunTestWithBp(t, bp)
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard Worker	foo := result.ModuleForTests("foo", "android_common")
191*333d2b36SAndroid Build Coastguard Worker	strictUpdatabilityCheck := foo.Output("lint_strict_updatability_check.stamp")
192*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(strictUpdatabilityCheck.RuleParams.Command,
193*333d2b36SAndroid Build Coastguard Worker		"--disallowed_issues NewApi") {
194*333d2b36SAndroid Build Coastguard Worker		t.Error("did not restrict baselining NewApi")
195*333d2b36SAndroid Build Coastguard Worker	}
196*333d2b36SAndroid Build Coastguard Worker	android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "foo_lint_baseline.xml")
197*333d2b36SAndroid Build Coastguard Worker	android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "bar_lint_baseline.xml")
198*333d2b36SAndroid Build Coastguard Worker}
199*333d2b36SAndroid Build Coastguard Worker
200*333d2b36SAndroid Build Coastguard Workerfunc TestJavaLintDatabaseSelectionFull(t *testing.T) {
201*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
202*333d2b36SAndroid Build Coastguard Worker		sdk_version   string
203*333d2b36SAndroid Build Coastguard Worker		expected_file string
204*333d2b36SAndroid Build Coastguard Worker	}{
205*333d2b36SAndroid Build Coastguard Worker		{
206*333d2b36SAndroid Build Coastguard Worker			"current",
207*333d2b36SAndroid Build Coastguard Worker			"api_versions_public.xml",
208*333d2b36SAndroid Build Coastguard Worker		}, {
209*333d2b36SAndroid Build Coastguard Worker			"core_platform",
210*333d2b36SAndroid Build Coastguard Worker			"api_versions_public.xml",
211*333d2b36SAndroid Build Coastguard Worker		}, {
212*333d2b36SAndroid Build Coastguard Worker			"system_current",
213*333d2b36SAndroid Build Coastguard Worker			"api_versions_system.xml",
214*333d2b36SAndroid Build Coastguard Worker		}, {
215*333d2b36SAndroid Build Coastguard Worker			"module_current",
216*333d2b36SAndroid Build Coastguard Worker			"api_versions_module_lib.xml",
217*333d2b36SAndroid Build Coastguard Worker		}, {
218*333d2b36SAndroid Build Coastguard Worker			"system_server_current",
219*333d2b36SAndroid Build Coastguard Worker			"api_versions_system_server.xml",
220*333d2b36SAndroid Build Coastguard Worker		}, {
221*333d2b36SAndroid Build Coastguard Worker			"S",
222*333d2b36SAndroid Build Coastguard Worker			"api_versions_public.xml",
223*333d2b36SAndroid Build Coastguard Worker		}, {
224*333d2b36SAndroid Build Coastguard Worker			"30",
225*333d2b36SAndroid Build Coastguard Worker			"api_versions_public.xml",
226*333d2b36SAndroid Build Coastguard Worker		}, {
227*333d2b36SAndroid Build Coastguard Worker			"10000",
228*333d2b36SAndroid Build Coastguard Worker			"api_versions_public.xml",
229*333d2b36SAndroid Build Coastguard Worker		},
230*333d2b36SAndroid Build Coastguard Worker	}
231*333d2b36SAndroid Build Coastguard Worker	bp := `
232*333d2b36SAndroid Build Coastguard Worker		java_library {
233*333d2b36SAndroid Build Coastguard Worker			name: "foo",
234*333d2b36SAndroid Build Coastguard Worker			srcs: [
235*333d2b36SAndroid Build Coastguard Worker				"a.java",
236*333d2b36SAndroid Build Coastguard Worker			],
237*333d2b36SAndroid Build Coastguard Worker			min_sdk_version: "29",
238*333d2b36SAndroid Build Coastguard Worker			sdk_version: "XXX",
239*333d2b36SAndroid Build Coastguard Worker			lint: {
240*333d2b36SAndroid Build Coastguard Worker				strict_updatability_linting: true,
241*333d2b36SAndroid Build Coastguard Worker			},
242*333d2b36SAndroid Build Coastguard Worker		}
243*333d2b36SAndroid Build Coastguard Worker`
244*333d2b36SAndroid Build Coastguard Worker	for _, testCase := range testCases {
245*333d2b36SAndroid Build Coastguard Worker		thisBp := strings.Replace(bp, "XXX", testCase.sdk_version, 1)
246*333d2b36SAndroid Build Coastguard Worker
247*333d2b36SAndroid Build Coastguard Worker		result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, FixtureWithPrebuiltApis(map[string][]string{
248*333d2b36SAndroid Build Coastguard Worker			"30":    {"foo"},
249*333d2b36SAndroid Build Coastguard Worker			"10000": {"foo"},
250*333d2b36SAndroid Build Coastguard Worker		})).
251*333d2b36SAndroid Build Coastguard Worker			RunTestWithBp(t, thisBp)
252*333d2b36SAndroid Build Coastguard Worker
253*333d2b36SAndroid Build Coastguard Worker		foo := result.ModuleForTests("foo", "android_common")
254*333d2b36SAndroid Build Coastguard Worker		sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto"))
255*333d2b36SAndroid Build Coastguard Worker		if !strings.Contains(*sboxProto.Commands[0].Command, "/"+testCase.expected_file) {
256*333d2b36SAndroid Build Coastguard Worker			t.Error("did not use full api database for case", testCase)
257*333d2b36SAndroid Build Coastguard Worker		}
258*333d2b36SAndroid Build Coastguard Worker	}
259*333d2b36SAndroid Build Coastguard Worker}
260*333d2b36SAndroid Build Coastguard Worker
261*333d2b36SAndroid Build Coastguard Workerfunc TestCantControlCheckSeverityWithFlags(t *testing.T) {
262*333d2b36SAndroid Build Coastguard Worker	bp := `
263*333d2b36SAndroid Build Coastguard Worker		java_library {
264*333d2b36SAndroid Build Coastguard Worker			name: "foo",
265*333d2b36SAndroid Build Coastguard Worker			srcs: [
266*333d2b36SAndroid Build Coastguard Worker				"a.java",
267*333d2b36SAndroid Build Coastguard Worker			],
268*333d2b36SAndroid Build Coastguard Worker			min_sdk_version: "29",
269*333d2b36SAndroid Build Coastguard Worker			sdk_version: "current",
270*333d2b36SAndroid Build Coastguard Worker			lint: {
271*333d2b36SAndroid Build Coastguard Worker				flags: ["--disabled", "NewApi"],
272*333d2b36SAndroid Build Coastguard Worker			},
273*333d2b36SAndroid Build Coastguard Worker		}
274*333d2b36SAndroid Build Coastguard Worker	`
275*333d2b36SAndroid Build Coastguard Worker	PrepareForTestWithJavaDefaultModules.
276*333d2b36SAndroid Build Coastguard Worker		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")).
277*333d2b36SAndroid Build Coastguard Worker		RunTestWithBp(t, bp)
278*333d2b36SAndroid Build Coastguard Worker}
279