From c245356b42870192eca57b96c3facac83c6a1c83 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Feb 2022 15:23:35 -0800 Subject: [PATCH] Try another hacky approach for tearing down DBs after all tests Co-Authored-By: Nathan Sobo --- Cargo.lock | 1 + crates/server/Cargo.toml | 1 + crates/server/src/db.rs | 47 +++++++++++++++++++++++++++------------- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11c9d229c8..1e9d43b2c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5850,6 +5850,7 @@ dependencies = [ "tide-compress", "time 0.2.25", "toml", + "util", "zed", ] diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml index 2ce5a6342d..a4357415da 100644 --- a/crates/server/Cargo.toml +++ b/crates/server/Cargo.toml @@ -61,6 +61,7 @@ gpui = { path = "../gpui" } zed = { path = "../zed", features = ["test-support"] } ctor = "0.1" env_logger = "0.8" +util = { path = "../util" } lazy_static = "1.4" serde_json = { version = "1.0.64", features = ["preserve_order"] } diff --git a/crates/server/src/db.rs b/crates/server/src/db.rs index b50d7daf46..5ef070bba2 100644 --- a/crates/server/src/db.rs +++ b/crates/server/src/db.rs @@ -534,6 +534,7 @@ pub mod tests { Postgres, }; use std::{mem, path::Path}; + use util::ResultExt as _; pub struct TestDb { pub db: Option, @@ -545,13 +546,31 @@ pub mod tests { static ref POOL: Mutex> = Default::default(); } - #[ctor::dtor] - fn clear_pool() { - for db in POOL.lock().drain(..) { - db.teardown(); + use std::os::raw::c_int; + + extern "C" { + fn atexit(callback: extern "C" fn()) -> c_int; + } + + #[ctor::ctor] + fn init() { + unsafe { + atexit(teardown_db_pool); } } + extern "C" fn teardown_db_pool() { + std::thread::spawn(|| { + block_on(async move { + for db in POOL.lock().drain(..) { + db.teardown().await.log_err(); + } + }); + }) + .join() + .log_err(); + } + impl TestDb { pub fn new() -> Self { let mut pool = POOL.lock(); @@ -606,22 +625,20 @@ pub mod tests { }) } - fn teardown(mut self) { + async fn teardown(mut self) -> Result<()> { let db = self.db.take().unwrap(); - block_on(async { - let query = " + let query = " SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '{}' AND pid <> pg_backend_pid(); "; - sqlx::query(query) - .bind(&self.name) - .execute(&db.pool) - .await - .unwrap(); - db.pool.close().await; - Postgres::drop_database(&self.url).await.unwrap(); - }); + sqlx::query(query) + .bind(&self.name) + .execute(&db.pool) + .await?; + db.pool.close().await; + Postgres::drop_database(&self.url).await?; + Ok(()) } }