mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
fix(ci): restore green main after merge skew and new advisory
Main CI failed on c09730e87 for two unrelated reasons, and the local
pre-push Rust lane also tripped on a load-sensitive test.
Mobile: #8223 was tested against a base from before #8206, which
removed buzzDevPushAppProfile along with app-profile selection. Its new
notification toggle test still put `appProfile` in the native grant map,
so the merged tree did not compile. The field no longer exists, so drop
it.
Security: cargo-deny now reports RUSTSEC-2024-0449 (unsafe-libyaml is
unmaintained), pulled in through serde_yaml. This is an unmaintained
notice, not a vulnerability. Removing the crate means migrating YAML
parsing across several crates, so ignore it with a reason, like the
existing unmaintained entries.
buzz-acp: the spawn_script test helper returned before bash was running,
and timing tests start their idle clock right away. Under full-suite
load, process startup alone took longer than the idle windows, so
keepalive_resets_idle_past_deadline, idle_resets_on_stdout_activity and
the steer capture tests timed out before the script wrote anything. The
helper now has the script print a ready line and consumes it before
returning, so each clock starts once the child is executing. The two
keepalive loops use brace expansion instead of $(seq), dropping an exec
from their first gap, and the keepalive test gets a 250ms idle deadline
(750ms floor) for more headroom; without the reset it still fails.
Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
This commit is contained in:
@@ -3198,10 +3198,30 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// Spawn `script` under bash and return once it is running.
|
||||
///
|
||||
/// Process startup can take hundreds of milliseconds on a loaded host,
|
||||
/// which would otherwise eat into the idle and timing windows the tests
|
||||
/// measure. The script prints a ready line first, consumed here, so each
|
||||
/// test's clock starts only after the child is actually executing.
|
||||
async fn spawn_script(script: &str) -> AcpClient {
|
||||
AcpClient::spawn("bash", &["-c".into(), script.into()], &[], false)
|
||||
const READY: &str = "buzz-acp-test-script-ready";
|
||||
let mut client = AcpClient::spawn(
|
||||
"bash",
|
||||
&["-c".into(), format!("echo {READY}; {script}")],
|
||||
&[],
|
||||
false,
|
||||
)
|
||||
.await
|
||||
.expect("failed to spawn test script");
|
||||
let ready = tokio::time::timeout(std::time::Duration::from_secs(10), client.reader.next())
|
||||
.await
|
||||
.expect("failed to spawn test script")
|
||||
.expect("test script should start within 10s");
|
||||
assert!(
|
||||
matches!(&ready, Some(Ok(line)) if line == READY),
|
||||
"expected ready line, got {ready:?}"
|
||||
);
|
||||
client
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -3367,7 +3387,7 @@ mod tests {
|
||||
// Send valid JSON (session/update notifications) to reset the idle timer.
|
||||
// Non-JSON lines no longer reset idle — only valid JSON notifications do.
|
||||
let mut client = spawn_script(
|
||||
r#"for i in $(seq 1 10); do echo '{"jsonrpc":"2.0","method":"session/update","params":{"update":{"sessionUpdate":"agent_thought_chunk","content":{"text":"thinking"}}}}'; sleep 0.05; done; sleep 10"#,
|
||||
r#"for i in {1..10}; do echo '{"jsonrpc":"2.0","method":"session/update","params":{"update":{"sessionUpdate":"agent_thought_chunk","content":{"text":"thinking"}}}}'; sleep 0.05; done; sleep 10"#,
|
||||
)
|
||||
.await;
|
||||
let max_dur = std::time::Duration::from_secs(10);
|
||||
@@ -3561,10 +3581,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn keepalive_resets_idle_past_deadline() {
|
||||
// Keepalive session/update lines every 50ms against a 100ms idle deadline.
|
||||
// The turn should survive well past the 100ms deadline (proves the fix).
|
||||
// Keepalive session/update lines every 50ms against a 250ms idle deadline.
|
||||
// The turn should survive well past the idle deadline (proves the fix).
|
||||
let mut client = spawn_script(
|
||||
r#"for i in $(seq 1 20); do echo '{"jsonrpc":"2.0","method":"session/update","params":{"update":{"sessionUpdate":"keepalive"}}}'; sleep 0.05; done; sleep 10"#,
|
||||
r#"for i in {1..20}; do echo '{"jsonrpc":"2.0","method":"session/update","params":{"update":{"sessionUpdate":"keepalive"}}}'; sleep 0.05; done; sleep 10"#,
|
||||
)
|
||||
.await;
|
||||
let max_dur = std::time::Duration::from_secs(10);
|
||||
@@ -3574,16 +3594,16 @@ mod tests {
|
||||
.read_until_response_with_idle_timeout(
|
||||
"test",
|
||||
999,
|
||||
std::time::Duration::from_millis(100),
|
||||
std::time::Duration::from_millis(250),
|
||||
hard_deadline,
|
||||
max_dur,
|
||||
)
|
||||
.await;
|
||||
let elapsed = start.elapsed();
|
||||
// 20 keepalives × 50ms = ~1000ms of activity, then idle fires after 100ms more.
|
||||
// Must survive well past the 100ms deadline.
|
||||
// 20 keepalives × 50ms = ~1000ms of activity, then idle fires after 250ms more.
|
||||
// Must survive well past the 250ms deadline.
|
||||
assert!(
|
||||
elapsed >= std::time::Duration::from_millis(500),
|
||||
elapsed >= std::time::Duration::from_millis(750),
|
||||
"keepalive should reset idle past the deadline; elapsed only {elapsed:?}"
|
||||
);
|
||||
assert!(elapsed < std::time::Duration::from_secs(5));
|
||||
|
||||
@@ -15,6 +15,11 @@ ignore = [
|
||||
# remove these when upstream catches up.
|
||||
{ id = "RUSTSEC-2026-0194", reason = "transitive via rust-s3 and mesh-llm→plist; trusted-input XML only; no upstream fix available yet" },
|
||||
{ id = "RUSTSEC-2026-0195", reason = "transitive via rust-s3 and mesh-llm→plist; trusted-input XML only; no upstream fix available yet" },
|
||||
# unsafe-libyaml 0.2.11 — unmaintained (repository archived 2024-03-25), not a
|
||||
# vulnerability report. Transitive dep: serde_yaml → unsafe-libyaml. The serde_yaml_ng
|
||||
# fork uses the same crate, so removing it means migrating YAML parsing in
|
||||
# buzz-agent, buzz-persona, buzz-relay, buzz-workflow and desktop.
|
||||
{ id = "RUSTSEC-2024-0449", reason = "transitive via serde_yaml; unmaintained, not vulnerable; removal needs a YAML parser migration" },
|
||||
]
|
||||
|
||||
[licenses]
|
||||
|
||||
@@ -78,7 +78,6 @@ void main() {
|
||||
'installationId': 'b' * 32,
|
||||
'endpointGrant': 'test-endpoint-grant',
|
||||
'endpointHash': 'c' * 64,
|
||||
'appProfile': buzzDevPushAppProfile,
|
||||
'endpointEpoch': 1,
|
||||
'generation': 1,
|
||||
'expiresAt': DateTime.now().millisecondsSinceEpoch ~/ 1000 + 3600,
|
||||
|
||||
Reference in New Issue
Block a user