001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.drjava.model.debug.jpda;
038:
039: import java.io.*;
040: import java.util.Vector;
041:
042: import edu.rice.cs.drjava.DrJava;
043: import edu.rice.cs.drjava.config.*;
044: import edu.rice.cs.drjava.model.*;
045: import edu.rice.cs.drjava.model.debug.*;
046: import edu.rice.cs.util.swing.Utilities;
047:
048: /** More tests over the JPDA debugger.
049: * @version $Id: DebugContextTest.java 4255 2007-08-28 19:17:37Z mgricken $
050: */
051: public final class DebugContextTest extends JPDADebugTestCase {
052:
053: // inherits _log from GlobalModelTestCase
054: // public static Log _log = new Log("Debug.txt", true);
055:
056: /** Tests that the sourcepath config option properly adds files to the search directories. */
057: public void testDebugSourcepath() throws Exception {
058: _log.log("----testDebugSourcePath----");
059: final StepTestListener debugListener = new StepTestListener();
060: _debugger.addListener(debugListener);
061:
062: // Start up
063: final OpenDefinitionsDocument doc = _startupDebugger(
064: "DrJavaDebugClass.java", DEBUG_CLASS);
065: final Vector<File> path = new Vector<File>();
066: path.addElement(_tempDir); // directory where doc's file is saved
067:
068: // Add a breakpoint
069: _debugger.toggleBreakpoint(doc, DEBUG_CLASS.indexOf("bar();"),
070: 4, true);
071:
072: // Run the foo() method, hitting breakpoint
073: synchronized (_notifierLock) {
074: _setPendingNotifies(3); // suspended, updated, breakpointReached
075: interpretIgnoreResult("new DrJavaDebugClass().foo()");
076: while (_pendingNotifies > 0)
077: _notifierLock.wait();
078: }
079: // Source is highlighted because document is stored in breakpoint
080: debugListener.assertThreadLocationUpdatedCount(1); // fires
081:
082: // Step into bar() method
083: synchronized (_notifierLock) {
084: _setPendingNotifies(2); // suspended, updated
085: _asyncStep(Debugger.StepType.STEP_INTO);
086: while (_pendingNotifies > 0)
087: _notifierLock.wait();
088: }
089: // Source is highlighted because file is in source root set
090: debugListener.assertStepRequestedCount(1); // fires (don't wait)
091: debugListener.assertThreadLocationUpdatedCount(2); // fires
092:
093: // Close file so it won't be in source root set
094: _model.closeFile(doc);
095: Utilities.clearEventQueue();
096: debugListener.assertRegionRemovedCount(1);
097:
098: // Step to next line
099: synchronized (_notifierLock) {
100: _setPendingNotifies(1); // suspended
101: _asyncStep(Debugger.StepType.STEP_OVER);
102: while (_pendingNotifies > 0)
103: _notifierLock.wait();
104: }
105: // Source is not highlighted
106: debugListener.assertStepRequestedCount(2); // fires (don't wait)
107: debugListener.assertThreadLocationUpdatedCount(2); // doesn't fire
108:
109: synchronized (_debugger) {
110: // Add _tempDir to our sourcepath
111: Utilities.invokeAndWait(new Runnable() {
112: public void run() {
113: DrJava.getConfig().setSetting(
114: OptionConstants.DEBUG_SOURCEPATH, path);
115: }
116: });
117: }
118:
119: // Step to next line
120: synchronized (_notifierLock) {
121: _asyncStep(Debugger.StepType.STEP_OVER);
122: _setPendingNotifies(2); // suspended, updated
123: while (_pendingNotifies > 0)
124: _notifierLock.wait();
125: }
126: // Source is highlighted because file is now on sourcepath
127: debugListener.assertStepRequestedCount(3); // fires (don't wait)
128: debugListener.assertThreadLocationUpdatedCount(3); // fires
129:
130: _log.log("Shutting down testDebugSourcePath");
131:
132: // Shut down
133: _shutdownAndWaitForInteractionEnded();
134: _debugger.removeListener(debugListener);
135: }
136:
137: /** Tests that breakpoints behave correctly in non-public classes. */
138: public synchronized void testBreakpointsAndStepsInNonPublicClasses()
139: throws Exception {
140: _log.log("----testBreakpointsAndStepsInNonPublicClasses----");
141: final StepTestListener debugListener = new StepTestListener();
142: _debugger.addListener(debugListener);
143:
144: // Start up
145: OpenDefinitionsDocument doc = _startupDebugger(
146: "DrJavaDebugClass.java", DEBUG_CLASS);
147:
148: // Add a breakpoint
149: _debugger.toggleBreakpoint(doc, DEBUG_CLASS
150: .indexOf("Baz Line 1"), 14, true);
151:
152: Utilities.clearEventQueue();
153: debugListener.assertRegionAddedCount(1);
154:
155: // Run the baz() method, hitting breakpoint
156: synchronized (_notifierLock) {
157: _setPendingNotifies(3); // suspended, updated, breakpointReached
158: interpretIgnoreResult("new DrJavaDebugClass2().baz()");
159: while (_pendingNotifies > 0)
160: _notifierLock.wait();
161: }
162:
163: // _log.log("----After breakpoint:\n" + getInteractionsText());
164:
165: // Ensure breakpoint is hit
166: debugListener.assertBreakpointReachedCount(1); //fires
167: debugListener.assertThreadLocationUpdatedCount(1); //fires
168: debugListener.assertCurrThreadSuspendedCount(1); //fires
169: debugListener.assertCurrThreadResumedCount(0);
170: debugListener.assertCurrThreadDiedCount(0);
171: assertInteractionsDoesNotContain("Baz Line 1");
172:
173: // _log.log("adding another breakpoint");
174:
175: // Set another breakpoint (after is class loaded)
176: _debugger
177: .toggleBreakpoint(doc, DEBUG_CLASS
178: .indexOf("System.out.println(\"Bar Line 2\")"),
179: 9, true);
180:
181: Utilities.clearEventQueue();
182: debugListener.assertRegionAddedCount(2);
183:
184: // Step to next line
185: synchronized (_notifierLock) {
186: _setPendingNotifies(2); // suspended, updated
187: _asyncStep(Debugger.StepType.STEP_OVER);
188: while (_pendingNotifies > 0)
189: _notifierLock.wait();
190: }
191:
192: // _log.log("****"+getInteractionsText());
193: debugListener.assertStepRequestedCount(1); // fires (don't wait)
194: debugListener.assertCurrThreadResumedCount(1); // fires (don't wait)
195: debugListener.assertThreadLocationUpdatedCount(2); // fires
196: debugListener.assertCurrThreadDiedCount(0);
197: debugListener.assertCurrThreadSuspendedCount(2); //fires
198: debugListener.assertBreakpointReachedCount(1);
199: assertInteractionsContains("Baz Line 1");
200: assertInteractionsDoesNotContain("Bar Line 1");
201:
202: // Resume until next breakpoint
203: synchronized (_notifierLock) {
204: // _log.log("resuming");
205: _setPendingNotifies(3); // suspended, updated, breakpointReached
206: _asyncResume();
207: while (_pendingNotifies > 0)
208: _notifierLock.wait();
209: }
210: // _log.log("----After one resume:\n" + getInteractionsText());
211: debugListener.assertCurrThreadResumedCount(2); //fires (no waiting)
212: debugListener.assertBreakpointReachedCount(2); //fires
213: debugListener.assertThreadLocationUpdatedCount(3); //fires
214: debugListener.assertCurrThreadSuspendedCount(3); //fires
215: debugListener.assertCurrThreadDiedCount(0);
216: assertInteractionsContains("Bar Line 1");
217: assertInteractionsDoesNotContain("Bar Line 2");
218:
219: // _log.log("-------- Adding interpret listener --------");
220: // Resume until finished, waiting for call to interpret to end
221: InterpretListener interpretListener = new InterpretListener();
222: _model.addListener(interpretListener);
223: synchronized (_notifierLock) {
224: // _log.log("-------- resuming --------");
225: _setPendingNotifies(3); // interactionEnded, interpreterChanged, currThreadDied (since it's the last thread)
226: _asyncResume();
227: while (_pendingNotifies > 0)
228: _notifierLock.wait();
229: }
230: interpretListener.assertInteractionEndCount(1);
231: _model.removeListener(interpretListener);
232:
233: _log.log("----After second resume:\n" + getInteractionsText());
234: debugListener.assertCurrThreadResumedCount(3); //fires (no waiting)
235: debugListener.assertBreakpointReachedCount(2);
236: debugListener.assertThreadLocationUpdatedCount(3);
237: debugListener.assertCurrThreadSuspendedCount(3);
238: assertInteractionsContains("Bar Line 2");
239:
240: // Shut down
241: _shutdownWithoutSuspendedInteraction();
242: _debugger.removeListener(debugListener);
243: }
244:
245: /** Tests that stepping into a breakpoint works. */
246: public synchronized void testStepIntoOverBreakpoint()
247: throws Exception {
248: _log.log("----testStepIntoOverBreakpoint----");
249: StepTestListener debugListener = new StepTestListener();
250: _debugger.addListener(debugListener);
251:
252: // Start up
253: OpenDefinitionsDocument doc = _startupDebugger(
254: "DrJavaDebugClass.java", DEBUG_CLASS);
255:
256: // Add a breakpoint
257: _debugger.toggleBreakpoint(doc, DEBUG_CLASS
258: .indexOf("Foo Line 1"), 3, true);
259: _debugger.toggleBreakpoint(doc,
260: DEBUG_CLASS.indexOf("bar();\n"), 4, true);
261:
262: Utilities.clearEventQueue();
263: debugListener.assertRegionAddedCount(2);
264:
265: // Run the foo() method, hitting breakpoint
266: synchronized (_notifierLock) {
267: _setPendingNotifies(3); // suspended, updated, breakpointReached
268: interpretIgnoreResult("new DrJavaDebugClass().foo()");
269: while (_pendingNotifies > 0)
270: _notifierLock.wait();
271: }
272:
273: // _log.log("----After breakpoint:\n" + getInteractionsText());
274:
275: // Ensure breakpoint is hit
276: debugListener.assertBreakpointReachedCount(1); //fires
277: debugListener.assertThreadLocationUpdatedCount(1); //fires
278: debugListener.assertCurrThreadSuspendedCount(1); //fires
279: debugListener.assertCurrThreadResumedCount(0);
280: debugListener.assertCurrThreadDiedCount(0);
281: assertInteractionsDoesNotContain("Foo Line 1");
282:
283: // Step over once
284: synchronized (_notifierLock) {
285: _setPendingNotifies(2); // suspended, updated
286: _asyncStep(Debugger.StepType.STEP_OVER);
287: while (_pendingNotifies > 0)
288: _notifierLock.wait();
289: }
290: debugListener.assertStepRequestedCount(1); // fires (don't wait)
291: debugListener.assertCurrThreadResumedCount(1); // fires (don't wait)
292: debugListener.assertThreadLocationUpdatedCount(2); // fires
293: debugListener.assertCurrThreadSuspendedCount(2); // fires
294: debugListener.assertBreakpointReachedCount(1);
295: debugListener.assertCurrThreadDiedCount(0);
296: assertInteractionsContains("Foo Line 1");
297:
298: // Step over again
299: synchronized (_notifierLock) {
300: _setPendingNotifies(2); // suspended, updated
301: _asyncStep(Debugger.StepType.STEP_OVER);
302: while (_pendingNotifies > 0)
303: _notifierLock.wait();
304: }
305:
306: // _log.log("****"+getInteractionsText());
307: debugListener.assertStepRequestedCount(2); // fires (don't wait)
308: debugListener.assertCurrThreadResumedCount(2); // fires (don't wait)
309: debugListener.assertThreadLocationUpdatedCount(3); // fires
310: debugListener.assertCurrThreadDiedCount(0);
311: debugListener.assertCurrThreadSuspendedCount(3); // fires
312: debugListener.assertBreakpointReachedCount(1);
313:
314: // Resume until finished, waiting for interpret call to finish
315: InterpretListener interpretListener = new InterpretListener();
316: _model.addListener(interpretListener);
317: synchronized (_notifierLock) {
318: _setPendingNotifies(3); // interactionEnded, interpreterChanged, currThreadDied (since it's the last thread)
319: _asyncResume();
320: while (_pendingNotifies > 0)
321: _notifierLock.wait();
322: }
323: interpretListener.assertInteractionEndCount(1);
324: _model.removeListener(interpretListener);
325:
326: // _log.log("----After resume:\n" + getInteractionsText());
327: debugListener.assertCurrThreadResumedCount(3); //fires (no waiting)
328: debugListener.assertBreakpointReachedCount(1);
329: debugListener.assertThreadLocationUpdatedCount(3);
330: debugListener.assertCurrThreadSuspendedCount(3);
331:
332: // Close doc and make sure breakpoints are removed
333: _model.closeFile(doc);
334: Utilities.clearEventQueue();
335: debugListener.assertRegionRemovedCount(2); //fires (no waiting)
336:
337: // Shutdown the debugger
338: // _log.log("Shutting down ...");
339:
340: synchronized (_notifierLock) {
341: _setPendingNotifies(1); // shutdown
342: _debugger.shutdown();
343: while (_pendingNotifies > 0)
344: _notifierLock.wait();
345: }
346:
347: debugListener.assertDebuggerShutdownCount(1); //fires
348: _log.log("Completed testStepIntoOverBreakpoint");
349: _debugger.removeListener(debugListener);
350: }
351:
352: /** Tests that static fields are consistent across different interpreter contexts. */
353: public void testStaticFieldsConsistent() throws Exception {
354: _log.log("----testStaticFieldsConsistent----");
355: StepTestListener debugListener = new StepTestListener();
356: _debugger.addListener(debugListener);
357:
358: // Start up
359: OpenDefinitionsDocument doc = _startupDebugger(
360: "DrJavaDebugStaticField.java", CLASS_WITH_STATIC_FIELD);
361:
362: // Set a breakpoint
363: _debugger.toggleBreakpoint(doc, CLASS_WITH_STATIC_FIELD
364: .indexOf("System.out.println"), 4, true);
365:
366: Utilities.clearEventQueue();
367: debugListener.assertRegionAddedCount(1);
368:
369: // Run the main method, hitting breakpoint
370: synchronized (_notifierLock) {
371: _setPendingNotifies(6); // (suspended, updated, breakpointReached) *2
372: interpretIgnoreResult("java DrJavaDebugStaticField");
373: while (_pendingNotifies > 0)
374: _notifierLock.wait();
375: }
376:
377: // TODO: Why is this call being made?
378: DebugThreadData threadA = new JPDAThreadData(_debugger
379: .getCurrentThread());
380: DebugThreadData threadB = new JPDAThreadData(_debugger
381: .getThreadAt(1));
382: // _log.log("----After breakpoint:\n" + getInteractionsText());
383:
384: // Ensure breakpoint is hit
385: debugListener.assertBreakpointReachedCount(2); //fires
386: debugListener.assertThreadLocationUpdatedCount(2); //fires
387: debugListener.assertCurrThreadSuspendedCount(2); //fires
388: debugListener.assertCurrThreadResumedCount(0);
389: debugListener.assertCurrThreadDiedCount(0);
390: assertEquals("x has correct value at start", "0",
391: interpret("DrJavaDebugStaticField.x"));
392: assertEquals("assigning x succeeds", "5",
393: interpret("DrJavaDebugStaticField.x = 5"));
394: assertEquals("assignment reflected in this", "5",
395: interpret("this.x"));
396:
397: // Step over once
398: synchronized (_notifierLock) {
399: _setPendingNotifies(2); // suspended, updated
400: _asyncStep(Debugger.StepType.STEP_OVER);
401: while (_pendingNotifies > 0)
402: _notifierLock.wait();
403: }
404: debugListener.assertStepRequestedCount(1); // fires (don't wait)
405: debugListener.assertCurrThreadResumedCount(1); // fires (don't wait)
406: debugListener.assertThreadLocationUpdatedCount(3); // fires
407: debugListener.assertCurrThreadSuspendedCount(3); // fires
408: debugListener.assertBreakpointReachedCount(2);
409: debugListener.assertCurrThreadDiedCount(0);
410: assertInteractionsContains("x == 5");
411: assertEquals("x retains correct value after step", "5",
412: interpret("DrJavaDebugStaticField.x"));
413: assertEquals("this has correct value for x after step", "5",
414: interpret("this.x"));
415:
416: // Step over again
417: synchronized (_notifierLock) {
418: _setPendingNotifies(2); // suspended, updated
419: _asyncStep(Debugger.StepType.STEP_OVER);
420: while (_pendingNotifies > 0)
421: _notifierLock.wait();
422: }
423: // _log.log("****"+getInteractionsText());
424: debugListener.assertStepRequestedCount(2); // fires (don't wait)
425: debugListener.assertCurrThreadResumedCount(2); // fires (don't wait)
426: debugListener.assertThreadLocationUpdatedCount(4); // fires
427: debugListener.assertCurrThreadSuspendedCount(4); // fires
428: debugListener.assertBreakpointReachedCount(2);
429: debugListener.assertCurrThreadDiedCount(0);
430: assertEquals("x has correct value after increment", "6",
431: interpret("DrJavaDebugStaticField.x"));
432: assertEquals("this has correct value for x after increment",
433: "6", interpret("this.x"));
434:
435: synchronized (_notifierLock) {
436: _setPendingNotifies(2); // suspended, updated
437: _asyncDoSetCurrentThread(threadB);
438: while (_pendingNotifies > 0)
439: _notifierLock.wait();
440: }
441: interpret("");
442: assertInteractionsContains("The current thread has changed.");
443: assertEquals("x has correct value in other thread", "6",
444: interpret("DrJavaDebugStaticField.x"));
445: assertEquals("this has correct value for x in other thread",
446: "6", interpret("this.x"));
447:
448: // Shut down
449: _shutdownAndWaitForInteractionEnded();
450: _debugger.removeListener(debugListener);
451: }
452:
453: /** Tests that watches can correctly see the values of local variables, fields and fields of outer classes. Also tests
454: * that we can watch objects initialized to null (bug #771040) and that we can watch final local variables of outer
455: * classes (bug #769174).
456: */
457: public void testNonStaticWatches() throws Exception {
458: _log.log("----testNonStaticWatches----");
459: StepTestListener debugListener = new StepTestListener();
460: _debugger.addListener(debugListener);
461:
462: final String monkey = MONKEY_WITH_INNER_CLASS;
463:
464: // Start up
465: OpenDefinitionsDocument doc = _startupDebugger("Monkey.java",
466: monkey);
467:
468: // Set a breakpoint
469: _debugger.toggleBreakpoint(doc, monkey
470: .indexOf("innerMethodFoo = 12;"), 10, true);
471: _debugger
472: .toggleBreakpoint(
473: doc,
474: monkey
475: .indexOf("System.out.println(\"localVar = \" + localVar);"),
476: 32, true);
477:
478: Utilities.clearEventQueue();
479: debugListener.assertRegionAddedCount(2);
480:
481: // Run an inner method, hitting breakpoint
482: synchronized (_notifierLock) {
483: _setPendingNotifies(3); // suspended, updated, breakpointReached
484: interpretIgnoreResult("new Monkey().bar()");//new MonkeyInner().new MonkeyInnerInner().innerMethod()");
485: while (_pendingNotifies > 0)
486: _notifierLock.wait();
487: }
488:
489: _debugger.addWatch("foo");
490: _debugger.addWatch("innerFoo");
491: _debugger.addWatch("innerInnerFoo");
492: _debugger.addWatch("innerMethodFoo");
493: _debugger.addWatch("asdf");
494: _debugger.addWatch("nullString");
495: _debugger.addWatch("localVar");
496: Utilities.clearEventQueue();
497: debugListener.assertWatchSetCount(7);
498:
499: // _log.log("first step");
500:
501: // Step to line 11
502: synchronized (_notifierLock) {
503: _setPendingNotifies(2); // suspended, updated
504: _asyncStep(Debugger.StepType.STEP_OVER);
505: while (_pendingNotifies > 0)
506: _notifierLock.wait();
507: }
508: debugListener.assertStepRequestedCount(1); // fires (don't wait)
509: debugListener.assertCurrThreadResumedCount(1); // fires (don't wait)
510: debugListener.assertThreadLocationUpdatedCount(2); // fires
511: debugListener.assertCurrThreadSuspendedCount(2); // fires
512: debugListener.assertBreakpointReachedCount(1);
513: debugListener.assertCurrThreadDiedCount(0);
514:
515: Vector<DebugWatchData> watches = _debugger.getWatches();
516: assertEquals("watch name incorrect", "foo", watches.get(0)
517: .getName());
518: assertEquals("watch name incorrect", "innerFoo", watches.get(1)
519: .getName());
520: assertEquals("watch name incorrect", "innerInnerFoo", watches
521: .get(2).getName());
522: assertEquals("watch name incorrect", "innerMethodFoo", watches
523: .get(3).getName());
524: assertEquals("watch name incorrect", "asdf", watches.get(4)
525: .getName());
526: assertEquals("watch name incorrect", "nullString", watches.get(
527: 5).getName());
528: assertEquals("watch value incorrect", "6", watches.get(0)
529: .getValue());
530: assertEquals("watch value incorrect", "8", watches.get(1)
531: .getValue());
532: assertEquals("watch value incorrect", "10", watches.get(2)
533: .getValue());
534: assertEquals("watch value incorrect", "12", watches.get(3)
535: .getValue());
536: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
537: watches.get(4).getValue());
538: assertEquals("watch value incorrect", "null", watches.get(5)
539: .getValue());
540: assertEquals("watch type incorrect", "java.lang.String",
541: watches.get(5).getType());
542:
543: interpret("innerFoo = 0");
544: watches = _debugger.getWatches();
545: assertEquals("watch name incorrect", "innerFoo", watches.get(1)
546: .getName());
547: assertEquals("watch value incorrect", "0", watches.get(1)
548: .getValue());
549:
550: interpret("innerFoo = 8");
551: assertEquals("watch name incorrect", "innerFoo", watches.get(1)
552: .getName());
553: assertEquals("watch value incorrect", "8", watches.get(1)
554: .getValue());
555:
556: // _log.log("second step in " + this);
557:
558: // Step to line 12
559: synchronized (_notifierLock) {
560: _setPendingNotifies(2); // suspended, updated
561: _asyncStep(Debugger.StepType.STEP_OVER);
562: while (_pendingNotifies > 0)
563: _notifierLock.wait();
564: }
565: debugListener.assertStepRequestedCount(2); // fires (don't wait)
566: debugListener.assertCurrThreadResumedCount(2); // fires (don't wait)
567: debugListener.assertThreadLocationUpdatedCount(3); // fires
568: debugListener.assertCurrThreadSuspendedCount(3); // fires
569: debugListener.assertBreakpointReachedCount(1);
570: debugListener.assertCurrThreadDiedCount(0);
571:
572: // _log.log("third step in " + this);
573:
574: // Step to line 13
575: synchronized (_notifierLock) {
576: _setPendingNotifies(2); // suspended, updated
577: _asyncStep(Debugger.StepType.STEP_OVER);
578: while (_pendingNotifies > 0)
579: _notifierLock.wait();
580: }
581: debugListener.assertStepRequestedCount(3); // fires (don't wait)
582: debugListener.assertCurrThreadResumedCount(3); // fires (don't wait)
583: debugListener.assertThreadLocationUpdatedCount(4); // fires
584: debugListener.assertCurrThreadSuspendedCount(4); // fires
585: debugListener.assertBreakpointReachedCount(1);
586: debugListener.assertCurrThreadDiedCount(0);
587:
588: // _log.log("fourth step in " + this);
589:
590: // Step to line 14
591: synchronized (_notifierLock) {
592: _setPendingNotifies(2); // suspended, updated
593: _asyncStep(Debugger.StepType.STEP_OVER);
594: while (_pendingNotifies > 0)
595: _notifierLock.wait();
596: }
597: debugListener.assertStepRequestedCount(4); // fires (don't wait)
598: debugListener.assertCurrThreadResumedCount(4); // fires (don't wait)
599: debugListener.assertThreadLocationUpdatedCount(5); // fires
600: debugListener.assertCurrThreadSuspendedCount(5); // fires
601: debugListener.assertBreakpointReachedCount(1);
602: debugListener.assertCurrThreadDiedCount(0);
603:
604: // _log.log("fifth step in " + this);
605:
606: // Step to line 15
607: synchronized (_notifierLock) {
608: _setPendingNotifies(2); // suspended, updated
609: _asyncStep(Debugger.StepType.STEP_OVER);
610: while (_pendingNotifies > 0)
611: _notifierLock.wait();
612: }
613: debugListener.assertStepRequestedCount(5); // fires (don't wait)
614: debugListener.assertCurrThreadResumedCount(5); // fires (don't wait)
615: debugListener.assertThreadLocationUpdatedCount(6); // fires
616: debugListener.assertCurrThreadSuspendedCount(6); // fires
617: debugListener.assertBreakpointReachedCount(1);
618: debugListener.assertCurrThreadDiedCount(0);
619:
620: watches = _debugger.getWatches();
621: assertEquals("watch name incorrect", "foo", watches.get(0)
622: .getName());
623: assertEquals("watch name incorrect", "innerFoo", watches.get(1)
624: .getName());
625: assertEquals("watch name incorrect", "innerInnerFoo", watches
626: .get(2).getName());
627: assertEquals("watch name incorrect", "innerMethodFoo", watches
628: .get(3).getName());
629: assertEquals("watch name incorrect", "asdf", watches.get(4)
630: .getName());
631: assertEquals("watch name incorrect", "nullString", watches.get(
632: 5).getName());
633: assertEquals("watch value incorrect", "7", watches.get(0)
634: .getValue());
635: assertEquals("watch value incorrect", "9", watches.get(1)
636: .getValue());
637: assertEquals("watch value incorrect", "11", watches.get(2)
638: .getValue());
639: assertEquals("watch value incorrect", "13", watches.get(3)
640: .getValue());
641: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
642: watches.get(4).getValue());
643: assertEquals("watch value incorrect", "null", watches.get(5)
644: .getValue());
645: assertEquals("watch type incorrect", "java.lang.String",
646: watches.get(5).getType());
647:
648: // _log.log("sixth step in " + this);
649:
650: // Step into static method
651: synchronized (_notifierLock) {
652: _setPendingNotifies(2); // suspended, updated
653: _asyncStep(Debugger.StepType.STEP_INTO);
654: while (_pendingNotifies > 0)
655: _notifierLock.wait();
656: }
657: debugListener.assertStepRequestedCount(6); // fires (don't wait)
658: debugListener.assertCurrThreadResumedCount(6); // fires (don't wait)
659: debugListener.assertThreadLocationUpdatedCount(7); // fires
660: debugListener.assertCurrThreadSuspendedCount(7); // fires
661: debugListener.assertBreakpointReachedCount(1);
662: debugListener.assertCurrThreadDiedCount(0);
663:
664: // Test watches in a static context.
665: watches = _debugger.getWatches();
666: assertEquals("watch name incorrect", "foo", watches.get(0)
667: .getName());
668: assertEquals("watch name incorrect", "innerFoo", watches.get(1)
669: .getName());
670: assertEquals("watch name incorrect", "innerInnerFoo", watches
671: .get(2).getName());
672: assertEquals("watch name incorrect", "innerMethodFoo", watches
673: .get(3).getName());
674: assertEquals("watch name incorrect", "asdf", watches.get(4)
675: .getName());
676: assertEquals("watch name incorrect", "nullString", watches.get(
677: 5).getName());
678: assertEquals("watch value incorrect", "7", watches.get(0)
679: .getValue());
680: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
681: watches.get(1).getValue());
682: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
683: watches.get(2).getValue());
684: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
685: watches.get(3).getValue());
686: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
687: watches.get(4).getValue());
688: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
689: watches.get(5).getValue());
690: assertEquals("watch type incorrect", DebugWatchData.NO_TYPE,
691: watches.get(5).getType());
692:
693: // Resumes one thread, finishing it and switching to the next break point
694: synchronized (_notifierLock) {
695: _setPendingNotifies(3); // breakpointReached, suspended, updated
696: _asyncResume();
697: while (_pendingNotifies > 0)
698: _notifierLock.wait();
699: }
700: debugListener.assertStepRequestedCount(6); // fires (don't wait)
701: debugListener.assertCurrThreadResumedCount(7); // fires (don't wait)
702: debugListener.assertThreadLocationUpdatedCount(8); // fires
703: debugListener.assertCurrThreadSuspendedCount(8); // fires
704: debugListener.assertBreakpointReachedCount(2);
705: debugListener.assertCurrThreadDiedCount(0);
706:
707: // Test watching a final local variable of an outer class
708: watches = _debugger.getWatches();
709: assertEquals("watch name incorrect", "localVar", watches.get(6)
710: .getName());
711: assertEquals("watch value incorrect", "11", watches.get(6)
712: .getValue());
713:
714: // Close doc and make sure breakpoints are removed
715: _model.closeFile(doc);
716: Utilities.clearEventQueue();
717: debugListener.assertRegionRemovedCount(2); //fires (no waiting)
718:
719: // Shut down
720: _shutdownAndWaitForInteractionEnded();
721: _debugger.removeListener(debugListener);
722: }
723:
724: /**
725: * Tests that watches can correctly see the values of local
726: * variables, fields and fields of outer classes.
727: */
728: public void testStaticWatches() throws Exception {
729: _log.log("----testStaticWatches----");
730: StepTestListener debugListener = new StepTestListener();
731: _debugger.addListener(debugListener);
732:
733: // Start up
734: OpenDefinitionsDocument doc = _startupDebugger(
735: "MonkeyStaticStuff.java", MONKEY_STATIC_STUFF);
736:
737: // Set a breakpoint
738: int index = MONKEY_STATIC_STUFF
739: .indexOf("System.out.println(MonkeyInner.MonkeyTwoDeep.twoDeepFoo);");
740: _debugger.toggleBreakpoint(doc, index, 14, true);
741:
742: Utilities.clearEventQueue();
743: debugListener.assertRegionAddedCount(1);
744:
745: // Run an inner method, hitting breakpoint
746: synchronized (_notifierLock) {
747: _setPendingNotifies(3); // suspended, updated, breakpointReached
748: interpretIgnoreResult("MonkeyStaticStuff.MonkeyInner.MonkeyTwoDeep.MonkeyThreeDeep.threeDeepMethod();");
749: while (_pendingNotifies > 0)
750: _notifierLock.wait();
751: }
752:
753: _debugger.addWatch("foo");
754: _debugger.addWatch("innerFoo");
755: _debugger.addWatch("twoDeepFoo");
756: _debugger.addWatch("threeDeepFoo");
757: _debugger.addWatch("asdf");
758: Utilities.clearEventQueue();
759: debugListener.assertWatchSetCount(5);
760:
761: Vector<DebugWatchData> watches = _debugger.getWatches();
762: assertEquals("watch name incorrect", "foo", watches.get(0)
763: .getName());
764: assertEquals("watch name incorrect", "innerFoo", watches.get(1)
765: .getName());
766: assertEquals("watch name incorrect", "twoDeepFoo", watches.get(
767: 2).getName());
768: assertEquals("watch name incorrect", "threeDeepFoo", watches
769: .get(3).getName());
770: assertEquals("watch name incorrect", "asdf", watches.get(4)
771: .getName());
772: assertEquals("watch value incorrect", "6", watches.get(0)
773: .getValue());
774: assertEquals("watch value incorrect", "8", watches.get(1)
775: .getValue());
776: assertEquals("watch value incorrect", "13", watches.get(2)
777: .getValue());
778: assertEquals("watch value incorrect", "18", watches.get(3)
779: .getValue());
780: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
781: watches.get(4).getValue());
782:
783: interpret("innerFoo = 0");
784: watches = _debugger.getWatches();
785: assertEquals("watch name incorrect", "innerFoo", watches.get(1)
786: .getName());
787: assertEquals("watch value incorrect", "0", watches.get(1)
788: .getValue());
789:
790: interpret("innerFoo = 8");
791: assertEquals("watch name incorrect", "innerFoo", watches.get(1)
792: .getName());
793: assertEquals("watch value incorrect", "8", watches.get(1)
794: .getValue());
795:
796: // Shut down
797: _shutdownAndWaitForInteractionEnded();
798: _debugger.removeListener(debugListener);
799: }
800:
801: /** Tests that watches can correctly see the values of final local variables and method parameters from enclosing
802: * classes. Note: Some final local variables are inlined by the compiler (even in debug mode), so they are
803: * unavailable to the debugger.
804: */
805: public void testWatchLocalVarsFromInnerClass() throws Exception {
806: _log.log("----testWatchLocalVarsFromInnerClass----");
807: StepTestListener debugListener = new StepTestListener();
808: _debugger.addListener(debugListener);
809:
810: // Start up
811: OpenDefinitionsDocument doc = _startupDebugger(
812: "InnerClassWithLocalVariables.java",
813: INNER_CLASS_WITH_LOCAL_VARS);
814:
815: // Set a breakpoint
816: int index = INNER_CLASS_WITH_LOCAL_VARS.indexOf("numArgs:");
817: _debugger.toggleBreakpoint(doc, index, 7, true);
818:
819: Utilities.clearEventQueue();
820: debugListener.assertRegionAddedCount(1);
821:
822: // Run the main method, hitting breakpoint
823: synchronized (_notifierLock) {
824: _setPendingNotifies(3); // suspended, updated, breakpointReached
825: interpretIgnoreResult("java InnerClassWithLocalVariables arg");
826: while (_pendingNotifies > 0)
827: _notifierLock.wait();
828: }
829: _debugger.addWatch("numArgs");
830: _debugger.addWatch("args");
831: _debugger.addWatch("inlined");
832: Utilities.clearEventQueue();
833: debugListener.assertWatchSetCount(3);
834:
835: // Check watch values
836: Vector<DebugWatchData> watches = _debugger.getWatches();
837: assertEquals("numArgs watch value incorrect", "1", watches.get(
838: 0).getValue());
839: String argsWatch = watches.get(1).getValue();
840: assertTrue("args watch value incorrect", argsWatch
841: .indexOf("java.lang.String") != -1);
842:
843: // unfortunately, inlined variable can't be seen
844: assertEquals("watch value incorrect", DebugWatchData.NO_VALUE,
845: watches.get(2).getValue());
846:
847: // Shut down
848: _shutdownAndWaitForInteractionEnded();
849: _debugger.removeListener(debugListener);
850: }
851:
852: /** Tests that watches can correctly see the values of final local variables and method parameters from enclosing
853: * classes. Note: Some final local variables are inlined by the compiler (even in debug mode), so they are
854: * unavailable to the debugger.
855: */
856: public void testThreadShouldDie() throws Exception {
857: _log.log("----testThreadShouldDie----");
858: StepTestListener debugListener = new StepTestListener();
859: _debugger.addListener(debugListener);
860:
861: // Start up
862: OpenDefinitionsDocument doc = _startupDebugger(
863: "DrJavaThreadDeathTest.java", THREAD_DEATH_CLASS);
864:
865: // Before bugs 697825 and 779111 were fixed, this line would just
866: // hang, since dead threads remained suspended indefinitely.
867: interpret("Jones.threadShouldDie()");
868:
869: // Shut down
870: _shutdownWithoutSuspendedInteraction();
871: _debugger.removeListener(debugListener);
872: }
873: }
|