Skip to content
Snippets Groups Projects

Breakpoint tests

Merged Johannes Kung requested to merge breakpoint_tests into main
1 file
+ 183
0
Compare changes
  • Side-by-side
  • Inline
+ 183
0
 
from simudator.core.breakpoint_state import StateBreakpoint
 
from simudator.core.breakpoint_memory import MemoryBreakpoint
 
from simudator.core.breakpoint_lambda import LambdaBreakpoint
 
from simudator.core.module import Module
 
from simudator.core.modules.memory import Memory
 
from simudator.core.processor import Processor
 
from simudator.core.signal import Signal
 
 
 
class DummyModule(Module):
 
def __init__(self, name: str = "") -> None:
 
super().__init__(name)
 
self.value = 0
 
 
def get_state(self) -> dict:
 
state = super().get_state()
 
state["value"] = self.value
 
return state
 
 
 
def test_state_breakpoint():
 
"""
 
Test the functionality of StateBreakpoint.
 
"""
 
m = DummyModule()
 
bp = StateBreakpoint(m, "value", 10)
 
 
# Module state is not set to break value => should not break
 
assert not bp.is_break()
 
 
# Module state is set to break value => should break
 
m.value = 10
 
assert bp.is_break()
 
 
# Module state is no longer set to break value => should no longer break
 
# Also checks that a value of a different type than that of the break value
 
# does not cause issues
 
m.value = "-"
 
assert not bp.is_break()
 
 
 
def test_memory_breakpoint():
 
"""
 
Test the functionality of MemoryBreakpoint.
 
"""
 
cpu = Processor()
 
in_s = Signal(cpu)
 
out_s = Signal(cpu)
 
ctrl_s = Signal(cpu)
 
adr_s = Signal(cpu)
 
mem = Memory(in_s, out_s, ctrl_s, adr_s, 8)
 
cpu.add_module(mem)
 
 
# Default memory value is not -2 => should not break
 
bp = MemoryBreakpoint(mem, 3, -2)
 
assert not bp.is_break()
 
 
# Write the relevant memory address to some other value
 
# => should not break
 
in_s.update_value("a")
 
adr_s.update_value(3)
 
ctrl_s.update_value(True)
 
cpu.do_tick() # Address the memory
 
cpu.do_tick() # Write to the memory
 
assert not bp.is_break()
 
 
# Write the breakpoint value to the relevant address => should break
 
in_s.update_value(-2)
 
cpu.do_tick()
 
assert bp.is_break()
 
 
# Writing to some other address should not affect
 
in_s.update_value(-2)
 
adr_s.update_value(7)
 
cpu.do_tick() # Address the memory
 
cpu.do_tick() # Write to the memory
 
assert bp.is_break()
 
 
# Writing some other value to the relevant address => should no longer break
 
adr_s.update_value(3)
 
in_s.update_value(4.6)
 
cpu.do_tick() # Address the memory
 
cpu.do_tick() # Write to the memory
 
assert not bp.is_break()
 
 
 
def test_lambda_breakpoint_no_args():
 
"""
 
Test the functionality of LambdaBreakpoint when supplied with a function
 
that takes no arguments.
 
"""
 
# Test functions with no arguments
 
# Function returns False => should not break
 
bp = LambdaBreakpoint(lambda: False)
 
assert not bp.is_break()
 
 
# Function returns True => should break
 
bp = LambdaBreakpoint(lambda: True)
 
assert bp.is_break()
 
 
 
def test_lambda_breakpoint_args():
 
"""
 
Test the functionality of LambdaBreakpoint when supplied with a function
 
that takes arguments.
 
"""
 
# Test functions with arguments
 
# Arguments of same type
 
def func_1(num, thres):
 
return num > thres
 
 
kwargs = {"num": 5, "thres": 10}
 
bp = LambdaBreakpoint(func_1, **kwargs)
 
assert bp.is_break() == func_1(**kwargs)
 
 
kwargs = {"num": 5, "thres": -2}
 
bp = LambdaBreakpoint(func_1, **kwargs)
 
assert bp.is_break() == func_1(**kwargs)
 
 
# Arguments of different types
 
def str_float_comp(string, num):
 
return float(string) == num
 
kwargs = {"string": "2.5", "num": 2.5}
 
bp = LambdaBreakpoint(str_float_comp, **kwargs)
 
assert bp.is_break() == str_float_comp(**kwargs)
 
 
def test_lambda_breakpoint_ref_args():
 
"""
 
Test the functionality of LambdaBreakpoint when supplied with a function
 
that takes references as arguments.
 
"""
 
# Explicit comparison of references
 
l1 = []
 
l2 = []
 
def func_list_ref_comp(l):
 
return l is l2
 
 
kwargs = {"l": l1}
 
bp = LambdaBreakpoint(func_list_ref_comp, **kwargs)
 
assert bp.is_break() == func_list_ref_comp(l1)
 
 
kwargs = {"l": l2}
 
bp = LambdaBreakpoint(func_list_ref_comp, **kwargs)
 
assert bp.is_break() == func_list_ref_comp(l2)
 
 
# Test that changes to a reference are reflected in the breakpoint
 
l = [1, 2, "a"]
 
def func_list_comp(l):
 
return l == [1, 2, "a", "b"]
 
 
kwargs = {"l": l}
 
bp = LambdaBreakpoint(func_list_comp, **kwargs)
 
 
# The supplied list is not equal to the internal list of the
 
# supplied function => shoud not break
 
assert bp.is_break() == func_list_comp(l)
 
 
# The list is modified to be equal to the internal list of the function
 
# => should break
 
l.append("b")
 
assert bp.is_break() == func_list_comp(l)
 
 
 
# Test with reference to a more advanced data structure, e.g. a class
 
class Dummy:
 
def __init__(self):
 
self.value = None
 
 
def func_dummy_val(dummy, value):
 
return dummy.value == value
 
 
dummy = Dummy()
 
value = True
 
kwargs = {"dummy": dummy, "value": value}
 
bp = LambdaBreakpoint(func_dummy_val, **kwargs)
 
assert bp.is_break() == func_dummy_val(dummy, value)
 
 
# The supplied argument should be a reference, so changes to `dummy`
 
# should affect the break point
 
dummy.value = value
 
assert bp.is_break() == func_dummy_val(dummy, value)
 
assert bp.is_break() == (not func_dummy_val(dummy, not value))
 
Loading