Replace proxy class names with deterministic ones for test output.

This should avoid potentially flaky test failures in 005-annotations
and 044-proxy.

Bug: 25838574
Bug: 12687968

Change-Id: I08765abd82e41258ce4d1d8bb9dffce70c8b6689
diff --git a/test/005-annotations/expected.txt b/test/005-annotations/expected.txt
index 180adf8..3d9fd8b 100644
--- a/test/005-annotations/expected.txt
+++ b/test/005-annotations/expected.txt
@@ -89,7 +89,7 @@
   annotations on FIELD int android.test.anno.FullyNoted.mBar:
     @android.test.anno.AnnoFancyField(nombre=fubar)
       interface android.test.anno.AnnoFancyField
-    aff: @android.test.anno.AnnoFancyField(nombre=fubar) / class $Proxy13
+    aff: @android.test.anno.AnnoFancyField(nombre=fubar) / true
     --> nombre is 'fubar'
 
 SimplyNoted.get(AnnoSimpleType) = @android.test.anno.AnnoSimpleType()
diff --git a/test/005-annotations/src/android/test/anno/TestAnnotations.java b/test/005-annotations/src/android/test/anno/TestAnnotations.java
index 2f0a8d3..bc89f16 100644
--- a/test/005-annotations/src/android/test/anno/TestAnnotations.java
+++ b/test/005-annotations/src/android/test/anno/TestAnnotations.java
@@ -20,6 +20,7 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.util.TreeMap;
 
 public class TestAnnotations {
@@ -81,7 +82,7 @@
             AnnoFancyField aff;
             aff = (AnnoFancyField) f.getAnnotation(AnnoFancyField.class);
             if (aff != null) {
-                System.out.println("    aff: " + aff + " / " + aff.getClass());
+                System.out.println("    aff: " + aff + " / " + Proxy.isProxyClass(aff.getClass()));
                 System.out.println("    --> nombre is '" + aff.nombre() + "'");
             }
         }
diff --git a/test/044-proxy/expected.txt b/test/044-proxy/expected.txt
index 052c8fa..be7023e 100644
--- a/test/044-proxy/expected.txt
+++ b/test/044-proxy/expected.txt
@@ -42,7 +42,7 @@
  (no args)
 --- blob
 Success: method blob res=mix
-$Proxy1.getTrace null:-1
+$PROXY_CLASS_NAME0$.getTrace null:-1
 Invoke public abstract void Shapes.upChuck()
  (no args)
 Got expected ioobe
@@ -51,7 +51,7 @@
 Got expected ie
 
 Proxy interfaces: [interface Quads, interface Colors, interface Trace]
-Proxy methods: [public final java.lang.String $Proxy1.blob(), public final double $Proxy1.blue(int), public final R0a $Proxy1.checkMe(), public final R0aa $Proxy1.checkMe(), public final R0base $Proxy1.checkMe(), public final void $Proxy1.circle(int), public final boolean $Proxy1.equals(java.lang.Object), public final void $Proxy1.getTrace(), public final int $Proxy1.green(double), public final int $Proxy1.hashCode(), public final int $Proxy1.mauve(java.lang.String), public final int $Proxy1.rectangle(int,int), public final int $Proxy1.red(float), public final int $Proxy1.square(int,int), public final java.lang.String $Proxy1.toString(), public final int $Proxy1.trapezoid(int,double,int), public final void $Proxy1.upCheck() throws java.lang.InterruptedException, public final void $Proxy1.upChuck()]
+Proxy methods: [public final java.lang.String $PROXY_CLASS_NAME0$.blob(), public final double $PROXY_CLASS_NAME0$.blue(int), public final R0a $PROXY_CLASS_NAME0$.checkMe(), public final R0aa $PROXY_CLASS_NAME0$.checkMe(), public final R0base $PROXY_CLASS_NAME0$.checkMe(), public final void $PROXY_CLASS_NAME0$.circle(int), public final boolean $PROXY_CLASS_NAME0$.equals(java.lang.Object), public final void $PROXY_CLASS_NAME0$.getTrace(), public final int $PROXY_CLASS_NAME0$.green(double), public final int $PROXY_CLASS_NAME0$.hashCode(), public final int $PROXY_CLASS_NAME0$.mauve(java.lang.String), public final int $PROXY_CLASS_NAME0$.rectangle(int,int), public final int $PROXY_CLASS_NAME0$.red(float), public final int $PROXY_CLASS_NAME0$.square(int,int), public final java.lang.String $PROXY_CLASS_NAME0$.toString(), public final int $PROXY_CLASS_NAME0$.trapezoid(int,double,int), public final void $PROXY_CLASS_NAME0$.upCheck() throws java.lang.InterruptedException, public final void $PROXY_CLASS_NAME0$.upChuck()]
 Decl annos: []
 Param annos (0) : []
 Modifiers: 17
@@ -84,7 +84,7 @@
 Invoke public abstract void InterfaceW1.bothThrowBase() throws BaseException,SubException,SubSubException
  (no args)
 Got expected exception
-Proxy methods: [public final boolean $Proxy3.equals(java.lang.Object), public final java.lang.Object $Proxy3.foo(), public final java.lang.String $Proxy3.foo(), public final int $Proxy3.hashCode(), public final java.lang.String $Proxy3.toString()]
+Proxy methods: [public final boolean $PROXY_CLASS_NAME1$.equals(java.lang.Object), public final java.lang.Object $PROXY_CLASS_NAME1$.foo(), public final java.lang.String $PROXY_CLASS_NAME1$.foo(), public final int $PROXY_CLASS_NAME1$.hashCode(), public final java.lang.String $PROXY_CLASS_NAME1$.toString()]
 Invocation of public abstract java.lang.String NarrowingTest$I2.foo()
 Invoking foo using I2 type: hello
 Invocation of public abstract java.lang.Object NarrowingTest$I1.foo()
diff --git a/test/044-proxy/src/BasicTest.java b/test/044-proxy/src/BasicTest.java
index 1573297..445a6cc 100644
--- a/test/044-proxy/src/BasicTest.java
+++ b/test/044-proxy/src/BasicTest.java
@@ -84,7 +84,8 @@
         });
         System.out.println("Proxy interfaces: " +
             Arrays.deepToString(proxy.getClass().getInterfaces()));
-        System.out.println("Proxy methods: " + Arrays.deepToString(methods));
+        System.out.println("Proxy methods: " +
+            Main.replaceProxyClassNamesForOutput(Arrays.deepToString(methods)));
         Method meth = methods[methods.length -1];
         System.out.println("Decl annos: " + Arrays.deepToString(meth.getDeclaredAnnotations()));
         Annotation[][] paramAnnos = meth.getParameterAnnotations();
@@ -100,6 +101,7 @@
         /* create the proxy class */
         Class proxyClass = Proxy.getProxyClass(Shapes.class.getClassLoader(),
                             new Class[] { Quads.class, Colors.class, Trace.class });
+        Main.registerProxyClassName(proxyClass.getCanonicalName());
 
         /* create a proxy object, passing the handler object in */
         Object proxy = null;
@@ -262,7 +264,8 @@
             for (int i = 0; i < stackTrace.length; i++) {
                 StackTraceElement ste = stackTrace[i];
                 if (ste.getMethodName().equals("getTrace")) {
-                  System.out.println(ste.getClassName() + "." + ste.getMethodName() + " " +
+                  String outputClassName = Main.replaceProxyClassNamesForOutput(ste.getClassName());
+                  System.out.println(outputClassName + "." + ste.getMethodName() + " " +
                                      ste.getFileName() + ":" + ste.getLineNumber());
                 }
             }
@@ -276,7 +279,8 @@
             for (int i = 0; i < stackTrace.length; i++) {
                 StackTraceElement ste = stackTrace[i];
                 if (ste.getMethodName().equals("getTrace")) {
-                  System.out.println(ste.getClassName() + "." + ste.getMethodName() + " " +
+                  String outputClassName = Main.replaceProxyClassNamesForOutput(ste.getClassName());
+                  System.out.println(outputClassName + "." + ste.getMethodName() + " " +
                                      ste.getFileName() + ":" + ste.getLineNumber());
                 }
             }
diff --git a/test/044-proxy/src/Main.java b/test/044-proxy/src/Main.java
index 05e8e5b..1f23b95 100644
--- a/test/044-proxy/src/Main.java
+++ b/test/044-proxy/src/Main.java
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+import java.util.HashMap;
+
 /**
  * Test java.lang.reflect.Proxy
  */
@@ -30,4 +32,24 @@
         FloatSelect.main(null);
         NativeProxy.main(args);
     }
+
+    // The following code maps from the actual proxy class names (eg $Proxy2) to their test output
+    // names (eg $PROXY_CLASS_NAME1$). This is to avoid the flaky test failures due to potentially
+    // undeterministic proxy class naming.
+
+    public static void registerProxyClassName(String proxyClassName) {
+        proxyClassNameMap.put(proxyClassName,
+                              "$PROXY_CLASS_NAME" + (uniqueTestProxyClassNum++) + "$");
+    }
+
+    public static String replaceProxyClassNamesForOutput(String str) {
+        for (String key : proxyClassNameMap.keySet()) {
+            str = str.replace(key, proxyClassNameMap.get(key));
+        }
+        return str;
+    }
+
+    private static final HashMap<String, String> proxyClassNameMap = new HashMap<String, String>();
+
+    private static int uniqueTestProxyClassNum = 0;
 }
diff --git a/test/044-proxy/src/NarrowingTest.java b/test/044-proxy/src/NarrowingTest.java
index 3b94b76..5b80d72 100644
--- a/test/044-proxy/src/NarrowingTest.java
+++ b/test/044-proxy/src/NarrowingTest.java
@@ -45,9 +45,11 @@
                        }
                    }
                });
+       Main.registerProxyClassName(proxy.getClass().getCanonicalName());
 
        Method[] methods = proxy.getClass().getDeclaredMethods();
-       System.out.println("Proxy methods: " + Arrays.deepToString(methods));
+       System.out.println("Proxy methods: " +
+                          Main.replaceProxyClassNamesForOutput(Arrays.deepToString(methods)));
 
        System.out.println("Invoking foo using I2 type: " + proxy.foo());