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
19/**
20 * @author Viacheslav G. Rybalov
21 */
22
23/**
24 * Created on 11.03.2005
25 */
26package org.apache.harmony.jpda.tests.jdwp.ClassType;
27
28import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
29import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
30import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
31import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
32import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject;
33import org.apache.harmony.jpda.tests.framework.jdwp.Value;
34import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
35import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
36
37
38/**
39 * JDWP unit test for ClassType.NewInstance command.
40 */
41public class NewInstanceTest extends JDWPSyncTestCase {
42
43    protected String getDebuggeeClassName() {
44        return "org.apache.harmony.jpda.tests.jdwp.share.debuggee.InvokeMethodDebuggee";
45    }
46
47    /**
48     * This testcase exercises ClassType.NewInstance command.
49     * <BR>At first the test starts debuggee.
50     * <BR>Then does the following checks:
51     * <BR>&nbsp;&nbsp; - send ClassType.NewInstance command for class,
52     * constructor of which should not throw any Exception, and checks,
53     * that returned new object has expected attributes and returned
54     * exception object is null;
55     * <BR>&nbsp;&nbsp; - send ClassType.NewInstance command for class,
56     * constructor of which should throw some Exception, and checks,
57     * that returned new object is null and returned exception object
58     * is not null and has expected attributes;
59     */
60    public void testNewInstance001() {
61        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
62
63        // Get referenceTypeID
64        CommandPacket packet = new CommandPacket(
65                JDWPCommands.VirtualMachineCommandSet.CommandSetID,
66                JDWPCommands.VirtualMachineCommandSet.ClassesBySignatureCommand);
67        String classSig = "Lorg/apache/harmony/jpda/tests/jdwp/share/debuggee/testClass2;";
68        packet.setNextValueAsString(classSig);
69        ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
70        checkReplyPacket(reply, "VirtualMachine::ClassesBySignature command");
71
72        int classes = reply.getNextValueAsInt();
73        assertTrue(classes == 1); //this class may be loaded only once
74        byte refTypeTag = reply.getNextValueAsByte();
75        long typeID = reply.getNextValueAsReferenceTypeID();
76        int status = reply.getNextValueAsInt();
77        logWriter.println(" VirtualMachine.ClassesBySignature: classes="
78                + classes + "; refTypeTag=" + refTypeTag + "; typeID= " + typeID
79                + "; status=" + status);
80
81        assertAllDataRead(reply);
82        assertEquals("VirtualMachine::ClassesBySignature returned invalid TypeTag,", JDWPConstants.TypeTag.CLASS, refTypeTag
83                , JDWPConstants.TypeTag.getName(JDWPConstants.TypeTag.CLASS)
84                , JDWPConstants.TypeTag.getName(refTypeTag));
85
86        // Get methodID
87        packet = new CommandPacket(
88                JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
89                JDWPCommands.ReferenceTypeCommandSet.MethodsCommand);
90        packet.setNextValueAsClassID(typeID);
91        reply = debuggeeWrapper.vmMirror.performCommand(packet);
92        checkReplyPacket(reply, "ReferenceType::Methods command");
93
94        int declared = reply.getNextValueAsInt();
95        logWriter.println(" ReferenceType.Methods: declared=" + declared);
96        long targetMethodID = 0;
97        for (int i = 0; i < declared; i++) {
98            long methodID = reply.getNextValueAsMethodID();
99            String name = reply.getNextValueAsString();
100            String signature = reply.getNextValueAsString();
101            int modBits = reply.getNextValueAsInt();
102            logWriter.println("  methodID=" + methodID + "; name=" + name
103                    + ";  signature=" + signature + "; modBits=" + modBits);
104            if (name.equals("<init>")) {
105                targetMethodID = methodID;
106            }
107        }
108        assertAllDataRead(reply);
109
110        // Set EventRequest
111        packet = new CommandPacket(
112                JDWPCommands.EventRequestCommandSet.CommandSetID,
113                JDWPCommands.EventRequestCommandSet.SetCommand);
114        packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
115        packet.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
116        packet.setNextValueAsInt(1);
117        packet.setNextValueAsByte((byte) 5);
118        packet.setNextValueAsString("*.InvokeMethodDebuggee");
119
120        reply = debuggeeWrapper.vmMirror.performCommand(packet);
121        checkReplyPacket(reply, "EventRequest::Set command");
122
123        int requestID = reply.getNextValueAsInt();
124        logWriter.println(" EventRequest.Set: requestID=" + requestID);
125        assertAllDataRead(reply);
126        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
127
128        long targetThreadID = 0;
129        // Wait event
130        CommandPacket event = debuggeeWrapper.vmMirror
131                .receiveCertainEvent(JDWPConstants.EventKind.METHOD_ENTRY);
132        byte suspendPolicy = event.getNextValueAsByte();
133        int events = event.getNextValueAsInt();
134        logWriter.println(" EVENT_THREAD event: suspendPolicy=" + suspendPolicy
135                + " events=" + events);
136        for (int i = 0; i < events; i++) {
137            byte eventKind = event.getNextValueAsByte();
138            int newRequestID = event.getNextValueAsInt();
139            long threadID = event.getNextValueAsThreadID();
140            //Location location =
141                event.getNextValueAsLocation();
142            logWriter.println("  EVENT_THREAD event " + i + ": eventKind="
143                    + eventKind + "; requestID=" + newRequestID + "; threadID="
144                    + threadID);
145            if (newRequestID == requestID) {
146                targetThreadID = threadID;
147            }
148        }
149        assertAllDataRead(event);
150        assertTrue("Invalid targetThreadID, must be != 0", targetThreadID != 0);
151
152        //  Let's clear event request
153        packet = new CommandPacket(
154                JDWPCommands.EventRequestCommandSet.CommandSetID,
155                JDWPCommands.EventRequestCommandSet.ClearCommand);
156        packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
157        packet.setNextValueAsInt(requestID);
158        reply = debuggeeWrapper.vmMirror.performCommand(packet);
159        checkReplyPacket(reply, "EventRequest::Clear command");
160        assertAllDataRead(reply);
161
162        // Make NewInstance without Exception
163        packet = new CommandPacket(
164                JDWPCommands.ClassTypeCommandSet.CommandSetID,
165                JDWPCommands.ClassTypeCommandSet.NewInstanceCommand);
166        packet.setNextValueAsClassID(typeID);
167        packet.setNextValueAsThreadID(targetThreadID);
168        packet.setNextValueAsMethodID(targetMethodID);
169        packet.setNextValueAsInt(1);
170        packet.setNextValueAsValue(new Value(false));
171        packet.setNextValueAsInt(0);
172        logWriter.println(" Send ClassType.NewInstance (without Exception)");
173        reply = debuggeeWrapper.vmMirror.performCommand(packet);
174        checkReplyPacket(reply, "ClassType::NewInstance command");
175
176        TaggedObject newObject = reply.getNextValueAsTaggedObject();
177        logWriter.println(" ClassType.NewInstance: newObject.tag="
178                + newObject.tag + "; newObject.objectID=" + newObject.objectID);
179        TaggedObject exception = reply.getNextValueAsTaggedObject();
180        logWriter.println(" ClassType.NewInstance: exception.tag="
181                + exception.tag + "; exception.objectID=" + exception.objectID);
182
183        assertNotNull("newObject is null", newObject);
184        assertTrue("newObject.objectID is 0", newObject.objectID != 0);
185        assertEquals("ClassType::NewInstance returned invalid newObject.tag,", JDWPConstants.Tag.OBJECT_TAG, newObject.tag
186                , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
187                , JDWPConstants.Tag.getName(newObject.tag));
188
189        assertNotNull("exception is null", newObject);
190        assertEquals("ClassType::NewInstance returned invalid exception.objectID,", 0, exception.objectID);
191        assertTrue(exception.tag == JDWPConstants.Tag.OBJECT_TAG);
192        assertAllDataRead(reply);
193
194        //  Let's check object reference
195        packet = new CommandPacket(
196                JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
197                JDWPCommands.ObjectReferenceCommandSet.ReferenceTypeCommand);
198        packet.setNextValueAsObjectID(newObject.objectID);
199        reply = debuggeeWrapper.vmMirror.performCommand(packet);
200        checkReplyPacket(reply, "ObjectReference::ReferenceType command");
201
202        byte newRefTypeTag = reply.getNextValueAsByte();
203        long newTypeID = reply.getNextValueAsReferenceTypeID();
204        logWriter.println(" ObjectReference.ReferenceType: refTypeTag="
205                + newRefTypeTag + "; typeID= " + newTypeID);
206        assertEquals("ObjectReference::ReferenceType returned invalid newRefTypeTag,",
207                JDWPConstants.TypeTag.CLASS, newRefTypeTag,
208                JDWPConstants.TypeTag.getName(JDWPConstants.TypeTag.CLASS),
209                JDWPConstants.TypeTag.getName(newRefTypeTag));
210        assertEquals("Invalid type ID,", typeID, newTypeID);
211        assertAllDataRead(reply);
212
213        // Make NewInstance with Exception
214        packet = new CommandPacket(
215                JDWPCommands.ClassTypeCommandSet.CommandSetID,
216                JDWPCommands.ClassTypeCommandSet.NewInstanceCommand);
217        packet.setNextValueAsClassID(typeID);
218        packet.setNextValueAsThreadID(targetThreadID);
219        packet.setNextValueAsMethodID(targetMethodID);
220        packet.setNextValueAsInt(1);
221        packet.setNextValueAsValue(new Value(true));
222        packet.setNextValueAsInt(0);
223        logWriter.println(" Send ClassType.NewInstance (with Exception)");
224        reply = debuggeeWrapper.vmMirror.performCommand(packet);
225        checkReplyPacket(reply, "ClassType::NewInstance command");
226
227        newObject = reply.getNextValueAsTaggedObject();
228        logWriter.println(" ClassType.NewInstance: newObject.tag="
229                + newObject.tag + "; newObject.objectID=" + newObject.objectID);
230        exception = reply.getNextValueAsTaggedObject();
231        logWriter.println(" ClassType.NewInstance: exception.tag="
232                + exception.tag + "; exception.objectID=" + exception.objectID);
233        assertNotNull("newObject is null", newObject);
234        assertEquals("ClassType::NewInstance returned invalid newObject.objectID,",
235                0, newObject.objectID);
236        assertEquals("ClassType::NewInstance returned invalid invalid newObject.tag,",
237                JDWPConstants.Tag.OBJECT_TAG, newObject.tag,
238                JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG),
239                JDWPConstants.Tag.getName(newObject.tag));
240
241        assertNotNull("ClassType::NewInstance returned invalid exception = null", newObject);
242        assertTrue("ClassType::NewInstance returned invalid exception.objectID = 0",
243                exception.objectID != 0);
244        assertEquals("ClassType::NewInstance returned invalid invalid exception.tag,",
245                JDWPConstants.Tag.OBJECT_TAG, exception.tag,
246                JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG),
247                JDWPConstants.Tag.getName(exception.tag));
248        assertAllDataRead(reply);
249
250        //  Let's resume application
251        packet = new CommandPacket(
252                JDWPCommands.VirtualMachineCommandSet.CommandSetID,
253                JDWPCommands.VirtualMachineCommandSet.ResumeCommand);
254        reply = debuggeeWrapper.vmMirror.performCommand(packet);
255        checkReplyPacket(reply, "VirtualMachine::Resume command");
256        assertAllDataRead(reply);
257
258        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
259    }
260
261    /**
262     * This testcase exercises ClassType.NewInstance command.
263     * <BR>At first the test starts debuggee.
264     * <BR>Then does the following check:
265     * <BR>&nbsp;&nbsp; - send ClassType.NewInstance command for class
266     * and passes invalid arguments' list for constructor.
267     * <BR>The testcase expects that ILLEGAL_ARGUMENT error is returned.
268     */
269    public void testNewInstance002() {
270        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
271
272        // Get referenceTypeID
273        CommandPacket packet = new CommandPacket(
274                JDWPCommands.VirtualMachineCommandSet.CommandSetID,
275                JDWPCommands.VirtualMachineCommandSet.ClassesBySignatureCommand);
276        String classSig = "Lorg/apache/harmony/jpda/tests/jdwp/share/debuggee/InvokeMethodDebuggee$testClass1;";
277        packet.setNextValueAsString(classSig);
278        ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
279        checkReplyPacket(reply, "VirtualMachine::ClassesBySignature command");
280
281        int classes = reply.getNextValueAsInt();
282        assertEquals("VirtualMachine::ClassesBySignature returned invalid cluss number,",
283                1, classes); //this class may be loaded only once
284        byte refTypeTag = reply.getNextValueAsByte();
285        long typeID = reply.getNextValueAsReferenceTypeID();
286        int status = reply.getNextValueAsInt();
287        logWriter.println(" VirtualMachine.ClassesBySignature: classes="
288                + classes + "; refTypeTag=" + refTypeTag + "; typeID= " + typeID
289                + "; status=" + status);
290
291        assertAllDataRead(reply);
292        assertEquals("VirtualMachine::ClassesBySignature returned invalid TypeTag,",
293                JDWPConstants.TypeTag.CLASS, refTypeTag,
294                JDWPConstants.TypeTag.getName(JDWPConstants.TypeTag.CLASS),
295                JDWPConstants.TypeTag.getName(refTypeTag));
296
297        // Get methodID
298        packet = new CommandPacket(
299                JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
300                JDWPCommands.ReferenceTypeCommandSet.MethodsCommand);
301        packet.setNextValueAsClassID(typeID);
302        reply = debuggeeWrapper.vmMirror.performCommand(packet);
303        checkReplyPacket(reply, "ReferenceType::Methods command");
304
305        int declared = reply.getNextValueAsInt();
306        logWriter.println(" ReferenceType.Methods: declared=" + declared);
307        long targetMethodID = 0;
308        for (int i = 0; i < declared; i++) {
309            long methodID = reply.getNextValueAsMethodID();
310            String name = reply.getNextValueAsString();
311            String signature = reply.getNextValueAsString();
312            int modBits = reply.getNextValueAsInt();
313            logWriter.println("  methodID=" + methodID + "; name=" + name
314                    + ";  signature=" + signature + "; modBits=" + modBits);
315            if (name.equals("<init>")) {
316                targetMethodID = methodID;
317            }
318        }
319        assertAllDataRead(reply);
320
321        // Set EventRequest
322        packet = new CommandPacket(
323                JDWPCommands.EventRequestCommandSet.CommandSetID,
324                JDWPCommands.EventRequestCommandSet.SetCommand);
325        packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
326        packet.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
327        packet.setNextValueAsInt(1);
328        packet.setNextValueAsByte((byte) 5);
329        packet.setNextValueAsString("*.InvokeMethodDebuggee");
330
331        reply = debuggeeWrapper.vmMirror.performCommand(packet);
332        checkReplyPacket(reply, "EventRequest::Set command");
333
334        int requestID = reply.getNextValueAsInt();
335        logWriter.println(" EventRequest.Set: requestID=" + requestID);
336        assertAllDataRead(reply);
337        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
338
339        long targetThreadID = 0;
340        // Wait event
341        CommandPacket event = debuggeeWrapper.vmMirror
342                .receiveCertainEvent(JDWPConstants.EventKind.METHOD_ENTRY);
343        byte suspendPolicy = event.getNextValueAsByte();
344        int events = event.getNextValueAsInt();
345        logWriter.println(" EVENT_THREAD event: suspendPolicy=" + suspendPolicy
346                + " events=" + events);
347        for (int i = 0; i < events; i++) {
348            byte eventKind = event.getNextValueAsByte();
349            int newRequestID = event.getNextValueAsInt();
350            long threadID = event.getNextValueAsThreadID();
351            //Location location =
352                event.getNextValueAsLocation();
353            logWriter.println("  EVENT_THREAD event " + i + ": eventKind="
354                    + eventKind + "; requestID=" + newRequestID + "; threadID="
355                    + threadID);
356            if (newRequestID == requestID) {
357                targetThreadID = threadID;
358            }
359        }
360        assertAllDataRead(event);
361        assertTrue("Invalid targetThreadID, must be != 0", targetThreadID != 0);
362
363        //  Let's clear event request
364        packet = new CommandPacket(
365                JDWPCommands.EventRequestCommandSet.CommandSetID,
366                JDWPCommands.EventRequestCommandSet.ClearCommand);
367        packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
368        packet.setNextValueAsInt(requestID);
369        reply = debuggeeWrapper.vmMirror.performCommand(packet);
370        checkReplyPacket(reply, "EventRequest::Clear command");
371        assertAllDataRead(reply);
372
373        // Make NewInstance without Exception
374        packet = new CommandPacket(
375                JDWPCommands.ClassTypeCommandSet.CommandSetID,
376                JDWPCommands.ClassTypeCommandSet.NewInstanceCommand);
377        packet.setNextValueAsClassID(typeID);
378        packet.setNextValueAsThreadID(targetThreadID);
379        packet.setNextValueAsMethodID(targetMethodID);
380        packet.setNextValueAsInt(0); // Providing of 'this' arg missed!
381        packet.setNextValueAsInt(0); // This int value will be interpreted as
382                                     // reference!?
383        logWriter.println(" Send ClassType.NewInstance");
384        reply = debuggeeWrapper.vmMirror.performCommand(packet);
385
386        short error = reply.getErrorCode();
387        logWriter.println(" ClassType.NewInstance: ErrorCode=" + error
388            + "(" + JDWPConstants.Error.getName(error) + ")");
389        assertEquals("ClassType.NewInstance returned invalid error code,",
390                JDWPConstants.Error.ILLEGAL_ARGUMENT, error,
391                JDWPConstants.Error.getName(JDWPConstants.Error.ILLEGAL_ARGUMENT),
392                JDWPConstants.Error.getName(error));
393        logWriter.println(" It is EXPECTED ERROR!");
394        assertAllDataRead(reply);
395
396        //  Let's resume application
397        packet = new CommandPacket(
398                JDWPCommands.VirtualMachineCommandSet.CommandSetID,
399                JDWPCommands.VirtualMachineCommandSet.ResumeCommand);
400        reply = debuggeeWrapper.vmMirror.performCommand(packet);
401        checkReplyPacket(reply, "VirtualMachine::Resume command");
402        assertAllDataRead(reply);
403
404        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
405    }
406}
407