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.jdwp.VirtualMachine.ReleaseEvents;
25 
26 import java.io.*;
27 
28 import nsk.share.*;
29 import nsk.share.jpda.*;
30 import nsk.share.jdwp.*;
31 
32 /**
33  * Test for JDWP command: VirtualMachine.ReleaseEvents.
34  *
35  * See releaseevents001.README for description of test execution.
36  *
37  * This class represents debugger part of the test.
38  * Test is executed by invoking method runIt().
39  * JDWP command is tested in the method testCommand().
40  *
41  * @see #runIt()
42  * @see #testCommand()
43  */
44 public class releaseevents001 {
45 
46     // exit status constants
47     static final int JCK_STATUS_BASE = 95;
48     static final int PASSED = 0;
49     static final int FAILED = 2;
50 
51     // communication signals constants
52     static final String READY = "ready";
53     static final String QUIT = "quit";
54 
55     // package and classes names constants
56     static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.ReleaseEvents";
57     static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "releaseevents001";
58     static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
59 
60     // tested JDWP command constants
61     static final String JDWP_COMMAND_NAME = "VirtualMachine.ReleaseEvents";
62     static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.ReleaseEvents;
63 
64     // usual scaffold objects
65     ArgumentHandler argumentHandler = null;
66     Log log = null;
67     Binder binder = null;
68     Debugee debugee = null;
69     Transport transport = null;
70     IOPipe pipe = null;
71 
72     // test passed or not
73     boolean success = true;
74 
75     // -------------------------------------------------------------------
76 
77     /**
78      * Start test from command line.
79      */
main(String argv[])80     public static void main (String argv[]) {
81         System.exit(run(argv,System.out) + JCK_STATUS_BASE);
82     }
83 
84     /**
85      * Start JCK-compilant test.
86      */
run(String argv[], PrintStream out)87     public static int run(String argv[], PrintStream out) {
88         return new releaseevents001().runIt(argv, out);
89     }
90 
91     // -------------------------------------------------------------------
92 
93     /**
94      * Perform test execution.
95      */
runIt(String argv[], PrintStream out)96     public int runIt(String argv[], PrintStream out) {
97 
98         // make log for debugger messages
99         argumentHandler = new ArgumentHandler(argv);
100         log = new Log(out, argumentHandler);
101 
102         // execute test and display results
103         try {
104             log.display("\n>>> Preparing debugee for testing \n");
105 
106             // launch debuggee
107             binder = new Binder(argumentHandler, log);
108             log.display("Launching debugee");
109             debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
110             transport = debugee.getTransport();
111             pipe = debugee.createIOPipe();
112 
113             // make debuggee ready for testing
114             prepareDebugee();
115 
116             // work with prepared debuggee
117             try {
118 
119                 // finally release events
120                 log.display("Holding events into debuggee");
121                 holdEvents();
122 
123                 // perform testing JDWP command
124                 log.display("\n>>> Testing JDWP command \n");
125                 testCommand();
126 
127             } finally {
128 
129                 // quit debugee
130                 log.display("\n>>> Finishing test \n");
131                 quitDebugee();
132             }
133 
134         } catch (Failure e) {
135             log.complain("TEST FAILED: " + e.getMessage());
136             success = false;
137         } catch (Exception e) {
138             e.printStackTrace(out);
139             log.complain("Caught unexpected exception while running the test:\n\t" + e);
140             success = false;
141         }
142 
143         if (!success) {
144             log.complain("TEST FAILED");
145             return FAILED;
146         }
147 
148         out.println("TEST PASSED");
149         return PASSED;
150 
151     }
152 
153     /**
154      * Prepare debugee for testing and waiting for ready signal.
155      */
prepareDebugee()156     void prepareDebugee() {
157         // wait for VM_INIT event from debugee
158         log.display("Waiting for VM_INIT event");
159         debugee.waitForVMInit();
160 
161         // query debugee for VM-dependent ID sizes
162         log.display("Querying for IDSizes");
163         debugee.queryForIDSizes();
164 
165         // resume initially suspended debugee
166         log.display("Resuming debugee VM");
167         debugee.resume();
168 
169         // wait for READY signal from debugee
170         log.display("Waiting for signal from debugee: " + READY);
171         String signal = pipe.readln();
172         log.display("Received signal from debugee: " + signal);
173         if (! signal.equals(READY)) {
174             throw new TestBug("Unexpected signal received from debugee: " + signal
175                             + " (expected: " + READY + ")");
176         }
177     }
178 
179     /**
180      * Sending debugee signal to quit and waiting for it exits.
181      */
quitDebugee()182     void quitDebugee() {
183         // send debugee signal to quit
184         log.display("Sending signal to debugee: " + QUIT);
185         pipe.println(QUIT);
186 
187         // wait for debugee exits
188         log.display("Waiting for debugee exits");
189         int code = debugee.waitFor();
190 
191         // analize debugee exit status code
192         if (code == JCK_STATUS_BASE + PASSED) {
193             log.display("Debugee PASSED with exit code: " + code);
194         } else {
195             log.complain("Debugee FAILED with exit code: " + code);
196             success = false;
197         }
198     }
199 
200     /**
201      * Hold events into debuggee.
202      */
holdEvents()203     void holdEvents() {
204         CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.HoldEvents);
205         ReplyPacket reply = debugee.receiveReplyFor(command);
206     }
207 
208     /**
209      * Perform testing JDWP command.
210      */
testCommand()211     void testCommand() {
212         // create command packet and fill requred out data
213         log.display("Create command packet:");
214         log.display("Command: " + JDWP_COMMAND_NAME);
215         CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
216         command.setLength();
217 
218         // send command packet to debugee
219         try {
220             log.display("Sending command packet:\n" + command);
221             transport.write(command);
222         } catch (IOException e) {
223             log.complain("Unable to send command packet:\n\t" + e);
224             success = false;
225             return;
226         }
227 
228         ReplyPacket reply = new ReplyPacket();
229 
230         // receive reply packet from debugee
231         try {
232             log.display("Waiting for reply packet");
233             transport.read(reply);
234             log.display("Reply packet received:\n" + reply);
235         } catch (IOException e) {
236             log.complain("Unable to read reply packet:\n\t" + e);
237             success = false;
238             return;
239         }
240 
241         // check reply packet header
242         try{
243             log.display("Checking reply packet header");
244             reply.checkHeader(command.getPacketID());
245         } catch (BoundException e) {
246             log.complain("Bad header of reply packet:\n\t" + e.getMessage());
247             success = false;
248             return;
249         }
250 
251         // start parsing reply packet data
252         log.display("Parsing reply packet:");
253         reply.resetPosition();
254 
255         // no data in reply packet
256 
257         // check for extra data in reply packet
258         if (!reply.isParsed()) {
259             log.complain("Extra trailing bytes found in reply packet at: "
260                         + reply.offsetString());
261             success = false;
262         }
263     }
264 
265 }
266