Ensure serialVersionUID computation for Throwable subclass is stable

Adds a test to ensure that the default serialVersionUID computed for
a Throwable subclass in an app with targetSdkVersion=23 does not change.
This is to protect against changes in Throwable breaking existing
behavior in those apps.

Did not add a test to check the default SUID computed for a Throwable
subclass for apps with targetSdkVersion>=23 as that behavior is
well tested in
    ./luni/src/test/java/libcore/java/io/ObjectStreamClassTest.java

(cherry picked 24ac60ad50fd9b984dd5de68c64c2acc9ee0823a)

Bug: 109930347
Test: atest core-tests:libcore.java.lang.ThrowableTest
Change-Id: I0d53d935919f1dcb2cc2cd082fc0dd4e6f1e86ce
diff --git a/luni/src/test/java/libcore/java/lang/ThrowableTest.java b/luni/src/test/java/libcore/java/lang/ThrowableTest.java
index 3479a22..74b1956 100644
--- a/luni/src/test/java/libcore/java/lang/ThrowableTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThrowableTest.java
@@ -16,13 +16,22 @@
 
 package libcore.java.lang;
 
+import java.io.ObjectStreamClass;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Arrays;
-import junit.framework.TestCase;
+import libcore.junit.junit3.TestCaseWithRules;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
 import libcore.libcore.util.SerializationTester;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
 
-public class ThrowableTest extends TestCase {
+public class ThrowableTest extends TestCaseWithRules {
+
+    @Rule
+    public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+
     private static class NoStackTraceException extends Exception {
         @Override
         public synchronized Throwable fillInStackTrace() {
@@ -315,6 +324,32 @@
         }.test();
     }
 
+    /**
+     * Detect issue that caused b/109930347
+     *
+     * <p>Due to a bug in the default serialVersionUID calculation that is used for apps with
+     * targetSdkVersion <= 23 changes in {@link Throwable} can affect the default SUID for
+     * subclasses of {@link Throwable}.
+     *
+     * <p>This test protects against changes in Throwable (e.g. removing Android specific patches)
+     * that would cause a change in the default SUID of Throwable subclasses in apps with
+     * targetSdkVersion <= 23. It does so by checking the default SUID for a Throwable subclass,
+     * computed as by an app with targetSdkVersion <= 23, against a known good value.
+     */
+    @TargetSdkVersion(23)
+    public void testThrowableSubclassSerialVersionUIDComputation_target23() {
+        ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(ThrowableSubclass.class);
+        assertEquals(
+            "SerialVersionUID computation for Throwable subclass is broken for targetSdkVersion 23",
+            -1036450421582688704L, objectStreamClass.getSerialVersionUID());
+    }
+
+    public static class ThrowableSubclass extends Throwable {
+        public ThrowableSubclass(String message) {
+            super(message);
+        }
+    }
+
     private void assertSerialized(final Throwable throwable, String golden) {
         new SerializationTester<Throwable>(throwable, golden) {
             @Override protected boolean equals(Throwable a, Throwable b) {