diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-02 10:58:21 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-02 10:58:21 -0400 |
| commit | 002e3d7d13c414ea874abbee8d82803dd3a72fe5 (patch) | |
| tree | 6627c12fa07f6a1cf73e5aaeb7390e698dd3a896 /debug/risc-v-gsp-rm-vm/rmharness/harness.sh | |
| parent | 2f249817df327f5dcccf0464ad517fa60d6071d3 (diff) | |
| download | open-iov-002e3d7d13c414ea874abbee8d82803dd3a72fe5.tar.gz open-iov-002e3d7d13c414ea874abbee8d82803dd3a72fe5.zip | |
debug: green-eye wave 3 - RM harness, local simulator, device map, MCP plugin, value-validation demos, CI pipeline, toolchain docs; add host RM tools rmtool/rmtop
Diffstat (limited to 'debug/risc-v-gsp-rm-vm/rmharness/harness.sh')
| -rwxr-xr-x | debug/risc-v-gsp-rm-vm/rmharness/harness.sh | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/debug/risc-v-gsp-rm-vm/rmharness/harness.sh b/debug/risc-v-gsp-rm-vm/rmharness/harness.sh new file mode 100755 index 0000000..60fce8a --- /dev/null +++ b/debug/risc-v-gsp-rm-vm/rmharness/harness.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash +# harness.sh - run a read-only RM tool, capture stdout/stderr, and record the +# run into a green-eye session directory (blob + events.jsonl line). +# +# usage: harness.sh [--session DIR] [--name LABEL] -- TOOL [ARGS...] +# TOOL is one of: rmtool rmtop rmq +# +# When --session is given the harness appends a "rm_harness_run" event and +# writes the captured streams under <session>/blobs/. Existing session files +# are never rewritten; recording is additive. Without --session the tool runs +# and streams pass through unchanged. +set -euo pipefail +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ALLOWED="rmtool rmtop rmq" + +usage() { + cat <<'EOF' +usage: harness.sh [--session DIR] [--name LABEL] -- TOOL [ARGS...] + +TOOL is one of: rmtool rmtop rmq (wrapper scripts in this directory). +Everything after -- is passed to the tool unchanged. +EOF +} + +session="" +label="" +while [[ $# -gt 0 ]]; do + case "$1" in + --session) + session="${2:?--session needs a directory}" + shift 2 + ;; + --name) + label="${2:?--name needs a label}" + shift 2 + ;; + -h | --help) + usage + exit 0 + ;; + --) + shift + break + ;; + -*) + echo "harness.sh: unknown option '$1'" >&2 + usage >&2 + exit 2 + ;; + *) + break + ;; + esac +done + +tool="${1:-}" +if [[ -z "$tool" ]]; then + usage >&2 + exit 2 +fi +shift +tool="${tool%.sh}" +case " $ALLOWED " in +*" $tool "*) ;; +*) + echo "harness.sh: tool '$tool' is not on the read-only allowlist" \ + "($ALLOWED)" >&2 + exit 2 + ;; +esac + +wrapper="$HERE/$tool.sh" +if [[ ! -x "$wrapper" ]]; then + echo "harness.sh: wrapper not found: $wrapper" >&2 + exit 2 +fi + +argv_json="$(python3 -c 'import json,sys; print(json.dumps(sys.argv[1:]))' \ + "$tool" "$@")" +out_file="$(mktemp)" +err_file="$(mktemp)" +trap 'rm -f "$out_file" "$err_file"' EXIT + +start="$(python3 -c 'import time; print(time.time())')" +rc=0 +"$wrapper" "$@" >"$out_file" 2>"$err_file" || rc=$? +end="$(python3 -c 'import time; print(time.time())')" + +cat "$out_file" +cat "$err_file" >&2 + +if [[ -n "$session" ]]; then + mkdir -p "$session/blobs" + stamp="$(date -u +%Y%m%dT%H%M%SZ)" + out_rel="blobs/rmharness-${stamp}-${tool}-stdout.txt" + err_rel="blobs/rmharness-${stamp}-${tool}-stderr.txt" + cp "$out_file" "$session/$out_rel" + cp "$err_file" "$session/$err_rel" + SESSION="$session" TOOL="$tool" ARGV_JSON="$argv_json" \ + RC="$rc" START="$start" END="$end" LABEL="$label" \ + OUT_REL="$out_rel" ERR_REL="$err_rel" \ + python3 - <<'PY' +import hashlib +import json +import os +import time + +session = os.environ["SESSION"] + + +def blob_info(rel): + path = os.path.join(session, rel) + with open(path, "rb") as fh: + data = fh.read() + return {"path": rel, "size": len(data), + "sha256": hashlib.sha256(data).hexdigest()} + + +event = { + "t": 0.0, + "type": "rm_harness_run", + "tool": os.environ["TOOL"], + "label": os.environ["LABEL"] or None, + "argv": json.loads(os.environ["ARGV_JSON"]), + "exit": int(os.environ["RC"]), + "start": float(os.environ["START"]), + "end": float(os.environ["END"]), + "duration_s": round(float(os.environ["END"]) - float(os.environ["START"]), 6), + "stdout": blob_info(os.environ["OUT_REL"]), + "stderr": blob_info(os.environ["ERR_REL"]), + "readonly": True, +} +meta = os.path.join(session, "session.json") +if not os.path.exists(meta): + with open(meta, "w", encoding="utf-8") as fh: + json.dump({"format": "greeneye-session/1", "name": "rmharness", + "created": time.time(), + "greeneye": "external-rmharness/1"}, fh, indent=1, + sort_keys=True) +with open(os.path.join(session, "events.jsonl"), "a", encoding="utf-8") as fh: + fh.write(json.dumps(event, sort_keys=True) + "\n") +print(f"[rmharness] recorded {os.environ['TOOL']} -> {session} " + f"({os.environ['OUT_REL']})") +PY +fi + +exit "$rc" |
