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