188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz/*
288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz * Licensed to the Apache Software Foundation (ASF) under one or more
388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz * contributor license agreements.  See the NOTICE file distributed with
488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz * this work for additional information regarding copyright ownership.
588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz * The ASF licenses this file to You under the Apache License, Version 2.0
688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz * (the "License"); you may not use this file except in compliance with
788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz * the License.  You may obtain a copy of the License at
888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *
988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *     http://www.apache.org/licenses/LICENSE-2.0
1088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *
1188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *  Unless required by applicable law or agreed to in writing, software
1288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *  distributed under the License is distributed on an "AS IS" BASIS,
1388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *
1588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *  See the License for the specific language governing permissions and
1688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz *  limitations under the License.
1788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz */
1888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
1988deedf7240f24595b661f378f30d045edf69411Sebastien Hertzpackage org.apache.harmony.jpda.tests.jdwp.ObjectReference;
2088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
2188deedf7240f24595b661f378f30d045edf69411Sebastien Hertzimport org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
2288deedf7240f24595b661f378f30d045edf69411Sebastien Hertzimport org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
2388deedf7240f24595b661f378f30d045edf69411Sebastien Hertzimport org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
2488deedf7240f24595b661f378f30d045edf69411Sebastien Hertzimport org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
2588deedf7240f24595b661f378f30d045edf69411Sebastien Hertzimport org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject;
2688deedf7240f24595b661f378f30d045edf69411Sebastien Hertzimport org.apache.harmony.jpda.tests.framework.jdwp.Value;
2788deedf7240f24595b661f378f30d045edf69411Sebastien Hertzimport org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
2888deedf7240f24595b661f378f30d045edf69411Sebastien Hertzimport org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
2988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
3088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
3188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz/**
3288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz * JDWP unit test for ObjectReference.InvokeMethod command.
3388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz */
3488deedf7240f24595b661f378f30d045edf69411Sebastien Hertzpublic class InvokeMethod003Test extends JDWPSyncTestCase {
35e1833aa2673d4f975ad35e7a39317feeea922fe1Sebastien Hertz    @Override
3688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz    protected String getDebuggeeClassName() {
3788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        return "org.apache.harmony.jpda.tests.jdwp.ObjectReference.InvokeMethod003Debuggee";
3888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz    }
3988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
4088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz    /**
4188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * This testcase exercises ObjectReference.InvokeMethod command.
4288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * <BR>The test first starts the debuggee, requests METHOD_ENTRY event so
4388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * the application suspends on first invoke.
4488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * <BR>Then sends ObjectReference.InvokeMethod command to invoke method
4588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * Object.toString on an instance of a subclass of Object overriding the
4688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * method toString.
4788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * <BR>Checks that returned value is expected string value and returned
4888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * exception object is null.
4988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     * <BR>Finally resumes the application.
5088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz     */
5188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz    public void testInvokeMethod_toString() {
5288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
5388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
5488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        // Get debuggee class ID.
5588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        String debuggeeClassSig = "Lorg/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethod003Debuggee;";
5688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        long debuggeeTypeID = debuggeeWrapper.vmMirror.getClassID(debuggeeClassSig);
5788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Failed to find debuggee class", debuggeeTypeID != 0);
5888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
5988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        // Set METHOD_ENTRY event request so application is suspended.
6088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        CommandPacket packet = new CommandPacket(
6188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                JDWPCommands.EventRequestCommandSet.CommandSetID,
6288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                JDWPCommands.EventRequestCommandSet.SetCommand);
6388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
6488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
6588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsInt(1);
6688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsByte((byte) 4);  // class-only modifier.
6788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsReferenceTypeID(debuggeeTypeID);
6888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
6988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        checkReplyPacket(reply, "EventRequest::Set command");
7088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
7188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        int requestID = reply.getNextValueAsInt();
7288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        logWriter.println(" EventRequest.Set: requestID=" + requestID);
7388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertAllDataRead(reply);
7488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
7588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
7688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        long targetThreadID = 0;
7788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        // Wait for METHOD_ENTRY event and collect event thread.
7888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        CommandPacket event = debuggeeWrapper.vmMirror.receiveEvent();
7988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        byte suspendPolicy = event.getNextValueAsByte();
8088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        int events = event.getNextValueAsInt();
8188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        logWriter.println(" EVENT_THREAD event: suspendPolicy=" + suspendPolicy + " events=" + events);
8288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        for (int i = 0; i < events; i++) {
8388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz            byte eventKind = event.getNextValueAsByte();
8488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz            int newRequestID = event.getNextValueAsInt();
8588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz            long threadID = event.getNextValueAsThreadID();
8688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz            //Location location =
8788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                event.getNextValueAsLocation();
8888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz            logWriter.println("  EVENT_THREAD event " + i + ": eventKind="
8988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                    + eventKind + " requestID=" + newRequestID + " threadID="
9088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                    + threadID);
9188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz            if (newRequestID == requestID) {
9288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                targetThreadID = threadID;
9388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz            }
9488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        }
9588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertAllDataRead(event);
9688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Invalid targetThreadID, must be != 0", targetThreadID != 0);
9788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
9888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        //  Now we're suspended, clear event request.
9988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet = new CommandPacket(
10088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                JDWPCommands.EventRequestCommandSet.CommandSetID,
10188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                JDWPCommands.EventRequestCommandSet.ClearCommand);
10288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
10388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsInt(requestID);
10488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        reply = debuggeeWrapper.vmMirror.performCommand(packet);
10588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        checkReplyPacket(reply, "EventRequest::Clear command");
10688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertAllDataRead(reply);
10788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
10888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        // Load value of the invoke's receiver.
10988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        long receiverFieldID = debuggeeWrapper.vmMirror.getFieldID(debuggeeTypeID, "invokeReceiver");
11088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Failed to find receiver field", receiverFieldID != 0);
11188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
11288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        logWriter.println(" Send ReferenceType.GetValues");
11388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet = new CommandPacket(
11488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
11588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                JDWPCommands.ReferenceTypeCommandSet.GetValuesCommand);
11688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsReferenceTypeID(debuggeeTypeID);
11788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsInt(1);  // looking for one field.
11888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsFieldID(receiverFieldID);  // the field we're looking for.
11988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        reply = debuggeeWrapper.vmMirror.performCommand(packet);
12088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        checkReplyPacket(reply, "ReferenceType::GetValues command");
12188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        int valuesCount = reply.getNextValueAsInt();  // number of field values.
12288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        Value fieldValue = reply.getNextValueAsValue();
12388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertAllDataRead(reply);
12488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertEquals("Not the right number of values", 1, valuesCount);
12588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertNotNull("Received null value", fieldValue);
12688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertEquals("Expected an object value", JDWPConstants.Tag.OBJECT_TAG, fieldValue.getTag());
12788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        long receiverObjectID = fieldValue.getLongValue();
12888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Field is null", receiverObjectID != 0);
12988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
13088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        // Get test class ID.
13188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        String testClassSig = "Lorg/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethod003Debuggee$TestClass;";
13288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        long testTypeID = debuggeeWrapper.vmMirror.getClassID(testClassSig);
13388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Failed to find test class", testTypeID != 0);
13488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
13588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        // Get java.lang.Object class ID.
13688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        long objectTypeID = debuggeeWrapper.vmMirror.getClassID("Ljava/lang/Object;");
13788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Failed to find java.lang.Object class", objectTypeID != 0);
13888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
13988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        // Get java.lang.Object.toString method ID.
14088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        long targetMethodID = debuggeeWrapper.vmMirror.getMethodID(objectTypeID, "toString");
14188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Failed to find method", targetMethodID != 0);
14288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
14388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        // Invoke method.
14488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet = new CommandPacket(
14588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
14688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                JDWPCommands.ObjectReferenceCommandSet.InvokeMethodCommand);
14788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsObjectID(receiverObjectID);
14888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsThreadID(targetThreadID);
14988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsClassID(testTypeID);  // TestClass type ID.
15088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsMethodID(targetMethodID);  // Object.toString method ID.
15188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsInt(0);  // no arguments.
15288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        packet.setNextValueAsInt(0);  // invoke options.
15388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        logWriter.println(" Send ObjectReference.InvokeMethod without Exception");
15488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        reply = debuggeeWrapper.vmMirror.performCommand(packet);
15588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        checkReplyPacket(reply, "ObjectReference::InvokeMethod command");
15688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
15788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        Value returnValue = reply.getNextValueAsValue();
15888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertNotNull("Returned value is null", returnValue);
15988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertEquals("Returned value tag is incorrect", JDWPConstants.Tag.STRING_TAG, returnValue.getTag());
16088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        long stringID = returnValue.getLongValue();
16188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Returned string is null", stringID != 0);
16288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
16388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        String returnedString = debuggeeWrapper.vmMirror.getStringValue(stringID);
16488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertEquals("Invalid returned value,", "TestClass.toString()", returnedString);
16588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        logWriter.println(" ObjectReference.InvokeMethod: returnedString=\""
16688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                + returnedString + "\"");
16788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
16888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        TaggedObject exception = reply.getNextValueAsTaggedObject();
16988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertNotNull("Returned exception is null", exception);
17088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertTrue("Invalid exception object ID:<" + exception.objectID + ">", exception.objectID == 0);
17188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertEquals("Invalid exception tag,", JDWPConstants.Tag.OBJECT_TAG, exception.tag
17288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
17388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                , JDWPConstants.Tag.getName(exception.tag));
17488deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        logWriter.println(" ClassType.InvokeMethod: exception.tag="
17588deedf7240f24595b661f378f30d045edf69411Sebastien Hertz                + exception.tag + " exception.objectID=" + exception.objectID);
17688deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        assertAllDataRead(reply);
17788deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
17888deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        //  Let's resume application
17988deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        debuggeeWrapper.vmMirror.resume();
18088deedf7240f24595b661f378f30d045edf69411Sebastien Hertz
18188deedf7240f24595b661f378f30d045edf69411Sebastien Hertz        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
18288deedf7240f24595b661f378f30d045edf69411Sebastien Hertz    }
18388deedf7240f24595b661f378f30d045edf69411Sebastien Hertz}
184