xref: /aosp_15_r20/frameworks/base/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Utils.kt (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.platform.test.ravenwood.ravenizer
17 
18 import android.platform.test.annotations.internal.InnerRunner
19 import android.platform.test.annotations.NoRavenizer
20 import android.platform.test.ravenwood.RavenwoodAwareTestRunner
21 import com.android.hoststubgen.asm.ClassNodes
22 import com.android.hoststubgen.asm.findAnyAnnotation
23 import com.android.hoststubgen.asm.startsWithAny
24 import com.android.hoststubgen.asm.toHumanReadableClassName
25 import org.junit.rules.TestRule
26 import org.junit.runner.RunWith
27 import org.objectweb.asm.Type
28 
29 data class TypeHolder(
30     val clazz: Class<*>,
31 ) {
32     val type = Type.getType(clazz)
33     val desc = type.descriptor
34     val descAsSet = setOf<String>(desc)
35     val internlName = type.internalName
36     val humanReadableName = type.internalName.toHumanReadableClassName()
37 }
38 
39 val testAnotType = TypeHolder(org.junit.Test::class.java)
40 val ruleAnotType = TypeHolder(org.junit.Rule::class.java)
41 val classRuleAnotType = TypeHolder(org.junit.ClassRule::class.java)
42 val runWithAnotType = TypeHolder(RunWith::class.java)
43 val innerRunnerAnotType = TypeHolder(InnerRunner::class.java)
44 val noRavenizerAnotType = TypeHolder(NoRavenizer::class.java)
45 
46 val testRuleType = TypeHolder(TestRule::class.java)
47 val ravenwoodTestRunnerType = TypeHolder(RavenwoodAwareTestRunner::class.java)
48 
49 /**
50  * Returns true, if a test looks like it's a test class which needs to be processed.
51  */
isTestLookingClassnull52 fun isTestLookingClass(classes: ClassNodes, className: String): Boolean {
53     // Similar to  com.android.tradefed.lite.HostUtils.testLoadClass(), except it's more lenient,
54     // and accept non-public and/or abstract classes.
55     // HostUtils also checks "Suppress" or "SuiteClasses" but this one doesn't.
56     // TODO: SuiteClasses may need to be supported.
57 
58     val cn = classes.findClass(className) ?: return false
59 
60     if (cn.findAnyAnnotation(runWithAnotType.descAsSet) != null) {
61         return true
62     }
63     cn.methods?.forEach { method ->
64         if (method.findAnyAnnotation(testAnotType.descAsSet) != null) {
65             return true
66         }
67     }
68 
69     // Check the super class.
70     if (cn.superName == null) {
71         return false
72     }
73     return isTestLookingClass(classes, cn.superName)
74 }
75 
isRavenwoodClassnull76 fun String.isRavenwoodClass(): Boolean {
77     return this.startsWithAny(
78         "com/android/hoststubgen/",
79         "android/platform/test/ravenwood",
80         "com/android/ravenwood/",
81         "com/android/platform/test/ravenwood/",
82     )
83 }
84 
85 /**
86  * Classes that should never be modified.
87  */
shouldByBypassednull88 fun String.shouldByBypassed(): Boolean {
89     if (this.isRavenwoodClass()) {
90         return true
91     }
92     return this.startsWithAny(
93         "java/", // just in case...
94         "javax/",
95         "junit/",
96         "org/junit/",
97         "org/mockito/",
98         "kotlin/",
99         "androidx/",
100         "android/support/",
101         // TODO -- anything else?
102     )
103 }
104 
105 /**
106  * Files that should be removed when "--strip-mockito" is set.
107  */
isMockitoFilenull108 fun String.isMockitoFile(): Boolean {
109     return this.startsWithAny(
110         "org/mockito/", // Mockito
111         "com/android/dx/", // DexMaker
112         "mockito-extensions/", // DexMaker overrides
113     )
114 }
115 
includeUnsupportedMockitonull116 fun includeUnsupportedMockito(classes: ClassNodes): Boolean {
117     return classes.findClass("com/android/dx/DexMaker") != null
118             || classes.findClass("org/mockito/Matchers") != null
119 }
120