// 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", ], static_libs: ["bar"], min_sdk_version: "29", sdk_version: "current", lint: { strict_updatability_linting: true, }, } java_library { name: "bar", srcs: [ "a.java", ], min_sdk_version: "29", sdk_version: "current", } ` 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") } bar := result.ModuleForTests("bar", "android_common") sboxProto = android.RuleBuilderSboxProtoForTests(t, bar.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") } } func TestJavaLintDatabaseSelectionFull(t *testing.T) { testCases := []string{ "current", "core_platform", "system_current", "S", "30", "10000", } bp := ` java_library { name: "foo", srcs: [ "a.java", ], min_sdk_version: "29", sdk_version: "XXX", lint: { strict_updatability_linting: true, }, } ` for _, testCase := range testCases { thisBp := strings.Replace(bp, "XXX", testCase, 1) result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, FixtureWithPrebuiltApis(map[string][]string{ "30": {"foo"}, "10000": {"foo"}, })). RunTestWithBp(t, thisBp) foo := result.ModuleForTests("foo", "android_common") sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto")) if strings.Contains(*sboxProto.Commands[0].Command, "/api_versions_public_filtered.xml") { t.Error("used public-filtered lint api database for case", testCase) } if !strings.Contains(*sboxProto.Commands[0].Command, "/api_versions.xml") { t.Error("did not use full api database for case", testCase) } } } func TestJavaLintDatabaseSelectionPublicFiltered(t *testing.T) { testCases := []string{ "module_current", "system_server_current", } bp := ` java_library { name: "foo", srcs: [ "a.java", ], min_sdk_version: "29", sdk_version: "XXX", lint: { strict_updatability_linting: true, }, } ` for _, testCase := range testCases { thisBp := strings.Replace(bp, "XXX", testCase, 1) result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules). RunTestWithBp(t, thisBp) foo := result.ModuleForTests("foo", "android_common") sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto")) if !strings.Contains(*sboxProto.Commands[0].Command, "/api_versions_public_filtered.xml") { t.Error("did not use public-filtered lint api database for case", testCase) } if strings.Contains(*sboxProto.Commands[0].Command, "/api_versions.xml") { t.Error("used full api database for case", testCase) } } }