• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.apache.harmony.jpda.tests.jdwp.EventModifiers;
2 
3 import org.apache.harmony.jpda.tests.framework.Breakpoint;
4 import org.apache.harmony.jpda.tests.framework.jdwp.Event;
5 import org.apache.harmony.jpda.tests.framework.jdwp.EventBuilder;
6 import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket;
7 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
8 import org.apache.harmony.jpda.tests.framework.jdwp.Location;
9 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent;
10 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent.EventThread;
11 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
12 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
13 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
14 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
15 
16 /**
17  * This base class provides utilities for all event modifier tests.
18  */
19 abstract class JDWPEventModifierTestCase extends JDWPSyncTestCase {
20     /**
21      * The suspend policy used for all events in the tests.
22      */
23     protected static final byte
24             TEST_SUSPEND_POLICY = JDWPConstants.SuspendPolicy.ALL;
25 
26     /**
27      * Returns value of the requested field.
28      *
29      * @param classSignature the signature of the field's declaring class
30      * @param fieldName the field name.
31      * @return the value of the field
32      */
getFieldValue(String classSignature, String fieldName)33     protected Value getFieldValue(String classSignature, String fieldName) {
34         long classID = debuggeeWrapper.vmMirror.getClassID(classSignature);
35         assertTrue("Failed to find debuggee class " + classSignature,
36                 classID != 0);
37         long fieldID = debuggeeWrapper.vmMirror.getFieldID(classID, fieldName);
38         assertTrue("Failed to find field " + classSignature + "." + fieldName,
39                 fieldID != 0);
40 
41         long[] fieldIDs = new long[] { fieldID };
42         Value[] fieldValues = debuggeeWrapper.vmMirror.getReferenceTypeValues(
43                 classID, fieldIDs);
44         assertNotNull("Failed to get field values for class " + classSignature,
45                 fieldValues);
46         assertEquals("Invalid number of field values", 1, fieldValues.length);
47         return fieldValues[0];
48     }
49 
50     /**
51      * Creates an {@link EventBuilder} for BREAKPOINT event and sets a
52      * LocationOnly modifier.
53      *
54      * @param typeTag the type tag of the location's class
55      * @param breakpoint the breakpoint info
56      * @return a new {@link EventBuilder}
57      */
createBreakpointEventBuilder(byte typeTag, Breakpoint breakpoint)58     protected EventBuilder createBreakpointEventBuilder(byte typeTag,
59             Breakpoint breakpoint) {
60         long typeID = debuggeeWrapper.vmMirror.getTypeID(breakpoint.className, typeTag);
61         long methodID = getMethodID(typeID, breakpoint.methodName);
62         byte eventKind = JDWPConstants.EventKind.BREAKPOINT;
63         return Event.builder(eventKind, TEST_SUSPEND_POLICY)
64                 .setLocationOnly(new Location(typeTag, typeID, methodID, breakpoint.index));
65     }
66 
67     /**
68      * Creates an {@link EventBuilder} for EXCEPTION event and sets an
69      * ExceptionOnly modifier.
70      *
71      * @param exceptionClassSignature the signature of the exception class
72      * @param caught whether the exception must be caught
73      * @param uncaught whether the exception must be uncaught
74      * @return a new {@link EventBuilder}
75      */
createExceptionEventBuilder( String exceptionClassSignature, boolean caught, boolean uncaught)76     protected EventBuilder createExceptionEventBuilder(
77             String exceptionClassSignature, boolean caught, boolean uncaught) {
78         byte eventKind = JDWPConstants.EventKind.EXCEPTION;
79         long exceptionClassID = debuggeeWrapper.vmMirror.getClassID(
80                 exceptionClassSignature);
81         assertTrue("Failed to find type ID " + exceptionClassSignature,
82                 exceptionClassID != 1);
83         return Event.builder(eventKind, TEST_SUSPEND_POLICY).setExceptionOnly(exceptionClassID,
84                 caught, uncaught);
85     }
86 
87     /**
88      * Creates an {@link EventBuilder} for METHOD_ENTRY event and sets a
89      * ClassMatch modifier.
90      *
91      * @param className a regular expression of class names matching the method
92      * entry events.
93      * @return a new {@link EventBuilder}
94      */
createMethodEntryEventBuilder(String className)95     protected EventBuilder createMethodEntryEventBuilder(String className) {
96         return Event.builder(JDWPConstants.EventKind.METHOD_ENTRY, TEST_SUSPEND_POLICY)
97                 .setClassMatch(className);
98     }
99 
100     /**
101      * Creates an {@link EventBuilder} for METHOD_EXIT event and sets a
102      * ClassMatch modifier.
103      *
104      * @param className a regular expression of class names matching the method
105      * exit events.
106      * @return a new {@link EventBuilder}
107      */
createMethodExitEventBuilder(String className)108     protected EventBuilder createMethodExitEventBuilder(String className) {
109         return Event.builder(JDWPConstants.EventKind.METHOD_EXIT, TEST_SUSPEND_POLICY)
110                 .setClassMatch(className);
111     }
112 
113     /**
114      * Creates an {@link EventBuilder} for METHOD_EXIT_WITH_RETURN_VALUE event
115      * and sets a ClassMatch modifier.
116      *
117      * @param className a regular expression of class names matching the method
118      * exit events.
119      * @return a new {@link EventBuilder}
120      */
createMethodExitWithReturnValueEventBuilder(String className)121     protected EventBuilder createMethodExitWithReturnValueEventBuilder(String className) {
122         return Event
123                 .builder(JDWPConstants.EventKind.METHOD_EXIT_WITH_RETURN_VALUE, TEST_SUSPEND_POLICY)
124                 .setClassMatch(className);
125     }
126 
127     /**
128      * Creates an {@link EventBuilder} for THREAD_START event.
129      *
130      * @return a new {@link EventBuilder}
131      */
createThreadStartBuilder()132     protected EventBuilder createThreadStartBuilder() {
133         return Event.builder(JDWPConstants.EventKind.THREAD_START, TEST_SUSPEND_POLICY);
134     }
135 
136     /**
137      * Creates an {@link EventBuilder} for THREAD_END event.
138      *
139      * @return a new {@link EventBuilder}
140      */
createThreadEndBuilder()141     protected EventBuilder createThreadEndBuilder() {
142         return Event.builder(JDWPConstants.EventKind.THREAD_END, TEST_SUSPEND_POLICY);
143     }
144 
145     /**
146      * Creates an {@link EventBuilder} for FIELD_ACCESS event and sets a
147      * FieldOnly modifier.
148      *
149      * @param typeTag the type tag of the field's declaring class
150      * @param classSignature the field's declaring class signature
151      * @param fieldName the field name
152      * @return a new {@link EventBuilder}
153      */
createFieldAccessEventBuilder(byte typeTag, String classSignature, String fieldName)154     protected EventBuilder createFieldAccessEventBuilder(byte typeTag,
155             String classSignature, String fieldName) {
156         return createFieldEventBuilder(typeTag, classSignature, fieldName, false);
157     }
158 
159     /**
160      * Creates an {@link EventBuilder} for FIELD_MODIFICATION event and sets a
161      * FieldOnly modifier.
162      *
163      * @param typeTag the type tag of the field's declaring class
164      * @param classSignature the field's declaring class signature
165      * @param fieldName the field name
166      * @return a new {@link EventBuilder}
167      */
createFieldModificationEventBuilder(byte typeTag, String classSignature, String fieldName)168     protected EventBuilder createFieldModificationEventBuilder(byte typeTag,
169             String classSignature, String fieldName) {
170         return createFieldEventBuilder(typeTag, classSignature, fieldName, true);
171     }
172 
createFieldEventBuilder(byte typeTag, String typeSignature, String fieldName, boolean modification)173     private EventBuilder createFieldEventBuilder(byte typeTag,
174                                                 String typeSignature,
175                                                 String fieldName,
176                                                 boolean modification) {
177         byte eventKind;
178         if (modification) {
179             eventKind = JDWPConstants.EventKind.FIELD_MODIFICATION;
180         } else {
181             eventKind = JDWPConstants.EventKind.FIELD_ACCESS;
182         }
183         long typeID = debuggeeWrapper.vmMirror.getTypeID(typeSignature, typeTag);
184         assertTrue("Failed to find type ID " + typeSignature, typeID != 1);
185         long fieldID = debuggeeWrapper.vmMirror.getFieldID(typeID, fieldName);
186         assertTrue("Failed to find field ID " + typeSignature + "." + fieldName,
187                 fieldID != 1);
188         return Event.builder(eventKind, TEST_SUSPEND_POLICY).setFieldOnly(typeID, fieldID);
189     }
190 
191     /**
192      * Sends a request for the given event.
193      *
194      * @param event the event to request
195      * @return the request ID
196      */
requestEvent(Event event)197     protected int requestEvent(Event event) {
198         String eventName = JDWPConstants.EventKind.getName(event.eventKind);
199         logWriter.println("Requesting " + eventName);
200         ReplyPacket reply = debuggeeWrapper.vmMirror.setEvent(event);
201         checkReplyPacket(reply, "Failed to request " + eventName);
202         int requestID = reply.getNextValueAsInt();
203         assertAllDataRead(reply);
204         return requestID;
205     }
206 
207     /**
208      * Waits for the first corresponding event.
209      *
210      * @param eventKind the event kind
211      * @param requestID the event request ID
212      * @return the event
213      */
waitForEvent(byte eventKind, int requestID)214     protected EventThread waitForEvent(byte eventKind, int requestID) {
215         logWriter.println("Signaling debuggee to continue");
216         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
217 
218         String eventName = JDWPConstants.EventKind.getName(eventKind);
219         logWriter.println(
220                 "Waiting for " + eventName + " with requestID " + requestID + " ...");
221         EventPacket eventPacket = debuggeeWrapper.vmMirror.receiveCertainEvent(
222                 eventKind);
223         ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(eventPacket);
224         assertNotNull(parsedEvents);
225         assertTrue(parsedEvents.length > 0);
226         ParsedEvent event = parsedEvents[0];
227         assertEquals(eventKind, event.getEventKind());
228         assertEquals(requestID, event.getRequestID());
229         logWriter.println("Received " + eventName + " event");
230         return (EventThread) event;
231     }
232 
233     /**
234      * Clears the corresponding event and resumes the VM.
235      *
236      * @param eventKind the event kind
237      * @param requestID the event request ID
238      */
clearAndResume(byte eventKind, int requestID)239     protected void clearAndResume(byte eventKind, int requestID) {
240         clearEvent(eventKind, requestID, true);
241         resumeDebuggee();
242     }
243 
244     /**
245      * Warns about an unsupported capability by printing a message in the
246      * console.
247      *
248      * @param capabilityName the capability name
249      */
logCapabilityWarning(String capabilityName)250     protected void logCapabilityWarning(String capabilityName) {
251         // Build the message to prompt.
252         StringBuilder messageBuilder =
253                 new StringBuilder("# WARNING: this VM doesn't possess capability: ");
254         messageBuilder.append(capabilityName);
255         messageBuilder.append(' ');
256         messageBuilder.append('#');
257         String message = messageBuilder.toString();
258 
259         // Build a sharp string long enough.
260         int sharpLineLength = message.length();
261         StringBuilder sharpLineBuilder = new StringBuilder(sharpLineLength);
262         for (int i = 0; i < sharpLineLength; ++i) {
263             sharpLineBuilder.append('#');
264         }
265         String sharpLine = sharpLineBuilder.toString();
266 
267         // Print warning message.
268         logWriter.println(sharpLine);
269         logWriter.println(message);
270         logWriter.println(sharpLine);
271     }
272 }
273