diff options
author | Sven-Hendrik Haase <svenstaro@gmail.com> | 2021-08-26 23:13:24 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-26 23:13:24 +0000 |
commit | 4ab0756eb007a0263e174d1116132a2b55ef0fe3 (patch) | |
tree | 89439bc8e5c772d95996542e992d95f8b96297a4 /tests/fixtures/mod.rs | |
parent | Upgrade deps (diff) | |
parent | new partial-injection syntax (diff) | |
download | miniserve-4ab0756eb007a0263e174d1116132a2b55ef0fe3.tar.gz miniserve-4ab0756eb007a0263e174d1116132a2b55ef0fe3.zip |
Merge pull request #506 from aliemjay/test-refactor
[Refactor] tests: Refactor!
Diffstat (limited to 'tests/fixtures/mod.rs')
-rw-r--r-- | tests/fixtures/mod.rs | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/tests/fixtures/mod.rs b/tests/fixtures/mod.rs index 1cf6c59..a227f84 100644 --- a/tests/fixtures/mod.rs +++ b/tests/fixtures/mod.rs @@ -1,7 +1,12 @@ +use assert_cmd::prelude::*; use assert_fs::fixture::TempDir; use assert_fs::prelude::*; use port_check::free_local_port; +use reqwest::Url; use rstest::fixture; +use std::process::{Child, Command, Stdio}; +use std::thread::sleep; +use std::time::{Duration, Instant}; /// Error type used by tests pub type Error = Box<dyn std::error::Error>; @@ -76,3 +81,100 @@ pub fn tmpdir() -> TempDir { pub fn port() -> u16 { free_local_port().expect("Couldn't find a free local port") } + +/// Run miniserve as a server; Start with a temporary directory, a free port and some +/// optional arguments then wait for a while for the server setup to complete. +#[fixture] +#[allow(dead_code)] +pub fn server<I>(#[default(&[] as &[&str])] args: I) -> TestServer +where + I: IntoIterator, + I::Item: AsRef<std::ffi::OsStr>, +{ + let port = port(); + let tmpdir = tmpdir(); + let child = Command::cargo_bin("miniserve") + .expect("Couldn't find test binary") + .arg(tmpdir.path()) + .arg("-p") + .arg(port.to_string()) + .args(args) + .stdout(Stdio::null()) + .spawn() + .expect("Couldn't run test binary"); + + wait_for_port(port); + TestServer::new(port, tmpdir, child) +} + +/// Same as `server()` but ignore stderr +#[fixture] +#[allow(dead_code)] +pub fn server_no_stderr<I>(#[default(&[] as &[&str])] args: I) -> TestServer +where + I: IntoIterator, + I::Item: AsRef<std::ffi::OsStr>, +{ + let port = port(); + let tmpdir = tmpdir(); + let child = Command::cargo_bin("miniserve") + .expect("Couldn't find test binary") + .arg(tmpdir.path()) + .arg("-p") + .arg(port.to_string()) + .args(args) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .expect("Couldn't run test binary"); + + wait_for_port(port); + TestServer::new(port, tmpdir, child) +} + +/// Wait a max of 1s for the port to become available. +fn wait_for_port(port: u16) { + let start_wait = Instant::now(); + + while !port_check::is_port_reachable(format!("localhost:{}", port)) { + sleep(Duration::from_millis(100)); + + if start_wait.elapsed().as_secs() > 1 { + panic!("timeout waiting for port {}", port); + } + } +} + +#[allow(dead_code)] +pub struct TestServer { + port: u16, + tmpdir: TempDir, + child: Child, +} + +#[allow(dead_code)] +impl TestServer { + pub fn new(port: u16, tmpdir: TempDir, child: Child) -> Self { + Self { + port, + tmpdir, + child, + } + } + pub fn url(&self) -> Url { + Url::parse(&format!("http://localhost:{}", self.port)).unwrap() + } + pub fn path(&self) -> &std::path::Path { + self.tmpdir.path() + } + pub fn port(&self) -> u16 { + self.port + } +} + +impl Drop for TestServer { + fn drop(&mut self) { + self.child.kill().expect("Couldn't kill test server"); + self.child.wait().unwrap(); + } +} |