1 /*
2  * Copyright (c) 2007, 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 /*
25  * @test
26  *
27  * @summary converted from VM Testbase nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn002.
28  * VM Testbase keywords: [quick, jpda, jdi, feature_jdk6_jpda, vm6]
29  * VM Testbase readme:
30  * DESCRIPTION
31  *         The test checks that a result of the method com.sun.jdi.forceEarlyReturn(Value value)
32  *         complies with its specification. The test checks:
33  *                 - attempt to call forceEarlyReturn for the type which has not yet been loaded throws ClassNotLoadedException
34  *                 - MethodExitEvent is generated as it would be in a normal return
35  *         Test scenario:
36  *         Debugger VM enable breakpoint in test method which return type is 'nsk.share.jdi.TestClass1',
37  *         force debugee call this method and when debugee VM stop at breakpoint, call forceEarlyReturn().
38  *         ClassNotLoadedException should be thrown (expect that nsk.share.jdi.TestClass1 isn't loaded in debuggee VM).
39  *         Debugger VM force debuggee VM create instance of 'nsk.share.jdi.TestClass1' and call test method again.
40  *         When debugee VM stop at breakpoint, call forceEarlyReturn() and check that no exception is thrown.
41  *         Debugee checks that correct value is returned from test method after force return.
42  *         Debugger checks that MethodExitEvent is generated after forceEarlyReturn.
43  *
44  * @library /vmTestbase
45  *          /test/lib
46  * @build nsk.jdi.ThreadReference.forceEarlyReturn.forceEarlyReturn002.forceEarlyReturn002
47  *        nsk.jdi.ThreadReference.forceEarlyReturn.forceEarlyReturn002.forceEarlyReturn002a
48  * @run main/othervm
49  *      nsk.jdi.ThreadReference.forceEarlyReturn.forceEarlyReturn002.forceEarlyReturn002
50  *      -verbose
51  *      -arch=${os.family}-${os.simpleArch}
52  *      -waittime=5
53  *      -debugee.vmkind=java
54  *      -transport.address=dynamic
55  *      -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
56  */
57 
58 package nsk.jdi.ThreadReference.forceEarlyReturn.forceEarlyReturn002;
59 
60 import java.io.PrintStream;
61 import com.sun.jdi.*;
62 import com.sun.jdi.request.*;
63 import com.sun.jdi.event.*;
64 import nsk.share.Consts;
65 import nsk.share.jdi.ForceEarlyReturnDebugger;
66 
67 public class forceEarlyReturn002 extends ForceEarlyReturnDebugger {
main(String argv[])68     public static void main(String argv[]) {
69         System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
70     }
71 
debuggeeClassName()72     public String debuggeeClassName() {
73         return forceEarlyReturn002a.class.getName();
74     }
75 
run(String argv[], PrintStream out)76     public static int run(String argv[], PrintStream out) {
77         return new forceEarlyReturn002().runIt(argv, out);
78     }
79 
doTest()80     public void doTest() {
81         // initialize breakpoint
82 
83         ReferenceType referenceType = debuggee.classByName(ClassUsingTestClass.class.getName());
84 
85         BreakpointRequest breakpointRequest = debuggee.makeBreakpoint(referenceType,
86                 ClassUsingTestClass.breakpointMethodName,
87                 ClassUsingTestClass.breakpointLine);
88 
89         breakpointRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
90         breakpointRequest.enable();
91 
92         pipe.println(forceEarlyReturn002a.COMMAND_CALL_OBJECT_METHOD);
93 
94         BreakpointEvent breakPointEvent = waitForBreakpoint(breakpointRequest);
95 
96         // if no breakpoint happened then test failed, stop testing
97         if (breakPointEvent == null)
98             return;
99 
100         /*
101          * Test can't guarantee that TestClass1 isn't loaded in the debuggee VM (it isn't loaded
102          * if VM implements lazy loading). Here test checks that TestClass1 isn't loaded and
103          * if class is really absent in the debuggee VM it is possible to check ClassNotLoadedException.
104          */
105         boolean testClassIsLoaded = false;
106 
107         ClassLoaderReference classLoader = debuggee.classByName(forceEarlyReturn002a.class.getName()).classLoader();
108         for (ReferenceType loadedClass : classLoader.visibleClasses()) {
109             if (loadedClass.name().equals("nsk.share.jdi.TestClass1")) {
110                 log.display("WARNING: TestClass1 is loaded in the debuggee VM, can't test ClassNotLoadedException");
111                 testClassIsLoaded = true;
112                 break;
113             }
114         }
115 
116         ThreadReference threadReference = debuggee.threadByName(forceEarlyReturn002a.mainThreadName);
117 
118         try {
119             if (testClassIsLoaded) {
120                 threadReference.forceEarlyReturn(null);
121             } else {
122                 try {
123                     threadReference.forceEarlyReturn(threadReference);
124                     setSuccess(false);
125                     log.complain("Expected 'ClassNotLoadedException' was not thrown");
126                 } catch (ClassNotLoadedException e) {
127                     log.display("Got expected ClassNotLoadedException");
128                 }
129             }
130         } catch (Exception e) {
131             unexpectedException(e);
132         }
133 
134         debuggee.resume();
135 
136         if (!isDebuggeeReady())
137             return;
138 
139         // after this command test class should be loaded
140         pipe.println(forceEarlyReturn002a.COMMAND_LOAD_CLASS_AND_CALL_OBJECT_METHOD);
141 
142         breakPointEvent = waitForBreakpoint(breakpointRequest);
143 
144         // if no breakpoint happened then test failed, stop testing
145         if (breakPointEvent == null)
146             return;
147 
148         // get value for early return
149         ObjectReference returnValue = (ObjectReference) referenceType.getValue(referenceType.fieldByName("expectedValue"));
150 
151         try {
152             // don't expect any exception
153             threadReference.forceEarlyReturn(returnValue);
154         } catch (Exception e) {
155             setSuccess(false);
156             log.complain("Unexpected exception: " + e);
157             e.printStackTrace(log.getOutStream());
158         }
159 
160         testMethodExitEvent(threadReference, ClassUsingTestClass.breakpointMethodName);
161 
162         if (!isDebuggeeReady())
163             return;
164     }
165 }
166