mirror of https://github.com/buster-so/buster.git
update testing
This commit is contained in:
parent
1feb7558c2
commit
2abf522c78
|
@ -381,60 +381,36 @@ async fn test_user_creation() -> Result<()> {
|
|||
#### Database Setup
|
||||
- All integration tests must import and utilize the application's schema from [schema.rs](mdc:src/database/schema.rs)
|
||||
- Database models from [models.rs](mdc:src/database/models.rs) should be used for test data setup and verification
|
||||
- Create a robust database test helper:
|
||||
- Use the `testkit` library for test IDs and directly access pools from the database library:
|
||||
```rust
|
||||
// tests/common/db.rs
|
||||
use anyhow::Result;
|
||||
use diesel_async::{AsyncPgConnection, AsyncConnection};
|
||||
use diesel_async::pooled_connection::AsyncDieselConnectionManager;
|
||||
use deadpool_diesel::postgres::Pool;
|
||||
use diesel_async::AsyncPgConnection;
|
||||
use database::pool::get_pg_pool;
|
||||
use testkit::test_id;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct TestDb {
|
||||
pub pool: Pool,
|
||||
pub test_id: String, // Unique identifier for this test run
|
||||
}
|
||||
|
||||
impl TestDb {
|
||||
/// Creates a new isolated test database environment
|
||||
pub async fn new() -> Result<Self> {
|
||||
// Initialize environment
|
||||
crate::common::env::init_test_env();
|
||||
|
||||
pub fn new() -> Self {
|
||||
// Generate unique test identifier
|
||||
let test_id = Uuid::new_v4().to_string();
|
||||
let test_id = test_id();
|
||||
|
||||
// Get database config from env
|
||||
let database_url = std::env::var("TEST_DATABASE_URL")
|
||||
.expect("TEST_DATABASE_URL must be set for tests");
|
||||
|
||||
// Create connection manager and pool
|
||||
let config = AsyncDieselConnectionManager::<AsyncPgConnection>::new(database_url);
|
||||
let pool = Pool::builder(config)
|
||||
.max_size(5)
|
||||
.build()?;
|
||||
|
||||
let db = Self { pool, test_id };
|
||||
|
||||
// Setup initial test data
|
||||
db.setup_schema().await?;
|
||||
|
||||
Ok(db)
|
||||
Self { test_id }
|
||||
}
|
||||
|
||||
/// Setup schema and initial test data
|
||||
async fn setup_schema(&self) -> Result<()> {
|
||||
let conn = &mut self.pool.get().await?;
|
||||
|
||||
// Run migrations or setup tables
|
||||
// Add any shared setup like creating test users
|
||||
|
||||
Ok(())
|
||||
/// Get a database connection from the pre-initialized pool
|
||||
pub async fn get_conn(&self) -> Result<diesel_async::pooled_connection::bb8::PooledConnection<AsyncPgConnection>> {
|
||||
Ok(get_pg_pool().get().await?)
|
||||
}
|
||||
|
||||
/// Clean up test data created by this test instance
|
||||
pub async fn cleanup(&self) -> Result<()> {
|
||||
let conn = &mut self.pool.get().await?;
|
||||
let mut conn = self.get_conn().await?;
|
||||
|
||||
// Delete data with test_id marker
|
||||
// Reset sequences if needed
|
||||
|
@ -444,6 +420,8 @@ async fn test_user_creation() -> Result<()> {
|
|||
|
||||
/// Create test data with proper isolation using the test_id
|
||||
pub async fn create_test_data(&self) -> Result<()> {
|
||||
let mut conn = self.get_conn().await?;
|
||||
|
||||
// Create test data tagged with test_id for isolation
|
||||
Ok(())
|
||||
}
|
||||
|
@ -458,16 +436,21 @@ async fn test_user_creation() -> Result<()> {
|
|||
```
|
||||
|
||||
#### Required Environment Variables
|
||||
Create a `.env.test` file with necessary test configurations:
|
||||
The testkit automatically creates a `.env.test` file if one doesn't exist, with necessary default test configurations. You can customize it with:
|
||||
|
||||
```env
|
||||
TEST_DATABASE_URL=postgres://user:pass@localhost/test_db
|
||||
TEST_POOLER_URL=postgres://user:pass@localhost/test_db
|
||||
TEST_REDIS_URL=redis://localhost:6379
|
||||
TEST_DATABASE_POOL_SIZE=10
|
||||
TEST_SQLX_POOL_SIZE=10
|
||||
TEST_API_KEY=test-key
|
||||
TEST_ENV=test
|
||||
# Optional: enable test logging
|
||||
# TEST_LOG=debug
|
||||
```
|
||||
|
||||
**IMPORTANT**: All integration tests must have all required services configured and accessible via environment variables loaded through dotenv. Tests should never be written with hardcoded service configurations.
|
||||
**IMPORTANT**: All integration tests should use the pools from the database library (already initialized by the testkit at build time). Tests should never be written with hardcoded service configurations or manual pool creation.
|
||||
|
||||
#### Service Mocks
|
||||
Create reusable mock services for common external dependencies:
|
||||
|
@ -992,29 +975,29 @@ mod tests {
|
|||
## Example Application Integration Test
|
||||
|
||||
```rust
|
||||
use crate::tests::common::{db::TestDb, env::init_test_env};
|
||||
use crate::database::{models, schema};
|
||||
use crate::tests::common::db::TestDb;
|
||||
use crate::database::{models, schema, pool};
|
||||
use crate::handlers::users::get_user_handler;
|
||||
use anyhow::Result;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_user_creation_flow() -> Result<()> {
|
||||
// Initialize test environment with proper setup
|
||||
init_test_env();
|
||||
|
||||
// Setup test database with isolation
|
||||
let test_db = TestDb::new().await?;
|
||||
// TestDb handles test ID generation and connection access
|
||||
let test_db = TestDb::new();
|
||||
|
||||
// Create test user using fixture or builder pattern
|
||||
let test_user = models::User::builder()
|
||||
.email("test@example.com")
|
||||
.name("Test User")
|
||||
.test_id(&test_db.test_id) // Set test ID for isolation
|
||||
.build();
|
||||
|
||||
// Insert test data with proper error handling
|
||||
let mut conn = test_db.get_conn().await?;
|
||||
diesel::insert_into(schema::users::table)
|
||||
.values(&test_user)
|
||||
.execute(&mut test_db.pool.get().await?)
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
|
||||
// Create HTTP client for API testing
|
||||
|
|
|
@ -381,60 +381,36 @@ async fn test_user_creation() -> Result<()> {
|
|||
#### Database Setup
|
||||
- All integration tests must import and utilize the application's schema from [schema.rs](mdc:src/database/schema.rs)
|
||||
- Database models from [models.rs](mdc:src/database/models.rs) should be used for test data setup and verification
|
||||
- Create a robust database test helper:
|
||||
- Use the `testkit` library for test IDs and directly access pools from the database library:
|
||||
```rust
|
||||
// tests/common/db.rs
|
||||
use anyhow::Result;
|
||||
use diesel_async::{AsyncPgConnection, AsyncConnection};
|
||||
use diesel_async::pooled_connection::AsyncDieselConnectionManager;
|
||||
use deadpool_diesel::postgres::Pool;
|
||||
use diesel_async::AsyncPgConnection;
|
||||
use database::pool::get_pg_pool;
|
||||
use testkit::test_id;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct TestDb {
|
||||
pub pool: Pool,
|
||||
pub test_id: String, // Unique identifier for this test run
|
||||
}
|
||||
|
||||
impl TestDb {
|
||||
/// Creates a new isolated test database environment
|
||||
pub async fn new() -> Result<Self> {
|
||||
// Initialize environment
|
||||
crate::common::env::init_test_env();
|
||||
|
||||
pub fn new() -> Self {
|
||||
// Generate unique test identifier
|
||||
let test_id = Uuid::new_v4().to_string();
|
||||
let test_id = test_id();
|
||||
|
||||
// Get database config from env
|
||||
let database_url = std::env::var("TEST_DATABASE_URL")
|
||||
.expect("TEST_DATABASE_URL must be set for tests");
|
||||
|
||||
// Create connection manager and pool
|
||||
let config = AsyncDieselConnectionManager::<AsyncPgConnection>::new(database_url);
|
||||
let pool = Pool::builder(config)
|
||||
.max_size(5)
|
||||
.build()?;
|
||||
|
||||
let db = Self { pool, test_id };
|
||||
|
||||
// Setup initial test data
|
||||
db.setup_schema().await?;
|
||||
|
||||
Ok(db)
|
||||
Self { test_id }
|
||||
}
|
||||
|
||||
/// Setup schema and initial test data
|
||||
async fn setup_schema(&self) -> Result<()> {
|
||||
let conn = &mut self.pool.get().await?;
|
||||
|
||||
// Run migrations or setup tables
|
||||
// Add any shared setup like creating test users
|
||||
|
||||
Ok(())
|
||||
/// Get a database connection from the pre-initialized pool
|
||||
pub async fn get_conn(&self) -> Result<diesel_async::pooled_connection::bb8::PooledConnection<AsyncPgConnection>> {
|
||||
Ok(get_pg_pool().get().await?)
|
||||
}
|
||||
|
||||
/// Clean up test data created by this test instance
|
||||
pub async fn cleanup(&self) -> Result<()> {
|
||||
let conn = &mut self.pool.get().await?;
|
||||
let mut conn = self.get_conn().await?;
|
||||
|
||||
// Delete data with test_id marker
|
||||
// Reset sequences if needed
|
||||
|
@ -444,6 +420,8 @@ async fn test_user_creation() -> Result<()> {
|
|||
|
||||
/// Create test data with proper isolation using the test_id
|
||||
pub async fn create_test_data(&self) -> Result<()> {
|
||||
let mut conn = self.get_conn().await?;
|
||||
|
||||
// Create test data tagged with test_id for isolation
|
||||
Ok(())
|
||||
}
|
||||
|
@ -458,16 +436,21 @@ async fn test_user_creation() -> Result<()> {
|
|||
```
|
||||
|
||||
#### Required Environment Variables
|
||||
Create a `.env.test` file with necessary test configurations:
|
||||
The testkit automatically creates a `.env.test` file if one doesn't exist, with necessary default test configurations. You can customize it with:
|
||||
|
||||
```env
|
||||
TEST_DATABASE_URL=postgres://user:pass@localhost/test_db
|
||||
TEST_POOLER_URL=postgres://user:pass@localhost/test_db
|
||||
TEST_REDIS_URL=redis://localhost:6379
|
||||
TEST_DATABASE_POOL_SIZE=10
|
||||
TEST_SQLX_POOL_SIZE=10
|
||||
TEST_API_KEY=test-key
|
||||
TEST_ENV=test
|
||||
# Optional: enable test logging
|
||||
# TEST_LOG=debug
|
||||
```
|
||||
|
||||
**IMPORTANT**: All integration tests must have all required services configured and accessible via environment variables loaded through dotenv. Tests should never be written with hardcoded service configurations.
|
||||
**IMPORTANT**: All integration tests should use the pools from the database library (already initialized by the testkit at build time). Tests should never be written with hardcoded service configurations or manual pool creation.
|
||||
|
||||
#### Service Mocks
|
||||
Create reusable mock services for common external dependencies:
|
||||
|
@ -992,29 +975,29 @@ mod tests {
|
|||
## Example Application Integration Test
|
||||
|
||||
```rust
|
||||
use crate::tests::common::{db::TestDb, env::init_test_env};
|
||||
use crate::database::{models, schema};
|
||||
use crate::tests::common::db::TestDb;
|
||||
use crate::database::{models, schema, pool};
|
||||
use crate::handlers::users::get_user_handler;
|
||||
use anyhow::Result;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_user_creation_flow() -> Result<()> {
|
||||
// Initialize test environment with proper setup
|
||||
init_test_env();
|
||||
|
||||
// Setup test database with isolation
|
||||
let test_db = TestDb::new().await?;
|
||||
// TestDb handles test ID generation and connection access
|
||||
let test_db = TestDb::new();
|
||||
|
||||
// Create test user using fixture or builder pattern
|
||||
let test_user = models::User::builder()
|
||||
.email("test@example.com")
|
||||
.name("Test User")
|
||||
.test_id(&test_db.test_id) // Set test ID for isolation
|
||||
.build();
|
||||
|
||||
// Insert test data with proper error handling
|
||||
let mut conn = test_db.get_conn().await?;
|
||||
diesel::insert_into(schema::users::table)
|
||||
.values(&test_user)
|
||||
.execute(&mut test_db.pool.get().await?)
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
|
||||
// Create HTTP client for API testing
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
# Test Environment Configuration
|
||||
TEST_ENV=test
|
||||
TEST_DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
|
||||
TEST_REDIS_URL=redis://localhost:6379
|
||||
TEST_LOG=true
|
||||
TEST_LOG_LEVEL=debug
|
|
@ -0,0 +1,139 @@
|
|||
# Testkit Library Usage Guide
|
||||
|
||||
## Overview
|
||||
The testkit library initializes database pools during build time and provides utilities for test isolation. The pools themselves are accessed directly from the database library.
|
||||
|
||||
## Key Features
|
||||
- Pre-initialized database connections at build time
|
||||
- Environment variable management for test-specific configurations
|
||||
- Test ID generation for test isolation
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
```rust
|
||||
use database::pool::get_pg_pool;
|
||||
use testkit::test_id;
|
||||
use anyhow::Result;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_database_operations() -> Result<()> {
|
||||
// Create a unique test ID for isolation
|
||||
let test_id = test_id();
|
||||
|
||||
// Pools are already initialized during build time
|
||||
// Get the pool from the database library
|
||||
let pool = get_pg_pool();
|
||||
|
||||
// Use the pool in your test
|
||||
let conn = pool.get().await?;
|
||||
|
||||
// Perform database operations...
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### Environment Configuration
|
||||
The testkit automatically loads environment variables from `.env.test` if available, otherwise from `.env` during the build process. Key environment variables include:
|
||||
|
||||
- `TEST_DATABASE_URL` - PostgreSQL connection string for tests
|
||||
- `TEST_POOLER_URL` - Connection string for the SQL pooler
|
||||
- `TEST_REDIS_URL` - Redis connection string
|
||||
- `TEST_DATABASE_POOL_SIZE` - Maximum connections in Diesel pool (default: 10)
|
||||
- `TEST_SQLX_POOL_SIZE` - Maximum connections in SQLx pool (default: 10)
|
||||
|
||||
### Accessing Database Pools
|
||||
Access the pre-initialized database pools directly through the database library:
|
||||
|
||||
```rust
|
||||
// Get the Diesel PostgreSQL pool (AsyncPgConnection)
|
||||
let pg_pool = database::pool::get_pg_pool();
|
||||
|
||||
// Get the SQLx PostgreSQL pool
|
||||
let sqlx_pool = database::pool::get_sqlx_pool();
|
||||
|
||||
// Get the Redis pool
|
||||
let redis_pool = database::pool::get_redis_pool();
|
||||
```
|
||||
|
||||
### Test ID Generation
|
||||
For test isolation, you can generate unique IDs to tag test data:
|
||||
|
||||
```rust
|
||||
let test_id = testkit::test_id();
|
||||
|
||||
// Use this ID to mark test data for cleanup
|
||||
diesel::insert_into(users::table)
|
||||
.values((
|
||||
users::name.eq("Test User"),
|
||||
users::email.eq("test@example.com"),
|
||||
users::test_id.eq(test_id), // Use the test ID for later cleanup
|
||||
))
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Pool Initialization
|
||||
The testkit initializes pools during the build process using `build.rs`. This ensures pools are always available when your tests run, with no initialization overhead or risk of connection timing issues.
|
||||
|
||||
### Error Handling
|
||||
- Build-time initialization failures are reported as warnings but don't fail the build
|
||||
- Unit tests that don't need database access will run fine even if pool initialization failed
|
||||
- Integration tests that need database access will fail fast if the database isn't available
|
||||
|
||||
### Database Reset (Optional Feature)
|
||||
For clearing test data, use the `db_reset` feature:
|
||||
|
||||
```rust
|
||||
// Only available when the `db_reset` feature is enabled
|
||||
#[cfg(feature = "db_reset")]
|
||||
testkit::reset_test_database().await?;
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Direct Pool Access**: Always use `get_pg_pool()`, `get_sqlx_pool()`, or `get_redis_pool()` directly
|
||||
2. **Use Test IDs**: Generate and use test IDs for proper test isolation
|
||||
3. **Cleanup After Tests**: Always clean up test data after tests
|
||||
4. **Connection Pooling**: Reuse connections from the pool instead of creating new ones
|
||||
5. **Environment Variables**: Use the `.env.test` file for test-specific configuration
|
||||
6. **Avoid Database in Unit Tests**: Unit tests should mock database operations
|
||||
|
||||
## Example Integration Test Pattern
|
||||
|
||||
```rust
|
||||
#[tokio::test]
|
||||
async fn test_example() -> Result<()> {
|
||||
// Generate unique test ID
|
||||
let test_id = testkit::test_id();
|
||||
|
||||
// Get pre-initialized database connection directly from database lib
|
||||
let pool = database::pool::get_pg_pool();
|
||||
let mut conn = pool.get().await?;
|
||||
|
||||
// Setup test data with test_id for tracking
|
||||
let test_user = create_test_user(&mut conn, &test_id).await?;
|
||||
|
||||
// Run the test against the test data
|
||||
let result = your_function_under_test(test_user.id).await?;
|
||||
assert_eq!(result.name, test_user.name);
|
||||
|
||||
// Clean up test data using test_id
|
||||
cleanup_test_data(&mut conn, &test_id).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn create_test_user(conn: &mut PgConnection, test_id: &str) -> Result<User> {
|
||||
// Insert user with test_id
|
||||
// ...
|
||||
}
|
||||
|
||||
async fn cleanup_test_data(conn: &mut PgConnection, test_id: &str) -> Result<()> {
|
||||
// Delete all data with matching test_id
|
||||
// ...
|
||||
}
|
||||
```
|
|
@ -1,76 +0,0 @@
|
|||
# Buster API Test Kit
|
||||
|
||||
The `testkit` crate provides standardized database pool initialization for tests across the Buster API workspace, leveraging the existing database pools from the database library.
|
||||
|
||||
## Features
|
||||
|
||||
- **Automatic Database Pool Configuration**: Uses the database library's pools with test configurations
|
||||
- **Environment Configuration**: Uses `.env.test` for test database configuration
|
||||
- **Test ID Generation**: Provides unique IDs for test data isolation
|
||||
|
||||
## Getting Started
|
||||
|
||||
Add the testkit as a dev-dependency in your workspace crate:
|
||||
|
||||
```toml
|
||||
[dev-dependencies]
|
||||
testkit = { path = "../../testkit" }
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```rust
|
||||
use anyhow::Result;
|
||||
|
||||
#[tokio::test]
|
||||
async fn my_test() -> Result<()> {
|
||||
// Get database pools - these are initialized from the database library
|
||||
let pg_pool = testkit::get_pg_pool();
|
||||
let redis_pool = testkit::get_redis_pool();
|
||||
|
||||
// Use the pools for testing
|
||||
let conn = pg_pool.get().await?;
|
||||
|
||||
// Generate a unique test ID for data isolation
|
||||
let test_id = testkit::test_id();
|
||||
|
||||
// Use test_id to tag and later clean up test data
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
## Test Data Isolation
|
||||
|
||||
Use the `test_id()` function to generate unique IDs for isolating test data:
|
||||
|
||||
```rust
|
||||
// Get a unique ID
|
||||
let test_id = testkit::test_id();
|
||||
|
||||
// Tag test data with the ID
|
||||
diesel::sql_query("INSERT INTO users (name, test_id) VALUES ($1, $2)")
|
||||
.bind::<diesel::sql_types::Text, _>("Test User")
|
||||
.bind::<diesel::sql_types::Text, _>(&test_id)
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
|
||||
// Clean up after test
|
||||
diesel::sql_query("DELETE FROM users WHERE test_id = $1")
|
||||
.bind::<diesel::sql_types::Text, _>(&test_id)
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
```
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
By default, the testkit checks for and creates a `.env.test` file with:
|
||||
|
||||
```
|
||||
TEST_DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
|
||||
TEST_REDIS_URL=redis://localhost:6379
|
||||
TEST_LOG=true
|
||||
TEST_LOG_LEVEL=debug
|
||||
```
|
||||
|
||||
When running tests, the testkit automatically sets `DATABASE_URL` to the value of `TEST_DATABASE_URL`, ensuring that tests use the test database.
|
|
@ -93,7 +93,8 @@ fn try_init_pools() -> Result<(), String> {
|
|||
Err(e) => return Err(e.to_string()),
|
||||
};
|
||||
|
||||
// Try to initialize pools but don't fail the build if it fails
|
||||
// Try to initialize pools through the testkit's internal function
|
||||
// This won't fail the build if it can't connect to the database
|
||||
runtime.block_on(async {
|
||||
match database::pool::init_pools().await {
|
||||
Ok(_) => Ok(()),
|
||||
|
|
|
@ -3,13 +3,13 @@ use dotenv::dotenv;
|
|||
use std::path::Path;
|
||||
use std::sync::Once;
|
||||
use once_cell::sync::OnceCell;
|
||||
use database::pool::{PgPool, PgPoolSqlx, RedisPool};
|
||||
|
||||
static ENV_INIT: Once = Once::new();
|
||||
static POOL_INIT: OnceCell<()> = OnceCell::new();
|
||||
|
||||
/// Initialize the test environment by setting up .env.test
|
||||
pub fn init_test_env() {
|
||||
/// This should only be used internally or by build.rs
|
||||
fn init_test_env() {
|
||||
ENV_INIT.call_once(|| {
|
||||
// Try loading .env.test first, then fall back to .env
|
||||
if Path::new(".env.test").exists() {
|
||||
|
@ -44,8 +44,10 @@ pub fn init_test_env() {
|
|||
});
|
||||
}
|
||||
|
||||
/// Initialize database and Redis pools for testing
|
||||
pub async fn init_pools() -> Result<()> {
|
||||
// This function is only for internal use by build.rs - the pools should be
|
||||
// initialized at build time, not during test runtime
|
||||
#[doc(hidden)]
|
||||
pub async fn _internal_init_pools() -> Result<()> {
|
||||
// Setup the environment first
|
||||
init_test_env();
|
||||
|
||||
|
@ -54,7 +56,7 @@ pub async fn init_pools() -> Result<()> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
// Use the init_test_pools function which is specifically designed for tests
|
||||
// Use the database crate's init_pools function
|
||||
let result = match database::pool::init_pools().await {
|
||||
Ok(_) => {
|
||||
// Success case - cache the result
|
||||
|
@ -72,42 +74,8 @@ pub async fn init_pools() -> Result<()> {
|
|||
result
|
||||
}
|
||||
|
||||
/// Get the initialized PG pool, initializing it first if needed
|
||||
pub fn get_pg_pool() -> &'static PgPool {
|
||||
ensure_pools_initialized();
|
||||
database::pool::get_pg_pool()
|
||||
}
|
||||
|
||||
/// Get the initialized SQLX pool, initializing it first if needed
|
||||
pub fn get_sqlx_pool() -> &'static PgPoolSqlx {
|
||||
ensure_pools_initialized();
|
||||
database::pool::get_sqlx_pool()
|
||||
}
|
||||
|
||||
/// Get the initialized Redis pool, initializing it first if needed
|
||||
pub fn get_redis_pool() -> &'static RedisPool {
|
||||
ensure_pools_initialized();
|
||||
database::pool::get_redis_pool()
|
||||
}
|
||||
|
||||
/// Helper function to ensure pools are initialized
|
||||
fn ensure_pools_initialized() {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap()
|
||||
.block_on(async {
|
||||
// Always initialize test environment
|
||||
init_test_env();
|
||||
|
||||
// If pools aren't initialized yet, try to initialize them
|
||||
if POOL_INIT.get().is_none() {
|
||||
if let Err(e) = init_pools().await {
|
||||
panic!("Failed to initialize database pools for tests: {}", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// No need for pool accessor functions - users should access pools directly
|
||||
// through the database library (database::pool::get_pg_pool(), etc.)
|
||||
|
||||
/// Generate a unique test ID - useful for creating test resources
|
||||
pub fn test_id() -> String {
|
||||
|
@ -119,38 +87,4 @@ pub async fn cleanup_connection() -> Result<()> {
|
|||
// This is a placeholder for any future cleanup that might be needed
|
||||
// Currently the pools handle their own cleanup
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reset the test database to a clean state
|
||||
/// Only use this in integration tests where you need a completely fresh DB
|
||||
/// Most tests should isolate their data instead
|
||||
#[cfg(feature = "db_reset")]
|
||||
pub async fn reset_test_database() -> Result<()> {
|
||||
let pool = get_pg_pool();
|
||||
let mut conn = pool.get().await?;
|
||||
|
||||
// Execute a transaction that truncates all tables
|
||||
// This code is only included when the db_reset feature is enabled
|
||||
// as it's potentially destructive
|
||||
|
||||
diesel::sql_query("BEGIN").execute(&mut conn).await?;
|
||||
|
||||
// List of tables to truncate - add more as needed
|
||||
let tables = vec![
|
||||
"users", "organizations", "users_to_organizations",
|
||||
"api_keys", "teams", "teams_to_users",
|
||||
"data_sources", "datasets", "dataset_columns",
|
||||
"permission_groups", "datasets_to_permission_groups",
|
||||
"terms", "collections", "dashboards", "threads", "messages"
|
||||
];
|
||||
|
||||
for table in tables {
|
||||
diesel::sql_query(format!("TRUNCATE TABLE {} CASCADE", table))
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
}
|
||||
|
||||
diesel::sql_query("COMMIT").execute(&mut conn).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue