Replace proxy class names with deterministic ones for test output.

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

(cherrypick commit bc7f8080d1f5d0138cb83cba73a747d43d62c23c)

Bug: 25838574
Bug: 12687968

Change-Id: I08765abd82e41258ce4d1d8bb9dffce70c8b6689
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());