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: "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: "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 sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto")) 192 if !strings.Contains(*sboxProto.Commands[0].Command, 193 "--baseline lint-baseline.xml --disallowed_issues NewApi") { 194 t.Error("did not restrict baselining NewApi") 195 } 196 197 bar := result.ModuleForTests("bar", "android_common") 198 sboxProto = android.RuleBuilderSboxProtoForTests(t, result.TestContext, bar.Output("lint.sbox.textproto")) 199 if !strings.Contains(*sboxProto.Commands[0].Command, 200 "--baseline lint-baseline.xml --disallowed_issues NewApi") { 201 t.Error("did not restrict baselining NewApi") 202 } 203} 204 205func TestJavaLintDatabaseSelectionFull(t *testing.T) { 206 testCases := []struct { 207 sdk_version string 208 expected_file string 209 }{ 210 { 211 "current", 212 "api_versions_public.xml", 213 }, { 214 "core_platform", 215 "api_versions_public.xml", 216 }, { 217 "system_current", 218 "api_versions_system.xml", 219 }, { 220 "module_current", 221 "api_versions_module_lib.xml", 222 }, { 223 "system_server_current", 224 "api_versions_system_server.xml", 225 }, { 226 "S", 227 "api_versions_public.xml", 228 }, { 229 "30", 230 "api_versions_public.xml", 231 }, { 232 "10000", 233 "api_versions_public.xml", 234 }, 235 } 236 bp := ` 237 java_library { 238 name: "foo", 239 srcs: [ 240 "a.java", 241 ], 242 min_sdk_version: "29", 243 sdk_version: "XXX", 244 lint: { 245 strict_updatability_linting: true, 246 }, 247 } 248` 249 for _, testCase := range testCases { 250 thisBp := strings.Replace(bp, "XXX", testCase.sdk_version, 1) 251 252 result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, FixtureWithPrebuiltApis(map[string][]string{ 253 "30": {"foo"}, 254 "10000": {"foo"}, 255 })). 256 RunTestWithBp(t, thisBp) 257 258 foo := result.ModuleForTests("foo", "android_common") 259 sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto")) 260 if !strings.Contains(*sboxProto.Commands[0].Command, "/"+testCase.expected_file) { 261 t.Error("did not use full api database for case", testCase) 262 } 263 } 264} 265 266func TestCantControlCheckSeverityWithFlags(t *testing.T) { 267 bp := ` 268 java_library { 269 name: "foo", 270 srcs: [ 271 "a.java", 272 ], 273 min_sdk_version: "29", 274 sdk_version: "current", 275 lint: { 276 flags: ["--disabled", "NewApi"], 277 }, 278 } 279 ` 280 PrepareForTestWithJavaDefaultModules. 281 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")). 282 RunTestWithBp(t, bp) 283} 284