def setup(self): """Init state.""" self.ram = RandomAccessMemory(WORD_SIZE, 256, 'big') self.registers = create_autospec(RegisterMemory, True, True) self.alu = create_autospec(ArithmeticLogicUnit, True, True) self.control_unit = ControlUnit(WORD_SIZE, BYTE_SIZE, self.registers, self.ram, self.alu, WORD_SIZE) self.test_const()
class TestControlUnit: """Test case for abstract bordachenkova control unit.""" ram = None registers = None alu = None control_unit = None arithmetic_opcodes = None condjump_opcodes = None ir_size = 32 operand_size = WORD_SIZE address_size = BYTE_SIZE def setup(self): """Init state.""" self.ram = RandomAccessMemory(WORD_SIZE, 256, 'big') self.registers = create_autospec(RegisterMemory, True, True) self.alu = create_autospec(ArithmeticLogicUnit, True, True) self.control_unit = ControlUnit(WORD_SIZE, BYTE_SIZE, self.registers, self.ram, self.alu, WORD_SIZE) self.test_const() def test_const(self): """Test internal constants.""" assert isinstance(self.control_unit, AbstractControlUnit) assert isinstance(self.control_unit, ControlUnit) assert self.control_unit.ir_size == self.ir_size assert self.control_unit.operand_size == self.operand_size assert self.control_unit.address_size == self.address_size assert self.control_unit.OPCODE_SIZE == BYTE_SIZE assert self.control_unit.OPCODES["move"] == OP_MOVE assert self.control_unit.OPCODES["load"] == OP_LOAD assert self.control_unit.OPCODES["store"] == OP_STORE assert self.control_unit.OPCODES["swap"] == OP_SWAP assert self.control_unit.OPCODES["add"] == OP_ADD assert self.control_unit.OPCODES["sub"] == OP_SUB assert self.control_unit.OPCODES["smul"] == OP_SMUL assert self.control_unit.OPCODES["sdivmod"] == OP_SDIVMOD assert self.control_unit.OPCODES["umul"] == OP_UMUL assert self.control_unit.OPCODES["udivmod"] == OP_UDIVMOD assert self.control_unit.OPCODES["comp"] == OP_COMP assert self.control_unit.OPCODES["stpush"] == OP_STPUSH assert self.control_unit.OPCODES["stpop"] == OP_STPOP assert self.control_unit.OPCODES["stdup"] == OP_STDUP assert self.control_unit.OPCODES["stswap"] == OP_STSWAP assert self.control_unit.OPCODES["jump"] == OP_JUMP assert self.control_unit.OPCODES["jeq"] == OP_JEQ assert self.control_unit.OPCODES["jneq"] == OP_JNEQ assert self.control_unit.OPCODES["sjl"] == OP_SJL assert self.control_unit.OPCODES["sjgeq"] == OP_SJGEQ assert self.control_unit.OPCODES["sjleq"] == OP_SJLEQ assert self.control_unit.OPCODES["sjg"] == OP_SJG assert self.control_unit.OPCODES["ujl"] == OP_UJL assert self.control_unit.OPCODES["ujgeq"] == OP_UJGEQ assert self.control_unit.OPCODES["ujleq"] == OP_UJLEQ assert self.control_unit.OPCODES["ujg"] == OP_UJG assert self.control_unit.OPCODES["halt"] == OP_HALT def test_fetch_and_decode(self): """Abstract class.""" with raises(NotImplementedError): self.control_unit.fetch_and_decode() def test_load(self): """Abstract class.""" with raises(NotImplementedError): self.control_unit.load() def test_write_back(self): """Abstract class.""" with raises(NotImplementedError): self.control_unit.write_back() def run_fetch(self, value, opcode, instruction_size, and_decode=True, address_size=BYTE_SIZE, ir_size=WORD_SIZE): """Run one fetch test.""" address = 10 self.ram.put(address, value, instruction_size) increment = instruction_size // self.ram.word_size self.registers.fetch.reset_mock() self.registers.put.reset_mock() def get_register(name, size): """Get PC.""" assert name == "PC" assert size == self.control_unit.address_size return address self.registers.fetch.side_effect = get_register if and_decode: self.control_unit.fetch_and_decode() else: self.control_unit.fetch_instruction(instruction_size) self.registers.fetch.assert_any_call("PC", address_size) self.registers.put.assert_has_calls([call("RI", value, ir_size), call("PC", address + increment, address_size)]) assert self.control_unit.opcode == opcode def test_fetch_instruction(self): """Right fetch and decode is a half of business.""" self.run_fetch(0x01020304, 0x01, WORD_SIZE, False) def test_basic_execute(self, should_move=True): """Test basic operations.""" self.registers.put.reset_mock() self.registers.fetch.reset_mock() if should_move is not None: self.control_unit.opcode = OP_MOVE self.alu.move.reset_mock() self.control_unit.execute() if should_move: self.alu.move.assert_called_once_with() else: assert not self.alu.move.called self.control_unit.opcode = OP_ADD self.alu.add.reset_mock() self.control_unit.execute() self.alu.add.assert_called_once_with() self.control_unit.opcode = OP_SUB self.alu.sub.reset_mock() self.control_unit.execute() self.alu.sub.assert_called_once_with() self.control_unit.opcode = OP_SMUL self.alu.smul.reset_mock() self.control_unit.execute() self.alu.smul.assert_called_once_with() self.control_unit.opcode = OP_UMUL self.alu.umul.reset_mock() self.control_unit.execute() self.alu.umul.assert_called_once_with() self.control_unit.opcode = OP_SDIVMOD self.alu.sdivmod.reset_mock() self.control_unit.execute() self.alu.sdivmod.assert_called_once_with() self.control_unit.opcode = OP_UDIVMOD self.alu.udivmod.reset_mock() self.control_unit.execute() self.alu.udivmod.assert_called_once_with() self.control_unit.opcode = OP_HALT self.alu.halt.reset_mock() self.control_unit.execute() self.alu.halt.assert_called_once_with() with raises(ValueError): self.control_unit.opcode = 0x98 self.control_unit.execute() assert not self.registers.fetch.called assert not self.registers.put.called