Run tests with an in-memory sqlite database
This commit is contained in:
parent
05a6bd914d
commit
dafdc4b4a5
1 changed files with 58 additions and 15 deletions
|
@ -22,6 +22,8 @@ pub struct Db<D: sqlx::Database> {
|
||||||
pool: sqlx::Pool<D>,
|
pool: sqlx::Pool<D>,
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
background: Option<std::sync::Arc<gpui::executor::Background>>,
|
background: Option<std::sync::Arc<gpui::executor::Background>>,
|
||||||
|
#[cfg(test)]
|
||||||
|
runtime: Option<tokio::runtime::Runtime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! test_support {
|
macro_rules! test_support {
|
||||||
|
@ -35,7 +37,8 @@ macro_rules! test_support {
|
||||||
if let Some(background) = $self.background.as_ref() {
|
if let Some(background) = $self.background.as_ref() {
|
||||||
background.simulate_random_delay().await;
|
background.simulate_random_delay().await;
|
||||||
}
|
}
|
||||||
tokio::runtime::Builder::new_current_thread().enable_io().enable_time().build().unwrap().block_on(body)
|
#[cfg(test)]
|
||||||
|
$self.runtime.as_ref().unwrap().block_on(body)
|
||||||
} else {
|
} else {
|
||||||
body.await
|
body.await
|
||||||
}
|
}
|
||||||
|
@ -60,17 +63,29 @@ impl RowsAffected for sqlx::postgres::PgQueryResult {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl Db<sqlx::Sqlite> {
|
impl Db<sqlx::Sqlite> {
|
||||||
|
const MIGRATIONS_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/migrations.sqlite");
|
||||||
|
|
||||||
pub async fn new(url: &str, max_connections: u32) -> Result<Self> {
|
pub async fn new(url: &str, max_connections: u32) -> Result<Self> {
|
||||||
|
use std::str::FromStr as _;
|
||||||
|
let options = sqlx::sqlite::SqliteConnectOptions::from_str(url)
|
||||||
|
.unwrap()
|
||||||
|
.create_if_missing(true)
|
||||||
|
.shared_cache(true);
|
||||||
let pool = sqlx::sqlite::SqlitePoolOptions::new()
|
let pool = sqlx::sqlite::SqlitePoolOptions::new()
|
||||||
|
.min_connections(2)
|
||||||
.max_connections(max_connections)
|
.max_connections(max_connections)
|
||||||
.connect(url)
|
.connect_with(options)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
pool,
|
pool,
|
||||||
background: None,
|
background: None,
|
||||||
|
runtime: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn teardown(&self, _url: &str) {}
|
||||||
|
|
||||||
pub async fn get_user_metrics_id(&self, id: UserId) -> Result<String> {
|
pub async fn get_user_metrics_id(&self, id: UserId) -> Result<String> {
|
||||||
test_support!(self, {
|
test_support!(self, {
|
||||||
let query = "
|
let query = "
|
||||||
|
@ -143,6 +158,8 @@ impl Db<sqlx::Sqlite> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Db<sqlx::Postgres> {
|
impl Db<sqlx::Postgres> {
|
||||||
|
const MIGRATIONS_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/migrations");
|
||||||
|
|
||||||
pub async fn new(url: &str, max_connections: u32) -> Result<Self> {
|
pub async fn new(url: &str, max_connections: u32) -> Result<Self> {
|
||||||
let pool = sqlx::postgres::PgPoolOptions::new()
|
let pool = sqlx::postgres::PgPoolOptions::new()
|
||||||
.max_connections(max_connections)
|
.max_connections(max_connections)
|
||||||
|
@ -152,6 +169,25 @@ impl Db<sqlx::Postgres> {
|
||||||
pool,
|
pool,
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
background: None,
|
background: None,
|
||||||
|
#[cfg(test)]
|
||||||
|
runtime: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn teardown(&self, url: &str) {
|
||||||
|
self.runtime.as_ref().unwrap().block_on(async {
|
||||||
|
use util::ResultExt;
|
||||||
|
let query = "
|
||||||
|
SELECT pg_terminate_backend(pg_stat_activity.pid)
|
||||||
|
FROM pg_stat_activity
|
||||||
|
WHERE pg_stat_activity.datname = current_database() AND pid <> pg_backend_pid();
|
||||||
|
";
|
||||||
|
sqlx::query(query).execute(&self.pool).await.log_err();
|
||||||
|
self.pool.close().await;
|
||||||
|
<sqlx::Sqlite as sqlx::migrate::MigrateDatabase>::drop_database(url)
|
||||||
|
.await
|
||||||
|
.log_err();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1295,33 +1331,39 @@ mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::executor::Background;
|
use gpui::executor::Background;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use sqlx::migrate::MigrateDatabase;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct TestDb {
|
pub struct TestDb {
|
||||||
pub db: Option<Arc<DefaultDb>>,
|
pub db: Option<Arc<DefaultDb>>,
|
||||||
|
pub conn: sqlx::sqlite::SqliteConnection,
|
||||||
pub url: String,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestDb {
|
impl TestDb {
|
||||||
pub fn new(background: Arc<Background>) -> Self {
|
pub fn new(background: Arc<Background>) -> Self {
|
||||||
let mut rng = StdRng::from_entropy();
|
let mut rng = StdRng::from_entropy();
|
||||||
let url = format!("/tmp/zed-test-{}", rng.gen::<u128>());
|
let url = format!("file:zed-test-{}?mode=memory", rng.gen::<u128>());
|
||||||
let db = tokio::runtime::Builder::new_current_thread()
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_io()
|
.enable_io()
|
||||||
.enable_time()
|
.enable_time()
|
||||||
.build()
|
.build()
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.block_on(async {
|
|
||||||
sqlx::Sqlite::create_database(&url).await.unwrap();
|
let (mut db, conn) = runtime.block_on(async {
|
||||||
let mut db = DefaultDb::new(&url, 5).await.unwrap();
|
let db = DefaultDb::new(&url, 5).await.unwrap();
|
||||||
db.background = Some(background);
|
db.migrate(Path::new(DefaultDb::MIGRATIONS_PATH), false)
|
||||||
let migrations_path = concat!(env!("CARGO_MANIFEST_DIR"), "/migrations.sqlite");
|
.await
|
||||||
db.migrate(Path::new(migrations_path), false).await.unwrap();
|
.unwrap();
|
||||||
db
|
let conn = db.pool.acquire().await.unwrap().detach();
|
||||||
|
(db, conn)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
db.background = Some(background);
|
||||||
|
db.runtime = Some(runtime);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
db: Some(Arc::new(db)),
|
db: Some(Arc::new(db)),
|
||||||
|
conn,
|
||||||
url,
|
url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1333,7 +1375,8 @@ mod test {
|
||||||
|
|
||||||
impl Drop for TestDb {
|
impl Drop for TestDb {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
std::fs::remove_file(&self.url).ok();
|
let db = self.db.take().unwrap();
|
||||||
|
db.teardown(&self.url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue