/*
Copyright 2014 Google Inc. All Rights Reserved.
Licensed 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 com.google.security.zynamics.binnavi.Debug.Debugger;
import static org.junit.Assert.assertEquals;
import com.google.security.zynamics.binnavi.Common.CommonTestObjects;
import com.google.security.zynamics.binnavi.debug.connection.packets.parsers.MessageParserException;
import com.google.security.zynamics.binnavi.debug.debugger.AbstractDebugger;
import com.google.security.zynamics.binnavi.debug.debugger.DebugExceptionWrapper;
import com.google.security.zynamics.binnavi.debug.debugger.ModuleTargetSettings;
import com.google.security.zynamics.binnavi.debug.debugger.synchronizers.DebuggerSynchronizer;
import com.google.security.zynamics.binnavi.debug.models.breakpoints.BreakpointManager;
import com.google.security.zynamics.binnavi.debug.models.breakpoints.enums.BreakpointStatus;
import com.google.security.zynamics.binnavi.debug.models.breakpoints.enums.BreakpointType;
import com.google.security.zynamics.binnavi.debug.models.processmanager.MemoryModule;
import com.google.security.zynamics.binnavi.disassembly.RelocatedAddress;
import com.google.security.zynamics.zylib.disassembly.CAddress;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.lang.reflect.Field;
@RunWith(JUnit4.class)
public final class BreakpointLifecycleTest {
private final CAddress mockFileBase = new CAddress(0);
private final RelocatedAddress mockImageBase = new RelocatedAddress(new CAddress(0x1000));
private static final long mockImageSize = 0x10000;
private final MemoryModule mockMemoryModule =
new MemoryModule("Mock Module", "C:\\mockmodule.exe", mockImageBase, mockImageSize);
private MockDebugger m_debugger;
private BreakpointManager m_breakpointManager;
private DebuggerSynchronizer m_synchronizer;
private final MockEventListener m_listener = new MockEventListener();
@Before
public void setUp() throws SecurityException, NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
m_debugger = new MockDebugger(new ModuleTargetSettings(CommonTestObjects.MODULE));
m_debugger.setAddressTranslator(CommonTestObjects.MODULE, mockFileBase,
mockImageBase.getAddress());
m_breakpointManager = m_debugger.getBreakpointManager();
m_synchronizer = new DebuggerSynchronizer(m_debugger);
m_synchronizer.addListener(m_listener);
// assign the synchronizer to the internally used one by the debugger so we can test the
// synchronizer itself
// as well as the combination of synchronizer and debugger
final Field synchronizerField = AbstractDebugger.class.getDeclaredField("synchronizer");
synchronizerField.setAccessible(true);
synchronizerField.set(m_debugger, m_synchronizer);
}
@After
public void tearDown() {
m_debugger.close();
}
@Test
public void testActiveToDeleting() throws DebugExceptionWrapper {
// Scenario:
//
// 1. User sets breakpoint
// 2. Debug clients sets breakpoint in the target process
// 3. User deletes breakpoint
// 4. Debug client removes breakpoint
//
// Expected result:
// - Breakpoint is removed from the target process
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DELETING);
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointRemoveSucc(
CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(0, m_breakpointManager.getNumberOfBreakpoints(BreakpointType.REGULAR));
assertEquals(
"CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;REMOVE_BREAKPOINTS/00000456/REGULAR;",
m_debugger.requests);
}
@Test
public void testActiveToDisabled() throws DebugExceptionWrapper {
// Scenario:
//
// 1. User sets breakpoint
// 2. Debug clients sets breakpoint in the target process
// 3. User disables breakpoint
// 4. Debug client removes breakpoint
//
// Expected result:
// - Breakpoint is removed from the target process
// - Final breakpoint status DISABLED
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DISABLED);
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointRemoveSucc(
CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(1, m_breakpointManager.getNumberOfBreakpoints(BreakpointType.REGULAR));
assertEquals(BreakpointStatus.BREAKPOINT_DISABLED, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals(
"CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;REMOVE_BREAKPOINTS/00000456/REGULAR;",
m_debugger.requests);
}
@Test
@Ignore
public void testActiveToEnabled() {
// Not possible; breakpoint lifecycle would go backwards
}
@Test
public void testActiveToHit() throws DebugExceptionWrapper, MessageParserException {
// Scenario:
//
// 1. User sets breakpoint
// 2. Debug clients sets breakpoint in the target process
// 3. Breakpoint is hit
//
// Expected result:
// - Final breakpoint status HIT
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildRegularBreakpointHit(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_HIT, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
}
@Test
@Ignore
public void testActiveToInactive() {
// Not possible; the correct way is to through either DELETING or DISABLED
}
@Test
@Ignore
public void testActiveToInvalid() {
// Not possible; active breakpoints can not suddenly go invalid
}
@Test
public void testDeletingToDisabled() throws DebugExceptionWrapper {
// Scenario:
//
// 1. User sets breakpoint
// 2. Debug client sets breakpoint
// 3. User deletes breakpoint
// 4. User disables breakpoints
//
// Expected result:
// - Not possible; exception
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
// 1. User sets breakpoint
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
// 2. Debug client sets breakpoint
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
// 3. User deletes breakpoint
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DELETING);
// assertEquals(BreakpointStatus.BREAKPOINT_DELETING,
// m_breakpointManager.getBreakpointStatus(CommonTestObjects.BP_ADDRESS_456,
// BreakpointType.REGULAR));
// try
// {
// // 4. User disables breakpoints
// m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
// BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DISABLED);
// fail();
// }
// catch (final IllegalStateException exception)
// {
// }
assertEquals(
"CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;REMOVE_BREAKPOINTS/00000456/REGULAR;",
m_debugger.requests);
// assertEquals(BreakpointStatus.BREAKPOINT_DISABLED,
// m_breakpointManager.getBreakpoint(BreakpointType.REGULAR, CommonTestObjects.BP_ADDRESS_456));
//
// // 5. Debug client deletes breakpoint
// m_synchronizer.handleBreakpointRemoveSucc(DebuggerMessageBuilder.buildEchoBreakpointRemoveSucc(CommonTestObjects.BP_ADDRESS_456_RELOC));
//
// assertEquals(0, m_breakpointManager.getNumberOfBreakpoints(BreakpointType.REGULAR));
}
@Test
public void testDisabledToDeleting() throws DebugExceptionWrapper {
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_INACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DISABLED);
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DELETING);
assertEquals(0, m_breakpointManager.getNumberOfBreakpoints(BreakpointType.REGULAR));
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DISABLED);
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointRemoveSucc(
CommonTestObjects.BP_ADDRESS_456_RELOC));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DELETING);
assertEquals(0, m_breakpointManager.getNumberOfBreakpoints(BreakpointType.REGULAR));
assertEquals(
"CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;REMOVE_BREAKPOINTS/00000456/REGULAR;",
m_debugger.requests);
}
@Test
public void testEnabledToActive() throws DebugExceptionWrapper {
// Scenario:
//
// 1. User sets breakpoint
// 2. SET reply arrives from the Debug Client
//
// Expected result:
// - Final breakpoint status ACTIVE
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
}
@Test
@Ignore
public void testEnabledToDeleting() {
// TODO: Unclear scenario
}
@Test
public void testEnabledToDisabled() throws DebugExceptionWrapper {
// Scenario:
//
// 1. User sets breakpoint (SET Message is sent to the Debug Client)
// 2. User disables breakpoint (REMOVE Message is sent to the Debug Client)
//
// At this point there are two messages on the way to the debug client which
// are guaranteed to come back in the order they were sent.
//
// Expected result:
// - Final breakpoint status DISABLED
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DISABLED);
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_DISABLED, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointRemoveSucc(
CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_DISABLED, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals(
"CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;REMOVE_BREAKPOINTS/00000456/REGULAR;",
m_debugger.requests);
}
@Test
@Ignore
public void testEnabledToHit() {
// Not possible; must go through ACTIVE first
}
@Test
@Ignore
public void testEnabledToInactive() {
// TODO: Scenario unclear
}
@Test
public void testEnabledToInvalid() throws DebugExceptionWrapper {
// Scenario:
//
// 1. User sets breakpoint
// 2. Debug client fails to set breakpoint
//
// Expected result:
//
// - Final breakpoint status INVALID
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointSetError(
CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_INVALID, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
}
@Test
public void testHitToDeleting() throws DebugExceptionWrapper, MessageParserException {
// Scenario:
//
// 1. User sets breakpoint (SET Message is sent to the Debug Client)
// 2. Debug client sets breakpoint
// 3. Debug client hits breakpoint
// 4. User deletes breakpoint (REMOVE Message is sent to the Debug Client)
//
// Expected result:
// - Breakpoint is removed from the breakpoint manager
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
// 1. User sets breakpoint (SET Message is sent to the Debug Client)
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
// 2. Debug client sets breakpoint
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
// 3. Debug client hits breakpoint
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildRegularBreakpointHit(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_HIT, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
// 4. User deletes breakpoint (REMOVE Message is sent to the Debug Client)
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DELETING);
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointRemoveSucc(
CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(0, m_breakpointManager.getNumberOfBreakpoints(BreakpointType.REGULAR));
assertEquals(
"CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;REMOVE_BREAKPOINTS/00000456/REGULAR;",
m_debugger.requests);
}
@Test
public void testHitToDisabled() throws DebugExceptionWrapper, MessageParserException {
// Scenario:
//
// 1. User sets breakpoint (SET Message is sent to the Debug Client)
// 2. Debug client sets breakpoint
// 3. Debug client hits breakpoint
// 4. User disables breakpoint (REMOVE Message is sent to the Debug Client)
//
// Expected result:
// - Final breakpoint status DISABLED
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
// 1. User sets breakpoint (SET Message is sent to the Debug Client)
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_ACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
// 2. Debug client sets breakpoint
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildBreakpointSuccess(CommonTestObjects.BP_ADDRESS_456_RELOC));
// 3. Debug client hits breakpoint
m_synchronizer.receivedEvent(
DebuggerMessageBuilder.buildRegularBreakpointHit(CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_HIT, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
// 4. User disables breakpoint (REMOVE Message is sent to the Debug Client)
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DISABLED);
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointRemoveSucc(
CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_DISABLED, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals(
"CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;REMOVE_BREAKPOINTS/00000456/REGULAR;",
m_debugger.requests);
}
@Test
@Ignore
public void testInactiveToActive() {
// Not possible; must go through ENABLED first
}
@Test
public void testInactiveToDeleting() {
// Scenario:
//
// 1. Debugger is inactive
// 2. User sets a breakpoint
// 3. User removes breakpoint
//
// Expected result:
// - Breakpoint is removed from the breakpoint manager
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_INACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DELETING);
assertEquals(0, m_breakpointManager.getNumberOfBreakpoints(BreakpointType.REGULAR));
assertEquals("", m_debugger.requests);
}
@Test
public void testInactiveToDisabled() {
// Scenario:
//
// 1. Debugger is inactive
// 2. User sets a breakpoint
// 3. User disables breakpoint
//
// Expected result:
// - Breakpoint is disabled
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_INACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DISABLED);
assertEquals(BreakpointStatus.BREAKPOINT_DISABLED, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("", m_debugger.requests);
}
@Test
public void testInactiveToEnabled() throws DebugExceptionWrapper {
// Scenario:
//
// 1. Debugger is inactive
// 2. User sets a breakpoint
// 3. Debugger is started
// 4. Process start event
//
// Expected result:
// - Final breakpoint status ENABLED
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
assertEquals(BreakpointStatus.BREAKPOINT_INACTIVE, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
assertEquals(BreakpointStatus.BREAKPOINT_ENABLED, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;SET_BREAKPOINTS/00000456/REGULAR;RESUME;", m_debugger.requests);
}
@Test
@Ignore
public void testInactiveToHit() {
// Not possible; must go through ENABLED first
}
@Test
@Ignore
public void testInactiveToInvalid() {
// Not possible; must go through ENABLED first
}
@Test
public void testInvalidToDeleting() throws DebugExceptionWrapper {
// Scenario:
//
// 1. User sets a breakpoint
// 2. Debug client fails to set breakpoint
// 3. User removes breakpoint
//
// Expected result:
// - Breakpoint is removed from the breakpoint manager
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointSetError(
CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_INVALID, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DELETING);
assertEquals(0, m_breakpointManager.getNumberOfBreakpoints(BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
}
@Test
public void testInvalidToDisabled() throws DebugExceptionWrapper {
// Scenario:
//
// 1. User sets a breakpoint
// 2. Debug client fails to set breakpoint
// 3. User disables breakpoint
//
// Expected result:
// - Breakpoint is removed from the breakpoint manager
m_debugger.connect();
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildProcessStartReply(mockMemoryModule));
m_breakpointManager.addBreakpoints(BreakpointType.REGULAR,
CommonTestObjects.BP_ADDRESS_456_SET);
m_synchronizer.receivedEvent(DebuggerMessageBuilder.buildRegularBreakpointSetError(
CommonTestObjects.BP_ADDRESS_456_RELOC));
assertEquals(BreakpointStatus.BREAKPOINT_INVALID, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
m_breakpointManager.setBreakpointStatus(CommonTestObjects.BP_ADDRESS_456_SET,
BreakpointType.REGULAR, BreakpointStatus.BREAKPOINT_DISABLED);
assertEquals(BreakpointStatus.BREAKPOINT_DISABLED, m_breakpointManager.getBreakpointStatus(
CommonTestObjects.BP_ADDRESS_456, BreakpointType.REGULAR));
assertEquals("CONNECT;READREGS;RESUME;SET_BREAKPOINTS/00000456/REGULAR;", m_debugger.requests);
}
}