Untested: row 328 record runner and child niceness per attempt

This commit is contained in:
jason.woltje committed 2026-10-24 13:20:28 -05:00
1 parent 1e8e5f0865
commit d7cef2ffbf
2 files changed
+51 -1

No files matched your search

+13
View File
@@ -92,3 +92,16 @@ Finally restored exact test bytes/SHA, empty git diff --stat HEAD, empty porcela
no own node/Chromium remaining. Scan saw only inspection Python, which exited. Slot
returned fethry0039 while Sage rules; no test/runner modifications. Raw and normalized
receipts retained in evidence/aborted-sage4194 with provenance and explicit EXCLUDED.md.
## sage4196 priority ruling — preparation only
Sage reports active ananicy-cpp (15s checks/apply_nice); no specific Python rule proven.
Priority drift alone is no longer a stop condition and has no bearing on test validity.
Fresh CLEAR required after Della. Begin again at attempt1, initial absolute nice19, Python-B.
Only stress.py instrumentation added: a read-only100ms /proc sampler records runner and
timeout/Node descendant pid, comm, nice and elapsed sample time for every attempt, retaining
changes. Existing wait, timeout, verdict, phase order, mutation and restoration paths unchanged.
No renice loop or host/rule change. Test/manifest remain identical to36668b698. Static AST
parse only; no runner or tests executed. Stop remains fixed red, dirty tree or other unexpected
event. Final clean checks include full git status --porcelain as well as diff --stat.
+38 -1
View File
@@ -8,6 +8,7 @@ from pathlib import Path
import re
import signal
import subprocess
import threading
import time
ROOT = Path(__file__).resolve().parents[4]
@@ -21,6 +22,37 @@ def digest(value):
return hashlib.sha256(value).hexdigest()
def sample_nice(child_pid, records, stopped):
"""Read-only samples of the runner and timeout/Node descendants (sage-4196)."""
seen = set()
started = time.monotonic()
while True:
pending = [os.getpid(), child_pid]
visited = set()
while pending:
pid = pending.pop()
if pid in visited:
continue
visited.add(pid)
proc = Path('/proc') / str(pid)
try:
stat = (proc / 'stat').read_text()
fields = stat.rsplit(')', 1)[1].split()
nice = int(fields[16]) # stat field19, after pid and parenthesized comm
command = stat.split('(', 1)[1].rsplit(')', 1)[0]
key = (pid, command, nice)
if key not in seen:
records.append({'pid': pid, 'command': command, 'nice': nice,
'seconds': round(time.monotonic() - started, 3)})
seen.add(key)
if pid != os.getpid():
pending.extend(map(int, (proc / 'task' / str(pid) / 'children').read_text().split()))
except (OSError, ValueError):
pass # Short-lived children may exit between the read-only samples.
if stopped.wait(.1):
return
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--clear-key', required=True, help='Sage message authorizing this test slot')
@@ -55,6 +87,9 @@ def main():
signals = []
with log.open('w') as stream:
child = subprocess.Popen(command, cwd=ROOT, env=env, stdout=stream, stderr=subprocess.STDOUT, start_new_session=True)
nice_samples, nice_stop = [], threading.Event()
sampler = threading.Thread(target=sample_nice, args=(child.pid, nice_samples, nice_stop), daemon=True)
sampler.start()
try:
code = child.wait(timeout=135)
except subprocess.TimeoutExpired:
@@ -62,6 +97,8 @@ def main():
signals.append('KILL')
code = child.wait()
finally:
nice_stop.set()
sampler.join()
try:
os.killpg(child.pid, signal.SIGTERM)
signals.append('TERM')
@@ -81,7 +118,7 @@ def main():
and "+ code: 'library-sync-busy'" in text and "- code: 'library-fetch-no-grant'" in text)
entry = {'phase': phase, 'attempt': number, 'command': command, 'TMPDIR': temporary, 'load': os.getloadavg(),
'exit': code, 'counts': counts, 'green': green, 'race': race, 'seconds': round(time.monotonic() - before, 3),
'cleanupSignals': signals, 'TAP': log.name, 'TAPSHA256': digest(log.read_bytes())}
'niceSamples': nice_samples, 'cleanupSignals': signals, 'TAP': log.name, 'TAPSHA256': digest(log.read_bytes())}
report['runs'].append(entry)
save()
print(json.dumps(entry), flush=True)