#![allow(dead_code)]
use deadpool_postgres::{Config, Pool, Runtime};
use testcontainers::ContainerAsync;
use testcontainers::runners::AsyncRunner;
use testcontainers_modules::postgres::Postgres;
use tokio_postgres::NoTls;
use venturi::postgres::PostgresStore;
use venturi::store::Store;
pub struct TestDb {
_container: ContainerAsync<Postgres>,
pool: Pool,
host: String,
port: u16,
}
impl TestDb {
pub async fn start() -> TestDb {
let container = Postgres::default()
.start()
.await
.expect("start postgres test container");
let host = container
.get_host()
.await
.expect("resolve container host")
.to_string();
let port = container
.get_host_port_ipv4(5432)
.await
.expect("resolve container port");
let mut config = Config::new();
config.host = Some(host.clone());
config.port = Some(port);
config.user = Some("postgres".to_owned());
config.password = Some("postgres".to_owned());
config.dbname = Some("postgres".to_owned());
let pool = config
.create_pool(Some(Runtime::Tokio1), NoTls)
.expect("build connection pool");
TestDb {
_container: container,
pool,
host,
port,
}
}
pub fn pool(&self) -> &Pool {
&self.pool
}
pub fn dsn(&self) -> String {
format!(
"host={} port={} user=postgres password=postgres dbname=postgres",
self.host, self.port
)
}
pub async fn store(&self, prefix: &str) -> PostgresStore {
let store =
PostgresStore::connect(&self.dsn(), prefix).expect("construct store with prefix");
store.migrate().await.expect("apply migrations");
store
}
pub async fn table_exists(&self, table: &str) -> bool {
let client = self.pool.get().await.expect("acquire connection");
let row = client
.query_one("SELECT to_regclass($1) IS NOT NULL", &[&table])
.await
.expect("query table existence");
row.get(0)
}
}