testcontainers / testcontainers-rs

A library for integration-testing against docker containers from within Rust.
https://rust.testcontainers.org
Apache License 2.0
769 stars 141 forks source link

Container doesn't stop after test with std::sync::OnceLock #528

Closed nearwall closed 7 months ago

nearwall commented 1 year ago

Hello for everyone!

I'm trying to use testcontiners for tests with static container.

testcontainers = "0.15.0"
rust-version = "1.70.0"

I've chosen std::sync::OnceLock for such purpose. There is my simple code snippet:

use std::sync::OnceLock;

use testcontainers::{clients, core::WaitFor, Container, GenericImage};

static DOCKER_CLI: OnceLock<clients::Cli> = OnceLock::new();
static DOCKER_CONTAINER: OnceLock<Container<'_, GenericImage>> = OnceLock::new();

const DOCKER_IMAGE_NAME: &str = "postgres";
const DOCKER_IMAGE_TAG: &str = "16.0-alpine3.18";
const DB_NAME: &str = "postgres";
const DB_USER: &str = "postgres";
const DB_PASSWORD: &str = "postgres";

fn get_static_container() -> &'static Container<'static, GenericImage> {
    let cli = DOCKER_CLI.get_or_init(clients::Cli::default);
    DOCKER_CONTAINER.get_or_init(|| {
        let image = GenericImage::new(DOCKER_IMAGE_NAME, DOCKER_IMAGE_TAG)
            .with_env_var("POSTGRES_DB".to_string(), DB_NAME)
            .with_env_var("POSTGRES_USER".to_string(), DB_USER)
            .with_env_var("POSTGRES_PASSWORD".to_string(), DB_PASSWORD)
            .with_wait_for(WaitFor::message_on_stdout("database system is ready to accept connections"));
        cli.run(image)
    })
}

#[tokio::test(flavor = "multi_thread")]
async fn test_async() {
    let _container = get_static_container();
   // `true` to `false` doesn't matter, container will be alive after test
    assert!(true, "test finished");
}

#[test]
fn test_sync() {
    let _container = get_static_container();
   // `true` to `false` doesn't matter, container will be alive after test
    assert!(true, "test finished");
}

But it doesn't work properly. The static initialized container is still alive after tests are finished. I've tested it with the whole test file and both testcases separately

Am I doing something wrong testcontainers or OnceLock ?

thomaseizinger commented 1 year ago

Yep that is currently not really well supported. We need to rework the API for this to work well: https://github.com/testcontainers/testcontainers-rs/issues/386. Contributions welcome!

DDtKey commented 7 months ago

I'm closing this issue in favor of #386. Please track that issue instead.

However I don't think this will be supported this way, because it's static item, see the doc

Static items do not call drop at the end of the program.

But something similar can be achieved by watchdog / ryuk