CI fixes
This commit is contained in:
parent
b6689a3927
commit
146583d32a
|
|
@ -61,7 +61,7 @@ jobs:
|
|||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: perf, memory, and 30s fuzz gates
|
||||
run: cargo test --release --test acceptance -- --ignored --nocapture
|
||||
run: cargo test --release --test acceptance -- --ignored --nocapture --test-threads=1
|
||||
|
||||
m4-perf-gates:
|
||||
name: M4 Perf Gates
|
||||
|
|
@ -71,7 +71,7 @@ jobs:
|
|||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: tree-sitter parse + highlight latency budgets
|
||||
run: cargo test --release --test m4_acceptance -- --ignored --nocapture
|
||||
run: cargo test --release --test m4_acceptance -- --ignored --nocapture --test-threads=1
|
||||
|
||||
# m5-perf-gates: luajit-only by design.
|
||||
# The keystroke-to-render gate measures protocol-path latency (Unix
|
||||
|
|
|
|||
|
|
@ -79,6 +79,18 @@ fn daemon_debug_enabled() -> bool {
|
|||
std::env::var_os(PMACS_ATTACH_DEBUG).is_some_and(|v| !v.is_empty() && v != "0")
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
fn peer_uid(stream: &UnixStream) -> Option<u32> {
|
||||
nix::sys::socket::getsockopt(stream, nix::sys::socket::sockopt::PeerCredentials)
|
||||
.ok()
|
||||
.map(|cred| cred.uid())
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
fn peer_uid(_stream: &UnixStream) -> Option<u32> {
|
||||
None
|
||||
}
|
||||
|
||||
fn daemon_debug(msg: impl AsRef<str>) {
|
||||
if daemon_debug_enabled() {
|
||||
eprintln!("pmacs daemon debug: {}", msg.as_ref());
|
||||
|
|
@ -698,16 +710,13 @@ fn per_attach_thread(
|
|||
// reconnect → same color slot. If SO_PEERCRED fails (e.g.,
|
||||
// non-Unix peer, kernel API unavailable), fall back to a
|
||||
// per-FrontendId slot (degrades to per-connection stability).
|
||||
let color_slot =
|
||||
match nix::sys::socket::getsockopt(&stream, nix::sys::socket::sockopt::PeerCredentials) {
|
||||
Ok(cred) => daemon_state.color_slot_for_uid(cred.uid()),
|
||||
Err(_) => {
|
||||
// Fallback: use frontend_id-based slot; per-connection
|
||||
// stability only (no cross-reconnect within session).
|
||||
u8::try_from(frontend_id.0 % (crate::overlay_color::PALETTE_LEN as u64))
|
||||
.unwrap_or(0)
|
||||
}
|
||||
};
|
||||
let color_slot = if let Some(uid) = peer_uid(&stream) {
|
||||
daemon_state.color_slot_for_uid(uid)
|
||||
} else {
|
||||
// Fallback: use frontend_id-based slot; per-connection
|
||||
// stability only (no cross-reconnect within session).
|
||||
u8::try_from(frontend_id.0 % (crate::overlay_color::PALETTE_LEN as u64)).unwrap_or(0)
|
||||
};
|
||||
|
||||
let session_state =
|
||||
crate::presence::SessionState::new(req.protocol_version, negotiated_caps, color_slot);
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ const READER_SEND_POLL_INTERVAL: Duration = Duration::from_millis(50);
|
|||
/// parser worker may still have already-read bytes in flight. This is
|
||||
/// not process termination grace; it is only the final output flush
|
||||
/// before the runtime handles are dropped.
|
||||
const EXIT_OUTPUT_DRAIN_TIMEOUT: Duration = Duration::from_millis(250);
|
||||
const EXIT_OUTPUT_DRAIN_TIMEOUT: Duration = Duration::from_secs(2);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Supervisor
|
||||
|
|
|
|||
|
|
@ -294,10 +294,18 @@ fn cli_attach_invokes_test_ssh_with_expected_argv() {
|
|||
});
|
||||
let lines: Vec<&str> = argv.lines().collect();
|
||||
// build_ssh_command for `ssh:mac-studio` (no user, no instance)
|
||||
// emits `[-T, host, "pmacs", "--daemon-attach"]`.
|
||||
// defaults to the stderr protocol channel and advertises the
|
||||
// remote fd through env.
|
||||
assert_eq!(
|
||||
lines,
|
||||
vec!["-T", "mac-studio", "pmacs", "--daemon-attach"],
|
||||
vec![
|
||||
"-T",
|
||||
"mac-studio",
|
||||
"env",
|
||||
"PMACS_ATTACH_PROTOCOL_FD=2",
|
||||
"pmacs",
|
||||
"--daemon-attach",
|
||||
],
|
||||
"argv shape: {lines:?}"
|
||||
);
|
||||
}
|
||||
|
|
@ -330,6 +338,8 @@ fn cli_attach_with_user_and_instance_name_passes_through_dash_l_and_dash_dash_so
|
|||
"-l",
|
||||
"alice",
|
||||
"workstation",
|
||||
"env",
|
||||
"PMACS_ATTACH_PROTOCOL_FD=2",
|
||||
"pmacs",
|
||||
"--daemon-attach",
|
||||
"--socket",
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ use pmacs::protocol::{
|
|||
mod common;
|
||||
use common::pty::spawn_pmacs_in_pty;
|
||||
|
||||
const PMACS_ATTACH_SSH_PROTOCOL: &str = "PMACS_ATTACH_SSH_PROTOCOL";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -145,6 +147,7 @@ fn handshake_retry_cap_fires_after_three_failed_handshakes() {
|
|||
let output = Command::new(env!("CARGO_BIN_EXE_pmacs"))
|
||||
.args(["--attach", "host"])
|
||||
.env(PMACS_TEST_SSH_BIN, &fake_ssh)
|
||||
.env(PMACS_ATTACH_SSH_PROTOCOL, "stdout")
|
||||
.env(PMACS_TEST_BACKOFF_SCALE_MS, "1")
|
||||
.env("HOME", isolated_home)
|
||||
.env("XDG_CONFIG_HOME", isolated_home)
|
||||
|
|
@ -261,6 +264,7 @@ fn ssh_stderr_from_handshake_attempts_reaches_user() {
|
|||
let output = Command::new(env!("CARGO_BIN_EXE_pmacs"))
|
||||
.args(["--attach", "host"])
|
||||
.env(PMACS_TEST_SSH_BIN, &fake_ssh)
|
||||
.env(PMACS_ATTACH_SSH_PROTOCOL, "stdout")
|
||||
.env(PMACS_TEST_BACKOFF_SCALE_MS, "1")
|
||||
.env("HOME", isolated_home)
|
||||
.env("XDG_CONFIG_HOME", isolated_home)
|
||||
|
|
@ -438,6 +442,7 @@ fn ssh_dies_mid_pump_then_reconnect_succeeds() {
|
|||
&["--attach", "host"],
|
||||
&[
|
||||
(PMACS_TEST_SSH_BIN, fx.fake_ssh.as_path()),
|
||||
(PMACS_ATTACH_SSH_PROTOCOL, Path::new("stdout")),
|
||||
(PMACS_TEST_BACKOFF_SCALE_MS, Path::new("1")),
|
||||
("HOME", fx.isolated_home.as_path()),
|
||||
("XDG_CONFIG_HOME", fx.isolated_home.as_path()),
|
||||
|
|
@ -489,6 +494,7 @@ fn ctrl_c_during_reconnect_sleep_yields_clean_exit() {
|
|||
&["--attach", "host"],
|
||||
&[
|
||||
(PMACS_TEST_SSH_BIN, fx.fake_ssh.as_path()),
|
||||
(PMACS_ATTACH_SSH_PROTOCOL, Path::new("stdout")),
|
||||
(PMACS_TEST_BACKOFF_SCALE_MS, Path::new("1000")),
|
||||
("HOME", fx.isolated_home.as_path()),
|
||||
("XDG_CONFIG_HOME", fx.isolated_home.as_path()),
|
||||
|
|
|
|||
|
|
@ -32,11 +32,17 @@
|
|||
use pmacs::editor::EditorState;
|
||||
use std::fmt::Write as _;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
static PUMP_TEST_LOCK: Mutex<()> = Mutex::new(());
|
||||
|
||||
fn pump_test_guard() -> MutexGuard<'static, ()> {
|
||||
PUMP_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
}
|
||||
|
||||
/// Locate a shell binary for tests that require one. Returns the
|
||||
/// resolved path or `None` if the shell is neither at `PMACS_TEST_<NAME>`
|
||||
/// nor on `PATH`. Per-test selective skipping (rather than skipping
|
||||
|
|
@ -70,6 +76,7 @@ fn locate_shell(name: &str) -> Option<PathBuf> {
|
|||
|
||||
/// Construct a fresh editor and run the given Lua chunk against it.
|
||||
fn run(chunk: &str) {
|
||||
let _guard = pump_test_guard();
|
||||
let mut editor = EditorState::new();
|
||||
editor
|
||||
.lua_host
|
||||
|
|
@ -84,7 +91,7 @@ fn run(chunk: &str) {
|
|||
/// `poll_until` pattern but routes through `tick_processes` so the M6.5
|
||||
/// after-tick contract is exercised end-to-end.
|
||||
fn run_with_pump(setup_chunk: &str, predicate_chunk: &str, timeout_ms: u64) {
|
||||
let _guard = PUMP_TEST_LOCK.lock().expect("pump test lock");
|
||||
let _guard = pump_test_guard();
|
||||
let mut editor = EditorState::new();
|
||||
editor
|
||||
.lua_host
|
||||
|
|
|
|||
Loading…
Reference in New Issue