aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2019-11-22 11:38:02 -0800
committerGitHub <noreply@github.com>2019-11-22 11:38:02 -0800
commit053c956619ace234de7257f4503d921efd80074e (patch)
tree4b3c8ba48439697786a4082c11e73573fc0cde4e
parentc56451fc5ab672d2ec49663ff83d0dc51c61aa57 (diff)
downloadriscv-tests-053c956619ace234de7257f4503d921efd80074e.zip
riscv-tests-053c956619ace234de7257f4503d921efd80074e.tar.gz
riscv-tests-053c956619ace234de7257f4503d921efd80074e.tar.bz2
Move to Python 3. (#218)
The impetus for this was mostly that after my Ubuntu upgrade, pylint suddenly starting to apply python3 rules, and I suppose it's time to adopt python 3 now that it's been released for more than a decade.
-rwxr-xr-xdebug/gdbserver.py70
-rw-r--r--debug/pylint.rc3
-rw-r--r--debug/targets.py5
-rw-r--r--debug/testlib.py75
4 files changed, 78 insertions, 75 deletions
diff --git a/debug/gdbserver.py b/debug/gdbserver.py
index 84d3f1d..c34e341 100755
--- a/debug/gdbserver.py
+++ b/debug/gdbserver.py
@@ -1,8 +1,9 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import argparse
import binascii
import random
+import struct
import sys
import tempfile
import time
@@ -11,7 +12,7 @@ import os
import targets
import testlib
from testlib import assertEqual, assertNotEqual, assertIn, assertNotIn
-from testlib import assertGreater, assertRegexpMatches, assertLess
+from testlib import assertGreater, assertRegex, assertLess
from testlib import GdbTest, GdbSingleHartTest, TestFailed
from testlib import assertTrue, TestNotApplicable
@@ -52,14 +53,14 @@ def ihex_line(address, record_type, data):
return line
def srec_parse(line):
- assert line.startswith('S')
+ assert line.startswith(b'S')
typ = line[:2]
count = int(line[2:4], 16)
data = ""
- if typ == 'S0':
+ if typ == b'S0':
# header
return 0, 0, 0
- elif typ == 'S3':
+ elif typ == b'S3':
# data with 32-bit address
# Any higher bits were chopped off.
address = int(line[4:12], 16)
@@ -67,7 +68,7 @@ def srec_parse(line):
data += "%c" % int(line[2*i:2*i+2], 16)
# Ignore the checksum.
return 3, address, data
- elif typ == 'S7':
+ elif typ == b'S7':
# ignore execution start field
return 7, 0, 0
else:
@@ -142,9 +143,9 @@ class SimpleF18Test(SimpleRegisterTest):
assertEqual(size, 4)
else:
output = self.gdb.p_raw("$" + name)
- assertRegexpMatches(output, r"void|Could not fetch register.*")
+ assertRegex(output, r"void|Could not fetch register.*")
output = self.gdb.p_raw("$" + alias)
- assertRegexpMatches(output, r"void|Could not fetch register.*")
+ assertRegex(output, r"void|Could not fetch register.*")
def test(self):
self.check_reg("f18", "fs2")
@@ -154,7 +155,7 @@ class CustomRegisterTest(SimpleRegisterTest):
return self.target.implements_custom_test
def check_custom(self, magic):
- regs = {k: v for k, v in self.gdb.info_registers("all").iteritems()
+ regs = {k: v for k, v in self.gdb.info_registers("all").items()
if k.startswith("custom")}
assertEqual(set(regs.keys()),
set(("custom1",
@@ -162,7 +163,7 @@ class CustomRegisterTest(SimpleRegisterTest):
"custom12346",
"custom12347",
"custom12348")))
- for name, value in regs.iteritems():
+ for name, value in regs.items():
number = int(name[6:])
if number % 2:
expect = number + magic
@@ -305,11 +306,12 @@ class MemTestBlock(GdbTest):
def write(self, temporary_file):
data = ""
- for i in range(self.length / self.line_length):
+ for i in range(self.length // self.line_length):
line_data = "".join(["%c" % random.randrange(256)
for _ in range(self.line_length)])
data += line_data
- temporary_file.write(ihex_line(i * self.line_length, 0, line_data))
+ temporary_file.write(ihex_line(i * self.line_length, 0,
+ line_data).encode())
temporary_file.flush()
return data
@@ -321,7 +323,7 @@ class MemTestBlock(GdbTest):
self.gdb.command("monitor riscv reset_delays 50")
self.gdb.command("restore %s 0x%x" % (a.name, self.hart.ram))
increment = 19 * 4
- for offset in range(0, self.length, increment) + [self.length-4]:
+ for offset in list(range(0, self.length, increment)) + [self.length-4]:
value = self.gdb.p("*((int*)0x%x)" % (self.hart.ram + offset))
written = ord(data[offset]) | \
(ord(data[offset+1]) << 8) | \
@@ -335,7 +337,7 @@ class MemTestBlock(GdbTest):
self.hart.ram, self.hart.ram + self.length), ops=self.length / 32)
self.gdb.command("shell cat %s" % b.name)
highest_seen = 0
- for line in b.xreadlines():
+ for line in b:
record_type, address, line_data = srec_parse(line)
if record_type == 3:
offset = address - (self.hart.ram & 0xffffffff)
@@ -551,7 +553,7 @@ class Hwbp1(DebugTest):
for _ in range(2):
output = self.gdb.c()
self.gdb.p("$pc")
- assertRegexpMatches(output, r"[bB]reakpoint")
+ assertRegex(output, r"[bB]reakpoint")
assertIn("rot13 ", output)
self.gdb.b("_exit")
self.exit()
@@ -568,7 +570,7 @@ class Hwbp2(DebugTest):
for expected in ("main", "rot13", "rot13"):
output = self.gdb.c()
self.gdb.p("$pc")
- assertRegexpMatches(output, r"[bB]reakpoint")
+ assertRegex(output, r"[bB]reakpoint")
assertIn("%s " % expected, output)
self.gdb.command("delete")
self.gdb.b("_exit")
@@ -598,14 +600,14 @@ class Registers(DebugTest):
for reg in ('zero', 'ra', 'sp', 'gp', 'tp'):
assertIn(reg, output)
for line in output.splitlines():
- assertRegexpMatches(line, r"^\S")
+ assertRegex(line, r"^\S")
#TODO
# mcpuid is one of the few registers that should have the high bit set
# (for rv64).
# Leave this commented out until gdb and spike agree on the encoding of
# mcpuid (which is going to be renamed to misa in any case).
- #assertRegexpMatches(output, ".*mcpuid *0x80")
+ #assertRegex(output, ".*mcpuid *0x80")
#TODO:
# The instret register should always be changing.
@@ -884,9 +886,9 @@ class SmpSimultaneousRunHalt(GdbTest):
old_mtime.update(mtime_value)
mtime_spread = max(mtime_value) - min(mtime_value)
- print "mtime_spread:", mtime_spread
+ print("mtime_spread:", mtime_spread)
counter_spread = max(counter) - min(counter)
- print "counter_spread:", counter_spread
+ print("counter_spread:", counter_spread)
assertLess(mtime_spread, 101 * (len(self.target.harts) - 1),
"Harts don't halt around the same time.")
@@ -935,9 +937,9 @@ class JumpHbreak(GdbSingleHartTest):
self.gdb.b("read_loop")
self.gdb.command("hbreak just_before_read_loop")
output = self.gdb.command("jump just_before_read_loop")
- assertRegexpMatches(output, r"Breakpoint \d, just_before_read_loop ")
+ assertRegex(output, r"Breakpoint \d, just_before_read_loop ")
output = self.gdb.c()
- assertRegexpMatches(output, r"Breakpoint \d, read_loop ")
+ assertRegex(output, r"Breakpoint \d, read_loop ")
class TriggerTest(GdbSingleHartTest):
compile_args = ("programs/trigger.S", )
@@ -1131,24 +1133,24 @@ class DownloadTest(GdbTest):
length = min(2**14, max(2**10, self.hart.ram_size - 2048))
self.download_c = tempfile.NamedTemporaryFile(prefix="download_",
suffix=".c", delete=False)
- self.download_c.write("#include <stdint.h>\n")
+ self.download_c.write(b"#include <stdint.h>\n")
self.download_c.write(
- "unsigned int crc32a(uint8_t *message, unsigned int size);\n")
- self.download_c.write("uint32_t length = %d;\n" % length)
- self.download_c.write("uint8_t d[%d] = {\n" % length)
+ b"unsigned int crc32a(uint8_t *message, unsigned int size);\n")
+ self.download_c.write(b"uint32_t length = %d;\n" % length)
+ self.download_c.write(b"uint8_t d[%d] = {\n" % length)
self.crc = 0
assert length % 16 == 0
- for i in range(length / 16):
- self.download_c.write(" /* 0x%04x */ " % (i * 16))
+ for i in range(length // 16):
+ self.download_c.write((" /* 0x%04x */ " % (i * 16)).encode())
for _ in range(16):
value = random.randrange(1<<8)
- self.download_c.write("0x%02x, " % value)
- self.crc = binascii.crc32("%c" % value, self.crc)
- self.download_c.write("\n")
- self.download_c.write("};\n")
- self.download_c.write("uint8_t *data = &d[0];\n")
+ self.download_c.write(("0x%02x, " % value).encode())
+ self.crc = binascii.crc32(struct.pack("B", value), self.crc)
+ self.download_c.write(b"\n")
+ self.download_c.write(b"};\n")
+ self.download_c.write(b"uint8_t *data = &d[0];\n")
self.download_c.write(
- "uint32_t main() { return crc32a(data, length); }\n")
+ b"uint32_t main() { return crc32a(data, length); }\n")
self.download_c.flush()
if self.crc < 0:
diff --git a/debug/pylint.rc b/debug/pylint.rc
index 0d9a640..cf07149 100644
--- a/debug/pylint.rc
+++ b/debug/pylint.rc
@@ -48,7 +48,8 @@ extension-pkg-whitelist=
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=bad-continuation, missing-docstring, invalid-name, locally-disabled,
- too-few-public-methods, too-many-arguments, fixme, duplicate-code
+ too-few-public-methods, too-many-arguments, fixme, duplicate-code,
+ no-else-return
[REPORTS]
diff --git a/debug/targets.py b/debug/targets.py
index d83e84b..d797f64 100644
--- a/debug/targets.py
+++ b/debug/targets.py
@@ -5,7 +5,7 @@ import tempfile
import testlib
-class Hart(object):
+class Hart:
# XLEN of the hart. May be overridden with --32 or --64 command line
# options.
xlen = 0
@@ -45,7 +45,7 @@ class Hart(object):
return self.misa & (1 << (ord(letter.upper()) - ord('A')))
return False
-class Target(object):
+class Target:
# pylint: disable=too-many-instance-attributes
# List of Hart object instances, one for each hart in the target.
@@ -117,7 +117,6 @@ class Target(object):
def create(self):
"""Create the target out of thin air, eg. start a simulator."""
- pass
def server(self):
"""Start the debug server that gdb connects to, eg. OpenOCD."""
diff --git a/debug/testlib.py b/debug/testlib.py
index 60cb897..1aa0e5b 100644
--- a/debug/testlib.py
+++ b/debug/testlib.py
@@ -38,17 +38,17 @@ def compile(args): # pylint: disable=redefined-builtin
else:
cmd.append(arg)
header("Compile")
- print "+", " ".join(cmd)
+ print("+", " ".join(cmd))
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
if process.returncode:
- print stdout,
- print stderr,
+ print(stdout, end=" ")
+ print(stderr, end=" ")
header("")
raise Exception("Compile failed!")
-class Spike(object):
+class Spike:
# pylint: disable=too-many-instance-attributes
# pylint: disable=too-many-locals
def __init__(self, target, halted=False, timeout=None, with_jtag_gdb=True,
@@ -81,7 +81,7 @@ class Spike(object):
self.logname = self.logfile.name
if print_log_names:
real_stdout.write("Temporary spike log: %s\n" % self.logname)
- self.logfile.write("+ %s\n" % " ".join(cmd))
+ self.logfile.write(("+ %s\n" % " ".join(cmd)).encode())
self.logfile.flush()
self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=self.logfile, stderr=self.logfile)
@@ -170,7 +170,7 @@ class Spike(object):
def wait(self, *args, **kwargs):
return self.process.wait(*args, **kwargs)
-class VcsSim(object):
+class VcsSim:
logfile = tempfile.NamedTemporaryFile(prefix='simv', suffix='.log')
logname = logfile.name
@@ -223,7 +223,7 @@ class VcsSim(object):
except OSError:
pass
-class Openocd(object):
+class Openocd:
logfile = tempfile.NamedTemporaryFile(prefix='openocd', suffix='.log')
logname = logfile.name
@@ -255,7 +255,7 @@ class Openocd(object):
if config:
self.config_file = find_file(config)
if self.config_file is None:
- print "Unable to read file " + config
+ print("Unable to read file", config)
exit(1)
cmd += ["-f", self.config_file]
@@ -306,7 +306,7 @@ class Openocd(object):
if not messaged and time.time() - start > 1:
messaged = True
- print "Waiting for OpenOCD to start..."
+ print("Waiting for OpenOCD to start...")
if (time.time() - start) > self.timeout:
raise Exception("Timed out waiting for OpenOCD to "
"listen for gdb")
@@ -330,12 +330,12 @@ class Openocd(object):
def smp(self):
"""Return true iff OpenOCD internally sees the harts as part of an SMP
group."""
- for line in file(self.config_file, "r"):
+ for line in open(self.config_file, "r"):
if "target smp" in line:
return True
return False
-class OpenocdCli(object):
+class OpenocdCli:
def __init__(self, port=4444):
self.child = pexpect.spawn(
"sh -c 'telnet localhost %d | tee openocd-cli.log'" % port)
@@ -346,7 +346,7 @@ class OpenocdCli(object):
self.child.expect(cmd)
self.child.expect("\n")
self.child.expect("> ")
- return self.child.before.strip("\t\r\n \0")
+ return self.child.before.strip("\t\r\n \0").decode("utf-8")
def reg(self, reg=''):
output = self.command("reg %s" % reg)
@@ -383,7 +383,7 @@ def parse_rhs(text):
if all([isinstance(p, dict) for p in parsed]):
dictionary = {}
for p in parsed:
- for k, v in p.iteritems():
+ for k, v in p.items():
dictionary[k] = v
parsed = dictionary
return parsed
@@ -394,12 +394,12 @@ def parse_rhs(text):
return {lhs: parse_rhs(rhs)}
elif re.match(r"-?(\d+\.\d+(e-?\d+)?|inf)", text):
return float(text)
- elif re.match(r"-nan\(0x[a-f0-9]+\)", text):
+ elif re.match(r"-?nan\(0x[a-f0-9]+\)", text):
return float("nan")
else:
return int(text, 0)
-class Gdb(object):
+class Gdb:
"""A single gdb class which can interact with one or more gdb instances."""
# pylint: disable=too-many-public-methods
@@ -428,7 +428,7 @@ class Gdb(object):
real_stdout.write("Temporary gdb log: %s\n" % logfile.name)
child = pexpect.spawn(cmd)
child.logfile = logfile
- child.logfile.write("+ %s\n" % cmd)
+ child.logfile.write(("+ %s\n" % cmd).encode())
self.children.append(child)
self.active_child = self.children[0]
@@ -468,7 +468,7 @@ class Gdb(object):
del child
def one_hart_per_gdb(self):
- return all(h['solo'] for h in self.harts.itervalues())
+ return all(h['solo'] for h in self.harts.values())
def lognames(self):
return [logfile.name for logfile in self.logfiles]
@@ -504,7 +504,7 @@ class Gdb(object):
self.active_child.sendline(command)
self.active_child.expect("\n", timeout=timeout)
self.active_child.expect(r"\(gdb\)", timeout=timeout)
- return self.active_child.before.strip()
+ return self.active_child.before.strip().decode("utf-8")
def global_command(self, command):
"""Execute this command on every gdb that we control."""
@@ -559,7 +559,7 @@ class Gdb(object):
def interrupt(self, ops=1):
self.active_child.send("\003")
self.active_child.expect(r"\(gdb\)", timeout=self.timeout * ops)
- return self.active_child.before.strip()
+ return self.active_child.before.strip().decode()
def interrupt_all(self):
for child in self.children:
@@ -678,7 +678,7 @@ class Gdb(object):
def where(self):
return self.command("where 1")
-class PrivateState(object):
+class PrivateState:
def __init__(self, gdb):
self.gdb = gdb
@@ -706,9 +706,9 @@ def run_all_tests(module, target, parsed):
for hart in target.harts:
if parsed.misaval:
hart.misa = int(parsed.misaval, 16)
- print "Using $misa from command line: 0x%x" % hart.misa
+ print("Using $misa from command line: 0x%x" % hart.misa)
elif hart.misa:
- print "Using $misa from hart definition: 0x%x" % hart.misa
+ print("Using $misa from hart definition: 0x%x" % hart.misa)
elif not examine_added:
todo.append(("ExamineTarget", ExamineTarget, None))
examine_added = True
@@ -735,7 +735,7 @@ def run_tests(parsed, target, todo):
log_name = os.path.join(parsed.logs, "%s-%s-%s.log" %
(time.strftime("%Y%m%d-%H%M%S"), type(target).__name__, name))
log_fd = open(log_name, 'w')
- print "[%s] Starting > %s" % (name, log_name)
+ print("[%s] Starting > %s" % (name, log_name))
instance = definition(target, hart)
sys.stdout.flush()
log_fd.write("Test: %s\n" % name)
@@ -754,7 +754,7 @@ def run_tests(parsed, target, todo):
sys.stdout = real_stdout
log_fd.write("Time elapsed: %.2fs\n" % (time.time() - start))
log_fd.flush()
- print "[%s] %s in %.2fs" % (name, result, time.time() - start)
+ print("[%s] %s in %.2fs" % (name, result, time.time() - start))
if result not in good_results and parsed.print_failures:
sys.stdout.write(open(log_name).read())
sys.stdout.flush()
@@ -767,12 +767,12 @@ def run_tests(parsed, target, todo):
def print_results(results):
result = 0
- for key, value in results.iteritems():
- print "%d tests returned %s" % (len(value), key)
+ for key, value in results.items():
+ print("%d tests returned %s" % (len(value), key))
if key not in good_results:
result = 1
for name, log_name in value:
- print " %s > %s" % (name, log_name)
+ print(" %s > %s" % (name, log_name))
return result
@@ -797,22 +797,22 @@ def add_test_run_options(parser):
def header(title, dash='-', length=78):
if title:
dashes = dash * (length - 4 - len(title))
- before = dashes[:len(dashes)/2]
- after = dashes[len(dashes)/2:]
- print "%s[ %s ]%s" % (before, title, after)
+ before = dashes[:len(dashes)//2]
+ after = dashes[len(dashes)//2:]
+ print("%s[ %s ]%s" % (before, title, after))
else:
- print dash * length
+ print(dash * length)
def print_log_handle(name, handle):
header(name)
for l in handle:
sys.stdout.write(l)
- print
+ print()
def print_log(path):
print_log_handle(path, open(path, "r"))
-class BaseTest(object):
+class BaseTest:
compiled = {}
def __init__(self, target, hart=None):
@@ -893,15 +893,16 @@ class BaseTest(object):
else:
result = "exception"
if isinstance(e, TestFailed):
+ # pylint: disable=no-member
header("Message")
- print e.message
+ print(e.message)
header("Traceback")
traceback.print_exc(file=sys.stdout)
try:
self.postMortem()
except Exception as e: # pylint: disable=broad-except
header("postMortem Exception")
- print e
+ print(e)
traceback.print_exc(file=sys.stdout)
return result
@@ -1007,7 +1008,7 @@ class ExamineTarget(GdbTest):
for i in range(26):
if hart.misa & (1<<i):
txt += chr(i + ord('A'))
- print txt,
+ print(txt, end=" ")
class TestFailed(Exception):
def __init__(self, message, comment=None):
@@ -1049,6 +1050,6 @@ def assertTrue(a):
if not a:
raise TestFailed("%r is not True" % a)
-def assertRegexpMatches(text, regexp):
+def assertRegex(text, regexp):
if not re.search(regexp, text):
raise TestFailed("can't find %r in %r" % (regexp, text))