fix testing infra

master
Anton Lydike 2 years ago
parent dd77d1b387
commit e1fbe4f11d

@ -14,6 +14,8 @@ from .types.exceptions import *
def align_addr(addr: int, to_bytes: int = 8) -> int: def align_addr(addr: int, to_bytes: int = 8) -> int:
""" """
align an address to `to_bytes` (meaning addr & to_bytes = 0) align an address to `to_bytes` (meaning addr & to_bytes = 0)
This will increase the address
""" """
return addr + (-addr % to_bytes) return addr + (-addr % to_bytes)

@ -1,73 +0,0 @@
import contextlib
import os
from abc import abstractmethod
from tempfile import NamedTemporaryFile
from typing import Optional, Union, Tuple
from unittest import TestCase
from riscemu import CPU, UserModeCPU, InstructionSetDict, RunConfig
from riscemu.types import Program
class EndToEndTest(TestCase):
def __init__(self, cpu: Optional[CPU] = None):
super().__init__()
if cpu is None:
cpu = UserModeCPU(InstructionSetDict.values(), RunConfig())
self.cpu = cpu
@abstractmethod
def get_source(self) -> Tuple[str, Union[bytes, str, bytearray]]:
"""
This method returns the source code of the program
:return:
"""
pass
def test_run_program(self):
"""
Runs the program and verifies output
:return:
"""
with self.with_source_file() as names:
fname, orig_name = names
loader = self.cpu.get_best_loader_for(fname)
self.program = loader.instantiate(fname, loader.get_options([])).parse()
self._change_program_file_name(self.program, orig_name)
self.cpu.load_program(self.program)
self.after_program_load(self.program)
if isinstance(self.cpu, UserModeCPU):
self.cpu.setup_stack()
try:
self.cpu.launch(self.program)
except Exception as ex:
if self.is_exception_expected(ex):
pass
raise ex
@contextlib.contextmanager
def with_source_file(self):
name, content = self.get_source()
if isinstance(content, str):
f = NamedTemporaryFile('w', suffix=name, delete=False)
else:
f = NamedTemporaryFile('wb', suffix=name, delete=False)
f.write(content)
f.flush()
f.close()
try:
yield f.name, name
finally:
os.unlink(f.name)
def after_program_load(self, program):
pass
def is_exception_expected(self, ex: Exception) -> bool:
return False
def _change_program_file_name(self, program: Program, new_name: str):
program.name = new_name
for sec in program.sections:
sec.owner = new_name

@ -1,7 +1,15 @@
from unittest import TestCase
from riscemu.helpers import * from riscemu.helpers import *
def test_align_address():
assert align_addr(3, 1) == 3
assert align_addr(3, 2) == 4
assert align_addr(3, 4) == 4
assert align_addr(3, 8) == 8
assert align_addr(8, 8) == 8
class TestHelpers(TestCase):
pass def test_parse_numeric():
assert parse_numeric_argument('13') == 13
assert parse_numeric_argument('0x100') == 256
assert parse_numeric_argument('-13') == -13

@ -1,19 +1,15 @@
from unittest import TestCase
from riscemu.types import Int32, UInt32 from riscemu.types import Int32, UInt32
class TestTokenizer(TestCase): def test_logical_right_shift():
a = Int32(100)
def test_logical_right_shift(self): assert a.shift_right_logical(0) == a
a = Int32(100) assert a.shift_right_logical(10) == 0
self.assertEqual(a.shift_right_logical(0), a) assert a.shift_right_logical(1) == 100 >> 1
self.assertEqual(a.shift_right_logical(10), 0)
self.assertEqual(a.shift_right_logical(1), 100>>1)
a = Int32(-100) a = Int32(-100)
self.assertEqual(a.shift_right_logical(0), a) assert a.shift_right_logical(0) == a
self.assertEqual(a.shift_right_logical(1), 2147483598) assert a.shift_right_logical(1) == 2147483598
self.assertEqual(a.shift_right_logical(10), 4194303) assert a.shift_right_logical(10) == 4194303
self.assertEqual(a.shift_right_logical(31), 1) assert a.shift_right_logical(31) == 1
self.assertEqual(a.shift_right_logical(32), 0) assert a.shift_right_logical(32) == 0

@ -45,7 +45,7 @@ assert_ops = {
} }
class TestIS(InstructionSet): class Z_test(InstructionSet):
def __init__(self, cpu: 'CPU'): def __init__(self, cpu: 'CPU'):
print('[Test] loading testing ISA, this is only meant for running testcases and is not part of the RISC-V ISA!') print('[Test] loading testing ISA, this is only meant for running testcases and is not part of the RISC-V ISA!')
self.failed = False self.failed = False
@ -71,5 +71,3 @@ class TestIS(InstructionSet):
print(FMT_ERROR + '[TestCase] 🔴 reached fail instruction! {}'.format(ins)) print(FMT_ERROR + '[TestCase] 🔴 reached fail instruction! {}'.format(ins))
self.cpu.halted = True self.cpu.halted = True
self.failed = True self.failed = True
def assert_mem(self, ins: Instruction):

@ -1,53 +0,0 @@
from riscemu import AssemblyFileLoader
from riscemu.colors import *
FMT_SUCCESS = FMT_GREEN + FMT_BOLD
def run_test(path: str):
from riscemu import CPU, UserModeCPU, RunConfig
from riscemu.instructions import InstructionSetDict
from test.test_isa import TestIS
import os
fname = os.path.basename(path)
ISAs = list(InstructionSetDict.values())
ISAs.append(TestIS)
cpu = UserModeCPU(ISAs, RunConfig())
try:
program = AssemblyFileLoader(path, {}).parse()
cpu.load_program(program)
cpu.launch(program)
except Exception as ex:
print(FMT_ERROR + '[Test] 🔴 failed with exception "{}" ({})'.format(ex, fname) + FMT_NONE)
raise ex
if cpu.halted:
for isa in cpu.instruction_sets:
if isinstance(isa, TestIS):
if not isa.failed:
print(FMT_SUCCESS + '[Test] 🟢 successful {}'.format(fname) + FMT_NONE)
return not isa.failed
return False
if __name__ == '__main__':
import os
import glob
successes = 0
failures = 0
ttl = 0
for path in glob.glob(f'{os.path.dirname(__file__)}/*.asm'):
print(FMT_BLUE + '[Test] running testcase ' + os.path.basename(path) + FMT_NONE)
ttl += 1
if run_test(path):
successes += 1
else:
failures += 1

@ -1,7 +0,0 @@
.data
data:
.word 0xFFFFFFFF, 0x0000FFFF, 0xFF00FF00, 0x7FFFFFFF
.text
ebreak

@ -1,20 +0,0 @@
.text
main:
addi a0, zero, main
addi a1, zero, main
addi t0, zero, 1000
assert a0, ==, 0x100
1:
addi a1, a1, 1
blt a1, t0, 1b
sub a1, a1, a0
j 1f
addi a1, zero, 0
fail
1:
assert a1, ==, 744
add a0, zero, a1 ; set exit code to a1
addi a7, zero, SCALL_EXIT ; exit syscall code
scall
fail
Loading…
Cancel
Save