Browse Source

Add some tests that pass and test something.

pull/39/head
Tim Newsome 10 years ago
parent
commit
651ad043ce
  1. 2
      Makefile.in
  2. 6
      riscv/gdbserver.cc
  3. 27
      tests/debug.c
  4. 49
      tests/gdbserver-smoke.py
  5. 46
      tests/testlib.py

2
Makefile.in

@ -335,7 +335,7 @@ deps : $(deps)
bintest_outs = $(bintests:=.out)
junk += $(bintest_outs)
%.out: % all
./$^ < /dev/null 2>&1 | tee $@
./$* < /dev/null 2>&1 | tee $@
check-cpp : $(test_outs)
echo; grep -h -e'Unit Tests' -e'FAILED' -e'Segmentation' $^ < /dev/null; echo

6
riscv/gdbserver.cc

@ -529,7 +529,8 @@ void gdbserver_t::handle_breakpoint(const std::vector<uint8_t> &packet)
return send_packet("E53");
}
mmu_t* mmu = sim->debug_mmu;
processor_t *p = sim->get_core(0);
mmu_t* mmu = p->mmu;
if (insert) {
bp.insert(mmu);
breakpoints[bp.address] = bp;
@ -540,8 +541,7 @@ void gdbserver_t::handle_breakpoint(const std::vector<uint8_t> &packet)
breakpoints.erase(bp.address);
}
mmu->flush_icache();
processor_t *p = sim->get_core(0);
p->mmu->flush_icache();
sim->debug_mmu->flush_icache();
return send_packet("OK");
}

27
tests/debug.c

@ -0,0 +1,27 @@
#include <stdio.h>
char c = 'x';
void print_row(int length)
{
for (int x=0; x<length; x++) {
printf("%c", c);
}
printf("\n");
}
int main()
{
volatile int i = 42;
const char *text = "constant\n";
int threshold = 7;
// Wait for the debugger to get us out of this loop.
while (i)
;
printf("%s", text);
for (int y=0; y < 10; y++) {
print_row(y);
}
}

49
tests/gdbserver-smoke.py

@ -0,0 +1,49 @@
#!/usr/bin/python
import os
import testlib
import unittest
import tempfile
import time
class SmokeTest(unittest.TestCase):
def setUp(self):
self.tmpf = tempfile.NamedTemporaryFile()
testlib.compile("debug.c", self.tmpf.name)
self.spike = testlib.spike(self.tmpf.name, halted=False)
self.gdb = testlib.Gdb()
self.gdb.command("file %s" % self.tmpf.name)
self.gdb.command("target extended-remote localhost:9824")
self.gdb.command("p i");
self.gdb.command("p i=0");
def cleanUp(self):
self.spike.kill()
def test_turbostep(self):
"""Single step until the program exits. TODO"""
last_pc = None
for _ in range(100):
self.gdb.command("stepi")
pc = self.gdb.command("p $pc")
self.assertNotEqual(last_pc, pc)
last_pc = pc
def test_exit(self):
output = self.gdb.command("c")
self.assertIn("Continuing", output)
self.assertIn("Remote connection closed", output)
def test_breakpoint(self):
self.gdb.command("b print_row")
# The breakpoint should be hit exactly 10 times.
for _ in range(10):
output = self.gdb.command("c")
self.assertIn("Continuing", output)
self.assertIn("Breakpoint 1", output)
output = self.gdb.command("c")
self.assertIn("Continuing", output)
self.assertIn("Remote connection closed", output)
if __name__ == '__main__':
unittest.main()

46
tests/testlib.py

@ -0,0 +1,46 @@
import os.path
import pexpect
import subprocess
import tempfile
import testlib
import unittest
# Note that gdb comes with its own testsuite. I was unable to figure out how to
# run that testsuite against the spike simulator.
def find_file(path):
for directory in (os.getcwd(), os.path.dirname(testlib.__file__)):
fullpath = os.path.join(directory, path)
if os.path.exists(fullpath):
return fullpath
raise ValueError("Couldn't find %r." % path)
def compile(src, dst):
"""Compile a single .c file into a binary."""
cc = os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gcc")
return os.system("%s -g -o %s %s" % (cc, dst, find_file(src)))
def spike(binary, halted=False):
cmd = [find_file("spike")]
if halted:
cmd.append('-H')
cmd += ['pk', binary]
logfile = open("spike.log", "w")
return subprocess.Popen(cmd, stdout=logfile, stderr=logfile)
class Gdb(object):
def __init__(self):
path = os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gdb")
self.child = pexpect.spawn(path)
self.child.logfile = file("gdb.log", "w")
self.wait()
def wait(self):
"""Wait for prompt."""
self.child.expect("\(gdb\)")
def command(self, command):
self.child.sendline(command)
self.child.expect("\n")
self.child.expect("\(gdb\)")
return self.child.before.strip()
Loading…
Cancel
Save