1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License.
17 */
18
19/**
20 * @author Aleksander V. Budniy
21 */
22
23/**
24 * Created on 8.7.2005
25 */
26package org.apache.harmony.jpda.tests.jdwp.MultiSession;
27
28import org.apache.harmony.jpda.tests.framework.TestOptions;
29import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
30import org.apache.harmony.jpda.tests.framework.jdwp.EventMod;
31import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
32import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
33import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent;
34import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
35import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
36import org.apache.harmony.jpda.tests.jdwp.share.JDWPUnitDebuggeeWrapper;
37import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
38
39
40/**
41 * JDWP Unit test for verifying canceling of SINGLE_STEP event after re-connection.
42 */
43public class SingleStepTest extends JDWPSyncTestCase {
44
45    private String debuggeeSignature = "Lorg/apache/harmony/jpda/tests/jdwp/MultiSession/SingleStepDebuggee;";
46
47    private String DEBUGGEE_CLASS_NAME = "org.apache.harmony.jpda.tests.jdwp.MultiSession.SingleStepDebuggee";
48
49    protected String getDebuggeeClassName() {
50        return DEBUGGEE_CLASS_NAME;
51    }
52
53    /**
54     * This testcase verifies canceling of SINGLE_STEP event after re-connection.
55     * <BR>It runs SingleStepDebuggee and sets request for BREAKPOINT event.
56     * After BREAKPOINT event occurs the testcase sets request for SINGLE_STEP event
57     * and re-connects.
58     * <BR>It is expected that only auto VM_DEATH event occurs after re-connection,
59     * but no any other event, including SINGLE_STEP event.
60     */
61    public void testSingleStep001() {
62        stepFunction(JDWPConstants.StepSize.LINE, JDWPConstants.StepDepth.OVER);
63    }
64
65    void stepFunction(byte StepSize, byte StepDepth) {
66        logWriter.println("=> testSingleStep started");
67
68        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
69
70        //find checked method
71        long refTypeID = debuggeeWrapper.vmMirror.getClassID(debuggeeSignature);
72
73        logWriter.println("=> Debuggee class = " + getDebuggeeClassName());
74        logWriter.println("=> referenceTypeID for Debuggee class = "
75                + refTypeID);
76        logWriter
77                .println("=> Send ReferenceType::Methods command and get methodIDs ");
78
79        long requestID = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin(
80                refTypeID, "breakpointTest");
81        logWriter.println("=> breakpointID = " + requestID);
82        logWriter.println("=> starting thread");
83
84        //execute the breakpoint
85        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
86
87        long breakpointThreadID = debuggeeWrapper.vmMirror
88                .waitForBreakpoint(requestID);
89
90        logWriter.println("=> breakpointThreadID = " + breakpointThreadID);
91
92        // Sending a SINGLE_STEP request
93
94        CommandPacket setRequestCommand = new CommandPacket(
95                JDWPCommands.EventRequestCommandSet.CommandSetID,
96                JDWPCommands.EventRequestCommandSet.SetCommand);
97
98        setRequestCommand
99                .setNextValueAsByte(JDWPConstants.EventKind.SINGLE_STEP);
100        setRequestCommand.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
101        setRequestCommand.setNextValueAsInt(1);
102        setRequestCommand.setNextValueAsByte(EventMod.ModKind.Step);
103        setRequestCommand.setNextValueAsThreadID(breakpointThreadID);
104        setRequestCommand.setNextValueAsInt(StepSize);
105        setRequestCommand.setNextValueAsInt(StepDepth);
106
107        ReplyPacket setRequestReply = debuggeeWrapper.vmMirror
108                .performCommand(setRequestCommand);
109
110        checkReplyPacket(setRequestReply, "Set SINGLE_STEP event");
111
112        requestID = setRequestReply.getNextValueAsInt();
113        logWriter.println("=> RequestID = " + requestID);
114
115        assertAllDataRead(setRequestReply);
116
117        logWriter.println("");
118        logWriter.println("=> CLOSE CONNECTION..");
119        closeConnection();
120        logWriter.println("=> CONNECTION IS CLOSED");
121
122        logWriter.println("");
123        logWriter.println("=> OPEN NEW CONNECTION..");
124        openConnection();
125        logWriter.println("=> CONNECTION IS OPENED");
126
127        //resume debuggee
128        //ReplyPacket reply = debuggeeWrapper.vmMirror.resume();
129        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
130
131        //      receive event
132        logWriter.println("=> Wait for event..");
133        CommandPacket eventPacket = debuggeeWrapper.vmMirror.receiveEvent();
134        ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(eventPacket);
135        int eventsCount = parsedEvents.length;
136        logWriter.println("=> Received event set: count=" + eventsCount);
137
138        //ckeck if received events are expected
139        int result = 0;
140        int autoEvents = 0;
141        int wrongEvents = 0;
142        for (int i = 0; i < eventsCount; i++) {
143            ParsedEvent event = parsedEvents[i];
144            logWriter.println("=> Event #" + i + ";");
145
146            // print event info
147            byte eventSuspendPolicy = event.getSuspendPolicy();
148            logWriter.println("=> SuspendPolicy=" + eventSuspendPolicy + "/"
149                    + JDWPConstants.SuspendPolicy.getName(eventSuspendPolicy));
150            byte eventKind = event.getEventKind();
151            logWriter.println("=> EventKind=" + eventKind + "/"
152                    + JDWPConstants.EventKind.getName(eventKind));
153            int eventRequestID = event.getRequestID();
154            logWriter.println("=> RequestID=" + eventRequestID);
155
156            // check if event is expected
157            if (eventKind == JDWPConstants.EventKind.VM_DEATH) {
158                if (parsedEvents[i].getRequestID() == 0) {
159                    autoEvents++;
160                    logWriter.println("=> found auto VM_DEATH event!");
161                    // for automatical event suspend policy can be changed
162                } else {
163                    logWriter.println("## FAILURE: VM_DEATH event "
164                            + "with unexpected RequestID: " + eventRequestID);
165                    result = 1;
166                }
167            } else {
168                wrongEvents++;
169                logWriter.println("## FAILURE: unexpected event kind: "
170                        + eventKind);
171                result = 2;
172            }
173        }
174
175        if (1 == result)
176            fail("VM_DEATH event with unexpected RequestID");
177        else if (2 == result)
178            fail("Unexpected event kind");
179
180        logWriter.println("==> testSingleStep001 PASSED!");
181    }
182
183    protected void beforeDebuggeeStart(JDWPUnitDebuggeeWrapper debuggeeWrapper) {
184        settings.setAttachConnectorKind();
185        if (settings.getTransportAddress() == null) {
186            settings.setTransportAddress(TestOptions.DEFAULT_ATTACHING_ADDRESS);
187        }
188        logWriter.println("ATTACH connector kind");
189        super.beforeDebuggeeStart(debuggeeWrapper);
190    }
191}
192