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, "--warning_check NewApi") { 117 // TODO(b/268261262): Change this to check for --error_check 118 t.Error("should check NewApi warnings") 119 } 120 121 if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") { 122 t.Error("should combine NewApi errors with SomeCheck errors") 123 } 124} 125 126func TestJavaLintBypassUpdatableChecks(t *testing.T) { 127 testCases := []struct { 128 name string 129 bp string 130 error string 131 }{ 132 { 133 name: "warning_checks", 134 bp: ` 135 java_library { 136 name: "foo", 137 srcs: [ 138 "a.java", 139 ], 140 min_sdk_version: "29", 141 sdk_version: "current", 142 lint: { 143 warning_checks: ["NewApi"], 144 }, 145 } 146 `, 147 error: "lint.warning_checks: Can't treat \\[NewApi\\] checks as warnings if min_sdk_version is different from sdk_version.", 148 }, 149 { 150 name: "disable_checks", 151 bp: ` 152 java_library { 153 name: "foo", 154 srcs: [ 155 "a.java", 156 ], 157 min_sdk_version: "29", 158 sdk_version: "current", 159 lint: { 160 disabled_checks: ["NewApi"], 161 }, 162 } 163 `, 164 error: "lint.disabled_checks: Can't disable \\[NewApi\\] checks if min_sdk_version is different from sdk_version.", 165 }, 166 } 167 168 for _, testCase := range testCases { 169 t.Run(testCase.name, func(t *testing.T) { 170 errorHandler := android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.error) 171 android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules). 172 ExtendWithErrorHandler(errorHandler). 173 RunTestWithBp(t, testCase.bp) 174 }) 175 } 176} 177 178// TODO(b/193460475): Re-enable this test 179//func TestJavaLintStrictUpdatabilityLinting(t *testing.T) { 180// bp := ` 181// java_library { 182// name: "foo", 183// srcs: [ 184// "a.java", 185// ], 186// static_libs: ["bar"], 187// min_sdk_version: "29", 188// sdk_version: "current", 189// lint: { 190// strict_updatability_linting: true, 191// }, 192// } 193// 194// java_library { 195// name: "bar", 196// srcs: [ 197// "a.java", 198// ], 199// min_sdk_version: "29", 200// sdk_version: "current", 201// } 202// ` 203// fs := android.MockFS{ 204// "lint-baseline.xml": nil, 205// } 206// 207// result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()). 208// RunTestWithBp(t, bp) 209// 210// foo := result.ModuleForTests("foo", "android_common") 211// sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto")) 212// if !strings.Contains(*sboxProto.Commands[0].Command, 213// "--baseline lint-baseline.xml --disallowed_issues NewApi") { 214// t.Error("did not restrict baselining NewApi") 215// } 216// 217// bar := result.ModuleForTests("bar", "android_common") 218// sboxProto = android.RuleBuilderSboxProtoForTests(t, bar.Output("lint.sbox.textproto")) 219// if !strings.Contains(*sboxProto.Commands[0].Command, 220// "--baseline lint-baseline.xml --disallowed_issues NewApi") { 221// t.Error("did not restrict baselining NewApi") 222// } 223//} 224 225func TestJavaLintDatabaseSelectionFull(t *testing.T) { 226 testCases := []struct { 227 sdk_version string 228 expected_file string 229 }{ 230 { 231 "current", 232 "api_versions_public.xml", 233 }, { 234 "core_platform", 235 "api_versions_public.xml", 236 }, { 237 "system_current", 238 "api_versions_system.xml", 239 }, { 240 "module_current", 241 "api_versions_module_lib.xml", 242 }, { 243 "system_server_current", 244 "api_versions_system_server.xml", 245 }, { 246 "S", 247 "api_versions_public.xml", 248 }, { 249 "30", 250 "api_versions_public.xml", 251 }, { 252 "10000", 253 "api_versions_public.xml", 254 }, 255 } 256 bp := ` 257 java_library { 258 name: "foo", 259 srcs: [ 260 "a.java", 261 ], 262 min_sdk_version: "29", 263 sdk_version: "XXX", 264 lint: { 265 strict_updatability_linting: true, 266 }, 267 } 268` 269 for _, testCase := range testCases { 270 thisBp := strings.Replace(bp, "XXX", testCase.sdk_version, 1) 271 272 result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, FixtureWithPrebuiltApis(map[string][]string{ 273 "30": {"foo"}, 274 "10000": {"foo"}, 275 })). 276 RunTestWithBp(t, thisBp) 277 278 foo := result.ModuleForTests("foo", "android_common") 279 sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto")) 280 if !strings.Contains(*sboxProto.Commands[0].Command, "/"+testCase.expected_file) { 281 t.Error("did not use full api database for case", testCase) 282 } 283 } 284} 285