feat(scheduler-core): implement REPL execution control (task 12.1)
Adds the interactive simulation REPL's execution-control slice (Req 5 AC 22): a single-threaded input loop (readline-based) supporting step [N], continue, quit, and help, pausing before the first replay event and blocking the driver loop while active. Review round 1 raised two findings, both resolved here: - GNU readline (GPL) was linked directly into xce_scheduler, a shipped production daemon. Switched the whole project to libedit (BSD) for line editing -- scheduler and controller (xce_test) both now use editline/readline.h, API-compatible (readline()/add_history()). - Getting a clean regression run after the libedit swap required a full clean rebuild, which exposed a genuine pre-existing SIGSEGV (bug-1504): SnapshotData.internalState was a capnp Data field, and this codebase's capnpc-c backend silently no-ops Data-field encoding without zero-initializing the caller's stack struct, leaving an uninitialized capn_ptr written onto the wire. Fixed by switching internalState to List(UInt8) (with a new internalStateLen wire field), matching the working FetchFileReply.content/bytesRead precedent -- no hand-written accessor code needed. A second, unrelated instance of the same bug class was found in the controller's WAL-catchup path (WalCatchupEntry.payload) and deliberately left unfixed as bug-1505, out of scheduler-core's boundary; needs its own project-wide Data-field audit. Scheduler suite: 34/34 clean. RED-phase reproduction recorded in tasks.md (repl_should_pause() step-budget check disabled -> 2/4 tests fail as expected -> reverted -> 34/34 green). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JPPXeKSUXUqcqvzNXY1rzJ
This commit is contained in:
parent
de00ccff37
commit
02f7f48ff9
17 changed files with 1491 additions and 81 deletions
|
|
@ -2,7 +2,17 @@ scheduler_test_src = [
|
|||
'test.c',
|
||||
]
|
||||
|
||||
scheduler_test_deps = [libxce_deps, librtti_dep, unity_dep, libxce_dep]
|
||||
# libedit_dep (defined in the parent meson.build, task 12.1, Req 5 AC 22):
|
||||
# every white-box test TU that #includes ../src/sim_loop.c now transitively
|
||||
# pulls in repl.h's inline wrappers, which reference repl.c's real
|
||||
# readline()/add_history() calls the moment ANY such TU also #includes
|
||||
# ../src/repl.c (already required at link time regardless -- sim_loop.c's
|
||||
# own repl.h wrappers reference xce_repl_start()/xce_repl_post_session_check()
|
||||
# unconditionally). Added to the shared deps list rather than per-test so
|
||||
# every current and future sim-family white-box test picks it up
|
||||
# automatically.
|
||||
scheduler_test_deps = [libxce_deps, librtti_dep, unity_dep, libxce_dep,
|
||||
libedit_dep]
|
||||
|
||||
incdir = include_directories('../include', '../../include', '.', '../src', '../../lib')
|
||||
|
||||
|
|
@ -535,6 +545,12 @@ sched_sim_isolation_test = executable(
|
|||
'-DXCE_SIM_RECORD_C_PATH="'
|
||||
+ (meson.current_source_dir() / '..' / 'src' / 'sim_record.c')
|
||||
+ '"',
|
||||
'-DXCE_SIM_REPL_C_PATH="'
|
||||
+ (meson.current_source_dir() / '..' / 'src' / 'repl.c')
|
||||
+ '"',
|
||||
'-DXCE_SIM_REPL_H_PATH="'
|
||||
+ (meson.current_source_dir() / '..' / 'include' / 'repl.h')
|
||||
+ '"',
|
||||
'-DXCE_SIM_LIB_PATH="'
|
||||
+ sched_sim_isolation_lib.full_path()
|
||||
+ '"'],
|
||||
|
|
@ -636,6 +652,24 @@ sched_sim_equivalence_test = executable(
|
|||
dependencies: [scheduler_test_deps],
|
||||
install: false)
|
||||
|
||||
# Contract test for the interactive simulation REPL's execution-control slice
|
||||
# (scheduler-core spec, task 12.1, Req 5 AC 22): starting simulation with
|
||||
# --interactive pauses before any event is processed, and a `step N` command
|
||||
# advances exactly N sessions before returning control to the prompt. Same
|
||||
# white-box #include pattern as sched_sim_alt_events_test/sched_sim_verify_test
|
||||
# (core.c, core_clock.c, core_events.c, core_session.c, decision.c, plugin.c,
|
||||
# plugins/builtin_fcfs.c, recording.c, recording_session.c, sim.c, sim_loop.c,
|
||||
# sim_record.c, sim_verify.c, snapshot.c/snapshot_wire.c/snapshot_load.c) PLUS
|
||||
# the new ../src/repl.c under test. Needs libedit_dep (parent meson.build)
|
||||
# at link time -- repl.c's real readline()/add_history() calls are pulled
|
||||
# into this TU by the white-box #include.
|
||||
sched_repl_execution_control_test = executable(
|
||||
'sched_repl_execution_control_test',
|
||||
['test_repl_execution_control.c'],
|
||||
include_directories:[incdir],
|
||||
dependencies: [scheduler_test_deps, libedit_dep],
|
||||
install: false)
|
||||
|
||||
# Register as meson tests so `meson test --suite scheduler` runs them all.
|
||||
# detect_leaks=0 matches the suite convention (fixtures are not torn down).
|
||||
test('scheduler test', scheduler_test, suite: 'scheduler',
|
||||
|
|
@ -726,3 +760,6 @@ test('scheduler sim record output test',
|
|||
test('scheduler sim equivalence test',
|
||||
sched_sim_equivalence_test, suite: 'scheduler',
|
||||
env: ['ASAN_OPTIONS=detect_leaks=0'])
|
||||
test('scheduler repl execution control test',
|
||||
sched_repl_execution_control_test, suite: 'scheduler',
|
||||
env: ['ASAN_OPTIONS=detect_leaks=0'])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue