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 * Created on 15.08.2005
24 */
25package org.apache.harmony.jpda.tests.jdwp.StackFrame;
26
27import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
28import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
29import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands.StackFrameCommandSet;
30import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
31import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
32import org.apache.harmony.jpda.tests.framework.jdwp.Value;
33
34import java.util.Arrays;
35
36/**
37 * JDWP Unit test for StackFrame.SetValues command.
38 */
39public class SetValuesTest extends JDWPStackTraceBaseTest {
40    /**
41     * This testcase exercises StackFrame.SetValues command.
42     * <BR>The test starts StackTraceDebuggee, sets breakpoint at the beginning of
43     * the tested method - 'nestledMethod3' and stops at the breakpoint.
44     * <BR> Then the test performs Method.VariableTable command and checks
45     * returned VariableTable.
46     * <BR> Next, the test performs StackFrame.SetValues command and checks
47     * result of this command with help of StackFrame.GetValues command -
48     * returned values of variables should be equal to values which were set.
49     *
50     */
51    public void testSetValues001() {
52        // Sets and checks local variables of tested method
53        examineGetValues();
54    }
55
56    /**
57     * This testcase exercises StackFrame.SetValues command.
58     * <BR>The test starts StackTraceDebuggee and waits for it to reach the
59     * tested method - 'nestledMethod3'.
60     * <BR> Then it performs StackFrame.SetValues command with an invalid
61     * thread ID and checks the command returns error INVALID_OBJECT.
62     */
63    public void testSetValues002_InvalidObjectError() {
64        long invalidThreadID = -1;
65        logWriter.println("Send StackFrame.SetValues with invalid thread " + invalidThreadID);
66        CommandPacket packet = new CommandPacket(StackFrameCommandSet.CommandSetID,
67                StackFrameCommandSet.SetValuesCommand);
68        packet.setNextValueAsThreadID(invalidThreadID);
69        packet.setNextValueAsFrameID(0);
70        packet.setNextValueAsInt(0);
71        ReplyPacket replyPacket = debuggeeWrapper.vmMirror.performCommand(packet);
72        checkReplyPacket(replyPacket, "StackFrame.SetValues",
73                JDWPConstants.Error.INVALID_OBJECT);
74    }
75
76    /**
77     * This testcase exercises StackFrame.SetValues command.
78     * <BR>The test starts StackTraceDebuggee and waits for it to reach the
79     * tested method - 'nestledMethod3'.
80     * <BR> Then it performs StackFrame.SetValues command to a non-suspended
81     * thread and checks the command returns error THREAD_NOT_SUSPENDED.
82     */
83    public void testSetValues003_ThreadNotSuspendedError() {
84        long threadID = getThreadID();
85
86        CommandPacket packet = new CommandPacket(StackFrameCommandSet.CommandSetID,
87                StackFrameCommandSet.SetValuesCommand);
88        packet.setNextValueAsThreadID(threadID);
89        packet.setNextValueAsFrameID(0);
90        packet.setNextValueAsInt(0);
91        ReplyPacket replyPacket = debuggeeWrapper.vmMirror.performCommand(packet);
92        checkReplyPacket(replyPacket, "StackFrame.SetValues",
93                JDWPConstants.Error.THREAD_NOT_SUSPENDED);
94    }
95
96    /**
97     * This testcase exercises StackFrame.SetValues command.
98     * <BR>The test starts StackTraceDebuggee and waits for it to reach the
99     * tested method - 'nestledMethod3'.
100     * <BR> Then it performs StackFrame.SetValues command to an invalid
101     * frame ID and checks the command returns error INVALID_FRAMEID.
102     */
103    public void testSetValues004_InvalidFrameIDError() {
104        long threadID = getThreadID();
105
106        // suspend thread
107        jdwpSuspendThread(threadID);
108
109        long invalidFrameID = -1;
110        logWriter.println("Send StackFrame.SetValues with invalid frameID " + invalidFrameID);
111        CommandPacket packet = new CommandPacket(StackFrameCommandSet.CommandSetID,
112                StackFrameCommandSet.SetValuesCommand);
113        packet.setNextValueAsThreadID(threadID);
114        packet.setNextValueAsFrameID(invalidFrameID);
115        packet.setNextValueAsInt(0);
116        ReplyPacket replyPacket = debuggeeWrapper.vmMirror.performCommand(packet);
117        checkReplyPacket(replyPacket, "StackFrame.SetValues",
118                JDWPConstants.Error.INVALID_FRAMEID);
119    }
120
121    /**
122     * This testcase exercises StackFrame.SetValues command.
123     * <BR>The test starts StackTraceDebuggee and waits for it to reach the
124     * tested method - 'nestledMethod3'.
125     * <BR> Then it performs StackFrame.SetValues command to an invalid
126     * slot ID and checks the command returns error INVALID_SLOT.
127     */
128    public void testSetValues005_InvalidSlotError() {
129        //sets and checks local variables of tested method
130
131        long threadID = getThreadID();
132
133        // suspend thread
134        jdwpSuspendThread(threadID);
135
136        FrameInfo frameInfo = findFrameInfo(threadID);
137
138        //getting Variable Table
139        logWriter.println("");
140        logWriter.println("=> Getting Variable Table...");
141        long refTypeID = getClassIDBySignature(getDebuggeeClassSignature());
142        logWriter.println("=> Debuggee class = " + getDebuggeeClassName());
143        logWriter.println("=> referenceTypeID for Debuggee class = "
144                + refTypeID);
145        varInfos = jdwpGetVariableTable(refTypeID, frameInfo.location.methodID);
146        if (GetValuesTest.checkVarTable(logWriter, varInfos, varTags, varSignatures, varNames)) {
147            logWriter.println("=> Variable table check passed.");
148        } else {
149            printErrorAndFail("Variable table check failed.");
150        }
151
152        int invalidSlotId = -1;
153        logWriter.println("Send StackFrame.SetValues with invalid slot " + invalidSlotId);
154        CommandPacket packet = new CommandPacket(StackFrameCommandSet.CommandSetID,
155                StackFrameCommandSet.SetValuesCommand);
156        packet.setNextValueAsThreadID(threadID);
157        packet.setNextValueAsFrameID(frameInfo.frameID);
158        packet.setNextValueAsInt(1);
159        packet.setNextValueAsInt(invalidSlotId);
160        packet.setNextValueAsByte(JDWPConstants.Tag.OBJECT_TAG);
161        packet.setNextValueAsObjectID(0 /* null */);
162        ReplyPacket replyPacket = debuggeeWrapper.vmMirror.performCommand(packet);
163        checkReplyPacket(replyPacket, "StackFrame.SetValues",
164                JDWPConstants.Error.INVALID_SLOT);
165    }
166
167    private void examineGetValues() {
168        long refTypeID = getClassIDBySignature(getDebuggeeClassSignature());
169        logWriter.println("=> Debuggee class = " + getDebuggeeClassName());
170        logWriter.println("=> referenceTypeID for Debuggee class = "
171                + refTypeID);
172        long threadID = debuggeeWrapper.vmMirror.getThreadID(testedThreadName);
173
174        logWriter.println("=> testedThreadID = " + threadID);
175        if (threadID == -1) {
176            printErrorAndFail("testedThread is not found!");
177        }
178
179        // suspend thread
180        jdwpSuspendThread(threadID);
181
182        // find frame for the tested method
183        FrameInfo frameInfo = findFrameInfo(threadID);
184
185        //getting Variable Table
186        logWriter.println("");
187        logWriter.println("=> Getting Variable Table...");
188        varInfos = jdwpGetVariableTable(refTypeID, frameInfo.location.methodID);
189        if (checkVarTable(logWriter, varInfos, varTags, varSignatures, varNames)) {
190            logWriter.println("=> Variable table check passed.");
191        } else {
192            printErrorAndFail("Variable table check failed.");
193        }
194
195        //prepare and perform SetValues command
196        logWriter.println("");
197        logWriter.println("==> Send StackFrame::SetValues command...");
198        CommandPacket packet = new CommandPacket(
199                JDWPCommands.StackFrameCommandSet.CommandSetID,
200                JDWPCommands.StackFrameCommandSet.SetValuesCommand);
201        packet.setNextValueAsThreadID(threadID);
202        packet.setNextValueAsFrameID(frameInfo.frameID);
203
204        packet.setNextValueAsInt(varTags.length-2);
205        packet.setNextValueAsInt(varInfoByName("boolLocalVariable").getSlot());
206        packet.setNextValueAsValue(new Value(false));
207        packet.setNextValueAsInt(varInfoByName("intLocalVariable").getSlot());
208        packet.setNextValueAsValue(new Value((int)12345));
209
210        ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
211        checkReplyPacket(reply, "StackFrame::SetValues command");
212
213        //prepare and perform GetValues command
214        logWriter.println("");
215        logWriter.println("=> Send StackFrame::GetValues command...");
216        packet = new CommandPacket(
217                JDWPCommands.StackFrameCommandSet.CommandSetID,
218                JDWPCommands.StackFrameCommandSet.GetValuesCommand);
219        packet.setNextValueAsThreadID(threadID);
220        packet.setNextValueAsFrameID(frameInfo.frameID);
221
222        logWriter.println("=> Thread: " + threadID);
223        logWriter.println("=> Frame: " + frameInfo.frameID);
224        packet.setNextValueAsInt(varTags.length);
225        for (int i = 0; i < varTags.length; i++) {
226            logWriter.println("");
227            logWriter.println("=> For variable #"+i+" " + varInfos[i].getName() + ":");
228            packet.setNextValueAsInt(varInfos[i].getSlot());
229            logWriter.println("=> Slot = "+varInfos[i].getSlot());
230            byte tag = varTags[Arrays.asList(varNames).indexOf(varInfos[i].getName())];
231            packet.setNextValueAsByte(tag);
232            logWriter.println("=> Tag = "+JDWPConstants.Tag.getName(tag));
233            logWriter.println("");
234        }
235
236        //check reply for errors
237        reply = debuggeeWrapper.vmMirror.performCommand(packet);
238        checkReplyPacket(reply, "StackFrame::GetValues command");
239
240        //check number of retrieved values
241        int numberOfValues = reply.getNextValueAsInt();
242        logWriter.println("=> Number of values = " + numberOfValues);
243        if (numberOfValues != varTags.length) {
244            logWriter.println("##FAILURE: unexpected number of values: "
245                    + numberOfValues + " instead of "+varTags.length);
246            assertTrue(false);
247        }
248
249        boolean success = true;
250        //print and check values of variables
251        logWriter.println("=> Values of variables: ");
252
253        for (int i = 0; i < numberOfValues; ++i ) {
254            Value val = reply.getNextValueAsValue();
255            switch (val.getTag()) {
256                case JDWPConstants.Tag.BOOLEAN_TAG: {
257                    logWriter.println("=>Tag is correct");
258                    boolean boolValue = val.getBooleanValue();
259                    if (!boolValue) {
260                        logWriter.println("=> "+varInfos[1].getName() + " = " + boolValue);
261                        logWriter.println("");
262                    } else {
263                        logWriter
264                        .printError("Unexpected value of boolean variable: "
265                                + boolValue + " instead of: false");
266                        logWriter.printError("");
267                        success = false;
268                    }
269                    break;
270                }
271
272                case JDWPConstants.Tag.INT_TAG: {
273                    logWriter.println("=>Tag is correct");
274                    int intValue = val.getIntValue();
275                    if (intValue == 12345) {
276                        logWriter.println("=> "+varInfos[2].getName() + " = " + intValue);
277                        logWriter.println("");
278                    } else {
279                        logWriter
280                        .printError("Unexpected value of int variable: "
281                                + intValue + " instead of: 12345");
282                        logWriter.printError("");
283                        success = false;
284                    }
285                    break;
286                }
287
288                case JDWPConstants.Tag.STRING_TAG: {
289                    logWriter.println("=>Tag is correct");
290                    long strLocalVariableID = val.getLongValue();
291                    String strLocalVariable = getStringValue(strLocalVariableID);
292                    if (strLocalVariable.equals("test string")) {
293                        logWriter.println("=> "+varInfos[2].getName() + " = "
294                                + strLocalVariable);
295                        logWriter.println("");
296                    } else {
297                        logWriter
298                        .printError("Unexpected value of string variable: "
299                                + strLocalVariable
300                                + " instead of: "
301                                + "test string");
302                        logWriter.printError("");
303                        success = false;
304                    }
305                    break;
306                }
307
308                case JDWPConstants.Tag.OBJECT_TAG: {
309                    logWriter.println("=> Tag is correct");
310                    logWriter.println("");
311                    break;
312                }
313                default:
314                    logWriter.printError("Unexpected tag of variable: "
315                            + JDWPConstants.Tag.getName(val.getTag()));
316                    logWriter.printError("");
317                    success = false;
318                    break;
319            }  // switch
320        }  // for
321
322        assertTrue(logWriter.getErrorMessage(), success);
323    }
324
325    private VarInfo varInfoByName(String name) {
326      for (int i = 0; i < varInfos.length; ++i) {
327        if (varInfos[i].getName().equals(name)) {
328          return varInfos[i];
329        }
330      }
331      return null;
332    }
333}
334