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.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 a VMDeathEvent set,                 <BR>
46  * the method returns values corresponding to one               <BR>
47  * which suspends the most threads.                             <BR>
48  * The cases to check include event set containing two more     <BR>
49  * VMDeathRequests with suspendPolicies                         <BR>
50  *      SUSPEND_EVENT_THREAD and SUSPEND_NONE.                  <BR>
51  * <BR>
52  * The test has three phases and works as follows.              <BR>
53  * <BR>
54  * In first phase,                                                      <BR>
55  * upon launching debuggee's VM which will be suspended,                <BR>
56  * a debugger waits for the VMStartEvent within a predefined            <BR>
57  * time interval. If no the VMStartEvent received, the test is FAILED.  <BR>
58  * Upon getting the VMStartEvent, it makes the request for debuggee's   <BR>
59  * ClassPrepareEvent with SUSPEND_EVENT_THREAD, resumes the VM,         <BR>
60  * and waits for the event within the predefined time interval.         <BR>
61  * If no the ClassPrepareEvent received, the test is FAILED.            <BR>
62  * Upon getting the ClassPrepareEvent,                                  <BR>
63  * the debugger sets up the breakpoint with SUSPEND_EVENT_THREAD        <BR>
64  * within debuggee's special methodForCommunication().                  <BR>
65  * <BR>
66  * In second phase to check the above,                                  <BR>
67  * the debugger and the debuggee perform the following loop.            <BR>
68  * - The debugger sets up VMDeathRequests, resumes                      <BR>
69  *   the debuggee, and waits for the VMDeathEvent.                      <BR>
70  * - The debuggee ends to be resulting in the event.                    <BR>
71  * - Upon getting new event, the debugger                               <BR>
72  *   performs the check corresponding to the event.                     <BR>
73  * <BR>
74  * Note. To inform each other of needed actions, the debugger and       <BR>
75  *       and the debuggee use debuggee's variable "instruction".        <BR>
76  * In third phase, at the end,                                          <BR>
77  * the debuggee changes the value of the "instruction"                  <BR>
78  * to inform the debugger of checks finished, and both end.             <BR>
79  * <BR>
80  */
81 
82 public class suspendpolicy014 extends JDIBase {
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 suspendpolicy014().runThis(argv, out);
94 
95         if (exitCode != PASSED) {
96             System.out.println("TEST FAILED");
97         }
98         return testExitCode;
99     }
100 
101     //  ************************************************    test parameters
102 
103     private String debuggeeName =
104         "nsk.jdi.EventSet.suspendPolicy.suspendpolicy014a";
105 
106     private String testedClassName =
107         "nsk.jdi.EventSet.suspendPolicy.TestClass";
108 
109     //====================================================== test program
110 
111     int policyToCheck = 0;
112 
runThis(String argv[], PrintStream out)113     private int runThis (String argv[], PrintStream out) {
114 
115         argsHandler     = new ArgumentHandler(argv);
116         logHandler      = new Log(out, argsHandler);
117         Binder binder   = new Binder(argsHandler, logHandler);
118 
119         waitTime        = argsHandler.getWaitTime() * 60000;
120 
121         try {
122             log2("launching a debuggee :");
123             log2("       " + debuggeeName);
124             if (argsHandler.verbose()) {
125                 debuggee = binder.bindToDebugee(debuggeeName + " -vbs");
126             } else {
127                 debuggee = binder.bindToDebugee(debuggeeName);
128             }
129             if (debuggee == null) {
130                 log3("ERROR: no debuggee launched");
131                 return FAILED;
132             }
133             log2("debuggee launched");
134         } catch ( Exception e ) {
135             log3("ERROR: Exception : " + e);
136             log2("       test cancelled");
137             return FAILED;
138         }
139 
140         debuggee.redirectOutput(logHandler);
141 
142         vm = debuggee.VM();
143 
144         eventQueue = vm.eventQueue();
145         if (eventQueue == null) {
146             log3("ERROR: eventQueue == null : TEST ABORTED");
147             vm.exit(PASS_BASE);
148             return FAILED;
149         }
150 
151         log2("invocation of the method runTest()");
152         switch (runTest()) {
153 
154             case 0 :  log2("test phase has finished normally");
155                       log2("   waiting for the debuggee to finish ...");
156                       debuggee.waitFor();
157 
158                       log2("......getting the debuggee's exit status");
159                       int status = debuggee.getStatus();
160                       if (status != PASS_BASE) {
161                           log3("ERROR: debuggee returned UNEXPECTED exit status: " +
162                               status + " != PASS_BASE");
163                           testExitCode = FAILED;
164                       } else {
165                           log2("......debuggee returned expected exit status: " +
166                               status + " == PASS_BASE");
167                       }
168                       break;
169 
170             default : log3("ERROR: runTest() returned unexpected value");
171 
172             case 1 :  log3("test phase has not finished normally: debuggee is still alive");
173                       log2("......forcing: vm.exit();");
174                       testExitCode = FAILED;
175                       try {
176                           vm.exit(PASS_BASE);
177                       } catch ( Exception e ) {
178                           log3("ERROR: Exception : e");
179                       }
180                       break;
181 
182             case 2 :  log3("test cancelled due to VMDisconnectedException");
183                       log2("......trying: vm.process().destroy();");
184                       testExitCode = FAILED;
185                       try {
186                           Process vmProcess = vm.process();
187                           if (vmProcess != null) {
188                               vmProcess.destroy();
189                           }
190                       } catch ( Exception e ) {
191                           log3("ERROR: Exception : e");
192                       }
193                       break;
194             }
195 
196         return testExitCode;
197     }
198 
199 
200    /*
201     * Return value: 0 - normal end of the test
202     *               1 - ubnormal end of the test
203     *               2 - VMDisconnectedException while test phase
204     */
205 
runTest()206     private int runTest() {
207 
208         try {
209             testRun();
210 
211             log2("waiting for VMDeathEvent");
212             getEventSet();
213             if ( !(eventIterator.nextEvent() instanceof VMDeathEvent) ) {
214                 log3("ERROR: last event is not the VMDeathEvent");
215                 return 1;
216             }
217             check();
218 
219             log2("waiting for VMDisconnectEvent");
220             getEventSet();
221             if ( !(eventIterator.nextEvent() instanceof VMDisconnectEvent) ) {
222                 log3("ERROR: last event is not the VMDisconnectEvent");
223                 return 1;
224             }
225 
226             return 0;
227 
228         } catch ( VMDisconnectedException e ) {
229             log3("ERROR: VMDisconnectedException : " + e);
230             return 2;
231         } catch ( Exception e ) {
232             log3("ERROR: Exception : " + e);
233             return 1;
234         }
235 
236     }
237 
testRun()238     private void testRun()
239                  throws JDITestRuntimeException, Exception {
240 
241         if ( !vm.canRequestVMDeathEvent() ) {
242             log2("......vm.canRequestVMDeathEvent == false :: test cancelled");
243             vm.exit(PASS_BASE);
244             return;
245         }
246 
247 
248         eventRManager = vm.eventRequestManager();
249 
250         log2("......getting ClassPrepareEvent for debuggee's class");
251         ClassPrepareRequest cpRequest = eventRManager.createClassPrepareRequest();
252         cpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD);
253         cpRequest.addClassFilter(debuggeeName);
254         cpRequest.enable();
255         vm.resume();
256         getEventSet();
257         cpRequest.disable();
258 
259         ClassPrepareEvent event = (ClassPrepareEvent) eventIterator.next();
260         debuggeeClass = event.referenceType();
261 
262         if (!debuggeeClass.name().equals(debuggeeName))
263            throw new JDITestRuntimeException("** Unexpected ClassName for ClassPrepareEvent **");
264         log2("      received: ClassPrepareEvent for debuggeeClass");
265 
266         log2("......setting up ClassPrepareEvent for breakpointForCommunication");
267 
268         String            bPointMethod = "methodForCommunication";
269         String            lineForComm  = "lineForComm";
270         BreakpointRequest bpRequest;
271         ThreadReference   mainThread = debuggee.threadByNameOrThrow("main");
272         bpRequest = settingBreakpoint(mainThread,
273                                       debuggeeClass,
274                                       bPointMethod, lineForComm, "zero");
275         bpRequest.enable();
276 
277         vm.resume();
278 
279     //------------------------------------------------------  testing section
280 
281         log1("     TESTING BEGINS");
282 
283         EventRequest eventRequest1 = null;
284         EventRequest eventRequest2 = null;
285         EventRequest eventRequest3 = null;
286 
287         final int SUSPEND_POLICY = EventRequest.SUSPEND_NONE;
288         final int SUSPEND_NONE   = EventRequest.SUSPEND_NONE;
289         final int SUSPEND_THREAD = EventRequest.SUSPEND_EVENT_THREAD;
290         final int SUSPEND_ALL    = EventRequest.SUSPEND_ALL;
291 
292         int policyExpected[] = {    SUSPEND_NONE,
293                                     SUSPEND_THREAD,
294                                     SUSPEND_ALL,
295                                     SUSPEND_THREAD,
296                                     SUSPEND_ALL,
297                                     SUSPEND_ALL,
298                                     SUSPEND_ALL      };
299         int policy = 0;
300 
301         breakpointForCommunication();
302 
303             //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part
304 
305         eventRequest1 = settingVMDeathRequest (SUSPEND_NONE, "VMDeathRequest1");
306         eventRequest1.enable();
307         eventRequest2 = settingVMDeathRequest (SUSPEND_THREAD, "VMDeathRequest2");
308         eventRequest2.enable();
309 
310         policyToCheck = policyExpected[3];
311         mainThread.resume();
312 
313             //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
314 
315         log1("    TESTING ENDS");
316         return;
317     }
318 
319     // ============================== test's additional methods
320 
settingVMDeathRequest( int suspendPolicy, String property )321     private VMDeathRequest settingVMDeathRequest( int    suspendPolicy,
322                                                   String property       )
323             throws JDITestRuntimeException {
324         try {
325             log2("......setting up VMDeathRequest:");
326             log2("      suspendPolicy: " + suspendPolicy + "; property: " + property);
327 
328             VMDeathRequest
329             vmdr = eventRManager.createVMDeathRequest();
330             vmdr.putProperty("number", property);
331             vmdr.setSuspendPolicy(suspendPolicy);
332 
333             return vmdr;
334         } catch ( Exception e ) {
335             log3("ERROR: ATTENTION: Exception within settingVMDeathRequest() : " + e);
336             log3("       VMDeathRequest HAS NOT BEEN SET UP");
337             throw new JDITestRuntimeException("** FAILURE to set up a VMDeathRequest **");
338         }
339     }
340 
check()341     void check() {
342         log2("......checking up on eventSet.suspendPolicy()");
343         int policy = eventSet.suspendPolicy();
344         if (policy != policyToCheck) {
345             log3("ERROR: eventSet.suspendPolicy() != policyExpected");
346             log3("       eventSet.suspendPolicy() == " + policy);
347             log3("       policyExpected           == " + policyToCheck);
348             testExitCode = FAILED;
349         }
350         vm.resume();
351     }
352 
353 }
354