1 /*
2  * Copyright (c) 2001, 2020, 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.EventSet.eventIterator;
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  * EventSet.                                                    <BR>
40  *                                                              <BR>
41  * The test checks that results of the method                   <BR>
42  * <code>com.sun.jdi.EventSet.eventIterator()</code>            <BR>
43  * complies with its spec.                                      <BR>
44  * <BR>
45  * The test checks that for VMStart, VMDeath, and               <BR>
46  * VMDisconnect Events:                                         <BR>
47  *  - the method returns non-null object, and                   <BR>
48  *  - object's class is subclass of class Iterator.             <BR>
49  * <BR>
50  * The test works as follows.                                   <BR>
51  * <BR>
52  * Upon launching debuggee's VM which will be suspended,                <BR>
53  * a debugger waits for the VMStartEvent within a predefined            <BR>
54  * time interval. If no the VMStartEvent received, the test is FAILED.  <BR>
55  * Upon getting the VMStartEvent, it checks up on the method and        <BR>
56  * sets up 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  * <BR>
61  * The debugger then resumes the debuggee which will normally end       <BR>
62  * that will result in VMDeathEvent and waits for the event.            <BR>
63  * Upon getting the VMDeathEvent, it checks up on the method and        <BR>
64  * waits for VMDisconnectEvent, and upon getting it, checks up on this. <BR>
65  * <BR>
66  */
67 
68 public class eventiterator004 extends JDIBase {
69 
main(String argv[])70     public static void main (String argv[]) {
71 
72         int result = run(argv, System.out);
73 
74         System.exit(result + PASS_BASE);
75     }
76 
run(String argv[], PrintStream out)77     public static int run (String argv[], PrintStream out) {
78 
79         int exitCode = new eventiterator004().runThis(argv, out);
80 
81         if (exitCode != PASSED) {
82             System.out.println("TEST FAILED");
83         }
84         return testExitCode;
85     }
86 
87     //  ************************************************    test parameters
88 
89     private String debuggeeName =
90         "nsk.jdi.EventSet.eventIterator.eventiterator004a";
91 
92     private String testedClassName =
93       "nsk.jdi.EventSet.eventIterator.TestClass";
94 
95     //====================================================== test program
96 
97     //  Event #:
98     //  0-6  : AccessWatchpoint, ModificationWatchpoint, Breakpoint, Exception,
99     //         MethodEntry, MethodExit, Step
100     //  7-8  : ClassPrepare, ClassUnload
101     //  9-10 : ThreadDeath, ThreadStart
102     // 11-13 : VMDeath, VMDisconnect, VMStart
103 
104     EventSet     eventSets[] = new EventSet [14];
105     EventRequest eRequests[] = new EventRequest[14];
106 
107     int eventFlags[] = { 0,0,0,0, 0,0,0,0, 3,0,0,0, 1,1 };
108 
runThis(String argv[], PrintStream out)109     private int runThis (String argv[], PrintStream out) {
110 
111         argsHandler     = new ArgumentHandler(argv);
112         logHandler      = new Log(out, argsHandler);
113         Binder binder   = new Binder(argsHandler, logHandler);
114 
115         waitTime        = argsHandler.getWaitTime() * 60000;
116 
117         try {
118             log2("launching a debuggee :");
119             log2("       " + debuggeeName);
120             if (argsHandler.verbose()) {
121                 debuggee = binder.bindToDebugeeNoWait(debuggeeName + " -vbs");
122             } else {
123                 debuggee = binder.bindToDebugeeNoWait(debuggeeName);
124             }
125             if (debuggee == null) {
126                 log3("ERROR: no debuggee launched");
127                 return FAILED;
128             }
129             log2("debuggee launched");
130         } catch ( Exception e ) {
131             log3("ERROR: Exception : " + e);
132             log2("       test cancelled");
133             return FAILED;
134         }
135 
136         debuggee.redirectOutput(logHandler);
137 
138         vm = debuggee.VM();
139 
140         eventQueue = vm.eventQueue();
141         if (eventQueue == null) {
142             log3("ERROR: eventQueue == null : TEST ABORTED");
143             vm.exit(PASS_BASE);
144             return FAILED;
145         }
146 
147         log2("invocation of the method runTest()");
148         switch (runTest()) {
149 
150             case 0 :  log2("test phase has finished normally");
151                       log2("   waiting for the debuggee to finish ...");
152                       debuggee.waitFor();
153 
154                       log2("......getting the debuggee's exit status");
155                       int status = debuggee.getStatus();
156                       if (status != PASS_BASE) {
157                           log3("ERROR: debuggee returned UNEXPECTED exit status: " +
158                               status + " != PASS_BASE");
159                           testExitCode = FAILED;
160                       } else {
161                           log2("......debuggee returned expected exit status: " +
162                               status + " == PASS_BASE");
163                       }
164                       break;
165 
166             default : log3("ERROR: runTest() returned unexpected value");
167 
168             case 1 :  log3("test phase has not finished normally: debuggee is still alive");
169                       log2("......forcing: vm.exit();");
170                       testExitCode = FAILED;
171                       try {
172                           vm.exit(PASS_BASE);
173                       } catch ( Exception e ) {
174                           log3("ERROR: Exception : e");
175                       }
176                       break;
177 
178             case 2 :  log3("test cancelled due to VMDisconnectedException");
179                       log2("......trying: vm.process().destroy();");
180                       testExitCode = FAILED;
181                       try {
182                           Process vmProcess = vm.process();
183                           if (vmProcess != null) {
184                               vmProcess.destroy();
185                           }
186                       } catch ( Exception e ) {
187                           log3("ERROR: Exception : e");
188                       }
189                       break;
190             }
191 
192         return testExitCode;
193     }
194 
195 
196    /*
197     * Return value: 0 - normal end of the test
198     *               1 - ubnormal end of the test
199     *               2 - VMDisconnectedException while test phase
200     */
201 
runTest()202     private int runTest() {
203 
204         try {
205             log2("waiting for VMStartEvent");
206             getEventSet();
207             check();
208 
209 
210             if (eventIterator.nextEvent() instanceof VMStartEvent) {
211                 log2("VMStartEvent received; test begins");
212 
213                 testRun();
214 
215                 log2("waiting for VMDeathEvent");
216                 getEventSet();
217                 check();
218 
219                 if ( !(eventIterator.nextEvent() instanceof VMDeathEvent) ) {
220                     log3("ERROR: last event is not the VMDeathEvent");
221                     return 1;
222                 }
223 
224                 log2("waiting for VMDisconnectEvent");
225                 getEventSet();
226                 check();
227                 if ( !(eventIterator.nextEvent() instanceof VMDisconnectEvent) ) {
228                     log3("ERROR: last event is not the VMDisconnectEvent");
229                     return 1;
230                 }
231 
232                 return 0;
233             } else {
234                 log3("ERROR: first event is not the VMStartEvent");
235                 return 1;
236             }
237         } catch ( VMDisconnectedException e ) {
238             log3("ERROR: VMDisconnectedException : " + e);
239             return 2;
240         } catch ( Exception e ) {
241             log3("ERROR: Exception : " + e);
242             return 1;
243         }
244 
245     }
246 
testRun()247     private void testRun()
248                  throws JDITestRuntimeException, Exception {
249 
250         eventRManager = vm.eventRequestManager();
251 
252         ClassPrepareRequest cpRequest = eventRManager.createClassPrepareRequest();
253         cpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD);
254         cpRequest.addClassFilter(debuggeeName);
255 
256         log2("......setting up ClassPrepareRequest");
257         eRequests[7] = cpRequest;
258 
259         cpRequest.enable();
260         vm.resume();
261 
262         getEventSet();
263         eventSets[7] = eventSet;
264 
265         cpRequest.disable();
266 
267         ClassPrepareEvent event = (ClassPrepareEvent) eventIterator.next();
268         debuggeeClass = event.referenceType();
269 
270         if (!debuggeeClass.name().equals(debuggeeName))
271            throw new JDITestRuntimeException("** Unexpected ClassName for ClassPrepareEvent **");
272 
273         log2("      received: ClassPrepareEvent for debuggeeClass");
274 
275         log2("......setting up ClassPrepareEvent");
276 
277         String bPointMethod = "methodForCommunication";
278         String lineForComm  = "lineForComm";
279         BreakpointRequest bpRequest;
280 
281         ThreadReference mainThread = debuggee.threadByNameOrThrow("main");
282 
283         bpRequest = settingBreakpoint(mainThread,
284                                       debuggeeClass,
285                                       bPointMethod, lineForComm, "zero");
286         bpRequest.enable();
287 
288     //------------------------------------------------------  testing section
289 
290         log1("     TESTING BEGINS");
291 
292         for (int i = 0; ; i++) {
293 
294             vm.resume();
295             breakpointForCommunication();
296 
297             int instruction = ((IntegerValue)
298                                (debuggeeClass.getValue(debuggeeClass.fieldByName("instruction")))).value();
299 
300             if (instruction == 0) {
301                 vm.resume();
302                 break;
303             }
304 
305             log1(":::::: case: # " + i);
306 
307             //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part
308             //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
309         }
310         log1("    TESTING ENDS");
311         return;
312     }
313 
314     // ============================== test's additional methods
315 
check()316     private void check() {
317 
318         log2("......checking up on EventIterator");
319         if (eventIterator == null) {
320             testExitCode = FAILED;
321             log3("ERROR: eventIterator == null");
322         }
323         if ( !(eventIterator instanceof Iterator) ) {
324             testExitCode = FAILED;
325             log3("ERROR: eventIterator is NOT instanceof Iterator");
326         }
327     }
328 
329 }
330