summaryrefslogtreecommitdiff
path: root/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthrowDebuggerLaunchTest.java
blob: 0cd82976be097eda8a28b2775ee1b7c56887e414 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * @author Aleksander V. Budniy
 */

/**
 * Created on 5.06.2006
 */
package org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand;

import org.apache.harmony.jpda.tests.framework.TestErrorException;
import org.apache.harmony.jpda.tests.framework.TestOptions;
import org.apache.harmony.jpda.tests.jdwp.share.JDWPRawTestCase;
import org.apache.harmony.jpda.tests.jdwp.share.JDWPUnitDebuggeeProcessWrapper;
import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
import org.apache.harmony.jpda.tests.share.JPDATestOptions;

/**
 * This test case exercises possibility of debuggee to invoke debugger
 * on demand with "onthrow" option.
 *
 * @see org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchDebuggee
 * @see org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001
 * @see org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002
 */
public class OnthrowDebuggerLaunchTest extends JDWPRawTestCase {

    public static final String EXCEPTION_CLASS_FOR_DEBUGGER =
        "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.ExceptionForDebugger";

    public static final String DEBUGGEE_CLASS =
        "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchDebuggee";

    /**
     * Test launches debuggee (without establishing synchronization connection)
     * with options suspend=y,onuncaught=n, debuggee executes
     * <code>OnthrowLaunchedDebugger001</code>, test establishes synch
     * connection with debugger and in cycle receives messages from debugger.
     */
    public void testDebuggerLaunch001() {
        logWriter.println("==> testDebuggerLaunch started");

        String DEBUGGER_NAME = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001";
        String isSuspend = "y";
        String isOnuncaught = "n";

        performTest(DEBUGGER_NAME, isSuspend, isOnuncaught);

        logWriter.println("==> testDebuggerLaunch ended");
    }

    /**
     * Test launches debuggee (without establishing synchronization connection)
     * with option suspend=y,onuncaught=n, debuggee executes
     * <code>OnthrowLaunchedDebugger002</code>, test establishes synch
     * connection with debugger and in cycle receives messages from debugger.
     *
     */

    public void testDebuggerLaunch002() {
        logWriter.println("==> testDebuggerLaunch002 started");

        String DEBUGGER_NAME = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002";
        String isSuspend = "y";
        String isOnuncaught = "n";

        performTest(DEBUGGER_NAME, isSuspend, isOnuncaught);

        logWriter.println("==> testDebuggerLaunch002 ended");
    }


    /**
     * Test launches debuggee (without establishing synchronization connection)
     * with option suspend=n,onuncaught=n debuggee executes
     * <code>OnthrowLaunchedDebugger001</code>, test establishes synch
     * connection with debugger and in cycle receives messages from debugger.
     *
     */
    public void testDebuggerLaunch003() {
        logWriter.println("==> testDebuggerLaunch started");

        String DEBUGGER_NAME = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001";
        String isSuspend = "n";
        String isOnuncaught = "n";

        performTest(DEBUGGER_NAME, isSuspend, isOnuncaught);

        logWriter.println("==> testDebuggerLaunch ended");
    }

    /**
     * Test executes debuggee (without establishing synchronization connection)
     * with option suspend=n,onuncaught=n debuggee executes
     * <code>OnthrowLaunchedDebugger002</code>, test establishes synch
     * connection with debugger and in cycle receives messages from debugger.
     *
     */
    public void testDebuggerLaunch004() {
        logWriter.println("==> testDebuggerLaunch started");

        String DEBUGGER_NAME = "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002";
        String isSuspend = "n";
        String isOnuncaught = "n";

        performTest(DEBUGGER_NAME, isSuspend, isOnuncaught);

        logWriter.println("==> testDebuggerLaunch ended");
    }

    /**
     * Method prepares cmd for launching debuggee and debugger. Passes
     * debugger's cmd as parameter "launch" to debuggee's cmd. Then launches
     * debuggee and wait for synch connection from debugger, that should be
     * launched by debuggee. After that, method starts receiving messages in
     * loop from debugger. Messages of three types: OK, FAIL, END. In case of
     * FAIL or END messages, loop is ended.
     *
     * @param DEBUGGER_NAME
     *            name of debugger that debuggee will launch
     * @param isSuspendDebuggee
     *            option defines should debuggee be suspended on start
     * @param isOnuncaught
     *            parameter that is passed to debuggee (see JDWP agent launch
     *            options)
     */
    void performTest(String debuggerName, String isSuspendDebuggee, String isOnuncaught) {

        try {
	        // prepare command line for debugger and debuggee processes

	        String address = settings.getTransportAddress();
	        String debuggerCmd = prepareDebuggerCmd(debuggerName, address,
                    isSuspendDebuggee, isOnuncaught);
	        logWriter.println("=> Debugger command: " + debuggerCmd);

	        String debuggeeCmd = prepareDebuggeeCmd(debuggerCmd, address,
	                                      isSuspendDebuggee, isOnuncaught);
	        logWriter.println("=> Debuggee command: " + debuggeeCmd);

	        // launch debuggee process, which will launch debugger process

	        debuggeeWrapper.launchProcessAndRedirectors(debuggeeCmd);

	        // listen for synch connection from launched debugger

	        logWriter.println("=> Listen for synch connection from launched debugger");
	        debuggerSynchronizer.startServer();
	        logWriter.println("=> Synch connection with launched debugger established");
        } catch (Exception e) {
            throw new TestErrorException(e);
        }

        // exchange synch messages with debugger

        for (;;) {
            String message = debuggerSynchronizer.receiveMessage();
            if (message != null) {
                logWriter.println("=> Message received from DEBUGGER: " + message);
                if (message.equals("FAILURE")) {
                    logWriter.println("##FAILURE: error message received from debugger");
                    fail("Some error received from debugger");
                } else if (message.equals("END")) {
                    logWriter.println("=> Debugger ends work");
                    break;
                } else if (!message.equals("OK")) {
                    logWriter.println("##FAILURE: unexpected message received from debugger");
                    fail("Unexpected message received from debugger");
                }
            } else {
                logWriter.println("##FAILURE: null message received from debugger");
                fail("Null message received from debugger");
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////

    protected String getDebuggeeClassName() {
        return DEBUGGEE_CLASS;
    }

    /**
     * Creates wrapper for debuggee process.
     */
    protected JDWPUnitDebuggeeProcessWrapper createDebuggeeWrapper() {
        return new JDWPUnitDebuggeeProcessWrapper(settings, logWriter);
    }

    /**
     * Creates wrapper for synch connection with debugger.
     */
    protected JPDADebuggeeSynchronizer createDebuggerSyncronizer(){
        return new JPDADebuggeeSynchronizer(logWriter, settings);
    }

    /**
     * Creates wrapper object for accessing test options;
     */
    protected JPDATestOptions createTestOptions() {
        return new LaunchedDebugger.JPDADebuggerOnDemandOptions();
    }

    protected void internalSetUp() throws Exception {
        super.internalSetUp();

        // set fixed address for attaching connection

        String address = settings.getTransportAddress();
        if (address == null) {
        	settings.setTransportAddress(TestOptions.DEFAULT_ATTACHING_ADDRESS);
        }

        // set fixed port for debuggee sync connection

    	debuggeeSyncPort = settings.getSyncPortString();
    	if (debuggeeSyncPort == null) {
    		debuggeeSyncPort = TestOptions.DEFAULT_STATIC_SYNC_PORT;
    	}

        // prepare for synch connection with debugger

        logWriter.println("=> Prepare synch connection with debugger");
        debuggerSynchronizer = createDebuggerSyncronizer();
        debuggerSyncPortNumber = debuggerSynchronizer.bindServer();

        // create wrapper for debuggee process

        debuggeeWrapper = createDebuggeeWrapper();
    }

    /**
     * Overrides inherited method to stop started debuggee VM and close all
     * connections.
     */
    protected void internalTearDown() {
        if (debuggerSynchronizer != null) {
            logWriter.println("Close synch connection with debugger");
            debuggerSynchronizer.stop();
        }

        if (debuggeeWrapper != null) {
            debuggeeWrapper.finishProcessAndRedirectors();
            logWriter.println("Finished debuggee VM process and closed connection");
        }
        super.internalTearDown();
    }

    /**
     * Prepares command line for launching debuggee.
     *
     * @param debuggerCmd cmd to launch debugger. Value of parameter "launch"
     * @param agentAddress address for connection with debugger
     * @param isSuspendDebuggee should debuggee be suspended on start
     * @param isOnuncaught should debuggee waits for uncaught exception (see JDWP agent launch options)
     * @return command line for launching debuggee
     */
    private String prepareDebuggerCmd(String debuggerName, String transportAddress,
            String isSuspendDebuggee, String isOnuncaught) {

        String cmdLine = settings.getDebuggeeJavaPath()
            + " -cp " + settings.getDebuggeeClassPath()
            + " -Djpda.settings.connectorKind=attach"
	        + " -Djpda.settings.debuggeeSuspend=" + isSuspendDebuggee
	        + " -Djpda.settings.transportAddress=" + transportAddress
	        + " -Djpda.settings.syncDebuggerPort=" + debuggerSyncPortNumber
	        + " -Djpda.settings.syncPort=" + debuggeeSyncPort
	        + " " + debuggerName;

        return cmdLine;
    }

    /**
     * Prepares command line for launching debuggee.
     *
     * @param debuggerCmd cmd to launch debugger. Value of parameter "launch"
     * @param agentAddress address for connection with debugger
     * @param isSuspendDebuggee should debuggee be suspended on start
     * @param isOnuncaught should debuggee waits for uncaught exception (see JDWP agent launch options)
     * @return command line for launching debuggee
     */
    private String prepareDebuggeeCmd(String debuggerCmd, String transportAddress,
            String isSuspendDebuggee, String isOnuncaught) {

    	String cmdLine = settings.getDebuggeeJavaPath()
    	        + " -cp "
                + settings.getDebuggeeClassPath()
    	        + " \""
                + "-agentlib:" + settings.getDebuggeeAgentName()
                + "=transport=dt_socket,address=" + transportAddress
                + ",server=y"
                + ",suspend=" + isSuspendDebuggee
                + ",onuncaught=" + isOnuncaught
                + ",onthrow=" + EXCEPTION_CLASS_FOR_DEBUGGER
                + ",launch=\'" + debuggerCmd + "\'"
                + "," + settings.getDebuggeeAgentExtraOptions()
    	        + "\""
                + " " + settings.getDebuggeeVMExtraOptions()
                + " -Djpda.settings.syncPort=" + debuggeeSyncPort
                + " " + getDebuggeeClassName();

        return cmdLine;
    }

    protected JDWPUnitDebuggeeProcessWrapper debuggeeWrapper;

    protected JPDADebuggeeSynchronizer debuggerSynchronizer;
    private int debuggerSyncPortNumber;
    private String debuggeeSyncPort;
}