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.EventSet.suspendPolicy;
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.suspendPolicy()</code>            <BR>
43  * complies with its spec.                                      <BR>
44  * <BR>
45  * The test checks that for Event sets,                         <BR>
46  * corresponding to VMStart, VMDeath, and VMDisconnect Events,  <BR>
47  * the method returns                                           <BR>
48  *      SUSPEND_ALL, SUSPEND_NONE, and SUSPEND_NONE.            <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,                                       <BR>
56  * it checks up on the value returned by the method suspendPolicy(),    <BR>
57  * resumes the VM, and waits for VMDeathEvent within                    <BR>
58  * the predefined time interval.                                        <BR>
59  * If no the event received, the test is FAILED.                        <BR>
60  * Upon getting the VMDeathEvent, the debugger                          <BR>
61  * checks up on the value returned by the method suspendPolicy() and    <BR>
62  * waits for VMDisconnectEvent within the predefined time interval.     <BR>
63  * If no the event received, the test is FAILED.                        <BR>
64  * Upon getting the VMDisconnectEvent, the debugger                     <BR>
65  * checks up on the value returned by the method suspendPolicy().       <BR>
66  * <BR>
67  */
68 
69 public class suspendpolicy018 {
70 
71     //----------------------------------------------------- templete section
72     static final int PASSED = 0;
73     static final int FAILED = 2;
74     static final int PASS_BASE = 95;
75 
76     //----------------------------------------------------- templete parameters
77     static final String
78     sHeader1 = "\n==> nsk/jdi/EventSet/suspendPolicy/suspendpolicy018 ",
79     sHeader2 = "--> debugger: ",
80     sHeader3 = "##> debugger: ";
81 
82     //----------------------------------------------------- main method
83 
main(String argv[])84     public static void main (String argv[]) {
85 
86         int result = run(argv, System.out);
87 
88         System.exit(result + PASS_BASE);
89     }
90 
run(String argv[], PrintStream out)91     public static int run (String argv[], PrintStream out) {
92 
93         int exitCode = new suspendpolicy018().runThis(argv, out);
94 
95         if (exitCode != PASSED) {
96             System.out.println("TEST FAILED");
97         }
98         return testExitCode;
99     }
100 
101     //--------------------------------------------------   log procedures
102 
103     private static Log  logHandler;
104 
log1(String message)105     private static void log1(String message) {
106         logHandler.display(sHeader1 + message);
107     }
log2(String message)108     private static void log2(String message) {
109         logHandler.display(sHeader2 + message);
110     }
log3(String message)111     private static void log3(String message) {
112         logHandler.complain(sHeader3 + message);
113     }
114 
115     //  ************************************************    test parameters
116 
117     private String debuggeeName =
118         "nsk.jdi.EventSet.suspendPolicy.suspendpolicy018a";
119 
120     private String testedClassName =
121         "nsk.jdi.EventSet.suspendPolicy.TestClass";
122 
123     //====================================================== test program
124     //------------------------------------------------------ common section
125 
126     static Debugee          debuggee;
127     static ArgumentHandler  argsHandler;
128 
129     static int waitTime;
130 
131     static VirtualMachine      vm            = null;
132     static EventRequestManager eventRManager = null;
133     static EventQueue          eventQueue    = null;
134     static EventSet            eventSet      = null;
135     static EventIterator       eventIterator = null;
136 
137     static ReferenceType       debuggeeClass = null;
138 
139     static int  testExitCode = PASSED;
140 
141 
142     class JDITestRuntimeException extends RuntimeException {
JDITestRuntimeException(String str)143         JDITestRuntimeException(String str) {
144             super("JDITestRuntimeException : " + str);
145         }
146     }
147 
148     int policyToCheck = 0;
149 
150     //------------------------------------------------------ methods
151 
runThis(String argv[], PrintStream out)152     private int runThis (String argv[], PrintStream out) {
153 
154         argsHandler     = new ArgumentHandler(argv);
155         logHandler      = new Log(out, argsHandler);
156         Binder binder   = new Binder(argsHandler, logHandler);
157 
158         waitTime        = argsHandler.getWaitTime() * 60000;
159 
160         try {
161             log2("launching a debuggee :");
162             log2("       " + debuggeeName);
163             if (argsHandler.verbose()) {
164                 debuggee = binder.bindToDebugeeNoWait(debuggeeName + " -vbs");
165             } else {
166                 debuggee = binder.bindToDebugeeNoWait(debuggeeName);
167             }
168             if (debuggee == null) {
169                 log3("ERROR: no debuggee launched");
170                 return FAILED;
171             }
172             log2("debuggee launched");
173         } catch ( Exception e ) {
174             log3("ERROR: Exception : " + e);
175             log2("       test cancelled");
176             return FAILED;
177         }
178 
179         debuggee.redirectOutput(logHandler);
180 
181         vm = debuggee.VM();
182 
183         eventQueue = vm.eventQueue();
184         if (eventQueue == null) {
185             log3("ERROR: eventQueue == null : TEST ABORTED");
186             vm.exit(PASS_BASE);
187             return FAILED;
188         }
189 
190         log2("invocation of the method runTest()");
191         switch (runTest()) {
192 
193             case 0 :  log2("test phase has finished normally");
194                       log2("   waiting for the debuggee to finish ...");
195                       debuggee.waitFor();
196 
197                       log2("......getting the debuggee's exit status");
198                       int status = debuggee.getStatus();
199                       if (status != PASS_BASE) {
200                           log3("ERROR: debuggee returned UNEXPECTED exit status: " +
201                               status + " != PASS_BASE");
202                           testExitCode = FAILED;
203                       } else {
204                           log2("......debuggee returned expected exit status: " +
205                               status + " == PASS_BASE");
206                       }
207                       break;
208 
209             default : log3("ERROR: runTest() returned unexpected value");
210 
211             case 1 :  log3("test phase has not finished normally: debuggee is still alive");
212                       log2("......forcing: vm.exit();");
213                       testExitCode = FAILED;
214                       try {
215                           vm.exit(PASS_BASE);
216                       } catch ( Exception e ) {
217                           log3("ERROR: Exception : e");
218                       }
219                       break;
220 
221             case 2 :  log3("test cancelled due to VMDisconnectedException");
222                       log2("......trying: vm.process().destroy();");
223                       testExitCode = FAILED;
224                       try {
225                           Process vmProcess = vm.process();
226                           if (vmProcess != null) {
227                               vmProcess.destroy();
228                           }
229                       } catch ( Exception e ) {
230                           log3("ERROR: Exception : e");
231                       }
232                       break;
233             }
234 
235         return testExitCode;
236     }
237 
238 
239    /*
240     * Return value: 0 - normal end of the test
241     *               1 - ubnormal end of the test
242     *               2 - VMDisconnectedException while test phase
243     */
244 
runTest()245     private int runTest() {
246 
247         try {
248             log2("waiting for VMStartEvent");
249             getEventSet();
250             if (eventIterator.nextEvent() instanceof VMStartEvent) {
251                 log2("VMStartEvent received; test begins");
252                 int sp1 = eventSet.suspendPolicy();
253                 if (sp1 != EventRequest.SUSPEND_ALL) {
254                     log3("ERROR: eventSet.suspendPolicy() != EventRequest.SUSPEND_ALL   but : " + sp1);
255                     testExitCode = FAILED;
256                 }
257 
258                 testRun();
259 
260                 log2("waiting for VMDeathEvent");
261                 getEventSet();
262                 if ( !(eventIterator.nextEvent() instanceof VMDeathEvent) ) {
263                     log3("ERROR: last event is not the VMDeathEvent");
264                     return 1;
265                 }
266                 sp1 = eventSet.suspendPolicy();
267                 if (sp1 != EventRequest.SUSPEND_NONE) {
268                     log3("ERROR: eventSet.suspendPolicy() != EventRequest.SUSPEND_NONE   but : " + sp1);
269                     testExitCode = FAILED;
270                 }
271 
272                 log2("waiting for VMDisconnectEvent");
273                 getEventSet();
274                 if ( !(eventIterator.nextEvent() instanceof VMDisconnectEvent) ) {
275                     log3("ERROR: last event is not the VMDisconnectEvent");
276                     return 1;
277                 }
278                 sp1 = eventSet.suspendPolicy();
279                 if (sp1 != EventRequest.SUSPEND_NONE) {
280                     log3("ERROR: eventSet.suspendPolicy() != EventRequest.SUSPEND_NONE   but : " + sp1);
281                     testExitCode = FAILED;
282                 }
283 
284                 return 0;
285             } else {
286                 log3("ERROR: first event is not the VMStartEvent");
287                 return 1;
288             }
289         } catch ( VMDisconnectedException e ) {
290             log3("ERROR: VMDisconnectedException : " + e);
291             return 2;
292         } catch ( Exception e ) {
293             log3("ERROR: Exception : " + e);
294             return 1;
295         }
296 
297     }
298 
testRun()299     private void testRun()
300                  throws JDITestRuntimeException, Exception {
301 
302         eventRManager = vm.eventRequestManager();
303 
304         log2("......getting ClassPrepareEvent for debuggee's class");
305         ClassPrepareRequest cpRequest = eventRManager.createClassPrepareRequest();
306         cpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD);
307         cpRequest.addClassFilter(debuggeeName);
308         cpRequest.enable();
309         vm.resume();
310         getEventSet();
311         cpRequest.disable();
312 
313         ClassPrepareEvent event = (ClassPrepareEvent) eventIterator.next();
314         debuggeeClass = event.referenceType();
315 
316         if (!debuggeeClass.name().equals(debuggeeName))
317            throw new JDITestRuntimeException("** Unexpected ClassName for ClassPrepareEvent **");
318         log2("      received: ClassPrepareEvent for debuggeeClass");
319 
320         vm.resume();
321 
322         log1("    TESTING ENDS");
323         return;
324     }
325 
getEventSet()326     private void getEventSet()
327                  throws JDITestRuntimeException {
328         try {
329 //            log2("       eventSet = eventQueue.remove(waitTime);");
330             eventSet = eventQueue.remove(waitTime);
331             if (eventSet == null) {
332                 throw new JDITestRuntimeException("** TIMEOUT while waiting for event **");
333             }
334 //            log2("       eventIterator = eventSet.eventIterator;");
335             eventIterator = eventSet.eventIterator();
336         } catch ( Exception e ) {
337             throw new JDITestRuntimeException("** EXCEPTION while waiting for event ** : " + e);
338         }
339     }
340 
341 }
342