mod common;
use anyhow::Result;
use pgevolve_core::ir::catalog::Catalog;
use pgevolve_core::parse::parse_directory;
use pgevolve_testkit::ephemeral_pg::{EphemeralPostgres, default_pg_version, docker_available};
use common::{apply_diff, assert_convergent, connect_and_bootstrap, introspect, schemas_of};
const TABLESPACE_DIR: &str = "/tmp/pgev_ts_e2e";
const SOURCE_SQL: &str = "\
-- @pgevolve schema=app
CREATE SCHEMA app;
CREATE TABLE app.items (
id bigint NOT NULL,
label text NOT NULL,
CONSTRAINT items_pkey PRIMARY KEY (id)
) TABLESPACE ts_e2e;
";
fn source_catalog() -> Result<Catalog> {
let dir = tempfile::tempdir()?;
std::fs::write(dir.path().join("0001-table-tablespace.sql"), SOURCE_SQL)?;
let catalog = parse_directory(dir.path(), &[])?;
Ok(catalog)
}
async fn provision_tablespace(pg: &EphemeralPostgres) -> Result<()> {
let client = pg.connect().await?;
client
.batch_execute(&format!(
"COPY (SELECT 1) TO PROGRAM 'mkdir -p {TABLESPACE_DIR} && chmod 700 {TABLESPACE_DIR}';"
))
.await?;
client
.batch_execute(&format!(
"CREATE TABLESPACE ts_e2e LOCATION '{TABLESPACE_DIR}';"
))
.await?;
Ok(())
}
#[ignore = "e2e test — requires Docker; run via `cargo test -- --ignored`"]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn table_tablespace_round_trips_against_ephemeral_pg() {
if !docker_available() {
eprintln!("skipping: docker unavailable");
return;
}
run().await.expect("table TABLESPACE round-trip");
}
async fn run() -> Result<()> {
let source = source_catalog()?;
let managed = schemas_of(&source);
assert_eq!(
source.tables.len(),
1,
"source catalog should declare exactly one table"
);
assert!(
source.tables[0].tablespace.is_some(),
"parsed table must carry tablespace = Some(\"ts_e2e\")"
);
let pg = EphemeralPostgres::start(default_pg_version()).await?;
provision_tablespace(&pg).await?;
let mut client = connect_and_bootstrap(&pg).await?;
let outcome = apply_diff(&mut client, &Catalog::empty(), &source, &managed, None).await?;
outcome.map_err(|e| anyhow::anyhow!("apply failed: {e}"))?;
let live = introspect(&pg, &managed).await?;
assert_eq!(
live.tables.len(),
1,
"live database should report exactly one table after apply"
);
assert_eq!(
live.tables[0]
.tablespace
.as_ref()
.map(pgevolve_core::identifier::Identifier::as_str),
Some("ts_e2e"),
"live table tablespace must be ts_e2e after apply"
);
assert_convergent(&live, &source)
}