#![cfg(feature = "sqlite")]
use autumn_web::config::DatabaseConfig;
use autumn_web::db::{RuntimeConnection, create_pool};
use autumn_web::migrate::{FRAMEWORK_MIGRATIONS, run_pending_sqlite};
use autumn_web::reexports::diesel;
use diesel_async::RunQueryDsl as _;
use diesel_async::pooled_connection::deadpool::Pool;
type SqlitePool = Pool<RuntimeConnection>;
#[derive(diesel::QueryableByName)]
struct TableName {
#[diesel(sql_type = diesel::sql_types::Text)]
name: String,
}
const EXPECTED_TABLES: &[&str] = &[
"api_tokens",
"autumn_repository_commit_hooks",
"_autumn_version_history",
"autumn_runtime_config_values",
"autumn_runtime_config_changes",
"autumn_feature_flags",
"feature_flag_changes",
"autumn_experiments",
"autumn_experiment_assignments",
"autumn_experiment_overrides",
"autumn_experiment_changes",
"autumn_migration_checksums",
"_autumn_ledger_revisions",
"_autumn_ledger_high_water",
"_autumn_derivations",
];
const SHIMMED_TABLES: &[&str] = &[
"autumn_jobs",
"autumn_job_tracking",
"_autumn_shard_directory",
"_autumn_shard_map",
];
#[tokio::test]
async fn framework_migrations_apply_on_sqlite() {
let tmp = tempfile::TempDir::new().expect("temp dir");
let db_path = tmp.path().join("framework.db");
let url = format!("sqlite://{}", db_path.display());
let result =
run_pending_sqlite(&url, FRAMEWORK_MIGRATIONS).expect("framework migrations apply");
assert!(
!result.applied.is_empty(),
"at least one framework migration applied"
);
let again = run_pending_sqlite(&url, FRAMEWORK_MIGRATIONS)
.expect("re-running pending framework migrations is a no-op");
assert!(
again.applied.is_empty(),
"second run applies nothing (got {:?})",
again.applied
);
let config = DatabaseConfig {
url: Some(url),
..Default::default()
};
let pool: SqlitePool = create_pool(&config)
.expect("sqlite pool builds")
.expect("a url is configured");
let mut conn = pool.get().await.expect("checkout a sqlite connection");
let rows: Vec<TableName> =
diesel::sql_query("SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name")
.load(&mut *conn)
.await
.expect("list tables");
let names: Vec<&str> = rows.iter().map(|r| r.name.as_str()).collect();
for expected in EXPECTED_TABLES {
assert!(
names.contains(expected),
"expected table `{expected}` was not created (got {names:?})"
);
}
for shimmed in SHIMMED_TABLES {
assert!(
!names.contains(shimmed),
"`{shimmed}` is owned by its own bootstrap and must not be \
created by FRAMEWORK_MIGRATIONS (got {names:?})"
);
}
}