1 /*
2  * Copyright (c) 2002, 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.ClassType.invokeMethod;
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.request.*;
32 import com.sun.jdi.event.*;
33 
34 import java.util.*;
35 import java.io.*;
36 
37 /**
38  *
39  * The test checks up the method com.sun.jdi.ClassType.invokeMethod()
40  *
41  * Test checks up the following assertion:
42  *    ...all threads in the target VM are resumed while the method is
43  *    being invoked if they were previously suspended by an event or by
44  *    VirtualMachine.suspend() or ThreadReference.suspend().
45  *
46  * This checking is implemented for three cases:
47  *    - when the tested thread is suspended by ThreadReference.suspend();
48  *    - when the tested thread is suspended by VirtualMachine.suspend();
49  *    - when the tested thread is suspended by an event.
50  */
51 
52 public class invokemethod007 {
53 
54     private final static String prefix = "nsk.jdi.ClassType.invokeMethod.";
55     private final static String debuggerName = prefix + "invokemethod007";
56     private final static String debugeeName = debuggerName + "a";
57 
58     public final static String SGNL_READY = "ready";
59     public final static String SGNL_QUIT = "quit";
60     public final static String SGNL_STRTHRD = "start_thread";
61 
62     private static int exitStatus;
63     private static Log log;
64     private static Debugee debugee;
65     private static long waitTime;
66 
67     private ClassType testedClass;
68     private ThreadReference thread;
69 
70     class TestRuntimeException extends RuntimeException {
TestRuntimeException(String msg)71         TestRuntimeException(String msg) {
72             super("TestRuntimeException: " + msg);
73         }
74     }
75 
76     public final static String method2Invoke = "invokedMethod";
77 
display(String msg)78     private static void display(String msg) {
79         log.display(msg);
80     }
81 
complain(String msg)82     private static void complain(String msg) {
83         log.complain("debugger FAILURE> " + msg + "\n");
84     }
85 
main(String argv[])86     public static void main(String argv[]) {
87         System.exit(Consts.JCK_STATUS_BASE + run(argv, System.out));
88     }
89 
run(String argv[], PrintStream out)90     public static int run(String argv[], PrintStream out) {
91 
92         exitStatus = Consts.TEST_PASSED;
93 
94         invokemethod007 thisTest = new invokemethod007();
95 
96         ArgumentHandler argHandler = new ArgumentHandler(argv);
97         log = new Log(out, argHandler);
98 
99         waitTime = argHandler.getWaitTime() * 60000;
100 
101         debugee = Debugee.prepareDebugee(argHandler, log, debugeeName);
102 
103         thisTest.execTest();
104         display("Test finished. exitStatus = " + exitStatus);
105 
106         return exitStatus;
107     }
108 
execTest()109     private void execTest() {
110 
111         debugee.VM().suspend();
112         testedClass = (ClassType )debugee.classByName(debugeeName);
113 
114         BreakpointRequest brkp = debugee.makeBreakpoint(testedClass,
115                                             invokemethod007a.brkpMethodName,
116                                             invokemethod007a.brkpLineNumber);
117         brkp.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
118         brkp.enable();
119 
120         display("\nTEST BEGINS");
121         display("===========");
122 
123         Value retValue;
124         List<Value> params = new Vector<Value>();
125         ThreadReference suspendedThread;
126         BreakpointEvent brkpEvent;
127 
128         Method method = debugee.methodByName(testedClass, method2Invoke);
129         display("Method      : " + method);
130 
131         for (int i = 0; i < 3; i++) {
132             display("");
133             switch (i) {
134             case 0:
135                 display("\nCASE#0 : Thread is suspended by ThreadReference.suspend()");
136                 break;
137             case 1:
138                 display("\nCASE#1 : Thread is suspended by VirtualMachine.suspend()");
139                 break;
140             case 2:
141                 display("\nCASE#2 : Thread is suspended by BreakPointRequest");
142                 brkp.disable();
143                 brkp.setSuspendPolicy(EventRequest.SUSPEND_ALL);
144                 brkp.enable();
145             }
146 
147             // starting thread
148             display("sending signal " + SGNL_STRTHRD);
149             debugee.sendSignal(SGNL_STRTHRD);
150             debugee.resume();
151             display("waiting for signal " + SGNL_READY);
152             debugee.receiveExpectedSignal(SGNL_READY);
153 
154             brkpEvent = waitForBreakpoint(brkp);
155 
156             thread = brkpEvent.thread();
157 
158             suspendedThread = debugee.threadByName(invokemethod007a.testedThread);
159             switch (i) {
160             case 0:
161                 suspendedThread.suspend();
162                 break;
163             case 1:
164                 debugee.VM().suspend();
165                 break;
166             }
167 
168             if ( !suspendedThread.isSuspended() ) {
169                 complain(suspendedThread.name() + " is not suspended");
170                 exitStatus = Consts.TEST_FAILED;
171             } else {
172                 display(suspendedThread.name() + " is suspended");
173             }
174             try {
175                 if (i == 1) {
176                     // for VirtualMachine.suspended() only!
177                     // resume thread for invokedMethod to have suspend count equal to 1.
178                     thread.resume();
179                 }
180                 display("invoking the method");
181                 retValue = testedClass.invokeMethod(thread, method, params, 0);
182 
183                 long resultTime = ((PrimitiveValue)retValue).longValue();
184                 if ( resultTime >= waitTime) {
185                     complain("CASE #" + i + " FAILED." +
186                         "\n\tTimeout occured while invocation of debugee's method");
187                     exitStatus = Consts.TEST_FAILED;
188                 } else {
189                     display("CASE #" + i + " PASSED");
190                 }
191             } catch(Exception e) {
192                 complain("Unexpected exception while invocation of debugee's method: " + e);
193                 exitStatus = Consts.TEST_FAILED;
194             }
195         }
196 
197         display("=============");
198         display("TEST FINISHES\n");
199 
200         debugee.resume();
201         debugee.quit();
202     }
203 
waitForBreakpoint(BreakpointRequest brkp)204     private BreakpointEvent waitForBreakpoint(BreakpointRequest brkp) {
205         Event event = null;
206         BreakpointEvent brkpEvent;
207 
208         try {
209             event = debugee.waitingEvent(brkp, waitTime);
210         } catch (InterruptedException e) {
211             throw new TestRuntimeException("unexpected InterruptedException");
212         }
213 
214         if (!(event instanceof BreakpointEvent )) {
215             debugee.resume();
216             throw new TestRuntimeException("BreakpointEvent didn't arrive");
217         }
218 
219         brkpEvent = (BreakpointEvent )event;
220         return brkpEvent;
221     }
222 }
223