Merge "Additional test for SourceDebugExtension"
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionDebuggee.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionDebuggee.java
index 5a04599..ea90778 100644
--- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionDebuggee.java
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionDebuggee.java
@@ -26,6 +26,7 @@
 package org.apache.harmony.jpda.tests.jdwp.ReferenceType;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Proxy;
 import java.net.URLClassLoader;
 import java.net.URL;
 import java.nio.ByteBuffer;
@@ -173,11 +174,17 @@
             }
         }
 
+        // Instantiate a proxy whose name should contain "$Proxy".
+        Class proxy = Proxy.getProxyClass(SomeInterface.class.getClassLoader(),
+                                          new Class[] { SomeInterface.class });
+
         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY);
         logWriter.println("--> Debuggee: SourceDebugExtensionDebuggee...");
         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
     }
 
+    interface SomeInterface {}
+
     public static void main(String [] args) {
         runDebuggee(SourceDebugExtensionDebuggee.class);
     }
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionTest.java
index 93dbfa9..7f40430 100644
--- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionTest.java
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionTest.java
@@ -43,8 +43,6 @@
     static final String thisCommandName = "ReferenceType.SourceDebugExtension command";
     static final String debuggeeSignature =
             "Lorg/apache/harmony/jpda/tests/jdwp/ReferenceType/SourceDebugExtensionDebuggee;";
-    static final String classWithSourceDebugExtension =
-            "Lorg/apache/harmony/jpda/tests/jdwp/Events/SourceDebugExtensionMockClass;";
     static final String expectedSourceDebugExtension = "SMAP\nhelloworld_jsp.java\nJSP\n*S JSP\n" +
             "*F\n+ 0 helloworld.jsp\nhelloworld.jsp\n*L\n1,5:53\n6:58,3\n7,4:61\n*E\n";
 
@@ -53,6 +51,58 @@
         return "org.apache.harmony.jpda.tests.jdwp.ReferenceType.SourceDebugExtensionDebuggee";
     }
 
+
+    private void doTest(String testName, String classSignature, int expectedErrorCode) {
+        //check capability, relevant for this test
+        logWriter.println("=> Check capability: canGetSourceDebugExtension");
+        if (!debuggeeWrapper.vmMirror.canGetSourceDebugExtension()) {
+            logWriter.println("##WARNING: this VM doesn't possess capability: canGetSourceDebugExtension");
+            return;
+        }
+
+        logWriter.println("==> " + testName + " for " + thisCommandName + ": START...");
+        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+        long refTypeID = getClassIDBySignature(classSignature);
+        logWriter.println("=> Class with SourceDebugExtension = " + classSignature);
+        logWriter.println("=> referenceTypeID for class with SourceDebugExtension = " + refTypeID);
+        logWriter.println("=> CHECK: send " + thisCommandName + " and check reply...");
+
+        CommandPacket checkedCommand = new CommandPacket(
+                JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
+                JDWPCommands.ReferenceTypeCommandSet.SourceDebugExtensionCommand);
+        checkedCommand.setNextValueAsReferenceTypeID(refTypeID);
+
+        ReplyPacket checkedReply = debuggeeWrapper.vmMirror.performCommand(checkedCommand);
+        checkedCommand = null;
+
+        short errorCode = checkedReply.getErrorCode();
+        assertEquals(expectedErrorCode, errorCode);
+
+        switch ( errorCode ) {
+            case JDWPConstants.Error.NONE:
+                logWriter.println("=> No any ERROR is returned");
+                String sourceDebugExtension = checkedReply.getNextValueAsString();
+                logWriter.println("=> Returned SourceDebugExtension = " + sourceDebugExtension);
+                assertEquals(expectedSourceDebugExtension, sourceDebugExtension);
+                break;
+            case JDWPConstants.Error.ABSENT_INFORMATION:
+                logWriter.println("=> ABSENT_INFORMATION is returned");
+                break;
+            default:
+                logWriter.println("\n## FAILURE: " + thisCommandName + " returns unexpected ERROR = "
+                    + errorCode + "(" + JDWPConstants.Error.getName(errorCode) + ")");
+                fail(thisCommandName + " returns unexpected ERROR = "
+                    + errorCode + "(" + JDWPConstants.Error.getName(errorCode) + ")");
+        }
+
+        assertAllDataRead(checkedReply);
+
+        logWriter.println("=> CHECK PASSED: Received expected result");
+
+        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+        logWriter.println("==> " + testName + " for " + thisCommandName + ": FINISH");
+    }
+
     /**
      * This testcase exercises ReferenceType.SourceDebugExtension command.
      *
@@ -65,51 +115,77 @@
      * the JSR45 metadata matches the expected value.
      */
     public void testSourceDebugExtension001() {
-        String thisTestName = "testSourceDebugExtension001";
+        doTest("testSourceDebugExtension001",
+               "Lorg/apache/harmony/jpda/tests/jdwp/Events/SourceDebugExtensionMockClass;",
+               JDWPConstants.Error.NONE);
+    }
 
-        //check capability, relevant for this test
-        logWriter.println("=> Check capability: canGetSourceDebugExtension");
-        if (!debuggeeWrapper.vmMirror.canGetSourceDebugExtension()) {
-            logWriter.println("##WARNING: this VM doesn't possess capability: canGetSourceDebugExtension");
-            return;
+    /**
+     * This testcase exercises ReferenceType.SourceDebugExtension command.
+     *
+     * The class queried is a primitive type which on ART does not
+     * have an associated DEX cache.
+     */
+    public void testSourceDebugExtension002() {
+        doTest("testSourceDebugExtension001", "I", JDWPConstants.Error.ABSENT_INFORMATION);
+    }
+
+    /**
+     * This testcase exercises ReferenceType.SourceDebugExtension command.
+     *
+     * The class queried is a primitive array which on ART does not
+     * have an associated DEX cache.
+     */
+    public void testSourceDebugExtension003() {
+        doTest("testSourceDebugExtension003", "[I", JDWPConstants.Error.ABSENT_INFORMATION);
+    }
+
+    /**
+     * This testcase exercises ReferenceType.SourceDebugExtension command.
+     *
+     * The class queried is an array which on ART does not have an
+     * associated DEX cache.
+     */
+    public void testSourceDebugExtension004() {
+        doTest("testSourceDebugExtension004", "[Ljava/lang/String;",
+               JDWPConstants.Error.ABSENT_INFORMATION);
+    }
+
+    /**
+     * This testcase exercises ReferenceType.SourceDebugExtension command.
+     *
+     * The test queries all classes to find a proxy class and then
+     * tries he SourceDebugExtension command on the proxy class. The
+     * debuggee instantiates a proxy so we know there is at least one.
+     */
+    public void testSourceDebugExtension005() {
+        // Identifying the name of a proxy class is tricky so get all class names and walk them:
+
+        logWriter.println("==> Send VirtualMachine::AllClasses command...");
+        CommandPacket packet = new CommandPacket(
+            JDWPCommands.VirtualMachineCommandSet.CommandSetID,
+            JDWPCommands.VirtualMachineCommandSet.AllClassesCommand);
+        ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
+        checkReplyPacket(reply, "VirtualMachine::AllClasses command");
+
+        long typeID;
+        String signature;
+        int status;
+        int classes = reply.getNextValueAsInt();
+        int count = 0;
+        for (int i = 0; i < classes; i++) {
+            reply.getNextValueAsByte();
+            typeID = reply.getNextValueAsReferenceTypeID();
+            signature = reply.getNextValueAsString();
+            status = reply.getNextValueAsInt();
+            if (signature.contains("$Proxy")) {
+                doTest("testSourceDebugExtension005", signature,
+                       JDWPConstants.Error.ABSENT_INFORMATION);
+                return;
+            }
         }
 
-        logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": START...");
-        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
-        long refTypeID = getClassIDBySignature(classWithSourceDebugExtension);
-        logWriter.println("=> Class with SourceDebugExtension = " + classWithSourceDebugExtension);
-        logWriter.println("=> referenceTypeID for class with SourceDebugExtension = " + refTypeID);
-        logWriter.println("=> CHECK: send " + thisCommandName + " and check reply...");
-
-        CommandPacket checkedCommand = new CommandPacket(
-                JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
-                JDWPCommands.ReferenceTypeCommandSet.SourceDebugExtensionCommand);
-        checkedCommand.setNextValueAsReferenceTypeID(refTypeID);
-
-        ReplyPacket checkedReply = debuggeeWrapper.vmMirror.performCommand(checkedCommand);
-        checkedCommand = null;
-
-        short errorCode = checkedReply.getErrorCode();
-
-        switch ( errorCode ) {
-            case JDWPConstants.Error.NONE:
-                logWriter.println("=> No any ERROR is returned");
-                String sourceDebugExtension = checkedReply.getNextValueAsString();
-                logWriter.println("=> Returned SourceDebugExtension = " + sourceDebugExtension);
-                assertEquals(expectedSourceDebugExtension, sourceDebugExtension);
-                break;
-            default:
-                logWriter.println("\n## FAILURE: " + thisCommandName + " returns unexpected ERROR = "
-                    + errorCode + "(" + JDWPConstants.Error.getName(errorCode) + ")");
-                fail(thisCommandName + " returns unexpected ERROR = "
-                    + errorCode + "(" + JDWPConstants.Error.getName(errorCode) + ")");
-        }
-
-        assertAllDataRead(checkedReply);
-
-        logWriter.println("=> CHECK PASSED: No any unexpected ERROR is returned");
-
-        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
-        logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": FINISH");
+        logWriter.println("\n## FAILURE: testSourceDebugExtension005 did not find a proxy class");
+        fail("testSourceDebugExtension005 did not find a proxy class");
     }
 }