Search code examples
testingrustrust-tokio

How to run a server (a process) for the duration of integration tests?


My problem is that server process doesn't get shut down after the last integration test.

In integration.rs, I have:

lazy_static! {
    static ref SERVER: Arc<Mutex<duct::ReaderHandle>> = {
        println!("Starting server");
        Arc::new(Mutex::new(
            cmd!("cargo", "run", "--", "13000")
                .reader()
                .expect("Valid server"),
        ))
    };
}

async fn wait_for_server() {
    lazy_static::initialize(&SERVER);
    // Code to wait
}

#[tokio::test]
async fn integration_test_query_amount() -> Result<()> {
    wait_for_server().await;
    let client = reqwest::Client::new();
    // Etc...
}

The tests work, but the server stays running after the cargo test invocation finishes. Is there a nice recipe for starting up and shutting down a server like this?


Solution

  • You can make a Drop wrapper for a process which will kill it when it goes out of scope. Something along the lines of:

    struct KillOnDrop(std::process::Child);
    
    impl Drop for KillOnDrop {
        fn drop(&mut self) {
            self.0.kill()
        }
    }
    

    Alternatively, as it looks like you're using tokio already, tokio::process supports this out of the box.