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