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