fix testing infra

This commit is contained in:
Anton Lydike 2023-05-01 16:36:58 +01:00
parent dd77d1b387
commit e1fbe4f11d
9 changed files with 25 additions and 174 deletions

View File

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

View File

@ -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

View File

@ -1,7 +1,15 @@
from unittest import TestCase
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

View File

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

View File

@ -45,7 +45,7 @@ assert_ops = {
}
class TestIS(InstructionSet):
class Z_test(InstructionSet):
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!')
self.failed = False
@ -71,5 +71,3 @@ class TestIS(InstructionSet):
print(FMT_ERROR + '[TestCase] 🔴 reached fail instruction! {}'.format(ins))
self.cpu.halted = True
self.failed = True
def assert_mem(self, ins: Instruction):

View File

@ -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

View File

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

View File

@ -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