Repository: p2panda/aquadoggo (language: rust)

Issue:
Irregular failing tests
This test sometimes fails on my machine:

```
thread 'db::stores::entry::tests::paginated_log_entries::case_6' panicked at 'Send to store: Custom("Entry's claimed seq num of 1 does not match expected seq num of 23 for given public key and log")', /home/adz/.cargo/registry/src/github.com-1ecc6299db9ec823/p2panda-rs-0.6.0/src/test_utils/db/test_db.rs:246:26
```

Related discussion: https://github.com/p2panda/aquadoggo/pull/266


Discussion / hints:
.. actually another whole bunch of other tests as well:

```
---- db::stores::entry::tests::paginated_log_entries::case_5 stdout ----
-------------- TEST START --------------
thread 'db::stores::entry::tests::paginated_log_entries::case_5' panicked at 'Send to store: EntryStoreError(Custom("Unexpected number of inserts occured for entry with id: 00201701fc74b4469c6b35e0534bf9a3f18c7c0916c9ae345cf77211572c4f035935"))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::entry::tests::paginated_log_entries::case_5

---- db::stores::entry::tests::paginated_log_entries::case_7 stdout ----
-------------- TEST START --------------
thread 'db::stores::entry::tests::paginated_log_entries::case_7' panicked at 'Send to store: ValidationError(LogIdDoesNotMatchNext(0, 1))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::entry::tests::paginated_log_entries::case_7

---- graphql::client::dynamic_query::test::single_query stdout ----
-------------- TEST START --------------
thread 'graphql::client::dynamic_query::test::single_query' panicked at 'assertion failed: `(left == right)`
  left: `Null`,
 right: `Object({Name("byViewId"): Object({Name("fields"): Object({Name("bool"): Boolean(true)})}), Name("byDocumentId"): Object({Name("fields"): Object({Name("bool"): Boolean(true)})})})`: [
    ServerError {
        message: "Unknown field \"schema_name_0020a11e93df5645457a2ac457f13b5aa72731f8db6f2c51a7fe33891a6932c00d10\" on type \"QueryRoot\".",
        locations: [
            Pos(2:17),
        ],
        path: [],
        extensions: None,
    },
    ServerError {
        message: "Unknown field \"schema_name_0020a11e93df5645457a2ac457f13b5aa72731f8db6f2c51a7fe33891a6932c00d10\" on type \"QueryRoot\".",
        locations: [
            Pos(5:17),
        ],
        path: [],
        extensions: None,
    },
]', aquadoggo/src/graphql/client/dynamic_query.rs:502:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    graphql::client::dynamic_query::test::single_query

---- db::stores::document::tests::get_documents_by_schema_deleted_document stdout ----
-------------- TEST START --------------
thread 'db::stores::document::tests::get_documents_by_schema_deleted_document' panicked at 'Send to store: ValidationError(LogIdDoesNotMatchNext(0, 1))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::document::tests::get_documents_by_schema_deleted_document

---- db::stores::document::tests::updates_a_document stdout ----
-------------- TEST START --------------
thread 'db::stores::document::tests::updates_a_document' panicked at 'Unwrap document', aquadoggo/src/db/stores/document.rs:881:22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::schema::tests::get_all_schema

---- db::stores::entry::tests::paginated_log_entries::case_2 stdout ----
-------------- TEST START --------------
thread 'db::stores::entry::tests::paginated_log_entries::case_2' panicked at 'Send to store: OperationStoreError(InsertionError(OperationId(Hash("0020fb515d98ef19b0998c4f8cab9eac9b7515ad5f90b4c96ee35c0d7938a61a206b"))))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::entry::tests::paginated_log_entries::case_2

---- db::stores::entry::tests::paginated_log_entries::case_5 stdout ----
-------------- TEST START --------------
thread 'db::stores::entry::tests::paginated_log_entries::case_5' panicked at 'Send to store: ValidationError(LogIdDoesNotMatchNext(0, 1))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::entry::tests::paginated_log_entries::case_5

---- db::stores::entry::tests::get_lipmaa_link_entries stdout ----
-------------- TEST START --------------
thread 'db::stores::entry::tests::get_lipmaa_link_entries' panicked at 'Send to store: ValidationError(LogIdDoesNotMatchNext(0, 1))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::entry::tests::get_lipmaa_link_entries

---- db::stores::document::tests::gets_documents_by_schema stdout ----
-------------- TEST START --------------
thread 'db::stores::document::tests::gets_documents_by_schema' panicked at 'Send to store: ValidationError(SeqNumDoesNotMatch(1, 3))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::document::tests::gets_documents_by_schema

---- db::stores::document::tests::updates_a_document stdout ----
-------------- TEST START --------------
thread 'db::stores::document::tests::updates_a_document' panicked at 'Send to store: ValidationError(LogIdDoesNotMatchNext(0, 1))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::document::tests::updates_a_document

---- db::stores::entry::tests::get_entry stdout ----
-------------- TEST START --------------
thread 'db::stores::entry::tests::get_entry' panicked at 'Send to store: ValidationError(LogIdDoesNotMatchExisting(1, 0))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    db::stores::entry::tests::get_entry

---- db::stores::document::tests::get_documents_by_schema_deleted_document stdout ----
-------------- TEST START --------------
thread 'db::stores::document::tests::get_documents_by_schema_deleted_document' panicked at 'Send to store: ValidationError(LogIdDoesNotMatchExisting(1, 0))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- db::stores::entry::tests::paginated_log_entries::case_1 stdout ----
-------------- TEST START --------------
thread 'db::stores::entry::tests::paginated_log_entries::case_1' panicked at 'Send to store: ValidationError(LogIdDoesNotMatchExisting(1, 0))', /home/adz/.cargo/git/checkouts/p2panda-fb44b351afe3c13e/d7beb86/p2panda-rs/src/test_utils/memory_store/helpers.rs:134:26


failures:
    db::stores::document::tests::get_documents_by_schema_deleted_document
    db::stores::entry::tests::paginated_log_entries::case_1
```

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e9a0c43e7..ed2dc95fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Update breaking API calls for new `p2panda-rs` 0.7.0 version [#293](https://github.com/p2panda/aquadoggo/pull/293)
 - Handle decoding and parsing empty pinned relation lists [#336](https://github.com/p2panda/aquadoggo/pull/336)
 - Make `value` on `QueryRow` an option [#339](https://github.com/p2panda/aquadoggo/pull/339)
+- Fix race conditions in SQLite database test runner [#345](https://github.com/p2panda/aquadoggo/pull/345)
 
 ## [0.4.0]
 


Test patch:
diff --git a/aquadoggo/src/test_utils/config.rs b/aquadoggo/src/test_utils/config.rs
index 31002fbee..5de9b82eb 100644
--- a/aquadoggo/src/test_utils/config.rs
+++ b/aquadoggo/src/test_utils/config.rs
@@ -2,19 +2,17 @@
 
 use std::fmt::Debug;
 
-use once_cell::sync::Lazy;
 use serde::Deserialize;
 
 /// Configuration used in test helper methods.
 #[derive(Deserialize, Debug)]
 #[serde(default)]
 pub struct TestConfiguration {
-    /// Database url (sqlite or postgres)
+    /// Database url (SQLite or PostgreSQL).
     pub database_url: String,
 }
 
 impl TestConfiguration {
-    /// Create a new configuration object for test environments.
     pub fn new() -> Self {
         envy::from_env::<TestConfiguration>()
             .expect("Could not read environment variables for test configuration")
@@ -23,11 +21,12 @@ impl TestConfiguration {
 
 impl Default for TestConfiguration {
     fn default() -> Self {
+        // Give each database an unique name
+        let db_name = format!("dbmem{}", rand::random::<u32>());
+
         Self {
             /// SQLite database stored in memory.
-            database_url: "sqlite::memory:".into(),
+            database_url: format!("sqlite://{db_name}?mode=memory&cache=private"),
         }
     }
 }
-
-pub static TEST_CONFIG: Lazy<TestConfiguration> = Lazy::new(TestConfiguration::new);
diff --git a/aquadoggo/src/test_utils/db.rs b/aquadoggo/src/test_utils/db.rs
index 80e71bfe2..20a54022d 100644
--- a/aquadoggo/src/test_utils/db.rs
+++ b/aquadoggo/src/test_utils/db.rs
@@ -4,34 +4,28 @@ use sqlx::migrate::MigrateDatabase;
 use sqlx::Any;
 
 use crate::db::{connection_pool, create_database, run_pending_migrations, Pool};
-use crate::test_utils::TEST_CONFIG;
+use crate::test_utils::TestConfiguration;
 
 /// Create test database.
-pub async fn initialize_db() -> Pool {
-    initialize_db_with_url(&TEST_CONFIG.database_url).await
-}
+pub async fn initialize_db() -> (TestConfiguration, Pool) {
+    let config = TestConfiguration::new();
 
-/// Create test database.
-pub async fn initialize_db_with_url(url: &str) -> Pool {
-    // Reset database first
-    drop_database().await;
-    create_database(url).await.unwrap();
+    drop_database(&config).await;
+    create_database(&config.database_url).await.unwrap();
+
+    let pool = connection_pool(&config.database_url, 1).await.unwrap();
 
-    // Create connection pool and run all migrations
-    let pool = connection_pool(url, 25).await.unwrap();
     if run_pending_migrations(&pool).await.is_err() {
         pool.close().await;
+        panic!("Database migration failed");
     }
 
-    pool
+    (config, pool)
 }
 
-// Delete test database
-pub async fn drop_database() {
-    if Any::database_exists(&TEST_CONFIG.database_url)
-        .await
-        .unwrap()
-    {
-        Any::drop_database(&TEST_CONFIG.database_url).await.unwrap();
+/// Delete test database.
+pub async fn drop_database(config: &TestConfiguration) {
+    if Any::database_exists(&config.database_url).await.unwrap() {
+        Any::drop_database(&config.database_url).await.unwrap();
     }
 }
diff --git a/aquadoggo/src/test_utils/mod.rs b/aquadoggo/src/test_utils/mod.rs
index 40a6c915f..287d2bc70 100644
--- a/aquadoggo/src/test_utils/mod.rs
+++ b/aquadoggo/src/test_utils/mod.rs
@@ -8,8 +8,8 @@ mod node;
 mod runner;
 
 pub use client::{graphql_test_client, TestClient};
-pub use config::{TestConfiguration, TEST_CONFIG};
-pub use db::{drop_database, initialize_db, initialize_db_with_url};
+pub use config::TestConfiguration;
+pub use db::{drop_database, initialize_db};
 pub use helpers::{build_document, doggo_fields, doggo_schema, schema_from_fields};
 pub use node::{
     add_document, add_schema, add_schema_and_documents, populate_and_materialize,
diff --git a/aquadoggo/src/test_utils/runner.rs b/aquadoggo/src/test_utils/runner.rs
index bcfb5d785..8d31d0f36 100644
--- a/aquadoggo/src/test_utils/runner.rs
+++ b/aquadoggo/src/test_utils/runner.rs
@@ -43,7 +43,7 @@ pub fn test_runner<F: AsyncTestFn + Send + Sync + 'static>(test: F) {
 
     runtime.block_on(async {
         // Initialise store
-        let pool = initialize_db().await;
+        let (_config, pool) = initialize_db().await;
         let store = SqlStore::new(pool);
 
         // Construct the actual test node