From bc7f8080d1f5d0138cb83cba73a747d43d62c23c Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Fri, 4 Dec 2015 16:18:49 -0800 Subject: [PATCH] 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 --- test/005-annotations/expected.txt | 2 +- .../src/android/test/anno/TestAnnotations.java | 3 ++- test/044-proxy/expected.txt | 6 +++--- test/044-proxy/src/BasicTest.java | 10 +++++++--- test/044-proxy/src/Main.java | 22 ++++++++++++++++++++++ test/044-proxy/src/NarrowingTest.java | 4 +++- 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/test/005-annotations/expected.txt b/test/005-annotations/expected.txt index 180adf868..3d9fd8bcf 100644 --- a/test/005-annotations/expected.txt +++ b/test/005-annotations/expected.txt @@ -89,7 +89,7 @@ annotations on TYPE class android.test.anno.FullyNoted(1): 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 2f0a8d31c..bc89f1682 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.annotation.Annotation; 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 @@ public class TestAnnotations { 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 052c8faf1..be7023e49 100644 --- a/test/044-proxy/expected.txt +++ b/test/044-proxy/expected.txt @@ -42,7 +42,7 @@ Invoke public abstract java.lang.String Shapes.blob() (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 @@ Invoke public abstract void Shapes.upCheck() throws java.lang.InterruptedExcepti 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 @@ Got expected exception 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 15732978a..445a6cc46 100644 --- a/test/044-proxy/src/BasicTest.java +++ b/test/044-proxy/src/BasicTest.java @@ -84,7 +84,8 @@ public class BasicTest { }); 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 @@ public class BasicTest { /* 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 @@ class MyInvocationHandler implements InvocationHandler { 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 @@ class MyInvocationHandler implements InvocationHandler { 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 05e8e5b51..1f23b95cf 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 @@ public class Main { 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 proxyClassNameMap = new HashMap(); + + private static int uniqueTestProxyClassNum = 0; } diff --git a/test/044-proxy/src/NarrowingTest.java b/test/044-proxy/src/NarrowingTest.java index 3b94b7627..5b80d7284 100644 --- a/test/044-proxy/src/NarrowingTest.java +++ b/test/044-proxy/src/NarrowingTest.java @@ -45,9 +45,11 @@ class NarrowingTest { } } }); + 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()); -- 2.11.0