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 package org.apache.harmony.jpda.tests.jdwp.ClassType;
20 
21 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
22 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
23 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
24 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
25 import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject;
26 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
27 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
28 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
29 
30 
31 /**
32  * JDWP unit test for ClassType.NewInstance command.
33  */
34 public class NewInstance002Test extends JDWPSyncTestCase {
35 
getDebuggeeClassName()36     protected String getDebuggeeClassName() {
37         return "org.apache.harmony.jpda.tests.jdwp.ClassType.NewInstance002Debuggee";
38     }
39 
40     /**
41      * This testcase exercises ClassType.NewInstance 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.NewInstance command to create a new instance and
45      * invoke a constructor with a null argument. Checks that returned value
46      * is expected int value and returned exception object is null.
47      * <BR>Finally resume the application.
48      */
testNewInstance_null_argument()49     public void testNewInstance_null_argument() {
50         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
51 
52         // Get debuggee class ID.
53         String debuggeeClassSig = "Lorg/apache/harmony/jpda/tests/jdwp/ClassType/NewInstance002Debuggee;";
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         // Get test class ID.
107         String testClassSig = "Lorg/apache/harmony/jpda/tests/jdwp/ClassType/NewInstance002Debuggee$TestClass;";
108         long testTypeID = debuggeeWrapper.vmMirror.getClassID(testClassSig);
109         assertTrue("Failed to find test class", testTypeID != 0);
110 
111         // Get constructor ID.
112         long targetMethodID = debuggeeWrapper.vmMirror.getMethodID(testTypeID, "<init>");
113         assertTrue("Failed to find constructor", targetMethodID != 0);
114 
115         // Make NewInstance without Exception
116         Value nullObjectValue = new Value(JDWPConstants.Tag.OBJECT_TAG, 0);
117         packet = new CommandPacket(
118                 JDWPCommands.ClassTypeCommandSet.CommandSetID,
119                 JDWPCommands.ClassTypeCommandSet.NewInstanceCommand);
120         packet.setNextValueAsClassID(testTypeID);
121         packet.setNextValueAsThreadID(targetThreadID);
122         packet.setNextValueAsMethodID(targetMethodID);
123         packet.setNextValueAsInt(1);
124         packet.setNextValueAsValue(nullObjectValue);
125         packet.setNextValueAsInt(0);
126         logWriter.println(" Send ClassType.NewInstance (without Exception)");
127         reply = debuggeeWrapper.vmMirror.performCommand(packet);
128         checkReplyPacket(reply, "ClassType::NewInstance command");
129 
130         TaggedObject newObject = reply.getNextValueAsTaggedObject();
131         logWriter.println(" ClassType.NewInstance: newObject.tag="
132                 + newObject.tag + "; newObject.objectID=" + newObject.objectID);
133         TaggedObject exception = reply.getNextValueAsTaggedObject();
134         logWriter.println(" ClassType.NewInstance: exception.tag="
135                 + exception.tag + "; exception.objectID=" + exception.objectID);
136 
137         assertNotNull("newObject is null", newObject);
138         assertTrue("newObject.objectID is 0", newObject.objectID != 0);
139         assertEquals("ClassType::NewInstance returned invalid newObject.tag,", JDWPConstants.Tag.OBJECT_TAG, newObject.tag
140                 , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
141                 , JDWPConstants.Tag.getName(newObject.tag));
142 
143         assertNotNull("exception is null", newObject);
144         assertEquals("ClassType::NewInstance returned invalid exception.objectID,", 0, exception.objectID);
145         assertTrue(exception.tag == JDWPConstants.Tag.OBJECT_TAG);
146         assertAllDataRead(reply);
147 
148         //  Let's resume application
149         debuggeeWrapper.vmMirror.resume();
150 
151         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
152     }
153 }
154