001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Aleksander V. Budniy
021: * @version $Revision: $
022: */
023:
024: /**
025: * Created on 5.06.2006
026: */package org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand;
027:
028: import org.apache.harmony.jpda.tests.framework.TestErrorException;
029: import org.apache.harmony.jpda.tests.framework.TestOptions;
030: import org.apache.harmony.jpda.tests.jdwp.share.JDWPRawTestCase;
031: import org.apache.harmony.jpda.tests.jdwp.share.JDWPUnitDebuggeeProcessWrapper;
032: import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
033: import org.apache.harmony.jpda.tests.share.JPDATestOptions;
034:
035: /**
036: * This test case exercises possibility of debugge to invoke debugger on demand with "onthrow" option.
037: *
038: * @see org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthowDebuggerLaunchDebuggee
039: * @see org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001
040: * @see org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002
041: */
042: public class OnthrowDebuggerLaunchTest extends JDWPRawTestCase {
043:
044: public static final String EXCEPTION_CLASS_FOR_DEBUGGER = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.ExceptionForDebugger";
045:
046: public static final String DEBUGGEE_CLASS = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthowDebuggerLaunchDebuggee";
047:
048: /**
049: * Test launches debuggee (without establishing synchronization connection)
050: * with options suspend=y,onuncaught=n, debuggee executes
051: * <code>OnthrowLaunchedDebugger001</code>, test establishes synch
052: * connection with debugger and in cycle receives messages from debugger.
053: */
054: public void testDebuggerLaunch001() {
055: logWriter.println("==> testDebuggerLaunch started");
056:
057: String DEBUGGER_NAME = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001";
058: String isSuspend = "y";
059: String isOnuncaught = "n";
060:
061: performTest(DEBUGGER_NAME, isSuspend, isOnuncaught);
062:
063: logWriter.println("==> testDebuggerLaunch ended");
064: }
065:
066: /**
067: * Test launches debuggee (without establishing synchronization connection)
068: * with option suspend=y,onuncaught=n, debuggee executes
069: * <code>OnthrowLaunchedDebugger002</code>, test establishes synch
070: * connection with debugger and in cycle receives messages from debugger.
071: *
072: */
073:
074: public void testDebuggerLaunch002() {
075: logWriter.println("==> testDebuggerLaunch002 started");
076:
077: String DEBUGGER_NAME = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002";
078: String isSuspend = "y";
079: String isOnuncaught = "n";
080:
081: performTest(DEBUGGER_NAME, isSuspend, isOnuncaught);
082:
083: logWriter.println("==> testDebuggerLaunch002 ended");
084: }
085:
086: /**
087: * Test launches debuggee (without establishing synchronization connection)
088: * with option suspend=n,onuncaught=n debuggee executes
089: * <code>OnthrowLaunchedDebugger001</code>, test establishes synch
090: * connection with debugger and in cycle receives messages from debugger.
091: *
092: */
093: public void testDebuggerLaunch003() {
094: logWriter.println("==> testDebuggerLaunch started");
095:
096: String DEBUGGER_NAME = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001";
097: String isSuspend = "n";
098: String isOnuncaught = "n";
099:
100: performTest(DEBUGGER_NAME, isSuspend, isOnuncaught);
101:
102: logWriter.println("==> testDebuggerLaunch ended");
103: }
104:
105: /**
106: * Test executes debuggee (without establishing synchronization connection)
107: * with option suspend=n,onuncaught=n debuggee executes
108: * <code>OnthrowLaunchedDebugger002</code>, test establishes synch
109: * connection with debugger and in cycle receives messages from debugger.
110: *
111: */
112: public void testDebuggerLaunch004() {
113: logWriter.println("==> testDebuggerLaunch started");
114:
115: String DEBUGGER_NAME = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002";
116: String isSuspend = "n";
117: String isOnuncaught = "n";
118:
119: performTest(DEBUGGER_NAME, isSuspend, isOnuncaught);
120:
121: logWriter.println("==> testDebuggerLaunch ended");
122: }
123:
124: /**
125: * Method prepares cmd for launching debuggee and debugger. Passes
126: * debugger's cmd as parameter "launch" to debuggee's cmd. Then launches
127: * debuggee and wait for synch connection from debugger, that should be
128: * launched by debuggee. After that, method starts receiving messages in
129: * loop from debugger. Messages of three types: OK, FAIL, END. In case of
130: * FAIL or END messages, loop is ended.
131: *
132: * @param DEBUGGER_NAME
133: * name of debugger that debuggee will launch
134: * @param isSuspendDebuggee
135: * option defines should debuggee be suspended on start
136: * @param isOnuncaught
137: * parameter that is passed to debuggee (see JDWP agent launch
138: * options)
139: */
140: void performTest(String debuggerName, String isSuspendDebuggee,
141: String isOnuncaught) {
142:
143: try {
144: // prepare command line for debugger and debuggee processes
145:
146: String address = settings.getTransportAddress();
147: String debuggerCmd = prepareDebuggerCmd(debuggerName,
148: address, isSuspendDebuggee, isOnuncaught);
149: logWriter.println("=> Debugger command: " + debuggerCmd);
150:
151: String debuggeeCmd = prepareDebuggeeCmd(debuggerCmd,
152: address, isSuspendDebuggee, isOnuncaught);
153: logWriter.println("=> Debuggee command: " + debuggeeCmd);
154:
155: // launch debuggee process, which will launch debugger process
156:
157: debuggeeWrapper.launchProcessAndRedirectors(debuggeeCmd);
158:
159: // listen for synch connection from launched debugger
160:
161: logWriter
162: .println("=> Listen for synch connection from launched debugger");
163: debuggerSynchronizer.startServer();
164: logWriter
165: .println("=> Synch connection with launched debugger established");
166: } catch (Exception e) {
167: throw new TestErrorException(e);
168: }
169:
170: // exchange synch messages with debugger
171:
172: for (;;) {
173: String message = debuggerSynchronizer.receiveMessage();
174: if (message != null) {
175: logWriter.println("=> Message received from DEBUGGER: "
176: + message);
177: if (message.equals("FAILURE")) {
178: logWriter
179: .println("##FAILURE: error message received from debugger");
180: fail("Some error received from debugger");
181: } else if (message.equals("END")) {
182: logWriter.println("=> Debugger ends work");
183: break;
184: } else if (!message.equals("OK")) {
185: logWriter
186: .println("##FAILURE: unexpected message received from debugger");
187: fail("Unexpected message received from debugger");
188: }
189: } else {
190: logWriter
191: .println("##FAILURE: null message received from debugger");
192: fail("Null message received from debugger");
193: }
194: }
195: }
196:
197: ////////////////////////////////////////////////////////////////////////////////////////////
198:
199: protected String getDebuggeeClassName() {
200: return DEBUGGEE_CLASS;
201: }
202:
203: /**
204: * Creates wrapper for debuggee process.
205: */
206: protected JDWPUnitDebuggeeProcessWrapper createDebuggeeWrapper() {
207: return new JDWPUnitDebuggeeProcessWrapper(settings, logWriter);
208: }
209:
210: /**
211: * Creates wrapper for synch connection with debugger.
212: */
213: protected JPDADebuggeeSynchronizer createDebuggerSyncronizer() {
214: return new JPDADebuggeeSynchronizer(logWriter, settings);
215: }
216:
217: /**
218: * Creates wrapper object for accessing test options;
219: */
220: protected JPDATestOptions createTestOptions() {
221: return new LaunchedDebugger.JPDADebuggerOnDemandOptions();
222: }
223:
224: protected void internalSetUp() throws Exception {
225: super .internalSetUp();
226:
227: // set fixed address for attaching connection
228:
229: String address = settings.getTransportAddress();
230: if (address == null) {
231: settings
232: .setTransportAddress(TestOptions.DEFAULT_ATTACHING_ADDRESS);
233: }
234:
235: // set fixed port for debuggee sync connection
236:
237: debuggeeSyncPort = settings.getSyncPortString();
238: if (debuggeeSyncPort == null) {
239: debuggeeSyncPort = TestOptions.DEFAULT_STATIC_SYNC_PORT;
240: }
241:
242: // prepare for synch connection with debugger
243:
244: logWriter.println("=> Prepare synch connection with debugger");
245: debuggerSynchronizer = createDebuggerSyncronizer();
246: debuggerSyncPortNumber = debuggerSynchronizer.bindServer();
247:
248: // create wrapper for debuggee process
249:
250: debuggeeWrapper = createDebuggeeWrapper();
251: }
252:
253: /**
254: * Overrides inherited method to stop started debuggee VM and close all
255: * connections.
256: */
257: protected void internalTearDown() {
258: if (debuggerSynchronizer != null) {
259: logWriter.println("Close synch connection with debugger");
260: debuggerSynchronizer.stop();
261: }
262:
263: if (debuggeeWrapper != null) {
264: debuggeeWrapper.finishProcessAndRedirectors();
265: logWriter
266: .println("Finished debuggee VM process and closed connection");
267: }
268: super .internalTearDown();
269: }
270:
271: /**
272: * Prepares command line for launching debuggee.
273: *
274: * @param debuggerCmd cmd to launch debugger. Value of parameter "launch"
275: * @param agentAddress address for connection with debugger
276: * @param isSuspendDebuggee should debuggee be suspended on start
277: * @param isOnuncaught should debuggee waits for uncaught exception (see JDWP agent launch options)
278: * @return command line for launching debuggee
279: */
280: private String prepareDebuggerCmd(String debuggerName,
281: String transportAddress, String isSuspendDebuggee,
282: String isOnuncaught) {
283:
284: String cmdLine = settings.getDebuggeeJavaPath() + " -cp "
285: + settings.getDebuggeeClassPath()
286: + " -Djpda.settings.connectorKind=attach"
287: + " -Djpda.settings.debuggeeSuspend="
288: + isSuspendDebuggee
289: + " -Djpda.settings.transportAddress="
290: + transportAddress
291: + " -Djpda.settings.syncDebuggerPort="
292: + debuggerSyncPortNumber + " -Djpda.settings.syncPort="
293: + debuggeeSyncPort + " " + debuggerName;
294:
295: return cmdLine;
296: }
297:
298: /**
299: * Prepares command line for launching debuggee.
300: *
301: * @param debuggerCmd cmd to launch debugger. Value of parameter "launch"
302: * @param agentAddress address for connection with debugger
303: * @param isSuspendDebuggee should debuggee be suspended on start
304: * @param isOnuncaught should debuggee waits for uncaught exception (see JDWP agent launch options)
305: * @return command line for launching debuggee
306: */
307: private String prepareDebuggeeCmd(String debuggerCmd,
308: String transportAddress, String isSuspendDebuggee,
309: String isOnuncaught) {
310:
311: String cmdLine = settings.getDebuggeeJavaPath() + " -cp "
312: + settings.getDebuggeeClassPath() + " \""
313: + "-agentlib:" + settings.getDebuggeeAgentName()
314: + "=transport=dt_socket,address=" + transportAddress
315: + ",server=y" + ",suspend=" + isSuspendDebuggee
316: + ",onuncaught=" + isOnuncaught + ",onthrow="
317: + EXCEPTION_CLASS_FOR_DEBUGGER + ",launch=\'"
318: + debuggerCmd + "\'" + ","
319: + settings.getDebuggeeAgentExtraOptions() + "\"" + " "
320: + settings.getDebuggeeVMExtraOptions()
321: + " -Djpda.settings.syncPort=" + debuggeeSyncPort + " "
322: + getDebuggeeClassName();
323:
324: return cmdLine;
325: }
326:
327: public static void main(String[] args) {
328: junit.textui.TestRunner.run(OnthrowDebuggerLaunchTest.class);
329: }
330:
331: protected JDWPUnitDebuggeeProcessWrapper debuggeeWrapper;
332:
333: protected JPDADebuggeeSynchronizer debuggerSynchronizer;
334: private int debuggerSyncPortNumber;
335: private String debuggeeSyncPort;
336: }
|