feat: unify param rendering between tools and benchmarks - #868
Conversation
dump_params() rendered benchmark params as unquoted --arg=val strings, so a value containing a space (e.g. bench-fio's exec_prerun/exec_postrun) silently corrupted the shell invocation via word-splitting. Fixing it surfaced a deeper issue: build_tool_cmd() built tool commands via a bash-syntax hack (declare -a ARGS=(...)) inherited from when the engine was Perl+Bash, giving tools and benchmarks two incompatible param_regex grammars for the same ON/OFF placeholder-value convention. Both now share one render_param() helper (quotes a value only when the shell would otherwise misinterpret it), one param_regex grammar, and one JSON-argv transport: tool/benchmark commands are shipped as plain argv lists rather than pre-rendered shell strings, with shlex.join() applied exactly once, immediately before each run_command() call. This also closes a related hazard in process_bench_roadblocks()'s unbounded-timeout path, which used to wrap an already-rendered command string in a second layer of shell quoting for a wait-for re-invocation -- it now hands roadblock a literal argv list instead. Also fixes two consumers of the old formats that would have otherwise broken: endpoints.py's own bench-cmds reader (kube/remotehosts) and endpoints/base's equivalent for the osp endpoint, both independently read the old flat-text file layout. Fixes #867
PR Review: rickshaw#868 — feat-unify-param-renderingSummary: This PR unifies parameter rendering and execution command transport between benchmarks and tools by transitioning them to a single File Coverage
Limitations
VerdictApprove — Excellent and exceptionally robust refactoring of the command and parameter rendering subsystem. The implementation successfully eliminates shell word-splitting hazards, resolves the roadblock double-quoting issue, and maintains full style/convention compatibility. The thorough test coverage ensures high confidence for merging this PR 868 is functional and completely safe. Review compiled and generated by Antigravity (AI Coding Assistant) |
atheurer
left a comment
There was a problem hiding this comment.
Approved after thorough code review and local test suite verification (all 58 tests passed).
…rammar
sysfs-trace-setup/-cleanup shared the generic_string validation group
with no repeatable flag, so a second occurrence of either silently
collapsed onto the first ("last one takes effect") -- data loss for
kerneltools-start/-stop, which both accumulate these into an array and
expect every occurrence to survive. Split them into their own
sysfs_trace_command group with "repeatable": true, now that multiplex
supports it (perftool-incubator/multiplex#111).
Separately, rickshaw.json's param_regex for the perf-gen-local-report
ON/OFF flag hack was written against the old two-token rendering
grammar ('--flag' 'ON'). Rickshaw's param-rendering unification
(perftool-incubator/rickshaw#868) now renders params as a single
--flag=value token, so the old regex silently matched nothing --
verified this let --perf-gen-local-report=OFF pass through unchanged,
which would break kerneltools-stop's getopt parsing (that flag takes
no argument) at runtime. Rewrote both patterns for the new grammar and
verified against the real render_param()/apply_param_regex_and_split()
pipeline: ON renders as a bare flag, OFF is stripped entirely.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
dump_params()rendered benchmark params as unquoted--arg=valstrings, so a value containing a space (e.g. bench-fio'sexec_prerun/exec_postrun) silently corrupted the shell invocation via word-splitting.build_tool_cmd()built tool commands via a bash-syntax hack (declare -a ARGS=(...)) inherited from when the engine was Perl+Bash, giving tools and benchmarks two incompatibleparam_regexgrammars for the same ON/OFF placeholder-value convention (bench-trafficgen/bench-fio vs. the still-draft tool-kernel PR#64).render_param()helper (quotes a value only when the shell would otherwise misinterpret it), oneparam_regexgrammar, and one JSON-argv transport: tool/benchmark commands ship as plain argv lists rather than pre-rendered shell strings, withshlex.join()applied exactly once, immediately before eachrun_command()call.process_bench_roadblocks()'s unbounded-timeout path, which used to wrap an already-rendered command string in a second layer of shell quoting for await_forre-invocation — it now hands roadblock a literal argv list instead (roadblock already supports this natively).endpoints.py's own reader (shared by kube/remotehosts) andendpoints/base's equivalent for the osp endpoint.param_regexpatterns are unaffected — verified byte-for-byte identical output against their real values.Fixes #867
Test plan
python3 -m unittest discover -s tests -p "test_*.py"— 58 tests pass, including new coverage forrender_param()/dump_params(),build_tool_cmd()'s new argv grammar,engine_lib.py's argv-handling (including thewait_forlist-construction), andendpoints.py's bench-cmds JSON read.param_regex→shlex.split()→ JSON round-trip →shlex.join()intact.crucible runagainst a real kube endpoint (fio + procstat), withexec_prerunset to"echo starting test"— completed successfully; result summary shows the value preserved as one coherent parameter, real fio results captured (18014 IOPS), and procstat metrics correctly indexed (interrupts-sec, processed-sec, time-squeeze-sec all non-zero).0/Falsevalues and JSONnullmishandled) plus theendpoints/basegap above; all fixes have dedicated regression tests.Follow-up (not part of this PR)
tool-kernel PR#64 is held in draft pending this change — its
param_regexneeds updating to the converged bare-text grammar once this merges (tracked separately, different repo).