Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f515de0 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Prevent any more JUnit 3 based tests on Ravenwood" into main

parents 2b074578 4d12e7ec
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -327,6 +327,10 @@ fun ClassNode.isSynthetic(): Boolean {
    return (this.access and Opcodes.ACC_SYNTHETIC) != 0
}

fun ClassNode.isAbstract(): Boolean {
    return (this.access and Opcodes.ACC_ABSTRACT) != 0
}

fun MethodNode.isSynthetic(): Boolean {
    return (this.access and Opcodes.ACC_SYNTHETIC) != 0
}
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ class RavenizerOptions(
    var enableValidation: SetOnce<Boolean> = SetOnce(true),

    /** Whether the validation failure is fatal or not. */
    var fatalValidation: SetOnce<Boolean> = SetOnce(false),
    var fatalValidation: SetOnce<Boolean> = SetOnce(true),

    /** Whether to remove mockito and dexmaker classes. */
    var stripMockito: SetOnce<Boolean> = SetOnce(false),
+73 −6
Original line number Diff line number Diff line
@@ -16,10 +16,12 @@
package com.android.platform.test.ravenwood.ravenizer

import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.asm.isAbstract
import com.android.hoststubgen.asm.startsWithAny
import com.android.hoststubgen.asm.toHumanReadableClassName
import com.android.hoststubgen.log
import org.objectweb.asm.tree.ClassNode
import java.util.regex.Pattern

fun validateClasses(classes: ClassNodes): Boolean {
    var allOk = true
@@ -41,25 +43,35 @@ fun checkClass(cn: ClassNode, classes: ClassNodes): Boolean {
    }
    var allOk = true

    log.i("Checking ${cn.name.toHumanReadableClassName()}")

    // See if there's any class that extends a legacy base class.
    // But ignore the base classes in android.test.
    if (!cn.name.startsWithAny("android/test/")) {
        allOk = checkSuperClass(cn, cn, classes) && allOk
    if (!cn.isAbstract() && !cn.name.startsWith("android/test/")
        && !isAllowListedLegacyTest(cn)
        ) {
        allOk = checkSuperClassForJunit3(cn, cn, classes) && allOk
    }
    return allOk
}

fun checkSuperClass(targetClass: ClassNode, currentClass: ClassNode, classes: ClassNodes): Boolean {
fun checkSuperClassForJunit3(
    targetClass: ClassNode,
    currentClass: ClassNode,
    classes: ClassNodes,
): Boolean {
    if (currentClass.superName == null || currentClass.superName == "java/lang/Object") {
        return true // No parent class
    }
    // Make sure the class doesn't extend a junit3 TestCase class.
    if (currentClass.superName.isLegacyTestBaseClass()) {
        log.e("Error: Class ${targetClass.name.toHumanReadableClassName()} extends"
                + " a legacy test class ${currentClass.superName.toHumanReadableClassName()}.")
                + " a legacy test class ${currentClass.superName.toHumanReadableClassName()}"
                + ", which is not supported on Ravenwood. Please migrate to Junit4 syntax.")
        return false
    }
    classes.findClass(currentClass.superName)?.let {
        return checkSuperClass(targetClass, it, classes)
        return checkSuperClassForJunit3(targetClass, it, classes)
    }
    // Super class not found.
    // log.w("Class ${currentClass.superName} not found.")
@@ -73,9 +85,64 @@ fun String.isLegacyTestBaseClass(): Boolean {
    return this.startsWithAny(
        "junit/framework/TestCase",

        // In case the test doesn't statically include JUnit, we need
        // In case the test doesn't statically include JUnit, we need the following.
        "android/test/AndroidTestCase",
        "android/test/InstrumentationTestCase",
        "android/test/InstrumentationTestSuite",
    )
}

private val allowListedLegacyTests = setOf(
// List of existing test classes that use the JUnit3 syntax. We exempt them for now, but
// will reject any more of them.
//
// Note, we want internal class names, but for convenience, we use '.'s and '%'s here
// and replace them later. (a '$' would be parsed as a string template.)
    *"""
android.util.proto.cts.DebuggingTest
android.util.proto.cts.EncodedBufferTest
android.util.proto.cts.ProtoOutputStreamBoolTest
android.util.proto.cts.ProtoOutputStreamBytesTest
android.util.proto.cts.ProtoOutputStreamDoubleTest
android.util.proto.cts.ProtoOutputStreamEnumTest
android.util.proto.cts.ProtoOutputStreamFixed32Test
android.util.proto.cts.ProtoOutputStreamFixed64Test
android.util.proto.cts.ProtoOutputStreamFloatTest
android.util.proto.cts.ProtoOutputStreamInt32Test
android.util.proto.cts.ProtoOutputStreamInt64Test
android.util.proto.cts.ProtoOutputStreamObjectTest
android.util.proto.cts.ProtoOutputStreamSFixed32Test
android.util.proto.cts.ProtoOutputStreamSFixed64Test
android.util.proto.cts.ProtoOutputStreamSInt32Test
android.util.proto.cts.ProtoOutputStreamSInt64Test
android.util.proto.cts.ProtoOutputStreamStringTest
android.util.proto.cts.ProtoOutputStreamSwitchedWriteTest
android.util.proto.cts.ProtoOutputStreamTagTest
android.util.proto.cts.ProtoOutputStreamUInt32Test
android.util.proto.cts.ProtoOutputStreamUInt64Test

android.os.cts.BadParcelableExceptionTest
android.os.cts.DeadObjectExceptionTest
android.os.cts.ParcelFormatExceptionTest
android.os.cts.PatternMatcherTest
android.os.cts.RemoteExceptionTest

android.os.storage.StorageManagerBaseTest
android.os.storage.StorageManagerIntegrationTest
android.util.LogTest%PerformanceTest

com.android.server.power.stats.BatteryStatsCounterTest
com.android.server.power.stats.BatteryStatsDualTimerTest
com.android.server.power.stats.BatteryStatsDurationTimerTest
com.android.server.power.stats.BatteryStatsSamplingTimerTest
com.android.server.power.stats.BatteryStatsStopwatchTimerTest
com.android.server.power.stats.BatteryStatsTimeBaseTest
com.android.server.power.stats.BatteryStatsTimerTest

    """.trim().replace('%', '$').replace('.', '/')
        .split(Pattern.compile("""\s+""")).toTypedArray()
)

private fun isAllowListedLegacyTest(targetClass: ClassNode): Boolean {
    return allowListedLegacyTests.contains(targetClass.name)
}
 No newline at end of file