Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions util/rpcid.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def analyze_rpc(id, client_num, server_num):
server_info = ""

for line in tt.stdout:
match = re.match(' *([-0-9.]+) us .* \[C([0-9]+)\]', line)
match = re.match(r' *([-0-9.]+) us .* \[C([0-9]+)\]', line)
if not match:
continue
time = float(match.group(1))
Expand Down Expand Up @@ -239,7 +239,7 @@ def analyze_rpc(id, client_num, server_num):
rpcs_analyzed += 1
print("Client (%s, id %s):" % (client, id))
for line in tt.stdout:
match = re.match(' *([-0-9.]+) us .* \[C([0-9]+)\]', line)
match = re.match(r' *([-0-9.]+) us .* \[C([0-9]+)\]', line)
if not match:
continue
time = float(match.group(1))
Expand Down
2 changes: 1 addition & 1 deletion util/smi.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
printed = 0

for line in f:
match = re.match(' *([-0-9.]+) us .* \[C([0-9]+)\]', line)
match = re.match(r' *([-0-9.]+) us .* \[C([0-9]+)\]', line)
if not match:
continue
time = float(match.group(1))
Expand Down
86 changes: 86 additions & 0 deletions util/tests/test_trace_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0+
"""Regression tests for the timetrace-line regexes in util/.

These document the W605 fix (invalid escape sequences in regex string
literals -> raw strings) and pin down the behaviour that must stay
unchanged. Run standalone:

python -W error::SyntaxWarning -m pytest util/tests/test_trace_line.py

There is no new CI wiring; this file is included as executable
documentation of the fix.
"""

import ast
import re
import warnings
from pathlib import Path

import pytest

UTIL = Path(__file__).resolve().parent.parent

# The canonical trace-line prefix regex, shared by rpcid.py / smi.py /
# tput.py / tthoma.py after the fix.
PREFIX = re.compile(r' *([-0-9.]+) us .* \[C([0-9]+)\]')

# Table-driven cases: positive, boundary, negative, corner.
PREFIX_CASES = [
{
"description": "positive: typical line, extracts timestamp and core",
"line": " 123.5 us (+ 2.0 us) [C07] homa_data_pkt invoked",
"expected": ("123.5", "07"),
},
{
"description": "boundary: negative relative timestamp is accepted",
"line": " -0.5 us stuff [C00] first event",
"expected": ("-0.5", "00"),
},
{
"description": "corner: multi-digit core id",
"line": "0 us x [C128] y",
"expected": ("0", "128"),
},
{
"description": "negative: literal brackets required, none present",
"line": " 123.5 us no core marker here",
"expected": None,
},
{
"description": "negative: '[C..]' must be literal, not a char class",
"line": " 123.5 us .* CX",
"expected": None,
},
]


@pytest.mark.parametrize("case", PREFIX_CASES, ids=lambda c: c["description"])
def test_prefix_regex(case):
m = PREFIX.match(case["line"])
if case["expected"] is None:
assert m is None
else:
assert m is not None
assert m.groups() == case["expected"]


# Every util/*.py that carried a W605 finding must now compile without any
# SyntaxWarning about invalid escape sequences. Compiling the source with
# warnings promoted to errors is the pytest form of the ruff W605 gate.
FIXED_SOURCES = [
"rpcid.py",
"smi.py",
"tput.py",
"tthoma.py",
"ttmerge.py",
"ttsyslog.py",
]


@pytest.mark.parametrize("name", FIXED_SOURCES)
def test_no_invalid_escape_sequences(name):
src = (UTIL / name).read_text()
with warnings.catch_warnings():
warnings.simplefilter("error", SyntaxWarning)
# Raises SyntaxWarning (-> error) if any invalid escape remains.
compile(ast.parse(src, filename=name), name, "exec")
2 changes: 1 addition & 1 deletion util/tput.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
rpcs = {}

for line in f:
match = re.match(' *([-0-9.]+) us .* \[C([0-9]+)\]', line)
match = re.match(r' *([-0-9.]+) us .* \[C([0-9]+)\]', line)
if not match:
continue
time = float(match.group(1))
Expand Down
10 changes: 5 additions & 5 deletions util/tthoma.py
Original file line number Diff line number Diff line change
Expand Up @@ -1736,7 +1736,7 @@ def parse(self, file):
global traces
start_ns = time.time_ns()
self.__build_parse_table()
prefix_matcher = re.compile(' *([-0-9.]+) us .* \[C([0-9]+)\] (.*)')
prefix_matcher = re.compile(r' *([-0-9.]+) us .* \[C([0-9]+)\] (.*)')

trace = {}
trace['file'] = file
Expand Down Expand Up @@ -1838,7 +1838,7 @@ def __build_parse_table(self):
# and 'cregexp' elements of pattern entries.
self.prefix_length = 1000
for pattern in self.patterns:
meta_matcher = re.compile('[()[\].+*?\\^${}]')
meta_matcher = re.compile(r'[()[\].+*?\^${}]')
pattern['parser'] = getattr(self, '_Dispatcher__' + pattern['name'])
pattern['cregexp'] = re.compile(pattern['regexp'])
if pattern['name'] in self.interests:
Expand Down Expand Up @@ -2014,7 +2014,7 @@ def __qdisc_queue_data(self, trace, time, core, match, interests):
patterns.append({
'name': 'qdisc_queue_data',
'regexp': '__dev_xmit_skb queueing homa data packet for '
'id ([0-9]+), offset ([0-9]+), qid ([0-9]+) \(([^)]+)\)'
r'id ([0-9]+), offset ([0-9]+), qid ([0-9]+) \(([^)]+)\)'
})

def __nic_data(self, trace, time, core, match, interests):
Expand Down Expand Up @@ -2355,7 +2355,7 @@ def __grant_check_unlock(self, trace, time, core, match, interests):

patterns.append({
'name': 'grant_check_unlock',
'regexp': 'homa_grant_check_rpc released grant lock \(id ([0-9]+)\)'
'regexp': r'homa_grant_check_rpc released grant lock \(id ([0-9]+)\)'
})

def __rpc_incoming(self, trace, time, core, match, interests):
Expand Down Expand Up @@ -12401,7 +12401,7 @@ def output(self):
dst = tempfile.NamedTemporaryFile(dir=os.path.dirname(file),
mode='w', delete=False)
for line in src:
match = re.match(' *([-0-9.]+) us (\(\+ *[-0-9.]+ us\) \[C[0-9]+\].*)',
match = re.match(r' *([-0-9.]+) us (\(\+ *[-0-9.]+ us\) \[C[0-9]+\].*)',
line)
if not match:
print(line, file=dst)
Expand Down
6 changes: 3 additions & 3 deletions util/ttmerge.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def next_line(info):
info["f"].close()
info["f"] = None
return
match = re.match(' *([0-9.]+) us \(\+ *([0-9.]+) us\) (.*)', line)
match = re.match(r' *([0-9.]+) us \(\+ *([0-9.]+) us\) (.*)', line)
if not match:
continue
info["time"] = (float(match.group(1)) * ghz / info["ghz"]) + info["offset"]
Expand All @@ -64,9 +64,9 @@ def next_line(info):
if not line:
continue
info = {"f": f}
match = re.match(' *([0-9.]+) us \(\+ *([0-9.]+) us\) .* '
match = re.match(r' *([0-9.]+) us \(\+ *([0-9.]+) us\) .* '
'First event has timestamp ([0-9]+) '
'\(cpu_ghz ([0-9.]+)\)', line)
r'\(cpu_ghz ([0-9.]+)\)', line)
if not match:
continue
info = {"name": file,
Expand Down
4 changes: 2 additions & 2 deletions util/ttsyslog.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
lines.append(line)

for line in reversed(lines):
match = re.match('.* ([0-9.]+) (\[C..\] .+)', line)
match = re.match(r'.* ([0-9.]+) (\[C..\] .+)', line)
if not match:
continue
this_time = float(match.group(1))
Expand All @@ -76,7 +76,7 @@

if extra:
for line in lines:
if not re.match('.* ([0-9.]+) (\[C..\] .+)', line):
if not re.match(r'.* ([0-9.]+) (\[C..\] .+)', line):
extra.write(line)
extra.write('\n')
extra.close()
Expand Down