1 /*
2  * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package nsk.jdi.StepRequest.size;
25 
26 import nsk.share.*;
27 import nsk.share.jpda.*;
28 import nsk.share.jdi.*;
29 
30 import com.sun.jdi.*;
31 import com.sun.jdi.event.*;
32 import com.sun.jdi.request.*;
33 
34 import java.util.*;
35 import java.io.*;
36 
37 /**
38  * The test for the implementation of an object of the type     <BR>
39  * StepRequest.                                                 <BR>
40  *                                                              <BR>
41  * The test checks that results of the method                   <BR>
42  * <code>com.sun.jdi.StepRequest.size()</code>                  <BR>
43  * complies with its spec.                                      <BR>
44  * <BR>
45  * The test checks if an int value StepRequest.STEP_LINE,               <BR>
46  * an argument of the method                                            <BR>
47  *    EventRequestManager.createAccessWatchpointRequest(),              <BR>
48  * is equal to one returned by the method StepRequest.size()            <BR>
49  * <BR>
50  * The test has three phases and works as follows.                      <BR>
51  * <BR>
52  * In first phase,                                                      <BR>
53  * upon launching debuggee's VM which will be suspended,                <BR>
54  * a debugger waits for the VMStartEvent within a predefined            <BR>
55  * time interval. If no the VMStartEvent received, the test is FAILED.  <BR>
56  * Upon getting the VMStartEvent, it makes the request for debuggee's   <BR>
57  * ClassPrepareEvent with SUSPEND_EVENT_THREAD, resumes the VM,         <BR>
58  * and waits for the event within the predefined time interval.         <BR>
59  * If no the ClassPrepareEvent received, the test is FAILED.            <BR>
60  * Upon getting the ClassPrepareEvent,                                  <BR>
61  * the debugger sets up the breakpoint with SUSPEND_EVENT_THREAD        <BR>
62  * within debuggee's special methodForCommunication().                  <BR>
63  * <BR>
64  * In second phase to check the assertion,                              <BR>
65  * the debugger and the debuggee perform the following.                 <BR>
66  * - The debugger resumes the debuggee and waits for the BreakpointEvent.<BR>
67  * - The debuggee creates a tested thread                               <BR>
68  *   and invokes the methodForCommunication to be suspended and         <BR>
69  *   to inform the debugger with the event.                             <BR>
70  * - Upon getting the BreakpointEvent, the debugger                     <BR>
71  *   - creates an StepRequest with the size StepRequest.STEP_LINE,      <BR>
72  *   - gets  the size of the Request with the method StepRequest.size(),<BR>
73  *   - and compares the values.                                         <BR>
74  * <BR>
75  * In third phase, at the end of the test, the debuggee changes         <BR>
76  * the value of the "instruction" which the debugger and debuggee       <BR>
77  * use to inform each other of needed actions,  and both end.           <BR>
78  * <BR>
79  */
80 
81 public class size002 {
82 
83     //----------------------------------------------------- templete section
84     static final int PASSED = 0;
85     static final int FAILED = 2;
86     static final int PASS_BASE = 95;
87 
88     //----------------------------------------------------- templete parameters
89     static final String
90     sHeader1 = "\n==> nsk/jdi/StepRequest/size/size002 ",
91     sHeader2 = "--> debugger: ",
92     sHeader3 = "##> debugger: ";
93 
94     //----------------------------------------------------- main method
95 
main(String argv[])96     public static void main (String argv[]) {
97 
98         int result = run(argv, System.out);
99 
100         System.exit(result + PASS_BASE);
101     }
102 
run(String argv[], PrintStream out)103     public static int run (String argv[], PrintStream out) {
104 
105         int exitCode = new size002().runThis(argv, out);
106 
107         if (exitCode != PASSED) {
108             System.out.println("TEST FAILED");
109         }
110         return testExitCode;
111     }
112 
113     //--------------------------------------------------   log procedures
114 
115     private static Log  logHandler;
116 
log1(String message)117     private static void log1(String message) {
118         logHandler.display(sHeader1 + message);
119     }
log2(String message)120     private static void log2(String message) {
121         logHandler.display(sHeader2 + message);
122     }
log3(String message)123     private static void log3(String message) {
124         logHandler.complain(sHeader3 + message);
125     }
126 
127     //  ************************************************    test parameters
128 
129     private String debuggeeName =
130         "nsk.jdi.StepRequest.size.size002a";
131 
132     private String testedClassName =
133       "nsk.jdi.StepRequest.size.size002aTestClass10";
134 
135     //====================================================== test program
136     //------------------------------------------------------ common section
137 
138     static Debugee          debuggee;
139     static ArgumentHandler  argsHandler;
140 
141     static int waitTime;
142 
143     static VirtualMachine      vm            = null;
144     static EventRequestManager eventRManager = null;
145     static EventQueue          eventQueue    = null;
146     static EventSet            eventSet      = null;
147     static EventIterator       eventIterator = null;
148 
149     static ReferenceType       debuggeeClass = null;
150 
151     static int  testExitCode = PASSED;
152 
153 
154     class JDITestRuntimeException extends RuntimeException {
JDITestRuntimeException(String str)155         JDITestRuntimeException(String str) {
156             super("JDITestRuntimeException : " + str);
157         }
158     }
159 
160     //------------------------------------------------------ methods
161 
runThis(String argv[], PrintStream out)162     private int runThis (String argv[], PrintStream out) {
163 
164         argsHandler     = new ArgumentHandler(argv);
165         logHandler      = new Log(out, argsHandler);
166         Binder binder   = new Binder(argsHandler, logHandler);
167 
168         waitTime        = argsHandler.getWaitTime() * 60000;
169 
170         try {
171             log2("launching a debuggee :");
172             log2("       " + debuggeeName);
173             if (argsHandler.verbose()) {
174                 debuggee = binder.bindToDebugee(debuggeeName + " -vbs");
175             } else {
176                 debuggee = binder.bindToDebugee(debuggeeName);
177             }
178             if (debuggee == null) {
179                 log3("ERROR: no debuggee launched");
180                 return FAILED;
181             }
182             log2("debuggee launched");
183         } catch ( Exception e ) {
184             log3("ERROR: Exception : " + e);
185             log2("       test cancelled");
186             return FAILED;
187         }
188 
189         debuggee.redirectOutput(logHandler);
190 
191         vm = debuggee.VM();
192 
193         eventQueue = vm.eventQueue();
194         if (eventQueue == null) {
195             log3("ERROR: eventQueue == null : TEST ABORTED");
196             vm.exit(PASS_BASE);
197             return FAILED;
198         }
199 
200         log2("invocation of the method runTest()");
201         switch (runTest()) {
202 
203             case 0 :  log2("test phase has finished normally");
204                       log2("   waiting for the debuggee to finish ...");
205                       debuggee.waitFor();
206 
207                       log2("......getting the debuggee's exit status");
208                       int status = debuggee.getStatus();
209                       if (status != PASS_BASE) {
210                           log3("ERROR: debuggee returned UNEXPECTED exit status: " +
211                               status + " != PASS_BASE");
212                           testExitCode = FAILED;
213                       } else {
214                           log2("......debuggee returned expected exit status: " +
215                               status + " == PASS_BASE");
216                       }
217                       break;
218 
219             default : log3("ERROR: runTest() returned unexpected value");
220 
221             case 1 :  log3("test phase has not finished normally: debuggee is still alive");
222                       log2("......forcing: vm.exit();");
223                       testExitCode = FAILED;
224                       try {
225                           vm.exit(PASS_BASE);
226                       } catch ( Exception e ) {
227                           log3("ERROR: Exception : " + e);
228                       }
229                       break;
230 
231             case 2 :  log3("test cancelled due to VMDisconnectedException");
232                       log2("......trying: vm.process().destroy();");
233                       testExitCode = FAILED;
234                       try {
235                           Process vmProcess = vm.process();
236                           if (vmProcess != null) {
237                               vmProcess.destroy();
238                           }
239                       } catch ( Exception e ) {
240                           log3("ERROR: Exception : " + e);
241                       }
242                       break;
243             }
244 
245         return testExitCode;
246     }
247 
248 
249    /*
250     * Return value: 0 - normal end of the test
251     *               1 - ubnormal end of the test
252     *               2 - VMDisconnectedException while test phase
253     */
254 
runTest()255     private int runTest() {
256 
257         try {
258             testRun();
259 
260             log2("waiting for VMDeathEvent");
261             getEventSet();
262             if (eventIterator.nextEvent() instanceof VMDeathEvent)
263                 return 0;
264 
265             log3("ERROR: last event is not the VMDeathEvent");
266             return 1;
267         } catch ( VMDisconnectedException e ) {
268             log3("ERROR: VMDisconnectedException : " + e);
269             return 2;
270         } catch ( Exception e ) {
271             log3("ERROR: Exception : " + e);
272             return 1;
273         }
274 
275     }
276 
testRun()277     private void testRun()
278                  throws JDITestRuntimeException, Exception {
279 
280         eventRManager = vm.eventRequestManager();
281 
282         ClassPrepareRequest cpRequest = eventRManager.createClassPrepareRequest();
283         cpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD);
284         cpRequest.addClassFilter(debuggeeName);
285 
286         cpRequest.enable();
287         vm.resume();
288         getEventSet();
289         cpRequest.disable();
290 
291         ClassPrepareEvent event = (ClassPrepareEvent) eventIterator.next();
292         debuggeeClass = event.referenceType();
293 
294         if (!debuggeeClass.name().equals(debuggeeName))
295            throw new JDITestRuntimeException("** Unexpected ClassName for ClassPrepareEvent **");
296 
297         log2("      received: ClassPrepareEvent for debuggeeClass");
298 
299         String bPointMethod = "methodForCommunication";
300         String lineForComm  = "lineForComm";
301 
302         ThreadReference   mainThread = threadByName("main");
303 
304         BreakpointRequest bpRequest = settingBreakpoint(mainThread,
305                                              debuggeeClass,
306                                             bPointMethod, lineForComm, "zero");
307         bpRequest.enable();
308 
309     //------------------------------------------------------  testing section
310 
311         log1("     TESTING BEGINS");
312 
313         EventRequest  eventRequest1 = null;
314 
315         ThreadReference thread1     = null;
316         String          threadName1 = "thread1";
317 
318         int size;
319 
320 
321         for (int i = 0; ; i++) {
322 
323             vm.resume();
324             breakpointForCommunication();
325 
326             int instruction = ((IntegerValue)
327                                (debuggeeClass.getValue(debuggeeClass.fieldByName("instruction")))).value();
328 
329             if (instruction == 0) {
330                 vm.resume();
331                 break;
332             }
333 
334 
335             log1(":::::: case: # " + i);
336 
337             //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part
338 
339             switch (i) {
340 
341               case 0:
342                      thread1 = threadByName(threadName1);
343 
344                      log2("......setting up StepRequest with size StepRequest.STEP_LINE");
345                      eventRequest1 = setting24StepRequest(thread1, StepRequest.STEP_LINE,
346                                               StepRequest.STEP_INTO);
347 
348                      log2("......getting: size = ((StepRequest) eventRequest1).size();");
349                      size = ((StepRequest) eventRequest1).size();
350 
351                      log2("      checking up on equality of values");
352                      if ( size != StepRequest.STEP_LINE ) {
353                          testExitCode = FAILED;
354                          log3("ERROR: size() != StepRequest.STEP_LINE : " + size);
355                      }
356 
357                       break;
358 
359               default:
360                       throw new JDITestRuntimeException("** default case 2 **");
361             }
362 
363             //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
364         }
365         log1("    TESTING ENDS");
366         return;
367     }
368 
threadByName(String name)369     private ThreadReference threadByName(String name)
370                  throws JDITestRuntimeException {
371 
372         List         all = vm.allThreads();
373         ListIterator li  = all.listIterator();
374 
375         for (; li.hasNext(); ) {
376             ThreadReference thread = (ThreadReference) li.next();
377             if (thread.name().equals(name))
378                 return thread;
379         }
380         throw new JDITestRuntimeException("** Thread IS NOT found ** : " + name);
381     }
382 
383    /*
384     * private BreakpointRequest settingBreakpoint(ThreadReference, ReferenceType,
385     *                                             String, String, String)
386     *
387     * It sets up a breakpoint at given line number within a given method in a given class
388     * for a given thread.
389     *
390     * Return value: BreakpointRequest object  in case of success
391     *
392     * JDITestRuntimeException   in case of an Exception thrown within the method
393     */
394 
settingBreakpoint( ThreadReference thread, ReferenceType testedClass, String methodName, String bpLine, String property)395     private BreakpointRequest settingBreakpoint ( ThreadReference thread,
396                                                   ReferenceType testedClass,
397                                                   String methodName,
398                                                   String bpLine,
399                                                   String property)
400             throws JDITestRuntimeException {
401 
402         log2("......setting up a breakpoint:");
403         log2("       thread: " + thread + "; class: " + testedClass +
404                         "; method: " + methodName + "; line: " + bpLine);
405 
406         List              alllineLocations = null;
407         Location          lineLocation     = null;
408         BreakpointRequest breakpRequest    = null;
409 
410         try {
411             Method  method  = (Method) testedClass.methodsByName(methodName).get(0);
412 
413             alllineLocations = method.allLineLocations();
414 
415             int n =
416                 ( (IntegerValue) testedClass.getValue(testedClass.fieldByName(bpLine) ) ).value();
417             if (n > alllineLocations.size()) {
418                 log3("ERROR:  TEST_ERROR_IN_settingBreakpoint(): number is out of bound of method's lines");
419             } else {
420                 lineLocation = (Location) alllineLocations.get(n);
421                 try {
422                     breakpRequest = eventRManager.createBreakpointRequest(lineLocation);
423                     breakpRequest.putProperty("number", property);
424                     breakpRequest.addThreadFilter(thread);
425                     breakpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD);
426                 } catch ( Exception e1 ) {
427                     log3("ERROR: inner Exception within settingBreakpoint() : " + e1);
428                     breakpRequest    = null;
429                 }
430             }
431         } catch ( Exception e2 ) {
432             log3("ERROR: ATTENTION:  outer Exception within settingBreakpoint() : " + e2);
433             breakpRequest    = null;
434         }
435 
436         if (breakpRequest == null) {
437             log2("      A BREAKPOINT HAS NOT BEEN SET UP");
438             throw new JDITestRuntimeException("**FAILURE to set up a breakpoint**");
439         }
440 
441         log2("      a breakpoint has been set up");
442         return breakpRequest;
443     }
444 
445 
getEventSet()446     private void getEventSet()
447                  throws JDITestRuntimeException {
448         try {
449 //            log2("       eventSet = eventQueue.remove(waitTime);");
450             eventSet = eventQueue.remove(waitTime);
451             if (eventSet == null) {
452                 throw new JDITestRuntimeException("** TIMEOUT while waiting for event **");
453             }
454 //            log2("       eventIterator = eventSet.eventIterator;");
455             eventIterator = eventSet.eventIterator();
456         } catch ( Exception e ) {
457             throw new JDITestRuntimeException("** EXCEPTION while waiting for event ** : " + e);
458         }
459     }
460 
461 
breakpointForCommunication()462     private void breakpointForCommunication()
463                  throws JDITestRuntimeException {
464 
465         log2("breakpointForCommunication");
466         getEventSet();
467 
468         if (eventIterator.nextEvent() instanceof BreakpointEvent)
469             return;
470 
471         throw new JDITestRuntimeException("** event IS NOT a breakpoint **");
472     }
473 
474     // ============================== test's additional methods
475 
setting24StepRequest( ThreadReference thread, int size, int depth )476     private StepRequest setting24StepRequest ( ThreadReference thread,
477                                                int             size,
478                                                int             depth )
479             throws JDITestRuntimeException {
480         try {
481             log2("......setting up StepRequest:");
482             log2("       thread: " + thread + "; size: " + size + "; depth: " + depth);
483 
484             StepRequest
485             str = eventRManager.createStepRequest(thread, size, depth);
486 
487             log2("      StepRequest has been set up");
488             return str;
489         } catch ( Exception e ) {
490             log3("ERROR: ATTENTION: Exception within settingStepRequest() : " + e);
491             log3("       StepRequest HAS NOT BEEN SET UP");
492             throw new JDITestRuntimeException("** FAILURE to set up StepRequest **");
493         }
494     }
495 
496 }
497