diff options
| author | 2024-10-31 13:52:21 -0700 | |
|---|---|---|
| committer | 2024-10-31 14:44:31 -0700 | |
| commit | 4d12e7eca4e7a50b22e6a889233c40e2b279c22c (patch) | |
| tree | 30cd1c0151d34d799841e319897970a25e09a0dc | |
| parent | 8dcfa5caa2339cb0bb95b7fc47a14d005357a2ec (diff) | |
Prevent any more JUnit 3 based tests on Ravenwood
Flag: EXEMPT host test change only
Bug: 363271377
Test: m $(./ravenwood/scripts/list-ravenwood-tests.sh )
Change-Id: I03553c286144c7259abdd7cb084fc15e29da1b85
3 files changed, 78 insertions, 7 deletions
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt index a02082d12934..f47aaba8ef22 100644 --- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt +++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt @@ -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 } diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt index 32dcbe546f3c..a0e5599c0a7c 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/RavenizerOptions.kt @@ -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), diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt index 27092d28ae5e..8ec0932d89dd 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt @@ -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 |