blob: 11165fbaf1317bc5c307d766b4a5adb0e2ed25a1 [file] [log] [blame]
/*
* 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.
*/
package org.netbeans.api.debugger.jpda;
import java.io.IOException;
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
import junit.framework.Test;
import org.netbeans.api.debugger.DebuggerManager;
import org.netbeans.api.debugger.jpda.event.JPDABreakpointEvent;
import org.netbeans.api.debugger.jpda.event.JPDABreakpointListener;
import org.netbeans.junit.NbTestCase;
/**
* Tests line breakpoints at various places.
*
* @author Maros Sandor, Jan Jancura
*/
public class LineBreakpointTest extends NbTestCase {
private static final String TEST_APP = Utils.getURL(System.getProperty ("test.dir.src") +
"org/netbeans/api/debugger/jpda/testapps/LineBreakpointApp.java");
private static final String TEST_APP_PATH = System.getProperty ("test.dir.src") +
"org/netbeans/api/debugger/jpda/testapps/LineBreakpointApp.java";
private JPDASupport support;
public LineBreakpointTest (String s) {
super (s);
}
public static Test suite() {
return JPDASupport.createTestSuite(LineBreakpointTest.class);
}
public void testConditionalBreakpoint() throws Exception {
Utils.BreakPositions bp = Utils.getBreakPositions(TEST_APP_PATH);
doTestBreakpointComplete (
bp.getStopLine("condition1"),
"x==22",
JPDABreakpointEvent.CONDITION_FALSE
);
doTestBreakpointComplete (
bp.getStopLine("condition2"),
"x==60",
JPDABreakpointEvent.CONDITION_TRUE
);
}
public void testMultipleLineBreakpoints () throws Exception {
try {
Utils.BreakPositions bp = Utils.getBreakPositions(TEST_APP_PATH);
LineBreakpoint[] lb = bp.getBreakpoints().toArray(new LineBreakpoint[0]);
{
LineBreakpoint b;
b = lb[4];
lb[4] = lb[2];
lb[2] = b;
}
/*
LineBreakpoint lb1 = LineBreakpoint.create (TEST_APP, 32);
LineBreakpoint lb2 = LineBreakpoint.create (TEST_APP, 37);
LineBreakpoint lb3 = LineBreakpoint.create (TEST_APP, 109);
lb3.setPreferredClassName("org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp$Inner");
LineBreakpoint lb4 = LineBreakpoint.create (TEST_APP, 92);
lb4.setPreferredClassName("org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp$InnerStatic");
LineBreakpoint lb5 = LineBreakpoint.create (TEST_APP, 41);
*/
DebuggerManager dm = DebuggerManager.getDebuggerManager ();
for (int i = 0; i < lb.length; i++) {
dm.addBreakpoint (lb[i]);
}
TestBreakpointListener[] tb = new TestBreakpointListener[lb.length];
for (int i = 0; i < lb.length; i++) {
tb[i] = new TestBreakpointListener (lb[i]);
lb[i].addJPDABreakpointListener (tb[i]);
}
support = JPDASupport.attach (
"org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp"
);
JPDADebugger debugger = support.getDebugger();
for (int j = 0; j < lb.length; j++) {
support.waitState (JPDADebugger.STATE_STOPPED); // j-th breakpoint hit
assertEquals (
"Debugger stopped at wrong line for breakpoint " + j,
lb[j].getLineNumber (),
debugger.getCurrentCallStackFrame ().getLineNumber (null)
);
for (int i = j+1; i < tb.length; i++) {
tb[i].checkNotNotified();
}
if (j < lb.length - 1) {
support.doContinue();
}
}
for (int i = 0; i < tb.length; i++) {
tb[i].checkResult ();
}
for (int i = 0; i < tb.length; i++) {
dm.removeBreakpoint (lb[i]);
}
support.doContinue ();
support.waitState (JPDADebugger.STATE_DISCONNECTED);
} finally {
if (support != null) support.doFinish ();
}
}
public void testStaticBlockBreakpoint() throws Exception {
Utils.BreakPositions bp = Utils.getBreakPositions(TEST_APP_PATH);
doTestBreakpointComplete(bp.getStopLine("staticx"));
doTestBreakpointComplete(bp.getStopLine("staticx2"));
}
public void testStaticInnerClassBreakpoint() throws Exception {
Utils.BreakPositions bp = Utils.getBreakPositions(TEST_APP_PATH);
doTestBreakpointComplete(bp.getStopLine("IS1"));
doTestBreakpointComplete(bp.getStopLine("IS2"));
doTestBreakpointComplete(bp.getStopLine("IS3"));
}
public void testMainLineBreakpoint() throws Exception {
Utils.BreakPositions bp = Utils.getBreakPositions(TEST_APP_PATH);
doTestBreakpointComplete(bp.getStopLine("M1"));
}
public void testConstructorLineBreakpoint() throws Exception {
Utils.BreakPositions bp = Utils.getBreakPositions(TEST_APP_PATH);
doTestBreakpointComplete(bp.getStopLine("C1"));
}
public void testInnerLineBreakpoint () throws Exception {
Utils.BreakPositions bp = Utils.getBreakPositions(TEST_APP_PATH);
doTestBreakpointComplete (bp.getStopLine("I1"));
doTestBreakpointComplete (bp.getStopLine("I2"));
doTestBreakpointComplete (bp.getStopLine("I3"));
}
private void doTestBreakpointComplete (
int line,
String condition,
int conditionResult
) throws IOException, IllegalConnectorArgumentsException,
DebuggerStartException {
try {
LineBreakpoint lb = doTestBreakpoint (
line,
condition,
conditionResult
);
if ( condition == null ||
conditionResult == JPDABreakpointEvent.CONDITION_TRUE
) {
support.doContinue();
support.waitState (JPDADebugger.STATE_DISCONNECTED);
}
DebuggerManager.getDebuggerManager ().removeBreakpoint (lb);
} finally {
if (support != null) support.doFinish();
}
}
private void doTestBreakpointComplete (int line) throws IOException,
IllegalConnectorArgumentsException, DebuggerStartException {
doTestBreakpointComplete (
line,
null,
JPDABreakpointEvent.CONDITION_NONE
);
}
private LineBreakpoint doTestBreakpoint (
int line,
String condition,
int conditionResult
) throws IOException, IllegalConnectorArgumentsException,
DebuggerStartException {
JPDASupport.removeAllBreakpoints ();
LineBreakpoint lb = LineBreakpoint.create (TEST_APP, line);
/*
if (73 <= line && line <= 98) {
lb.setPreferredClassName("org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp$InnerStatic");
} else if (100 <= line && line <= 115) {
lb.setPreferredClassName("org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp$Inner");
}
*/
lb.setCondition (condition);
TestBreakpointListener tbl = new TestBreakpointListener
(lb, conditionResult);
lb.addJPDABreakpointListener (tbl);
DebuggerManager.getDebuggerManager ().addBreakpoint (lb);
support = JPDASupport.attach (
"org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp"
);
if ( condition == null ||
conditionResult == JPDABreakpointEvent.CONDITION_TRUE
) {
support.waitState (JPDADebugger.STATE_STOPPED);
} else {
support.waitState (JPDADebugger.STATE_DISCONNECTED);
}
tbl.checkResult ();
return lb;
}
/**
* Tests debugger's ability to make difference between different projects
* with the same classes while getting the locations during class-loaded event.
*
* 1. The user creates 2 classes: ${test.dir.src}/.../LineBreakpointApp.java
* and ${test.dir.src_2}/.../LineBreakpointApp.java
* 2. Then set a breakpoint in ${test.dir.src_2}/.../LineBreakpointApp.java.
*
* Debugger should stop _only_ in the second project. If debugger stopped in
* the first one, then assertion violation would arise because of source path
* equality test.
*/
public void testBreakpointUnambiguity1 () throws Exception {
try {
Utils.BreakPositions bp = Utils.getBreakPositions(System.getProperty ("test.dir.src") +
"org/netbeans/api/debugger/jpda/testapps/LineBreakpointApp.java");
LineBreakpoint lb1 = LineBreakpoint.create (TEST_APP, bp.getStopLine("condition1"));
// lb1.setSourceRoot(System.getProperty ("test.dir.src"));
DebuggerManager dm = DebuggerManager.getDebuggerManager ();
dm.addBreakpoint (lb1);
TestBreakpointListener tb1 = new TestBreakpointListener (lb1);
lb1.addJPDABreakpointListener (tb1);
support = JPDASupport.attach (
"org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp"
);
JPDADebugger debugger = support.getDebugger();
support.waitState (JPDADebugger.STATE_STOPPED); // breakpoint hit, the source root is correct
assertEquals (
"Debugger stopped at wrong line",
lb1.getLineNumber (),
debugger.getCurrentCallStackFrame ().getLineNumber (null)
);
tb1.checkResult ();
support.doContinue();
support.waitState (JPDADebugger.STATE_DISCONNECTED);
dm.removeBreakpoint (lb1);
support.doFinish ();
/*
// Second run - BP should not be hit with a different source root - viz testBreakpointUnambiguity2()
support = null;
lb1 = LineBreakpoint.create (TEST_APP, 39);
lb1.setSourceRoot(System.getProperty ("test.dir.src")+"_2");
dm = DebuggerManager.getDebuggerManager ();
dm.addBreakpoint (lb1);
tb1 = new TestBreakpointListener (lb1);
lb1.addJPDABreakpointListener (tb1);
support = JPDASupport.attach (
"org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp"
);
debugger = support.getDebugger();
support.waitState (JPDADebugger.STATE_STOPPED); // Stopped or disconnected
assertEquals(
"Debugger should not stop on BP with faked source root",
debugger.getState(),
JPDADebugger.STATE_DISCONNECTED
);
tb1.checkNotNotified();
dm.removeBreakpoint (lb1);
*/
} finally {
if (support != null) support.doFinish ();
}
}
/**
* Tests debugger's ability to make difference between different projects
* with the same classes while getting the locations during class-loaded event.
*
* 1. The user creates 2 classes: ${test.dir.src}/.../LineBreakpointApp.java
* and ${test.dir.src_2}/.../LineBreakpointApp.java
* 2. Then set a breakpoint in ${test.dir.src_2}/.../LineBreakpointApp.java.
*
* Debugger should stop _only_ in the second project. If debugger stopped in
* the first one, then assertion violation would arise because of source path
* equality test.
*/
public void testBreakpointUnambiguity2 () throws Exception {
try {
Utils.BreakPositions bp = Utils.getBreakPositions(System.getProperty ("test.dir.src") +
"org/netbeans/api/debugger/jpda/testapps/LineBreakpointApp.java");
LineBreakpoint lb1 = LineBreakpoint.create(
Utils.getURL(System.getProperty ("user.home") + // intentionally bad path
java.io.File.separator +
"org/netbeans/api/debugger/jpda/testapps/LineBreakpointApp.java"), bp.getStopLine("condition1"));
//lb1.setSourceRoot(System.getProperty ("test.dir.src") + "_2");
DebuggerManager dm = DebuggerManager.getDebuggerManager ();
dm.addBreakpoint (lb1);
TestBreakpointListener tb1 = new TestBreakpointListener (lb1);
lb1.addJPDABreakpointListener (tb1);
support = JPDASupport.attach (
"org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp"
);
JPDADebugger debugger = support.getDebugger();
support.waitState (JPDADebugger.STATE_STOPPED); // Stopped or disconnected
assertEquals(
"Debugger should not stop on BP with faked source root",
debugger.getState(),
JPDADebugger.STATE_DISCONNECTED
);
tb1.checkNotNotified();
dm.removeBreakpoint (lb1);
} finally {
if (support != null) support.doFinish ();
}
}
// innerclasses ............................................................
private class TestBreakpointListener implements JPDABreakpointListener {
private LineBreakpoint lineBreakpoint;
private int conditionResult;
private JPDABreakpointEvent event;
private AssertionError failure;
public TestBreakpointListener (LineBreakpoint lineBreakpoint) {
this (lineBreakpoint, JPDABreakpointEvent.CONDITION_NONE);
}
public TestBreakpointListener (
LineBreakpoint lineBreakpoint,
int conditionResult
) {
this.lineBreakpoint = lineBreakpoint;
this.conditionResult = conditionResult;
}
public void breakpointReached (JPDABreakpointEvent event) {
try {
checkEvent (event);
} catch (AssertionError e) {
failure = e;
} catch (Throwable e) {
failure = new AssertionError (e);
}
}
private void checkEvent (JPDABreakpointEvent event) {
this.event = event;
assertEquals (
"Breakpoint event: Wrong source breakpoint",
lineBreakpoint,
event.getSource ()
);
assertNotNull (
"Breakpoint event: Context thread is null",
event.getThread ()
);
int result = event.getConditionResult ();
if ( result == JPDABreakpointEvent.CONDITION_FAILED &&
conditionResult != JPDABreakpointEvent.CONDITION_FAILED
)
failure = new AssertionError (event.getConditionException ());
else
if (result != conditionResult)
failure = new AssertionError (
"Unexpected breakpoint condition result: " + result
);
}
public void checkResult () {
if (event == null) {
CallStackFrame f = support.getDebugger ().
getCurrentCallStackFrame ();
int ln = -1;
if (f != null) {
ln = f.getLineNumber (null);
}
throw new AssertionError (
"Breakpoint was not hit (listener was not notified) " + ln
);
}
if (failure != null) throw failure;
}
public void checkNotNotified() {
if (event != null) {
JPDAThread t = event.getThread();
throw new AssertionError (
"Breakpoint was hit (listener was notified) in thread " + t
);
}
if (failure != null) throw failure;
}
}
}