use super::{SCHEMA, registered, run, schema_client};
use std::io::{Read, Write};
use std::net::TcpListener;
use std::sync::mpsc;
use std::time::Duration;
type TestResult = Result<(), Box<dyn std::error::Error>>;
#[test]
fn schema_request_has_a_total_deadline() -> TestResult {
let listener = TcpListener::bind("127.0.0.1:0")?;
let address = url::Url::parse(&format!("http://{}/schema", listener.local_addr()?))?;
let (release, released) = mpsc::channel();
let server = std::thread::spawn(move || -> std::io::Result<()> {
let (_stream, _) = listener.accept()?;
released.recv().map_err(std::io::Error::other)?;
Ok(())
});
let (send, receive) = mpsc::channel();
let worker = std::thread::spawn(move || -> Result<(), String> {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.map_err(|error| error.to_string())?;
let http = schema_client(Duration::from_millis(50))?;
let result = runtime.block_on(registered(&http, &address, "fixture"));
send.send(result).map_err(|error| error.to_string())
});
let answer = receive.recv_timeout(Duration::from_secs(2));
release.send(())?;
server.join().map_err(|_| "server panicked")??;
worker.join().map_err(|_| "request panicked")??;
assert!(
answer.is_ok(),
"schema request outlived its configured total timeout"
);
assert!(answer?.is_err());
Ok(())
}
#[test]
fn schema_status_leaves_stdout_available_for_install_json() -> TestResult {
let listener = TcpListener::bind("127.0.0.1:0")?;
let issuer = format!("http://{}/", listener.local_addr()?);
let server = std::thread::spawn(move || -> std::io::Result<()> {
let (mut stream, _) = listener.accept()?;
let mut byte = [0];
let mut head = Vec::new();
while !head.ends_with(b"\r\n\r\n") {
stream.read_exact(&mut byte)?;
head.push(byte[0]);
}
let schema: serde_json::Value = serde_json::from_str(SCHEMA)?;
let body = serde_json::json!({"version": 1, "schema": schema}).to_string();
write!(
stream,
"HTTP/1.1 200 OK\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{body}",
body.len()
)?;
Ok(())
});
let output = std::process::Command::new(std::env::current_exe()?)
.args([
"--exact",
"serve::lys_schema::deadline_tests::schema_output_child",
"--nocapture",
])
.env("HAEMATITE_SCHEMA_TEST_ISSUER", issuer)
.output()?;
server.join().map_err(|_| "server panicked")??;
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout)?;
let stderr = String::from_utf8(output.stderr)?;
assert!(
!stdout.contains("registered:"),
"schema status polluted stdout: {stdout}"
);
assert!(
stderr.contains("registered:"),
"schema status was absent from stderr: {stderr}"
);
Ok(())
}
#[test]
fn schema_output_child() -> TestResult {
let Ok(issuer) = std::env::var("HAEMATITE_SCHEMA_TEST_ISSUER") else {
return Ok(());
};
let dir = tempfile::tempdir()?;
let path = dir.path().join("credential");
std::fs::write(&path, "lys-app.haematite.fixture")?;
run([
"--issuer".to_owned(),
issuer,
"--credential-file".to_owned(),
path.display().to_string(),
"--check".to_owned(),
]
.into_iter())?;
Ok(())
}