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