Block_on function does not always block in unit tests

I have some unit test code that first creates a new tokio runtime and triggers each test using block_on. The first call to block_on, after creating the runtime, is blocking properly but any subsequent calls to block_on do not.

pub fn test_rt() -> &'static tokio::runtime::Runtime {
    lazy_static! {
        static ref RT: tokio::runtime::Runtime = {
            println!("log: start setup RT");
            let rt = tokio::runtime::Builder::new_current_thread()
                .enable_all()
                .build()
                .unwrap();

            rt.block_on(async {
                println!("log: start setup_test_db_data()");
                let conn = get_conn_pool().await;
                _ = setup_test_db_data(&conn).await;
                println!("log: end setup_test_db_data()");
            });
            println!("log: end setup RT");
            rt
        };
    }
    &RT
}

pub fn run_test<F: std::future::Future>(f: F) -> F::Output {
    test_rt().block_on(f)
}

async fn test_insert_profile_body() {
    println!("log: start test_insert_profile_body");
    let fixtures = setup_fixtures().await;
    let db_repo = InsertProfileDbRepo;            

    let profile_id = db_repo.insert_profile(&fixtures.conn, ProfileCreate { 
        user_name: "user_a".to_string(), 
        full_name: "User A".to_string(), 
        description: "Profile's description".to_string(), 
        region: Some("usa".to_string()), 
        main_url: Some("http://whatever.com".to_string()), 
        avatar: vec![] 
    }).await.unwrap();

    assert!(profile_id > 0);
    println!("log: end test_insert_profile_body");
}

#[test]
fn test_insert_profile() {
    run_test(test_insert_profile_body())
}

This might have something to do with you using a single-threaded runtime (Builder::new_current_thread()) and tests being run in parallel by the test runner.

Is there any particular reason why you can't use #[tokio::test] to create a new runtime for each test? You'd still need some sort of helper to make sure the database is set up exactly once, but that won't make much difference.

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.