use std::io::Read;
use std::net::TcpListener as StdTcpListener;
use std::process::{Child, Command, Stdio};
use std::time::Duration;
fn binary_path() -> &'static str {
env!("CARGO_BIN_EXE_velesdb-memory")
}
fn pick_free_port() -> u16 {
StdTcpListener::bind("127.0.0.1:0")
.expect("bind an ephemeral port")
.local_addr()
.expect("read the bound address")
.port()
}
struct ChildGuard(Child);
impl Drop for ChildGuard {
fn drop(&mut self) {
let _ = self.0.kill();
let _ = self.0.wait();
}
}
fn startup_stderr(store: &std::path::Path) -> String {
let mut child = Command::new(binary_path())
.arg("--http")
.arg("--http-insecure")
.arg("--http-port")
.arg(pick_free_port().to_string())
.env("VELESDB_MEMORY_PATH", store)
.env_remove("VELESDB_MEMORY_CONFIG")
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::piped())
.spawn()
.expect("spawn velesdb-memory");
let mut stderr = child.stderr.take().expect("piped stderr");
let mut guard = ChildGuard(child);
std::thread::sleep(Duration::from_secs(2));
let _ = guard.0.kill();
let _ = guard.0.wait();
let mut out = String::new();
let _ = stderr.read_to_string(&mut out);
out
}
#[test]
fn a_config_beside_the_moved_store_is_the_one_that_is_read() {
let store = tempfile::tempdir().expect("scratch store");
std::fs::write(
store.path().join("velesdb-memory.toml"),
"[http]\nmax_sessions = 7\n",
)
.expect("write the scratch config");
let stderr = startup_stderr(store.path());
let expected = store.path().join("velesdb-memory.toml");
assert!(
stderr.contains(&expected.display().to_string()),
"the config beside the moved store must be the one loaded; \
stderr was: {stderr}"
);
}
#[test]
fn no_config_beside_the_moved_store_loads_nothing() {
let store = tempfile::tempdir().expect("scratch store");
let stderr = startup_stderr(store.path());
assert!(
!stderr.contains("setting(s) from"),
"an empty store must load no config at all — not the default store's; \
stderr was: {stderr}"
);
}