postgres.rs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #![allow(missing_docs)]
  2. #![cfg(feature = "test-postgres")]
  3. //! PostgreSQL conformance run.
  4. //!
  5. //! The same `store_tests!` suite the SQLite backend passes, driven against a
  6. //! real PostgreSQL instance so the Postgres-only code paths (the `FOR UPDATE`
  7. //! row locks behind `lock_clause`, the `ON CONFLICT` upserts) are actually
  8. //! exercised. Point `DATABASE_URL` at a Postgres database to run it; the CI
  9. //! `Test (PostgreSQL)` job supplies one.
  10. //!
  11. //! Unlike `sqlite::memory:`, where every pool is its own fresh database, all
  12. //! tests here share one Postgres database and the conformance tests reuse fixed
  13. //! ids. Each store therefore gets its own uniquely-named schema, and the pool is
  14. //! pinned to a single connection so the session `search_path` set below persists
  15. //! for the store's whole lifetime.
  16. use std::sync::atomic::{AtomicU64, Ordering};
  17. use kuatia_storage_sql::SqlStore;
  18. use sqlx::{Any, Pool};
  19. static SCHEMA_SEQ: AtomicU64 = AtomicU64::new(0);
  20. async fn new_store() -> SqlStore {
  21. sqlx::any::install_default_drivers();
  22. let url = std::env::var("DATABASE_URL")
  23. .expect("DATABASE_URL must point at a PostgreSQL instance for this suite");
  24. // One connection per store so the session-level `search_path` set below
  25. // survives across every query the store issues.
  26. let pool: Pool<Any> = sqlx::any::AnyPoolOptions::new()
  27. .max_connections(1)
  28. .connect(&url)
  29. .await
  30. .unwrap();
  31. // Isolate each store in its own schema: the conformance tests reuse fixed
  32. // ids, so a shared schema would collide across tests.
  33. let n = SCHEMA_SEQ.fetch_add(1, Ordering::Relaxed);
  34. let schema = format!("conformance_{n}");
  35. for stmt in [
  36. format!("DROP SCHEMA IF EXISTS {schema} CASCADE"),
  37. format!("CREATE SCHEMA {schema}"),
  38. format!("SET search_path TO {schema}"),
  39. ] {
  40. sqlx::query(&stmt).execute(&pool).await.unwrap();
  41. }
  42. let store = SqlStore::new(pool);
  43. store.migrate().await.unwrap();
  44. store
  45. }
  46. kuatia_storage::store_tests!(new_store);