aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2022-06-23 08:08:19 -0700
committerGitHub <noreply@github.com>2022-06-23 08:08:19 -0700
commitfc38747b2dba58c7c80edd99e965c57a373cf294 (patch)
tree2df4215b16c6485dcdd1e2165d1de6674c9d5600
parent8567faa64561f504c1e9a70ffec74ac1a9f2091b (diff)
downloadriscv-tests-fc38747b2dba58c7c80edd99e965c57a373cf294.zip
riscv-tests-fc38747b2dba58c7c80edd99e965c57a373cf294.tar.gz
riscv-tests-fc38747b2dba58c7c80edd99e965c57a373cf294.tar.bz2
Another pylint upgrade. (#398)
* Another pylint upgrade. Lots of format string changes, which are more readable. More files to come... * Satisfy pylint for two more files.
-rwxr-xr-xdebug/rbb_daisychain.py10
-rw-r--r--debug/targets.py41
-rw-r--r--debug/testlib.py313
3 files changed, 191 insertions, 173 deletions
diff --git a/debug/rbb_daisychain.py b/debug/rbb_daisychain.py
index b7c21e6..4d9ea8a 100755
--- a/debug/rbb_daisychain.py
+++ b/debug/rbb_daisychain.py
@@ -56,8 +56,8 @@ class Chain:
assert len(values) == 0
values = list(tap.execute(bytes(tmp_commands)))
if self.debug:
- sys.stdout.write(" %d %r -> %r\n" % (i, bytes(tmp_commands),
- bytes(values)))
+ sys.stdout.write(f" {i} {bytes(tmp_commands)!r} -> "
+ f"{bytes(values)!r}\n")
return bytes(values)
def main():
@@ -80,7 +80,7 @@ def main():
for port in args.tap_port:
chain.append(Tap(port))
- sys.stdout.write("Listening on port %d.\n" % server.getsockname()[1])
+ sys.stdout.write(f"Listening on port {server.getsockname()[1]}.\n")
sys.stdout.flush()
while True:
@@ -98,10 +98,10 @@ def main():
break
if args.debug:
- sys.stdout.write("%r\n" % commands)
+ sys.stdout.write(f"{commands!r}\n")
result = chain.execute(commands)
if args.debug:
- sys.stdout.write(" -> %r\n" % result)
+ sys.stdout.write(f" -> {result!r}\n")
client.send(result)
client.close()
diff --git a/debug/targets.py b/debug/targets.py
index 727a882..504a550 100644
--- a/debug/targets.py
+++ b/debug/targets.py
@@ -143,7 +143,7 @@ class Target:
self.name = type(self).__name__
# Default OpenOCD config file to <name>.cfg
if not self.openocd_config_path:
- self.openocd_config_path = "%s.cfg" % self.name
+ self.openocd_config_path = f"{self.name}.cfg"
self.openocd_config_path = os.path.join(self.directory,
self.openocd_config_path)
for i, hart in enumerate(self.harts):
@@ -151,10 +151,10 @@ class Target:
if not hasattr(hart, 'id'):
hart.id = i
if not hart.name:
- hart.name = "%s-%d" % (self.name, i)
+ hart.name = f"{self.name}-{i}"
# Default link script to <name>.lds
if not hart.link_script_path:
- hart.link_script_path = "%s.lds" % self.name
+ hart.link_script_path = f"{self.name}.lds"
hart.link_script_path = os.path.join(self.directory,
hart.link_script_path)
@@ -169,11 +169,12 @@ class Target:
freertos=test.freertos())
def do_compile(self, hart, *sources):
- binary_name = "%s_%s-%x" % (
- self.name,
- os.path.basename(os.path.splitext(sources[0])[0]),
- hart.misa)
+ binary_name = (
+ self.name + "_" +
+ os.path.basename(os.path.splitext(sources[0])[0]) + "-" +
+ f"{hart.misa:x}")
if Target.isolate:
+ # pylint: disable-next=consider-using-with
self.temporary_binary = tempfile.NamedTemporaryFile(
prefix=binary_name + "_")
binary_name = self.temporary_binary.name
@@ -181,12 +182,12 @@ class Target:
args = list(sources) + [
"programs/entry.S", "programs/init.c",
- "-DNHARTS=%d" % len(self.harts),
+ f"-DNHARTS={len(self.harts)}",
"-I", "../env",
"-T", hart.link_script_path,
"-nostartfiles",
"-mcmodel=medany",
- "-DXLEN=%d" % hart.xlen,
+ f"-DXLEN={hart.xlen}",
"-o", binary_name]
if hart.extensionSupported('e'):
@@ -194,17 +195,17 @@ class Target:
args.append("-mabi=ilp32e")
args.append("-DRV32E")
else:
- march = "rv%dima" % hart.xlen
+ march = f"rv{hart.xlen}ima"
for letter in "fdc":
if hart.extensionSupported(letter):
march += letter
if hart.extensionSupported("v") and self.compiler_supports_v:
march += "v"
- args.append("-march=%s" % march)
+ args.append(f"-march={march}")
if hart.xlen == 32:
args.append("-mabi=ilp32")
else:
- args.append("-mabi=lp%d" % hart.xlen)
+ args.append(f"-mabi=lp{hart.xlen}")
testlib.compile(args)
return binary_name
@@ -221,8 +222,8 @@ class Target:
r"ISA extension `(\w)'", e.stderr.decode())
if m and m.group(1) in "v":
extension = m.group(1)
- print("Disabling extension %r because the "
- "compiler doesn't support it." % extension)
+ print(f"Disabling extension {extension!r} because the "
+ "compiler doesn't support it.")
self.compiler_supports_v = False
else:
raise
@@ -260,18 +261,18 @@ def target(parsed):
definition = getattr(module, name)
if isinstance(definition, type) and issubclass(definition, Target):
found.append(definition)
- assert len(found) == 1, "%s does not define exactly one subclass of " \
- "targets.Target" % parsed.target
+ assert len(found) == 1, (f"{parsed.target} does not define exactly one "
+ "subclass of targets.Target")
t = found[0](parsed.target, parsed)
- assert t.harts, "%s doesn't have any harts defined!" % t.name
+ assert t.harts, f"{t.name} doesn't have any harts defined!"
if parsed.xlen > 0:
for h in t.harts:
if h.xlen == 0:
h.xlen = parsed.xlen
elif h.xlen != parsed.xlen:
- raise Exception("The target hart specified an XLEN of %d, but "\
- "the command line specified an XLEN of %d. They must "\
- "match." % (h.xlen, parsed.xlen))
+ raise Exception("The target hart specified an XLEN of "
+ f"{h.xlen}, but the command line specified an XLEN of "
+ f"{parsed.xlen}. They must match.")
return t
diff --git a/debug/testlib.py b/debug/testlib.py
index 6b4854f..cfb31a3 100644
--- a/debug/testlib.py
+++ b/debug/testlib.py
@@ -50,14 +50,14 @@ def compile(args): # pylint: disable=redefined-builtin
cmd.append(arg)
header("Compile")
print("+", " ".join(cmd))
- process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = process.communicate()
- if process.returncode:
- print(stdout.decode('ascii'), end=" ")
- print(stderr.decode('ascii'), end=" ")
- header("")
- raise CompileError(stdout, stderr)
+ with subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE) as process:
+ stdout, stderr = process.communicate()
+ if process.returncode:
+ print(stdout.decode('ascii'), end=" ")
+ print(stderr.decode('ascii'), end=" ")
+ header("")
+ raise CompileError(stdout, stderr)
class Spike:
# pylint: disable=too-many-instance-attributes
@@ -86,22 +86,25 @@ class Spike:
"programs/checksum.c", "programs/tiny-malloc.c",
"programs/infinite_loop.S", "-DDEFINE_MALLOC", "-DDEFINE_FREE")
cmd.append(self.infinite_loop)
+ # pylint: disable-next=consider-using-with
self.logfile = tempfile.NamedTemporaryFile(prefix="spike-",
suffix=".log")
logname = self.logfile.name
self.lognames = [logname]
if print_log_names:
- real_stdout.write("Temporary spike log: %s\n" % logname)
- self.logfile.write(("+ %s\n" % " ".join(cmd)).encode())
+ real_stdout.write("Temporary spike log: {logname}\n")
+ self.logfile.write(("+ " + " ".join(cmd) + "\n").encode())
self.logfile.flush()
+ # pylint: disable-next=consider-using-with
self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=self.logfile, stderr=self.logfile)
if with_jtag_gdb:
self.port = None
for _ in range(30):
- m = re.search(r"Listening for remote bitbang connection on "
- r"port (\d+).", open(logname).read())
+ with open(logname, encoding='utf-8') as fd:
+ m = re.search(r"Listening for remote bitbang connection on "
+ r"port (\d+).", fd.read())
if m:
self.port = int(m.group(1))
os.environ['REMOTE_BITBANG_PORT'] = m.group(1)
@@ -120,7 +123,7 @@ class Spike:
else:
cmd = ["spike"]
- cmd += ["-p%d" % len(self.harts)]
+ cmd += [f"-p{len(self.harts)}"]
assert len(set(t.xlen for t in self.harts)) == 1, \
"All spike harts must have the same XLEN"
@@ -128,7 +131,7 @@ class Spike:
if self.isa:
isa = self.isa
else:
- isa = "RV%dG" % self.harts[0].xlen
+ isa = f"RV{self.harts[0].xlen}G"
cmd += ["--isa", isa]
cmd += ["--dm-auth"]
@@ -153,14 +156,14 @@ class Spike:
cmd.append("--dm-no-halt-groups")
if 'V' in isa[2:]:
- cmd.append("--varch=vlen:%d,elen:%d" % (self.vlen, self.elen))
+ cmd.append(f"--varch=vlen:{self.vlen},elen:{self.elen}")
assert len(set(t.ram for t in self.harts)) == 1, \
"All spike harts must have the same RAM layout"
assert len(set(t.ram_size for t in self.harts)) == 1, \
"All spike harts must have the same RAM layout"
- os.environ['WORK_AREA'] = '0x%x' % self.harts[0].ram
- cmd += ["-m0x%x:0x%x" % (self.harts[0].ram, self.harts[0].ram_size)]
+ os.environ['WORK_AREA'] = f'0x{self.harts[0].ram:x}'
+ cmd += [f"-m0x{self.harts[0].ram:x}:0x{self.harts[0].ram_size:x}"]
if timeout:
cmd = ["timeout", str(timeout)] + cmd
@@ -190,6 +193,7 @@ class MultiSpike:
self.spikes = spikes
self.lognames = sum((spike.lognames for spike in spikes), [])
+ # pylint: disable-next=consider-using-with
self.logfile = tempfile.NamedTemporaryFile(prefix="daisychain-",
suffix=".log")
self.lognames.append(self.logfile.name)
@@ -197,15 +201,16 @@ class MultiSpike:
# Now create the daisy-chain process.
cmd = ["./rbb_daisychain.py", "0"] + \
[str(spike.port) for spike in spikes]
- self.logfile.write(("+ %s\n" % cmd).encode())
+ self.logfile.write(f"+ {cmd}\n".encode())
self.logfile.flush()
+ # pylint: disable-next=consider-using-with
self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=self.logfile, stderr=self.logfile)
self.port = None
for _ in range(30):
- m = re.search(r"Listening on port (\d+).",
- open(self.lognames[-1]).read())
+ with open(self.lognames[-1], encoding='utf=8') as fd:
+ m = re.search(r"Listening on port (\d+).", fd.read())
if m:
self.port = int(m.group(1))
break
@@ -227,6 +232,7 @@ class MultiSpike:
pass
class VcsSim:
+ # pylint: disable-next=consider-using-with
logfile = tempfile.NamedTemporaryFile(prefix='simv', suffix='.log')
logname = logfile.name
@@ -240,37 +246,39 @@ class VcsSim:
cmd[0] = cmd[0] + "-debug"
cmd += ["+vcdplusfile=output/gdbserver.vpd"]
- logfile = open(self.logname, "w")
+ # pylint: disable-next=consider-using-with
+ logfile = open(self.logname, "w", encoding='utf-8')
if print_log_names:
- real_stdout.write("Temporary VCS log: %s\n" % self.logname)
- logfile.write("+ %s\n" % " ".join(cmd))
+ real_stdout.write(f"Temporary VCS log: {self.logname}\n")
+ logfile.write("+ " + " ".join(cmd) + "\n")
logfile.flush()
- listenfile = open(self.logname, "r")
- listenfile.seek(0, 2)
- self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
- stdout=logfile, stderr=logfile)
- done = False
- start = time.time()
- while not done:
- # Fail if VCS exits early
- exit_code = self.process.poll()
- if exit_code is not None:
- raise RuntimeError('VCS simulator exited early with status %d'
- % exit_code)
-
- line = listenfile.readline()
- if not line:
- time.sleep(1)
- match = re.match(r"^Listening on port (\d+)$", line)
- if match:
- done = True
- self.port = int(match.group(1))
- os.environ['JTAG_VPI_PORT'] = str(self.port)
-
- if (time.time() - start) > timeout:
- raise Exception("Timed out waiting for VCS to listen for JTAG "
- "vpi")
+ with open(self.logname, "r", encoding='utf-8') as listenfile:
+ listenfile.seek(0, 2)
+ # pylint: disable-next=consider-using-with
+ self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+ stdout=logfile, stderr=logfile)
+ done = False
+ start = time.time()
+ while not done:
+ # Fail if VCS exits early
+ exit_code = self.process.poll()
+ if exit_code is not None:
+ raise RuntimeError(
+ f'VCS simulator exited early with status {exit_code}')
+
+ line = listenfile.readline()
+ if not line:
+ time.sleep(1)
+ match = re.match(r"^Listening on port (\d+)$", line)
+ if match:
+ done = True
+ self.port = int(match.group(1))
+ os.environ['JTAG_VPI_PORT'] = str(self.port)
+
+ if (time.time() - start) > timeout:
+ raise Exception(
+ "Timed out waiting for VCS to listen for JTAG vpi")
def __del__(self):
try:
@@ -280,6 +288,7 @@ class VcsSim:
pass
class Openocd:
+ # pylint: disable-next=consider-using-with
logfile = tempfile.NamedTemporaryFile(prefix='openocd', suffix='.log')
logname = logfile.name
@@ -325,24 +334,26 @@ class Openocd:
else:
extra_env['USE_FREERTOS'] = "0"
+ # pylint: disable-next=consider-using-with
raw_logfile = open(Openocd.logname, "wb")
try:
+ # pylint: disable-next=consider-using-with
spike_dasm = subprocess.Popen("spike-dasm", stdin=subprocess.PIPE,
stdout=raw_logfile, stderr=raw_logfile)
logfile = spike_dasm.stdin
except FileNotFoundError:
logfile = raw_logfile
if print_log_names:
- real_stdout.write("Temporary OpenOCD log: %s\n" % Openocd.logname)
+ real_stdout.write(f"Temporary OpenOCD log: {Openocd.logname}\n")
env_entries = ("REMOTE_BITBANG_HOST", "REMOTE_BITBANG_PORT",
"WORK_AREA")
env_entries = [key for key in env_entries if key in os.environ]
parts = [
- " ".join("%s=%s" % (key, os.environ[key]) for key in env_entries),
- " ".join("%s=%s" % (k, v) for k, v in extra_env.items()),
+ " ".join(f"{key}={os.environ[key]}" for key in env_entries),
+ " ".join(f"{k}={v}" for k, v in extra_env.items()),
" ".join(map(pipes.quote, cmd))
]
- logfile.write(("+ %s\n" % " ".join(parts)).encode())
+ logfile.write(("+ " + " ".join(parts) + "\n").encode())
logfile.flush()
self.gdb_ports = []
@@ -350,6 +361,7 @@ class Openocd:
def start(self, cmd, logfile, extra_env):
combined_env = {**os.environ, **extra_env}
+ # pylint: disable-next=consider-using-with
process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=logfile, stderr=logfile, env=combined_env)
@@ -360,29 +372,29 @@ class Openocd:
# attempt too early.
start = time.time()
messaged = False
- fd = open(Openocd.logname, "r")
- while True:
- line = fd.readline()
- if not line:
- if not process.poll() is None:
- raise Exception("OpenOCD exited early.")
- time.sleep(0.1)
- continue
-
- m = re.search(r"Listening on port (\d+) for gdb connections",
- line)
- if m:
- self.gdb_ports.append(int(m.group(1)))
-
- if "telnet server disabled" in line:
- return process
-
- if not messaged and time.time() - start > 1:
- messaged = True
- print("Waiting for OpenOCD to start...")
- if (time.time() - start) > self.timeout:
- raise Exception("Timed out waiting for OpenOCD to "
- "listen for gdb")
+ with open(Openocd.logname, "r", encoding='utf-8') as fd:
+ while True:
+ line = fd.readline()
+ if not line:
+ if not process.poll() is None:
+ raise Exception("OpenOCD exited early.")
+ time.sleep(0.1)
+ continue
+
+ m = re.search(
+ r"Listening on port (\d+) for gdb connections", line)
+ if m:
+ self.gdb_ports.append(int(m.group(1)))
+
+ if "telnet server disabled" in line:
+ return process
+
+ if not messaged and time.time() - start > 1:
+ messaged = True
+ print("Waiting for OpenOCD to start...")
+ if (time.time() - start) > self.timeout:
+ raise Exception("Timed out waiting for OpenOCD to "
+ "listen for gdb")
except Exception:
print_log(Openocd.logname)
@@ -403,15 +415,16 @@ class Openocd:
def smp(self):
"""Return true iff OpenOCD internally sees the harts as part of an SMP
group."""
- for line in open(self.config_file, "r"):
- if "target smp" in line:
- return True
+ with open(self.config_file, "r", encoding='utf-8') as handle:
+ for line in handle:
+ if "target smp" in line:
+ return True
return False
class OpenocdCli:
def __init__(self, port=4444):
self.child = pexpect.spawn(
- "sh -c 'telnet localhost %d | tee openocd-cli.log'" % port)
+ f"sh -c 'telnet localhost {port} | tee openocd-cli.log'")
self.child.expect("> ")
def command(self, cmd):
@@ -422,7 +435,7 @@ class OpenocdCli:
return self.child.before.strip("\t\r\n \0").decode("utf-8")
def reg(self, reg=''):
- output = self.command("reg %s" % reg)
+ output = self.command(f"reg {reg}")
matches = re.findall(r"(\w+) \(/\d+\): (0x[0-9A-F]+)", output)
values = {r: int(v, 0) for r, v in matches}
if reg:
@@ -430,7 +443,7 @@ class OpenocdCli:
return values
def load_image(self, image):
- output = self.command("load_image %s" % image)
+ output = self.command(f"load_image {image}")
if 'invalid ELF file, only 32bits files are supported' in output:
raise TestNotApplicable(output)
@@ -456,7 +469,7 @@ class NoSymbol(Exception):
self.symbol = symbol
def __repr__(self):
- return "NoSymbol(%r)" % self.symbol
+ return f"NoSymbol({self.symbol!r})"
Thread = collections.namedtuple('Thread', ('id', 'description', 'target_id',
'name', 'frame'))
@@ -541,13 +554,13 @@ def parse_tokens(tokens):
return parse_dict_or_list(tokens)
if isinstance(tokens[0], str):
return tokens.pop(0)
- raise Exception("Unsupported tokens: %r" % tokens)
+ raise Exception(f"Unsupported tokens: {tokens!r}")
def parse_rhs(text):
tokens = list(tokenize(text))
result = parse_tokens(tokens)
if tokens:
- raise Exception("Unexpected input: %r" % tokens)
+ raise Exception(f"Unexpected input: {tokens!r}")
return result
class Gdb:
@@ -576,14 +589,15 @@ class Gdb:
self.logfiles = []
self.children = []
for port in ports:
- logfile = tempfile.NamedTemporaryFile(prefix="gdb@%d-" % port,
- suffix=".log")
+ # pylint: disable-next=consider-using-with
+ logfile = tempfile.NamedTemporaryFile(prefix=f"gdb@{port}-",
+ suffix=".log")
self.logfiles.append(logfile)
if print_log_names:
- real_stdout.write("Temporary gdb log: %s\n" % logfile.name)
+ real_stdout.write(f"Temporary gdb log: {logfile.name}\n")
child = pexpect.spawn(self.cmd)
child.logfile = logfile
- child.logfile.write(("+ %s\n" % self.cmd).encode())
+ child.logfile.write(f"+ {self.cmd}\n".encode())
self.children.append(child)
self.select_child(child)
self.wait()
@@ -593,9 +607,8 @@ class Gdb:
self.command("set height 0", reset_delays=None)
# Force consistency.
self.command("set print entry-values no", reset_delays=None)
- self.command("set remotetimeout %d" % self.timeout,
- reset_delays=None)
- self.command("set remotetimeout %d" % self.target.timeout_sec)
+ self.command(f"set remotetimeout {self.timeout}", reset_delays=None)
+ self.command(f"set remotetimeout {self.target.timeout_sec}")
self.active_child = self.children[0]
def connect(self):
@@ -603,10 +616,10 @@ class Gdb:
for port, child, binary in zip(self.ports, self.children,
self.binaries):
self.select_child(child)
- self.command("target extended-remote localhost:%d" % port,
+ self.command(f"target extended-remote localhost:{port}",
ops=10, reset_delays=None)
if binary:
- output = self.command("file %s" % binary)
+ output = self.command(f"file {binary}")
assertIn("Reading symbols", output)
threads = self.threads()
for t in threads:
@@ -648,7 +661,7 @@ class Gdb:
h = self.harts[hart.id]
self.select_child(h['child'])
if not h['solo']:
- output = self.command("thread %s" % h['thread'].id, ops=5)
+ output = self.command(f"thread {h['thread'].id}", ops=5)
assert "Unknown" not in output
def push_state(self):
@@ -673,7 +686,7 @@ class Gdb:
reset_delays = self.reset_delays[self.reset_delay_index]
self.reset_delay_index = (self.reset_delay_index + 1) % \
len(self.reset_delays)
- self.command("monitor riscv reset_delays %d" % reset_delays,
+ self.command(f"monitor riscv reset_delays {reset_delays}",
reset_delays=None)
timeout = max(1, ops) * self.timeout
self.active_child.sendline(command)
@@ -732,13 +745,13 @@ class Gdb:
else:
sync = "&"
if wait:
- output = self.command("c%s" % sync, ops=ops)
+ output = self.command(f"c{sync}", ops=ops)
if checkOutput:
assert "Continuing" in output
assert "Could not insert hardware" not in output
return output
else:
- self.active_child.sendline("c%s" % sync)
+ self.active_child.sendline(f"c{sync}")
self.active_child.expect("Continuing", timeout=ops * self.timeout)
return ""
@@ -774,8 +787,7 @@ class Gdb:
self.interrupt()
def x(self, address, size='w', count=1):
- output = self.command("x/%d%s %s" % (count, size, address),
- ops=count / 16)
+ output = self.command(f"x/{count}{size} {address}", ops=count / 16)
values = []
for line in output.splitlines():
for value in line.split(':')[1].strip().split():
@@ -785,14 +797,14 @@ class Gdb:
return values
def p_raw(self, obj):
- output = self.command("p %s" % obj)
+ output = self.command(f"p {obj}")
m = re.search("Cannot access memory at address (0x[0-9a-f]+)", output)
if m:
raise CannotAccess(int(m.group(1), 0))
return output.split('=', 1)[-1].strip()
def p(self, obj, fmt="/x", ops=1):
- output = self.command("p%s %s" % (fmt, obj), ops=ops).splitlines()[-1]
+ output = self.command(f"p{fmt} {obj}", ops=ops).splitlines()[-1]
rhs = output.split('=', 1)[-1]
return parse_rhs(rhs)
@@ -803,12 +815,12 @@ class Gdb:
return result
def p_string(self, obj):
- output = self.command("p %s" % obj)
+ output = self.command(f"p {obj}")
value = shlex.split(output.split('=')[-1].strip())[1]
return value
def info_registers(self, group="", ops=5):
- output = self.command("info registers %s" % group, ops=ops)
+ output = self.command(f"info registers {group}", ops=ops)
result = {}
for line in output.splitlines():
m = re.match(r"(\w+)\s+({.*})(?:\s+(\(.*\)))?", line)
@@ -836,7 +848,7 @@ class Gdb:
assert "MIS" not in output
def b(self, location):
- output = self.command("b %s" % location, ops=5)
+ output = self.command(f"b {location}", ops=5)
assert "not defined" not in output
assert "Breakpoint" in output
m = re.search(r"Breakpoint (\d+),? ", output)
@@ -844,13 +856,13 @@ class Gdb:
return int(m.group(1))
def hbreak(self, location):
- output = self.command("hbreak %s" % location, ops=5)
+ output = self.command(f"hbreak {location}", ops=5)
assert "not defined" not in output
assert "Hardware assisted breakpoint" in output
return output
def watch(self, expr):
- output = self.command("watch %s" % expr, ops=5)
+ output = self.command(f"watch {expr}", ops=5)
assert "not defined" not in output
assert "atchpoint" in output
return output
@@ -858,7 +870,7 @@ class Gdb:
def swatch(self, expr):
self.command("show can-use-hw-watchpoints")
self.command("set can-use-hw-watchpoints 0")
- output = self.command("watch %s" % expr, ops=5)
+ output = self.command(f"watch {expr}", ops=5)
assert "not defined" not in output
assert "atchpoint" in output
self.command("set can-use-hw-watchpoints 1")
@@ -879,7 +891,7 @@ class Gdb:
return threads
def thread(self, thread):
- return self.command("thread %s" % thread.id)
+ return self.command(f"thread {thread.id}")
def where(self):
return self.command("where 1")
@@ -925,17 +937,16 @@ 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(f"Using $misa from command line: 0x{hart.misa:x}")
elif hart.misa:
- print("Using $misa from hart definition: 0x%x" % hart.misa)
+ print(f"Using $misa from hart definition: 0x{hart.misa:x}")
elif not examine_added:
todo.insert(0, ("ExamineTarget", ExamineTarget, None))
examine_added = True
results, count = run_tests(parsed, target, todo)
- header("ran %d tests in %.0fs" % (count, time.time() - overall_start),
- dash=':')
+ header(f"ran {count} tests in {time.time() - overall_start:.0f}s", dash=':')
return print_results(results)
@@ -945,31 +956,34 @@ def run_tests(parsed, target, todo):
count = 0
for name, definition, hart in 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))
+ timestamp = time.strftime("%Y%m%d-%H%M%S")
+ log_name = os.path.join(parsed.logs,
+ f"{timestamp}-"
+ f"{type(target).__name__}-{name}.log")
+ # pylint: disable-next=consider-using-with
+ log_fd = open(log_name, 'w', encoding='utf-8')
+ print(f"[{name}] Starting > {log_name}")
instance = definition(target, hart)
sys.stdout.flush()
- log_fd.write("Test: %s\n" % name)
- log_fd.write("Target: %s\n" % type(target).__name__)
+ log_fd.write(f"Test: {name}\n")
+ log_fd.write(f"Target: {type(target).__name__}\n")
start = time.time()
global real_stdout # pylint: disable=global-statement
real_stdout = sys.stdout
sys.stdout = log_fd
try:
result = instance.run()
- log_fd.write("Result: %s\n" % result)
- log_fd.write("Logfile: %s\n" % log_name)
- log_fd.write("Reproduce: %s %s %s\n" % (sys.argv[0], parsed.target,
- name))
+ log_fd.write(f"Result: {result}\n")
+ log_fd.write(f"Logfile: {log_name}\n")
+ log_fd.write(f"Reproduce: {sys.argv[0]} {parsed.target} {name}\n")
finally:
sys.stdout = real_stdout
- log_fd.write("Time elapsed: %.2fs\n" % (time.time() - start))
+ log_fd.write(f"Time elapsed: {time.time() - start:.2f}s\n")
log_fd.flush()
- print("[%s] %s in %.2fs" % (name, result, time.time() - start))
+ print(f"[{name}] {result} in {time.time() - start:.2f}s")
if result not in good_results and parsed.print_failures:
- sys.stdout.write(open(log_name).read())
+ with open(log_name, encoding='utf-8') as handle:
+ sys.stdout.write(handle.read())
sys.stdout.flush()
results.setdefault(result, []).append((name, log_name))
count += 1
@@ -981,11 +995,11 @@ def run_tests(parsed, target, todo):
def print_results(results):
result = 0
for key, value in results.items():
- print("%d tests returned %s" % (len(value), key))
+ print(f"{len(value)} tests returned {key}")
if key not in good_results:
result = 1
for name, log_name in value:
- print(" %s > %s" % (name, log_name))
+ print(f" {name} > {log_name}")
return result
@@ -1016,7 +1030,7 @@ def header(title, dash='-', length=78):
dashes = dash * (length - 4 - len(title))
before = dashes[:len(dashes)//2]
after = dashes[len(dashes)//2:]
- print("%s[ %s ]%s" % (before, title, after))
+ print(f"{before}[ {title} ]{after}")
else:
print(dash * length)
@@ -1027,7 +1041,8 @@ def print_log_handle(name, handle):
print()
def print_log(path):
- print_log_handle(path, open(path, "r", errors='ignore'))
+ with open(path, "r", errors='ignore', encoding='utf-8') as handle:
+ print_log_handle(path, handle)
class BaseTest:
# pylint: disable=too-many-instance-attributes
@@ -1139,7 +1154,9 @@ class BaseTest:
# Get handles to logs before the files are deleted.
logs = []
for log in self.logs:
- logs.append((log, open(log, "r", errors='ignore')))
+ # pylint: disable=consider-using-with
+ logs.append((log,
+ open(log, "r", errors='ignore', encoding='utf-8')))
self.classTeardown()
for name, handle in logs:
@@ -1159,8 +1176,8 @@ class GdbTest(BaseTest):
def write_nop_program(self, count):
for i in range(count):
# 0x13 is nop
- self.gdb.command("p *((int*) 0x%x)=0x13" % (self.hart.ram + i * 4))
- self.gdb.p("$pc=0x%x" % self.hart.ram)
+ self.gdb.command(f"p *((int*) 0x{self.hart.ram + i * 4:x})=0x13")
+ self.gdb.p(f"$pc=0x{self.hart.ram:x}")
def classSetup(self):
BaseTest.classSetup(self)
@@ -1214,8 +1231,8 @@ class GdbTest(BaseTest):
self.gdb.p("$pmpaddr0=0x" + "f" * (self.hart.xlen // 4))
else:
# pmcfg0 readback matches write, so TOR is supported.
- self.gdb.p("$pmpaddr0=0x%x" %
- ((self.hart.ram + self.hart.ram_size) >> 2))
+ self.gdb.p("$pmpaddr0="
+ f"0x{(self.hart.ram + self.hart.ram_size) >> 2:x}")
except CouldNotFetch:
# PMP registers are optional
pass
@@ -1241,14 +1258,14 @@ class ExamineTarget(GdbTest):
elif ((hart.misa & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) >> 126) == 3:
misa_xlen = 128
else:
- raise TestFailed("Couldn't determine XLEN from $misa (0x%x)" %
- self.hart.misa)
+ raise TestFailed("Couldn't determine XLEN from $misa "
+ f"(0x{self.hart.misa:x})")
if misa_xlen != hart.xlen:
- raise TestFailed("MISA reported XLEN of %d but we were "\
- "expecting XLEN of %d\n" % (misa_xlen, hart.xlen))
+ raise TestFailed(f"MISA reported XLEN of {misa_xlen} but we "
+ f"were expecting XLEN of {hart.xlen}\n")
- txt += ("%d" % misa_xlen)
+ txt += f"{misa_xlen}"
for i in range(26):
if hart.misa & (1<<i):
@@ -1260,7 +1277,7 @@ class TestFailed(Exception):
Exception.__init__(self)
self.message = message
if comment:
- self.message += ": %s" % comment
+ self.message += f": {comment}"
class TestNotApplicable(Exception):
def __init__(self, message=""):
@@ -1269,32 +1286,32 @@ class TestNotApplicable(Exception):
def assertEqual(a, b, comment=None):
if a != b:
- raise TestFailed("%r != %r" % (a, b), comment)
+ raise TestFailed(f"{a!r} != {b!r}", comment)
def assertNotEqual(a, b, comment=None):
if a == b:
- raise TestFailed("%r == %r" % (a, b), comment)
+ raise TestFailed(f"{a!r} == {b!r}", comment)
def assertIn(a, b):
if a not in b:
- raise TestFailed("%r not in %r" % (a, b))
+ raise TestFailed(f"{a!r} not in {b!r}")
def assertNotIn(a, b, comment=None):
if a in b:
- raise TestFailed("%r in %r" % (a, b), comment)
+ raise TestFailed(f"{a!r} in {b!r}", comment)
def assertGreater(a, b):
if not a > b:
- raise TestFailed("%r not greater than %r" % (a, b))
+ raise TestFailed(f"{a!r} not greater than {b!r}")
def assertLess(a, b, comment=None):
if not a < b:
- raise TestFailed("%r not less than %r" % (a, b), comment)
+ raise TestFailed(f"{a!r} not less than {b!r}", comment)
def assertTrue(a):
if not a:
- raise TestFailed("%r is not True" % a)
+ raise TestFailed(f"{a!r} is not True" % a)
def assertRegex(text, regexp):
if not re.search(regexp, text):
- raise TestFailed("can't find %r in %r" % (regexp, text))
+ raise TestFailed(f"can't find {regexp!r} in {text!r}")