blob: b67e42291dff718ac1ef41ee727b99c3c1c891fe [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2001 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/**
25 * @test
26 * @bug 4467564
27 * @summary Test the popping of frames in synchronous context
28 * (that is, when stopped at an event)
29 *
30 * @author Robert Field
31 *
32 * @run build TestScaffold VMConnection TargetListener TargetAdapter
33 * @run compile -g PopSynchronousTest.java
34 * @run main PopSynchronousTest
35 */
36import com.sun.jdi.*;
37import com.sun.jdi.event.*;
38import com.sun.jdi.request.*;
39
40import java.util.*;
41
42 /********** target program **********/
43
44class PopSynchronousTarg {
45 static String s;
46 static PopSynchronousTarg sole;
47
48 synchronized void a(int y, boolean w) {
49 if (y == 6 && w) {
50 s += "@";
51 } else {
52 s += " aArgFail ";
53 }
54 }
55 String b(String h) {
56 if (h.equals("yo")) {
57 s += "[";
58 } else {
59 s += " bArgFail ";
60 }
61 a(6, true);
62 s += "]";
63 return s;
64 }
65 long c() {
66 s += "<";
67 synchronized (s) {
68 b("yo");
69 }
70 s += ">";
71 return 17;
72 }
73 static void p() {
74 s += "(";
75 if (sole.c() != 17) {
76 s += " cReturnFail ";
77 }
78 s += ")";
79 }
80 static void report() {
81 }
82 public static void main(String[] args){
83 s = new String();
84 sole = new PopSynchronousTarg();
85 for (int i = 0; i < 100; ++i) {
86 p();
87 // System.out.println(s);
88 report();
89 }
90 }
91}
92
93 /********** test program **********/
94
95public class PopSynchronousTest extends TestScaffold {
96 ReferenceType targetClass;
97 ThreadReference mainThread;
98 int stateIndex = 0;
99 String expected = "";
100 static final String[] calls = {"a", "b", "c", "p", "main"};
101 static final int popMax = calls.length - 1;
102 static final String[] states =
103 {"main-i", "p-e", "p-i", "c-e", "c-i", "b-e", "b-i", "a-e", "a-l", "b-l", "c-l", "p-l", "main-r", "report-e"};
104 static final String[] output =
105 {"", "", "(", "", "<", "", "[", "", "@", "]", ">", ")", "", ""};
106
107
108 PopSynchronousTest (String args[]) {
109 super(args);
110 }
111
112 public static void main(String[] args) throws Exception {
113 new PopSynchronousTest(args).startTests();
114 }
115
116
117 /********** test assist **********/
118
119 StackFrame frameFor(String methodName) throws Exception {
120 Iterator it = mainThread.frames().iterator();
121
122 while (it.hasNext()) {
123 StackFrame frame = (StackFrame)it.next();
124 if (frame.location().method().name().equals(methodName)) {
125 return frame;
126 }
127 }
128 failure("FAIL: " + methodName + " not on stack");
129 return null;
130 }
131
132 String actual() throws Exception {
133 Field field = targetClass.fieldByName("s");
134 StringReference sr = (StringReference)(targetClass.getValue(field));
135 return sr.value();
136 }
137
138 void checkExpected() throws Exception {
139 if (!actual().equals(expected)) {
140 failure("FAIL: expected value: " + expected +
141 " got: " + actual());
142 }
143 }
144
145 int methodIndex(String methodName) {
146 for (int i = 0; i < popMax; ++i) {
147 if (methodName.equals(calls[i])) {
148 return i;
149 }
150 }
151 return -1;
152 }
153
154 boolean isTop(String methodName) throws Exception {
155 return mainThread.frame(0).location().method().name().equals(methodName);
156 }
157
158 void checkTop(String methodName, boolean atStart) throws Exception {
159 Location loc = mainThread.frame(0).location();
160 Method meth = loc.method();
161 String name = meth.name();
162 if (!isTop(methodName)) {
163 failure("FAIL: expected " + methodName +
164 " at top of stack, instead: " + name);
165 } else if ((meth.location().codeIndex() == loc.codeIndex()) != atStart) {
166 failure("FAIL: not at expect position: " + loc.codeIndex());
167 }
168 }
169
170 void checkState() throws Exception {
171 String name = states[stateIndex];
172 int dash = name.indexOf('-');
173 String methodName = name.substring(0,dash);
174 String posName = name.substring(dash+1);
175 checkTop(methodName, posName.equals("e"));
176 checkExpected();
177 }
178
179 void incrementState() {
180 stateIndex = (stateIndex + 1) % (states.length);
181 }
182
183 void resetState(String stateName) {
184 for (int i=0; i < states.length; ++i) {
185 if (states[i].equals(stateName)) {
186 stateIndex = i;
187 return;
188 }
189 }
190 failure("TEST FAILURE: cannot find state: " + stateName);
191 }
192
193 void resetExpected() throws Exception {
194 println("Current value: " + actual());
195 Field field = targetClass.fieldByName("s");
196 expected = "";
197 ((ClassType)targetClass).setValue(field, vm().mirrorOf(expected));
198 }
199
200 void stateTo(String stateName) {
201 do {
202 incrementState();
203 expected += output[stateIndex];
204 } while(!states[stateIndex].equals(stateName));
205 }
206
207 void resumeTo(String methodName) throws Exception {
208 List meths = targetClass.methodsByName(methodName);
209 Method meth = (Method)(meths.get(0));
210 resumeTo(meth.location());
211 stateTo(methodName + "-e");
212 checkState();
213 }
214
215 void pop(String methodName) throws Exception {
216 mainThread.popFrames(frameFor(methodName));
217 resetState(methodName + "-e");
218 --stateIndex;
219 checkState();
220 }
221
222 void reenter(String methodName) throws Exception {
223 pop(methodName);
224 stepIntoInstruction(mainThread);
225 incrementState();
226 checkState();
227 }
228
229 /********** test core **********/
230
231 protected void runTests() throws Exception {
232 /*
233 * Get to the top of main()
234 * to determine targetClass and mainThread
235 */
236 BreakpointEvent bpe = startToMain("PopSynchronousTarg");
237 targetClass = bpe.location().declaringType();
238 mainThread = bpe.thread();
239
240 /*
241 * Testing
242 */
243
244 /* individual tests */
245 for (int i = 0; i < popMax; ++i) {
246 String from = calls[i];
247 for (int j = i; j < popMax; ++j) {
248 String to = calls[j];
249 String prev = calls[j+1];
250 println("TEST pop from '" + from + "' to '" + to + "'");
251 resumeTo(from);
252 reenter(to);
253 resumeTo("report");
254 resetExpected();
255 }
256 }
257
258 /* sequential tests */
259
260 println("TEST pop a b c p");
261 resumeTo("a");
262 pop("a");
263 pop("b");
264 pop("c");
265 pop("p");
266 resumeTo("report");
267 resetExpected();
268
269 println("TEST pop a c p");
270 resumeTo("a");
271 pop("a");
272 pop("c");
273 pop("p");
274 resumeTo("report");
275 resetExpected();
276
277 println("TEST stress a");
278 resumeTo("a");
279 for (int i = 0; i < 100; ++i) {
280 reenter("a");
281 }
282 resumeTo("report");
283 resetExpected();
284
285 println("TEST stress c");
286 resumeTo("c");
287 for (int i = 0; i < 100; ++i) {
288 reenter("c");
289 }
290 resumeTo("report");
291 resetExpected();
292
293 /*
294 * we are done, get rid of target
295 */
296 vm().dispose();
297
298 /*
299 * deal with results of test
300 * if anything has called failure("foo") testFailed will be true
301 */
302 if (!testFailed) {
303 println("PopSynchronousTest: passed");
304 } else {
305 throw new Exception("PopSynchronousTest: failed");
306 }
307 }
308}