Merge changes Ia74a2b83,I30a46c8f,Iac7c0149
* changes: Add lint.strict_updatability_linting Move Java lint tests to lint_test.go Forbid bypassing updatability lint checks.
This commit is contained in:
@@ -83,6 +83,7 @@ bootstrap_go_package {
|
|||||||
"java_test.go",
|
"java_test.go",
|
||||||
"jdeps_test.go",
|
"jdeps_test.go",
|
||||||
"kotlin_test.go",
|
"kotlin_test.go",
|
||||||
|
"lint_test.go",
|
||||||
"platform_bootclasspath_test.go",
|
"platform_bootclasspath_test.go",
|
||||||
"platform_compat_config_test.go",
|
"platform_compat_config_test.go",
|
||||||
"plugin_test.go",
|
"plugin_test.go",
|
||||||
|
@@ -1203,107 +1203,6 @@ func TestIncludeSrcs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJavaLint(t *testing.T) {
|
|
||||||
ctx, _ := testJavaWithFS(t, `
|
|
||||||
java_library {
|
|
||||||
name: "foo",
|
|
||||||
srcs: [
|
|
||||||
"a.java",
|
|
||||||
"b.java",
|
|
||||||
"c.java",
|
|
||||||
],
|
|
||||||
min_sdk_version: "29",
|
|
||||||
sdk_version: "system_current",
|
|
||||||
}
|
|
||||||
`, map[string][]byte{
|
|
||||||
"lint-baseline.xml": nil,
|
|
||||||
})
|
|
||||||
|
|
||||||
foo := ctx.ModuleForTests("foo", "android_common")
|
|
||||||
|
|
||||||
sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
|
|
||||||
if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
|
|
||||||
t.Error("did not pass --baseline flag")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJavaLintWithoutBaseline(t *testing.T) {
|
|
||||||
ctx, _ := testJavaWithFS(t, `
|
|
||||||
java_library {
|
|
||||||
name: "foo",
|
|
||||||
srcs: [
|
|
||||||
"a.java",
|
|
||||||
"b.java",
|
|
||||||
"c.java",
|
|
||||||
],
|
|
||||||
min_sdk_version: "29",
|
|
||||||
sdk_version: "system_current",
|
|
||||||
}
|
|
||||||
`, map[string][]byte{})
|
|
||||||
|
|
||||||
foo := ctx.ModuleForTests("foo", "android_common")
|
|
||||||
|
|
||||||
sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
|
|
||||||
if strings.Contains(*sboxProto.Commands[0].Command, "--baseline") {
|
|
||||||
t.Error("passed --baseline flag for non existent file")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
|
|
||||||
android.GroupFixturePreparers(
|
|
||||||
PrepareForTestWithJavaDefaultModules,
|
|
||||||
android.PrepareForTestDisallowNonExistentPaths,
|
|
||||||
).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{`source path "mybaseline.xml" does not exist`})).
|
|
||||||
RunTestWithBp(t, `
|
|
||||||
java_library {
|
|
||||||
name: "foo",
|
|
||||||
srcs: [
|
|
||||||
],
|
|
||||||
min_sdk_version: "29",
|
|
||||||
sdk_version: "system_current",
|
|
||||||
lint: {
|
|
||||||
baseline_filename: "mybaseline.xml",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
|
|
||||||
ctx, _ := testJavaWithFS(t, `
|
|
||||||
java_library {
|
|
||||||
name: "foo",
|
|
||||||
srcs: [
|
|
||||||
"a.java",
|
|
||||||
"b.java",
|
|
||||||
"c.java",
|
|
||||||
],
|
|
||||||
min_sdk_version: "29",
|
|
||||||
sdk_version: "system_current",
|
|
||||||
lint: {
|
|
||||||
error_checks: ["SomeCheck"],
|
|
||||||
baseline_filename: "mybaseline.xml",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`, map[string][]byte{
|
|
||||||
"mybaseline.xml": nil,
|
|
||||||
})
|
|
||||||
|
|
||||||
foo := ctx.ModuleForTests("foo", "android_common")
|
|
||||||
|
|
||||||
sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
|
|
||||||
if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
|
|
||||||
t.Error("did not use the correct file for baseline")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check NewApi") {
|
|
||||||
t.Error("should check NewApi errors")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
|
|
||||||
t.Error("should combine NewApi errors with SomeCheck errors")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGeneratedSources(t *testing.T) {
|
func TestGeneratedSources(t *testing.T) {
|
||||||
ctx, _ := testJavaWithFS(t, `
|
ctx, _ := testJavaWithFS(t, `
|
||||||
java_library {
|
java_library {
|
||||||
|
26
java/lint.go
26
java/lint.go
@@ -26,6 +26,10 @@ import (
|
|||||||
"android/soong/remoteexec"
|
"android/soong/remoteexec"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// lint checks automatically enforced for modules that have different min_sdk_version than
|
||||||
|
// sdk_version
|
||||||
|
var updatabilityChecks = []string{"NewApi"}
|
||||||
|
|
||||||
type LintProperties struct {
|
type LintProperties struct {
|
||||||
// Controls for running Android Lint on the module.
|
// Controls for running Android Lint on the module.
|
||||||
Lint struct {
|
Lint struct {
|
||||||
@@ -53,6 +57,9 @@ type LintProperties struct {
|
|||||||
|
|
||||||
// Name of the file that lint uses as the baseline. Defaults to "lint-baseline.xml".
|
// Name of the file that lint uses as the baseline. Defaults to "lint-baseline.xml".
|
||||||
Baseline_filename *string
|
Baseline_filename *string
|
||||||
|
|
||||||
|
// If true, baselining updatability lint checks (e.g. NewApi) is prohibited. Defaults to false.
|
||||||
|
Strict_updatability_linting *bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,6 +260,13 @@ func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.Ru
|
|||||||
cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks)
|
cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks)
|
||||||
cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks)
|
cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks)
|
||||||
|
|
||||||
|
if BoolDefault(l.properties.Lint.Strict_updatability_linting, false) {
|
||||||
|
if baselinePath := l.getBaselineFilepath(ctx); baselinePath.Valid() {
|
||||||
|
cmd.FlagWithInput("--baseline ", baselinePath.Path())
|
||||||
|
cmd.FlagForEachArg("--disallowed_issues ", updatabilityChecks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return lintPaths{
|
return lintPaths{
|
||||||
projectXML: projectXMLPath,
|
projectXML: projectXMLPath,
|
||||||
configXML: configXMLPath,
|
configXML: configXMLPath,
|
||||||
@@ -298,7 +312,17 @@ func (l *linter) lint(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if l.minSdkVersion != l.compileSdkVersion {
|
if l.minSdkVersion != l.compileSdkVersion {
|
||||||
l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, "NewApi")
|
l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, updatabilityChecks...)
|
||||||
|
_, filtered := android.FilterList(l.properties.Lint.Warning_checks, updatabilityChecks)
|
||||||
|
if len(filtered) != 0 {
|
||||||
|
ctx.PropertyErrorf("lint.warning_checks",
|
||||||
|
"Can't treat %v checks as warnings if min_sdk_version is different from sdk_version.", filtered)
|
||||||
|
}
|
||||||
|
_, filtered = android.FilterList(l.properties.Lint.Disabled_checks, updatabilityChecks)
|
||||||
|
if len(filtered) != 0 {
|
||||||
|
ctx.PropertyErrorf("lint.disabled_checks",
|
||||||
|
"Can't disable %v checks if min_sdk_version is different from sdk_version.", filtered)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
|
extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
|
||||||
|
204
java/lint_test.go
Normal file
204
java/lint_test.go
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
// Copyright 2021 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package java
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"android/soong/android"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestJavaLint(t *testing.T) {
|
||||||
|
ctx, _ := testJavaWithFS(t, `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: [
|
||||||
|
"a.java",
|
||||||
|
"b.java",
|
||||||
|
"c.java",
|
||||||
|
],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
sdk_version: "system_current",
|
||||||
|
}
|
||||||
|
`, map[string][]byte{
|
||||||
|
"lint-baseline.xml": nil,
|
||||||
|
})
|
||||||
|
|
||||||
|
foo := ctx.ModuleForTests("foo", "android_common")
|
||||||
|
|
||||||
|
sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
|
||||||
|
if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
|
||||||
|
t.Error("did not pass --baseline flag")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJavaLintWithoutBaseline(t *testing.T) {
|
||||||
|
ctx, _ := testJavaWithFS(t, `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: [
|
||||||
|
"a.java",
|
||||||
|
"b.java",
|
||||||
|
"c.java",
|
||||||
|
],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
sdk_version: "system_current",
|
||||||
|
}
|
||||||
|
`, map[string][]byte{})
|
||||||
|
|
||||||
|
foo := ctx.ModuleForTests("foo", "android_common")
|
||||||
|
|
||||||
|
sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
|
||||||
|
if strings.Contains(*sboxProto.Commands[0].Command, "--baseline") {
|
||||||
|
t.Error("passed --baseline flag for non existent file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
|
||||||
|
android.GroupFixturePreparers(
|
||||||
|
PrepareForTestWithJavaDefaultModules,
|
||||||
|
android.PrepareForTestDisallowNonExistentPaths,
|
||||||
|
).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{`source path "mybaseline.xml" does not exist`})).
|
||||||
|
RunTestWithBp(t, `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: [
|
||||||
|
],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
sdk_version: "system_current",
|
||||||
|
lint: {
|
||||||
|
baseline_filename: "mybaseline.xml",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
|
||||||
|
ctx, _ := testJavaWithFS(t, `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: [
|
||||||
|
"a.java",
|
||||||
|
"b.java",
|
||||||
|
"c.java",
|
||||||
|
],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
sdk_version: "system_current",
|
||||||
|
lint: {
|
||||||
|
error_checks: ["SomeCheck"],
|
||||||
|
baseline_filename: "mybaseline.xml",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`, map[string][]byte{
|
||||||
|
"mybaseline.xml": nil,
|
||||||
|
})
|
||||||
|
|
||||||
|
foo := ctx.ModuleForTests("foo", "android_common")
|
||||||
|
|
||||||
|
sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
|
||||||
|
if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
|
||||||
|
t.Error("did not use the correct file for baseline")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check NewApi") {
|
||||||
|
t.Error("should check NewApi errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
|
||||||
|
t.Error("should combine NewApi errors with SomeCheck errors")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJavaLintBypassUpdatableChecks(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
bp string
|
||||||
|
error string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "warning_checks",
|
||||||
|
bp: `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: [
|
||||||
|
"a.java",
|
||||||
|
],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
sdk_version: "current",
|
||||||
|
lint: {
|
||||||
|
warning_checks: ["NewApi"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
error: "lint.warning_checks: Can't treat \\[NewApi\\] checks as warnings if min_sdk_version is different from sdk_version.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "disable_checks",
|
||||||
|
bp: `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: [
|
||||||
|
"a.java",
|
||||||
|
],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
sdk_version: "current",
|
||||||
|
lint: {
|
||||||
|
disabled_checks: ["NewApi"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
error: "lint.disabled_checks: Can't disable \\[NewApi\\] checks if min_sdk_version is different from sdk_version.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
errorHandler := android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.error)
|
||||||
|
android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
|
||||||
|
ExtendWithErrorHandler(errorHandler).
|
||||||
|
RunTestWithBp(t, testCase.bp)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
|
||||||
|
bp := `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: [
|
||||||
|
"a.java",
|
||||||
|
],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
sdk_version: "current",
|
||||||
|
lint: {
|
||||||
|
strict_updatability_linting: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`
|
||||||
|
fs := android.MockFS{
|
||||||
|
"lint-baseline.xml": nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
|
||||||
|
RunTestWithBp(t, bp)
|
||||||
|
|
||||||
|
foo := result.ModuleForTests("foo", "android_common")
|
||||||
|
sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
|
||||||
|
if !strings.Contains(*sboxProto.Commands[0].Command,
|
||||||
|
"--baseline lint-baseline.xml --disallowed_issues NewApi") {
|
||||||
|
t.Error("did not restrict baselining NewApi")
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user