fix me lol

This commit is contained in:
2026-08-29 17:11:55 -05:00
parent 4b7ab4f10a
commit 94a2d4fed6
12 changed files with 1912 additions and 55 deletions
+32 -2
View File
@@ -42,14 +42,44 @@ fn bare_subcommands_are_recognised() {
assert_eq!(parse_args(&args(&["--version"])).unwrap(), Command::Version);
assert_eq!(
parse_args(&args(&["ndi-sources"])).unwrap(),
Command::ListNdiSources { timeout_secs: 5 }
Command::ListNdiSources { timeout_secs: 5, extra_ips: Vec::new() }
);
assert_eq!(
parse_args(&args(&["ndi-sources", "--timeout", "20"])).unwrap(),
Command::ListNdiSources { timeout_secs: 20 }
Command::ListNdiSources { timeout_secs: 20, extra_ips: Vec::new() }
);
}
#[test]
fn ndi_sources_accepts_repeated_unicast_hints() {
assert_eq!(
parse_args(&args(&[
"ndi-sources", "--extra-ip", "10.0.0.5", "--timeout", "8",
"--extra-ip", "ndi.example.test",
]))
.unwrap(),
Command::ListNdiSources {
timeout_secs: 8,
extra_ips: vec!["10.0.0.5".into(), "ndi.example.test".into()],
}
);
assert_eq!(
parse_args(&args(&["ndi-sources", "--timeout", "300"])).unwrap(),
Command::ListNdiSources { timeout_secs: 300, extra_ips: Vec::new() }
);
}
#[test]
fn ndi_sources_rejects_bad_options_and_values() {
assert!(parse_args(&args(&["ndi-sources", "--timeout"])).is_err());
assert!(parse_args(&args(&["ndi-sources", "--timeout", "soon"])).is_err());
assert!(parse_args(&args(&["ndi-sources", "--timeout", "0"])).is_err());
assert!(parse_args(&args(&["ndi-sources", "--timeout", "301"])).is_err());
assert!(parse_args(&args(&["ndi-sources", "--timeout", "18446744073709551615"])).is_err());
assert!(parse_args(&args(&["ndi-sources", "--extra-ip"])).is_err());
assert!(parse_args(&args(&["ndi-sources", "--source", "anything"])).is_err());
}
#[test]
fn no_arguments_is_an_error_with_usage() {
let e = parse_args(&[]).unwrap_err();
+86
View File
@@ -0,0 +1,86 @@
//! Process-level checks for the NDI runtime boundary.
//!
//! These deliberately run the real binary in fresh processes so the loader's
//! one-time cache cannot leak from one assertion into another.
use std::path::PathBuf;
use std::process::Command;
use std::time::{SystemTime, UNIX_EPOCH};
fn binary() -> &'static str {
env!("CARGO_BIN_EXE_video-output")
}
fn definitely_missing_runtime_dir() -> PathBuf {
let nonce = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("the system clock should be after 1970")
.as_nanos();
std::env::temp_dir().join(format!(
"video-output-missing-ndi-runtime-{}-{nonce}",
std::process::id()
))
}
#[test]
fn missing_ndi_runtime_is_clear_and_does_not_affect_non_ndi_commands() {
let missing = definitely_missing_runtime_dir();
let ndi = Command::new(binary())
.args(["ndi-sources", "--timeout", "1"])
.env("NDI_RUNTIME_DIR_V6", &missing)
.env_remove("JOURNAL_STREAM")
.output()
.expect("run video-output ndi-sources");
assert!(!ndi.status.success(), "NDI discovery must fail without its runtime");
let diagnostic = format!(
"{}{}",
String::from_utf8_lossy(&ndi.stdout),
String::from_utf8_lossy(&ndi.stderr)
)
.to_ascii_lowercase();
assert!(
diagnostic.contains("could not load the ndi runtime"),
"expected a clear NDI loader error, got: {diagnostic}"
);
let version = Command::new(binary())
.arg("--version")
.env("NDI_RUNTIME_DIR_V6", &missing)
.env_remove("JOURNAL_STREAM")
.output()
.expect("run video-output --version");
assert!(
version.status.success(),
"a missing NDI runtime must not affect non-NDI commands: {}",
String::from_utf8_lossy(&version.stderr)
);
assert!(String::from_utf8_lossy(&version.stdout).contains("video-output"));
}
#[cfg(target_os = "linux")]
#[test]
fn elf_has_no_hard_dependency_on_libndi() {
let output = match Command::new("readelf").args(["-d", binary()]).output() {
Ok(output) => output,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
eprintln!("skipping ELF dependency check: readelf is not installed");
return;
}
Err(e) => panic!("could not run readelf: {e}"),
};
assert!(
output.status.success(),
"readelf failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let dynamic = String::from_utf8_lossy(&output.stdout);
let needed: Vec<&str> = dynamic.lines().filter(|line| line.contains("(NEEDED)")).collect();
assert!(
needed.iter().all(|line| !line.to_ascii_lowercase().contains("libndi")),
"binary acquired a hard NDI dependency:\n{}",
needed.join("\n")
);
}