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