예제 #1
0
    def test_reset(self):
        """
        Tests for CPU reset
        """
        e = ElfCPU()
        e.load_string('1,0,0,0,99')
        e.execute()
        e.reset()

        # Halted gets cleared
        self.assertFalse(e.is_halted)
        # Program counter goes to 0
        self.assertEqual(e.pc, 0)
        # Memory gets wiped so address 1 becomes invalid
        with self.assertRaises(ValueError):
            e.peek(1)
예제 #2
0
 def test_halt(self):
     """
     Tests for the halt op code
     """
     e = ElfCPU()
     e.load_string('1,0,0,0,99')
     e.step()
     self.assertFalse(e.is_halted)
     e.step()
     self.assertTrue(e.is_halted)
예제 #3
0
    def test_op_input(self):
        """
        Tests input op code

        Use unittest.mock.patch to fake the input value
        """
        e = ElfCPU()
        e.load_string('3,3,99,-1')
        with patch('builtins.input', return_value='1234'):
            e.execute()
            self.assertEqual(e.peek(3), 1234)
예제 #4
0
 def test_invalid_instr(self):
     """
     Tests for invalid op code
     """
     e = ElfCPU()
     e.load_string('123456789')
     with self.assertRaises(InvalidInstructionError):
         e.execute()
예제 #5
0
 def test_gpf(self):
     """
     Tests for a general protection fault by allowing the program counter to
     go past the end of the memory
     """
     e = ElfCPU()
     e.load_string('1,0,0,0')
     with self.assertRaises(ProtectionFaultError):
         e.execute()
예제 #6
0
 def test_load_string_types(self):
     """
     Checks for TypeError
     """
     e = ElfCPU()
     with self.assertRaises(TypeError):
         # noinspection PyTypeChecker
         e.load_string(0)
     e.load_string('1,2,3,4')
예제 #7
0
    def test_op_output(self):
        """
        Tests output op code

        Use io.StringIO() to capture the output
        """
        e = ElfCPU()
        e.load_string('4,5,104,66,99,55')

        result = None
        with patch('sys.stdout', new=io.StringIO()) as output:
            e.execute()
            result = output.getvalue()
        result = result.splitlines()

        # First is a reference to memory address 5
        self.assertEqual(result[0].strip(), '55')
        # Second is an immediate value
        self.assertEqual(result[1].strip(), '66')
예제 #8
0
    def test_op_add(self):
        """
        Tests ADD op code
        [dst]:=[a]+[b]
        """
        e = ElfCPU()
        # Invalid address 44 for a
        e.load_string('1,44,0,0')
        with self.assertRaises(ProtectionFaultError):
            e.step()

        # Invalid address 44 for b
        e.load_string('1,0,44,0')
        with self.assertRaises(ProtectionFaultError):
            e.step()

        # Invalid address 44 for dst
        e.load_string('1,0,0,44')
        with self.assertRaises(ProtectionFaultError):
            e.step()

        # 1 + 1 = 2 @ address 0
        e.load_string('1,0,0,0,99')
        e.step()
        self.assertEqual(e.peek(0), 2)

        # 2**64 + 1 = 1 @ address 0 (overflow and wrap)
        e.load_string('1,5,6,0,99,' + str(2**64) + ',1')
        e.step()
        self.assertEqual(e.peek(0), 1)
예제 #9
0
    def test_poke(self):
        """
        Tests address range and data for poke
        """
        e = ElfCPU()
        e.load_string('0,1,2,3,4,5,6,7,8,9')

        # Address
        with self.assertRaises(TypeError):
            # noinspection PyTypeChecker
            e.poke('x', 2)
        with self.assertRaises(ValueError):
            e.poke(20, 2)
        with self.assertRaises(ValueError):
            e.poke(-1, 2)

        # Value
        with self.assertRaises(ValueError):
            e.poke(0, 2**64 + 1)

        self.assertEqual(e.poke(0, 99), 99)
        self.assertEqual(e.poke(9, 88), 88)
        self.assertEqual(e.peek(0), 99)
        self.assertEqual(e.peek(9), 88)
예제 #10
0
    def test_peek(self):
        """
        Tests address range for peek
        """
        e = ElfCPU()
        e.load_string('0,1,2,3,4,5,6,7,8,9')
        with self.assertRaises(TypeError):
            # noinspection PyTypeChecker
            e.peek('x')
        with self.assertRaises(ValueError):
            e.peek(20)
        with self.assertRaises(ValueError):
            e.peek(-1)

        self.assertEqual(e.peek(0), 0)
        self.assertEqual(e.peek(9), 9)
예제 #11
0
    def test_op_eq(self):
        """
        Tests equals op code
        """

        e = ElfCPU()
        """
        Tests if value of address 5 (10) is equal to value
        of address 6 (10).  Since this is true, write 1 to
        address 7.
        """
        e.load_string('8,5,6,7,99,10,10,-1')
        e.execute()
        self.assertEqual(e.peek(7), 1)
        """
        Tests if value of address 5 (10) is equal to value
        of address 6 (0).  Since this is false, write 0 to
        address 7.
        """
        e.load_string('8,5,6,7,99,10,0,-1')
        e.execute()
        self.assertEqual(e.peek(7), 0)
        """
        Tests if immediate value 10 is equal to immediate value
        10.  Since this is true, write 1 to address 7.
        """
        e.load_string('1108,10,10,7,99,2,3,-1')
        e.execute()
        self.assertEqual(e.peek(7), 1)
        """
        Tests if immediate value of 0 is equal to immediate value
        10.  Since this is false, write 0 to address 7.
        """
        e.load_string('1108,0,10,7,99,2,3,-1')
        e.execute()
        self.assertEqual(e.peek(7), 0)
예제 #12
0
 def test_op_cmp_lessthan(self):
     """
     Tests compare less than op code
     """
     e = ElfCPU()
     """
     Tests if value of address 5 (5) is less than value of
     address 6 (10).  Since this is true write 1 to address 7.
     """
     e.load_string('7,5,6,7,99,5,10,-1')
     e.execute()
     self.assertEqual(e.peek(7), 1)
     """
     Tests if value of address 5 (10) is less than value of
     address 6 (5).  Since this is false write 0 to address 7.
     """
     e.load_string('7,5,6,7,99,10,5,-1')
     e.execute()
     self.assertEqual(e.peek(7), 0)
     """
     Tests if immediate value of 5 is less than immediate value of
     10.  Since this is true write 1 to address 7.
     """
     e.load_string('1107,5,10,7,99,0,0,-1')
     e.execute()
     self.assertEqual(e.peek(7), 1)
     """
     Tests if immediate value of 10 is less than immediate value of
     5.  Since this is false write 0 to address 7.
     """
     e.load_string('1107,10,5,7,99,0,0,-1')
     e.execute()
     self.assertEqual(e.peek(7), 0)
예제 #13
0
    def test_op_jmp_true(self):
        """
        Tests jump if true op code
        """

        e = ElfCPU()
        """
        Tests address 8 (which is 1) if it is non-zero.  Since this is
        true, it jumps to the value of address 9 (which is 7).  This
        terminates the program.
        """
        e.load_string('5,8,9,1101,1,1,8,99,1,7')
        e.execute()
        self.assertEqual(e.peek(8), 1)
        """
        Tests immediate value 8 if it is non-zero.  Since it is
        true, jump to immediate address 7 which terminates.
        """
        e.load_string('1105,8,7,1101,1,1,8,99,1,7')
        e.execute()
        self.assertEqual(e.peek(8), 1)
        """
        Tests address 8 (which is 0) if it is non-zero.  Since this is
        false it does not jump and instead adds 1+1 to address 8.
        """
        e.load_string('5,8,9999,1101,1,1,8,99,0,7')
        e.execute()
        self.assertEqual(e.peek(8), 2)
        """
        Tests immediate value 0 if it is non-zero.  Since it is
        false it does not jump and instead adds 1+1 to address 8. 
        """
        e.load_string('1105,0,9999,1101,1,1,8,99,0,7')
        e.execute()
        self.assertEqual(e.peek(8), 2)
예제 #14
0
    def test_op_mul(self):
        """
        Tests MUL op code
        [dst]:=[a]*[b]
        """
        e = ElfCPU()
        # Invalid address 44 for a
        e.load_string('2,44,0,0')
        with self.assertRaises(ProtectionFaultError):
            e.step()

        # Invalid address 44 for b
        e.load_string('2,0,44,0')
        with self.assertRaises(ProtectionFaultError):
            e.step()

        # Invalid address 44 for dst
        e.load_string('2,0,0,44')
        with self.assertRaises(ProtectionFaultError):
            e.step()

        # 2 * 2 = 4 @ address 0
        e.load_string('2,0,0,0,99')
        e.step()
        self.assertEqual(e.peek(0), 4)

        # 2**63 * 3 = 9223372036854775808 @ address 0 (overflow and wrap)
        e.load_string('2,5,6,0,99,' + str(2**63) + ',3')
        e.step()
        self.assertEqual(e.peek(0), 9223372036854775808)