mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 00:02:23 +00:00
fix(ci): gate the tty7-server test suites that need --stdio on Unix
`--stdio` is refused on Windows by design, and the control socket it probes for is Unix-domain, so `stdio_conformance` and `workspace_store` join `remote_router`/`routed_pane` in carrying a file-level `cfg(unix)`. `cli.rs` keeps its argument-handling cases everywhere — `--version`, `--help`, `agent-hook` and the usage error say nothing about transports — and gates only the bridge and probe cases, which spawn a `--stdio` child or stand up a listener.
This commit is contained in:
@@ -6,22 +6,40 @@
|
||||
//! a connection to a control server that is already running, which is the path
|
||||
//! an `ssh host tty7-server --stdio` takes on a machine with a live daemon and
|
||||
//! which no amount of `Host` conformance would exercise.
|
||||
//!
|
||||
//! Everything `--stdio` is Unix-only — the flag is refused on Windows, where a
|
||||
//! machine is reached over its own transport rather than by shipping a server
|
||||
//! onto it (contract §8). The plain argument handling below is not, and runs
|
||||
//! everywhere.
|
||||
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::io;
|
||||
#[cfg(unix)]
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
#[cfg(unix)]
|
||||
use std::process::Child;
|
||||
#[cfg(unix)]
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[cfg(unix)]
|
||||
use tty7_core::daemon::control::{ControlHello, LinkShutdown};
|
||||
#[cfg(unix)]
|
||||
use tty7_core::host::Host;
|
||||
#[cfg(unix)]
|
||||
use tty7_core::host::local::LocalHost;
|
||||
#[cfg(unix)]
|
||||
use tty7_core::host::remote::RemoteHost;
|
||||
#[cfg(unix)]
|
||||
use tty7_core::host::server;
|
||||
|
||||
const EXE: &str = env!("CARGO_BIN_EXE_tty7-server");
|
||||
|
||||
#[cfg(unix)]
|
||||
struct ServerProcess(Mutex<Option<Child>>);
|
||||
|
||||
#[cfg(unix)]
|
||||
impl LinkShutdown for ServerProcess {
|
||||
fn shutdown_link(&self) -> io::Result<()> {
|
||||
if let Some(mut c) = self.0.lock().unwrap_or_else(|e| e.into_inner()).take() {
|
||||
@@ -33,6 +51,7 @@ impl LinkShutdown for ServerProcess {
|
||||
}
|
||||
|
||||
/// Start `tty7-server --stdio <args>` and connect a `RemoteHost` to its pipes.
|
||||
#[cfg(unix)]
|
||||
fn stdio_child(args: &[&str]) -> io::Result<Arc<RemoteHost>> {
|
||||
let mut child = Command::new(EXE)
|
||||
.arg("--stdio")
|
||||
@@ -49,6 +68,7 @@ fn stdio_child(args: &[&str]) -> io::Result<Arc<RemoteHost>> {
|
||||
}
|
||||
|
||||
/// A control server on a temp socket, for the bridge to reach.
|
||||
#[cfg(unix)]
|
||||
fn listening_server(dir: &tempfile::TempDir) -> PathBuf {
|
||||
let sock = dir.path().join("control.sock");
|
||||
let listener = server::bind_control_socket(&sock).unwrap();
|
||||
@@ -63,6 +83,7 @@ fn listening_server(dir: &tempfile::TempDir) -> PathBuf {
|
||||
/// stream carries belongs to the client and the server at the far end, and a
|
||||
/// bridge with an opinion about the protocol would become a third party to a
|
||||
/// negotiation it is not qualified to join.
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn the_bridge_carries_a_whole_session() {
|
||||
let dir = tempfile::TempDir::new().unwrap();
|
||||
@@ -92,6 +113,7 @@ fn the_bridge_carries_a_whole_session() {
|
||||
/// `--bridge` with nowhere to bridge to fails rather than quietly serving
|
||||
/// itself. An operator who asked for the bridge is telling us a server exists;
|
||||
/// silently becoming that server would fork the machine's state in two.
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn an_explicit_bridge_with_no_server_fails() {
|
||||
let dir = tempfile::TempDir::new().unwrap();
|
||||
@@ -105,6 +127,7 @@ fn an_explicit_bridge_with_no_server_fails() {
|
||||
|
||||
/// With neither flag, `--stdio` probes: nothing listening means serve here, so a
|
||||
/// machine that has never run a daemon is still reachable over ssh.
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn the_default_mode_serves_when_nothing_is_listening() {
|
||||
let dir = tempfile::TempDir::new().unwrap();
|
||||
@@ -117,6 +140,7 @@ fn the_default_mode_serves_when_nothing_is_listening() {
|
||||
|
||||
/// ...and something listening means bridge to it, so a second `--stdio` session
|
||||
/// joins the machine's existing server instead of standing up a rival.
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn the_default_mode_bridges_when_a_server_is_listening() {
|
||||
let dir = tempfile::TempDir::new().unwrap();
|
||||
@@ -130,6 +154,7 @@ fn the_default_mode_bridges_when_a_server_is_listening() {
|
||||
}
|
||||
|
||||
/// Contradictory flags are refused rather than one silently winning.
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn serve_and_bridge_together_are_refused() {
|
||||
let out = Command::new(EXE)
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
//! isolation: no case can be explained by another's leftover state, a hung
|
||||
//! server fails exactly one case, and a crash names the behaviour that caused it.
|
||||
|
||||
// Unix-only: every case here is a `--stdio` child, and `--stdio` is refused on
|
||||
// Windows by design — a Windows machine is reached over its own transport, not
|
||||
// by shipping a server onto it (contract §8).
|
||||
#![cfg(unix)]
|
||||
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
//! another's leftovers and nothing here can touch the developer's real
|
||||
//! `~/.local/share/tty7/workspaces.json`.
|
||||
|
||||
// Unix-only, for the same reason as `stdio_conformance.rs`: the server under
|
||||
// test is a `--stdio` child, and two of the cases stand up a control socket.
|
||||
#![cfg(unix)]
|
||||
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Child, Command, Stdio};
|
||||
|
||||
Reference in New Issue
Block a user