1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License.
17 */
18
19package org.apache.harmony.jpda.tests.jdwp.ObjectReference;
20
21import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
22import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
23import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
24import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
25import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject;
26import org.apache.harmony.jpda.tests.framework.jdwp.Value;
27import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
28import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
29
30
31/**
32 * JDWP unit test for ObjectReference.InvokeMethod command.
33 */
34public class InvokeMethod002Test extends JDWPSyncTestCase {
35    @Override
36    protected String getDebuggeeClassName() {
37        return "org.apache.harmony.jpda.tests.jdwp.ObjectReference.InvokeMethod002Debuggee";
38    }
39
40    /**
41     * This testcase exercises ObjectReference.InvokeMethod command.
42     * <BR>The test first starts the debuggee, request METHOD_ENTRY event so the
43     * application suspends on first invoke.
44     * <BR>Then sends ClassType.InvokeMethod command for method with null
45     * argument. Checks that returned value is expected int value and returned
46     * exception object is null.
47     * <BR>Finally resume the application.
48     */
49    public void testInvokeMethod_null_argument() {
50        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
51
52        // Get debuggee class ID.
53        String debuggeeClassSig = "Lorg/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethod002Debuggee;";
54        long debuggeeTypeID = debuggeeWrapper.vmMirror.getClassID(debuggeeClassSig);
55        assertTrue("Failed to find debuggee class", debuggeeTypeID != 0);
56
57        // Set METHOD_ENTRY event request so application is suspended.
58        CommandPacket packet = new CommandPacket(
59                JDWPCommands.EventRequestCommandSet.CommandSetID,
60                JDWPCommands.EventRequestCommandSet.SetCommand);
61        packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
62        packet.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
63        packet.setNextValueAsInt(1);
64        packet.setNextValueAsByte((byte) 4);  // class-only modifier.
65        packet.setNextValueAsReferenceTypeID(debuggeeTypeID);
66        ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
67        checkReplyPacket(reply, "EventRequest::Set command");
68
69        int requestID = reply.getNextValueAsInt();
70        logWriter.println(" EventRequest.Set: requestID=" + requestID);
71        assertAllDataRead(reply);
72        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
73
74        long targetThreadID = 0;
75        // Wait for METHOD_ENTRY event and collect event thread.
76        CommandPacket event = debuggeeWrapper.vmMirror.receiveEvent();
77        byte suspendPolicy = event.getNextValueAsByte();
78        int events = event.getNextValueAsInt();
79        logWriter.println(" EVENT_THREAD event: suspendPolicy=" + suspendPolicy + " events=" + events);
80        for (int i = 0; i < events; i++) {
81            byte eventKind = event.getNextValueAsByte();
82            int newRequestID = event.getNextValueAsInt();
83            long threadID = event.getNextValueAsThreadID();
84            //Location location =
85                event.getNextValueAsLocation();
86            logWriter.println("  EVENT_THREAD event " + i + ": eventKind="
87                    + eventKind + " requestID=" + newRequestID + " threadID="
88                    + threadID);
89            if (newRequestID == requestID) {
90                targetThreadID = threadID;
91            }
92        }
93        assertAllDataRead(event);
94        assertTrue("Invalid targetThreadID, must be != 0", targetThreadID != 0);
95
96        //  Now we're suspended, clear event request.
97        packet = new CommandPacket(
98                JDWPCommands.EventRequestCommandSet.CommandSetID,
99                JDWPCommands.EventRequestCommandSet.ClearCommand);
100        packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
101        packet.setNextValueAsInt(requestID);
102        reply = debuggeeWrapper.vmMirror.performCommand(packet);
103        checkReplyPacket(reply, "EventRequest::Clear command");
104        assertAllDataRead(reply);
105
106        // Load value of the invoke's receiver.
107        long receiverFieldID = debuggeeWrapper.vmMirror.getFieldID(debuggeeTypeID, "invokeReceiver");
108        assertTrue("Failed to find receiver field", receiverFieldID != 0);
109
110        logWriter.println(" Send ReferenceType.GetValues");
111        packet = new CommandPacket(
112                JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
113                JDWPCommands.ReferenceTypeCommandSet.GetValuesCommand);
114        packet.setNextValueAsReferenceTypeID(debuggeeTypeID);
115        packet.setNextValueAsInt(1);  // looking for one field.
116        packet.setNextValueAsFieldID(receiverFieldID);  // the field we're looking for.
117        reply = debuggeeWrapper.vmMirror.performCommand(packet);
118        checkReplyPacket(reply, "ReferenceType::GetValues command");
119        int valuesCount = reply.getNextValueAsInt();  // number of field values.
120        Value fieldValue = reply.getNextValueAsValue();
121        assertAllDataRead(reply);
122        assertEquals("Not the right number of values", 1, valuesCount);
123        assertNotNull("Received null value", fieldValue);
124        assertEquals("Expected an object value", JDWPConstants.Tag.OBJECT_TAG, fieldValue.getTag());
125        long receiverObjectID = fieldValue.getLongValue();
126        assertTrue("Field is null", receiverObjectID != 0);
127
128        // Get test class ID.
129        String testClassSig = "Lorg/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethod002Debuggee$TestClass;";
130        long testTypeID = debuggeeWrapper.vmMirror.getClassID(testClassSig);
131        assertTrue("Failed to find test class", testTypeID != 0);
132
133        // Get test method ID.
134        long targetMethodID = debuggeeWrapper.vmMirror.getMethodID(testTypeID, "testMethod");
135        assertTrue("Failed to find method", targetMethodID != 0);
136
137        // Invoke test method with null argument.
138        Value nullObjectValue = Value.createObjectValue(JDWPConstants.Tag.OBJECT_TAG, 0);
139        packet = new CommandPacket(
140                JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
141                JDWPCommands.ObjectReferenceCommandSet.InvokeMethodCommand);
142        packet.setNextValueAsObjectID(receiverObjectID);
143        packet.setNextValueAsThreadID(targetThreadID);
144        packet.setNextValueAsClassID(testTypeID);
145        packet.setNextValueAsMethodID(targetMethodID);
146        packet.setNextValueAsInt(1);
147        packet.setNextValueAsValue(nullObjectValue);
148        packet.setNextValueAsInt(0);
149        logWriter.println(" Send ObjectReference.InvokeMethod without Exception");
150        reply = debuggeeWrapper.vmMirror.performCommand(packet);
151        checkReplyPacket(reply, "ObjectReference::InvokeMethod command");
152
153        Value returnValue = reply.getNextValueAsValue();
154        assertNotNull("Returned value is null", returnValue);
155        assertEquals("Invalid returned value,", 123, returnValue.getIntValue());
156        logWriter.println(" ClassType.InvokeMethod: returnValue.getIntValue()="
157                + returnValue.getIntValue());
158
159        TaggedObject exception = reply.getNextValueAsTaggedObject();
160        assertNotNull("Returned exception is null", exception);
161        assertTrue("Invalid exception object ID:<" + exception.objectID + ">", exception.objectID == 0);
162        assertEquals("Invalid exception tag,", JDWPConstants.Tag.OBJECT_TAG, exception.tag
163                , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
164                , JDWPConstants.Tag.getName(exception.tag));
165        logWriter.println(" ClassType.InvokeMethod: exception.tag="
166                + exception.tag + " exception.objectID=" + exception.objectID);
167        assertAllDataRead(reply);
168
169        //  Let's resume application
170        debuggeeWrapper.vmMirror.resume();
171
172        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
173    }
174}
175