#![cfg(feature = "mongodb_backend")]
#[macro_use]
mod storage_harness;
use mongodb::Client;
use std::sync::OnceLock;
use std::sync::atomic::{AtomicU64, Ordering};
use storage_harness::*;
use testcontainers::runners::AsyncRunner;
use testcontainers_modules::mongo::Mongo;
use this::storage::{MongoDataService, MongoLinkService};
struct MongoTestEnv {
_container: testcontainers::ContainerAsync<Mongo>,
connection_url: String,
}
static TEST_ENV: OnceLock<MongoTestEnv> = OnceLock::new();
async fn init_mongo_env() -> &'static MongoTestEnv {
if let Some(env) = TEST_ENV.get() {
return env;
}
let container = Mongo::default()
.start()
.await
.expect("Failed to start MongoDB container — is Docker running?");
let host = container.get_host().await.unwrap();
let port = container.get_host_port_ipv4(27017).await.unwrap();
let url = format!("mongodb://{}:{}", host, port);
let env = MongoTestEnv {
_container: container,
connection_url: url,
};
let _ = TEST_ENV.set(env);
TEST_ENV.get().unwrap()
}
static DB_COUNTER: AtomicU64 = AtomicU64::new(0);
async fn mongo_database() -> mongodb::Database {
let env = init_mongo_env().await;
let client = Client::with_uri_str(&env.connection_url)
.await
.expect("Failed to connect to MongoDB");
let db_num = DB_COUNTER.fetch_add(1, Ordering::SeqCst);
client.database(&format!("this_test_{}", db_num))
}
async fn clean_mongo_data_service() -> MongoDataService<TestDataEntity> {
let db = mongo_database().await;
db.collection::<mongodb::bson::Document>("test_data_entities")
.drop()
.await
.expect("Failed to drop test_data_entities collection");
MongoDataService::new(db)
}
async fn clean_mongo_link_service() -> MongoLinkService {
let db = mongo_database().await;
db.collection::<mongodb::bson::Document>("links")
.drop()
.await
.expect("Failed to drop links collection");
MongoLinkService::new(db)
}
data_service_tests!(clean_mongo_data_service().await);
link_service_tests!(clean_mongo_link_service().await);
rest_integration_tests!(clean_mongo_data_service().await);