diff options
| author | 2023-02-23 16:53:28 -0800 | |
|---|---|---|
| committer | 2023-02-28 11:43:00 -0800 | |
| commit | dfb7ec50fc86e754d5d495ddddd171808bf03d41 (patch) | |
| tree | b9d2577e708700e339558958641ce8692d42f454 | |
| parent | 49f323d997aa4bc436ebb0419f3e61eef16e5208 (diff) | |
Create linter to detect demoting test without attaching a bug id.
Test: `atest SystemUILintCheckerTest`
Bug: 270628073
Change-Id: Id5b64293b6d49391e644bfe5cc47a4a94644737c
3 files changed, 230 insertions, 1 deletions
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DemotingTestWithoutBugDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DemotingTestWithoutBugDetector.kt new file mode 100644 index 000000000000..f64ea4561906 --- /dev/null +++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DemotingTestWithoutBugDetector.kt @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * 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 com.android.internal.systemui.lint + +import com.android.tools.lint.client.api.UElementHandler +import com.android.tools.lint.detector.api.Category +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Implementation +import com.android.tools.lint.detector.api.Issue +import com.android.tools.lint.detector.api.JavaContext +import com.android.tools.lint.detector.api.Scope +import com.android.tools.lint.detector.api.Severity +import com.android.tools.lint.detector.api.SourceCodeScanner +import org.jetbrains.uast.UAnnotation +import org.jetbrains.uast.UElement + +class DemotingTestWithoutBugDetector : Detector(), SourceCodeScanner { + override fun getApplicableUastTypes(): List<Class<out UElement>> { + return listOf(UAnnotation::class.java) + } + + override fun createUastHandler(context: JavaContext): UElementHandler { + return object : UElementHandler() { + override fun visitAnnotation(node: UAnnotation) { + if (node.qualifiedName !in DEMOTING_ANNOTATION) { + return + } + val bugId = node.findAttributeValue("bugId")!!.evaluate() as Int + if (bugId <= 0) { + val location = context.getLocation(node) + val message = "Please attach a bug id to track demoted test" + context.report(ISSUE, node, location, message) + } + } + } + } + + companion object { + val DEMOTING_ANNOTATION = + listOf("androidx.test.filters.FlakyTest", "android.platform.test.annotations.FlakyTest") + + @JvmField + val ISSUE: Issue = + Issue.create( + id = "DemotingTestWithoutBug", + briefDescription = "Demoting a test without attaching a bug.", + explanation = + """ + Annotations (`@FlakyTest`) demote tests to an unmonitored \ + test suite. Please set the `bugId` field in such annotations to track \ + the test status. + """, + category = Category.TESTING, + priority = 8, + severity = Severity.WARNING, + implementation = + Implementation( + DemotingTestWithoutBugDetector::class.java, + Scope.JAVA_FILE_SCOPE + ) + ) + } +} diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt index 84f70502fa45..387b67d231cd 100644 --- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt +++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt @@ -39,7 +39,8 @@ class SystemUIIssueRegistry : IssueRegistry() { RegisterReceiverViaContextDetector.ISSUE, SoftwareBitmapDetector.ISSUE, NonInjectedServiceDetector.ISSUE, - StaticSettingsProviderDetector.ISSUE + StaticSettingsProviderDetector.ISSUE, + DemotingTestWithoutBugDetector.ISSUE ) override val api: Int diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DemotingTestWithoutBugDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DemotingTestWithoutBugDetectorTest.kt new file mode 100644 index 000000000000..557c300635eb --- /dev/null +++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DemotingTestWithoutBugDetectorTest.kt @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * 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 com.android.internal.systemui.lint + +import com.android.tools.lint.checks.infrastructure.TestFile +import com.android.tools.lint.checks.infrastructure.TestFiles +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Issue +import org.junit.Test + +class DemotingTestWithoutBugDetectorTest : SystemUILintDetectorTest() { + + override fun getDetector(): Detector = DemotingTestWithoutBugDetector() + override fun getIssues(): List<Issue> = listOf(DemotingTestWithoutBugDetector.ISSUE) + + @Test + fun testMarkFlaky_withBugId() { + lint() + .files( + TestFiles.java( + """ + package test.pkg; + import androidx.test.filters.FlakyTest; + + @FlakyTest(bugId = 123) + public class TestClass { + public void testCase() {} + } + """ + ) + .indented(), + *stubs + ) + .issues(DemotingTestWithoutBugDetector.ISSUE) + .run() + .expectClean() + + lint() + .files( + TestFiles.java( + """ + package test.pkg; + import android.platform.test.annotations.FlakyTest; + + @FlakyTest(bugId = 123) + public class TestClass { + public void testCase() {} + } + """ + ) + .indented(), + *stubs + ) + .issues(DemotingTestWithoutBugDetector.ISSUE) + .run() + .expectClean() + } + + @Test + fun testMarkFlaky_withoutBugId() { + lint() + .files( + TestFiles.java( + """ + package test.pkg; + import androidx.test.filters.FlakyTest; + + @FlakyTest + public class TestClass { + public void testCase() {} + } + """ + ) + .indented(), + *stubs + ) + .issues(DemotingTestWithoutBugDetector.ISSUE) + .run() + .expect( + """ + src/test/pkg/TestClass.java:4: Warning: Please attach a bug id to track demoted test [DemotingTestWithoutBug] + @FlakyTest + ~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + + lint() + .files( + TestFiles.java( + """ + package test.pkg; + import android.platform.test.annotations.FlakyTest; + + @FlakyTest + public class TestClass { + public void testCase() {} + } + """ + ) + .indented(), + *stubs + ) + .issues(DemotingTestWithoutBugDetector.ISSUE) + .run() + .expect( + """ + src/test/pkg/TestClass.java:4: Warning: Please attach a bug id to track demoted test [DemotingTestWithoutBug] + @FlakyTest + ~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + private val filtersFlakyTestStub: TestFile = + java( + """ + package androidx.test.filters; + + public @interface FlakyTest { + int bugId() default -1; + } + """ + ) + private val annotationsFlakyTestStub: TestFile = + java( + """ + package android.platform.test.annotations; + + public @interface FlakyTest { + int bugId() default -1; + } + """ + ) + private val stubs = arrayOf(filtersFlakyTestStub, annotationsFlakyTestStub) +} |