mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-21 20:18:06 +02:00
[pitboss/grind] deferred session-0011 (20260516T052512Z-20f8)
This commit is contained in:
parent
c162c638a2
commit
d126f3c15c
15 changed files with 510 additions and 10 deletions
|
|
@ -193,6 +193,18 @@ pub trait StubProvider: Send + Sync + std::fmt::Debug {
|
|||
/// empty vec (the oracle treats "no events" as "stub was not
|
||||
/// touched").
|
||||
fn drain_events(&self) -> Vec<StubEvent>;
|
||||
|
||||
/// Optional companion env var that publishes a host-visible
|
||||
/// recording-path the harness can append observations to. The
|
||||
/// primary [`StubProvider::endpoint`] is the *connection* the
|
||||
/// harness uses (e.g. a SQLite DB path); the recording endpoint is
|
||||
/// the *side channel* a per-language shim helper writes structured
|
||||
/// records into so the host can correlate them on
|
||||
/// [`StubProvider::drain_events`]. Default `None` means the stub
|
||||
/// does not need a side-channel recording path.
|
||||
fn recording_endpoint(&self) -> Option<(&'static str, String)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Aggregate handle the verifier owns for the lifetime of one
|
||||
|
|
@ -242,11 +254,22 @@ impl StubHarness {
|
|||
/// the sandbox env. The order matches `StubHarness::start`'s kinds
|
||||
/// argument so later entries override earlier ones if a harness is
|
||||
/// re-used with conflicting requests (it currently never is).
|
||||
///
|
||||
/// Each stub publishes its primary connection endpoint
|
||||
/// ([`StubKind::env_var`]) first, then any companion recording
|
||||
/// endpoint ([`StubProvider::recording_endpoint`]) it owns. Today
|
||||
/// only [`SqlStub`] publishes a recording endpoint
|
||||
/// (`NYX_SQL_LOG`); the other three stubs keep their primary
|
||||
/// endpoint as the sole pair.
|
||||
pub fn endpoints(&self) -> Vec<(&'static str, String)> {
|
||||
self.stubs
|
||||
.iter()
|
||||
.map(|s| (s.kind().env_var(), s.endpoint()))
|
||||
.collect()
|
||||
let mut out = Vec::with_capacity(self.stubs.len() * 2);
|
||||
for s in &self.stubs {
|
||||
out.push((s.kind().env_var(), s.endpoint()));
|
||||
if let Some(pair) = s.recording_endpoint() {
|
||||
out.push(pair);
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Borrow the underlying stub list (for tests and oracle wiring).
|
||||
|
|
@ -379,4 +402,29 @@ mod tests {
|
|||
assert!(names.contains(&"NYX_HTTP_ENDPOINT"));
|
||||
assert!(names.contains(&"NYX_FS_ROOT"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn endpoints_includes_sql_recording_path_companion_var() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
let h = StubHarness::start(&[StubKind::Sql], dir.path()).unwrap();
|
||||
let pairs = h.endpoints();
|
||||
let names: Vec<&str> = pairs.iter().map(|(n, _)| *n).collect();
|
||||
assert!(
|
||||
names.contains(&"NYX_SQL_ENDPOINT"),
|
||||
"primary endpoint must be present"
|
||||
);
|
||||
assert!(
|
||||
names.contains(&"NYX_SQL_LOG"),
|
||||
"SqlStub recording-path companion env var must be published"
|
||||
);
|
||||
let log_pair = pairs
|
||||
.iter()
|
||||
.find(|(n, _)| *n == "NYX_SQL_LOG")
|
||||
.expect("NYX_SQL_LOG entry");
|
||||
assert!(
|
||||
log_pair.1.ends_with("nyx_sql_stub.queries.log"),
|
||||
"recording path must point at the queries log file, got {}",
|
||||
log_pair.1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,11 @@ impl SqlStub {
|
|||
}
|
||||
}
|
||||
|
||||
/// Companion env var that publishes [`SqlStub::log_path`] so a
|
||||
/// language-side shim can append executed queries the host will pick
|
||||
/// up on [`SqlStub::drain_events`].
|
||||
pub const SQL_STUB_LOG_ENV_VAR: &str = "NYX_SQL_LOG";
|
||||
|
||||
impl StubProvider for SqlStub {
|
||||
fn kind(&self) -> StubKind {
|
||||
StubKind::Sql
|
||||
|
|
@ -120,6 +125,10 @@ impl StubProvider for SqlStub {
|
|||
self.db_path.to_string_lossy().into_owned()
|
||||
}
|
||||
|
||||
fn recording_endpoint(&self) -> Option<(&'static str, String)> {
|
||||
Some((SQL_STUB_LOG_ENV_VAR, self.log_path.to_string_lossy().into_owned()))
|
||||
}
|
||||
|
||||
fn drain_events(&self) -> Vec<StubEvent> {
|
||||
let mut cursor = match self.cursor.lock() {
|
||||
Ok(g) => g,
|
||||
|
|
@ -263,4 +272,16 @@ mod tests {
|
|||
let stub = SqlStub::start(dir.path()).unwrap();
|
||||
assert_eq!(stub.kind(), StubKind::Sql);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recording_endpoint_publishes_log_path_under_nyx_sql_log() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
let stub = SqlStub::start(dir.path()).unwrap();
|
||||
let pair = stub
|
||||
.recording_endpoint()
|
||||
.expect("SqlStub must publish a recording endpoint");
|
||||
assert_eq!(pair.0, SQL_STUB_LOG_ENV_VAR);
|
||||
assert_eq!(pair.0, "NYX_SQL_LOG");
|
||||
assert_eq!(pair.1, stub.log_path().to_string_lossy());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue