feat(provider): add test_race to BlockchainProvider2 tests (#11523)

This commit is contained in:
joshieDo
2024-10-07 11:06:28 +02:00
committed by GitHub
parent d2ab6352c6
commit 7842673903
4 changed files with 188 additions and 11 deletions

View File

@ -44,6 +44,7 @@ pub use reth_db_api::*;
pub mod test_utils {
use super::*;
use crate::mdbx::DatabaseArguments;
use parking_lot::RwLock;
use reth_db_api::{
database::Database,
database_metrics::{DatabaseMetadata, DatabaseMetadataValue, DatabaseMetrics},
@ -52,6 +53,7 @@ pub mod test_utils {
use reth_fs_util;
use reth_libmdbx::MaxReadTransactionDuration;
use std::{
fmt::Formatter,
path::{Path, PathBuf},
sync::Arc,
};
@ -69,10 +71,19 @@ pub mod test_utils {
pub const ERROR_TEMPDIR: &str = "Not able to create a temporary directory.";
/// A database will delete the db dir when dropped.
#[derive(Debug)]
pub struct TempDatabase<DB> {
db: Option<DB>,
path: PathBuf,
/// Executed right before a database transaction is created.
pre_tx_hook: RwLock<Box<dyn Fn() + Send + Sync>>,
/// Executed right after a database transaction is created.
post_tx_hook: RwLock<Box<dyn Fn() + Send + Sync>>,
}
impl<DB: std::fmt::Debug> std::fmt::Debug for TempDatabase<DB> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TempDatabase").field("db", &self.db).field("path", &self.path).finish()
}
}
impl<DB> Drop for TempDatabase<DB> {
@ -85,6 +96,16 @@ pub mod test_utils {
}
impl<DB> TempDatabase<DB> {
/// Create new [`TempDatabase`] instance.
pub fn new(db: DB, path: PathBuf) -> Self {
Self {
db: Some(db),
path,
pre_tx_hook: RwLock::new(Box::new(|| ())),
post_tx_hook: RwLock::new(Box::new(|| ())),
}
}
/// Returns the reference to inner db.
pub fn db(&self) -> &DB {
self.db.as_ref().unwrap()
@ -99,13 +120,28 @@ pub mod test_utils {
pub fn into_inner_db(mut self) -> DB {
self.db.take().unwrap() // take out db to avoid clean path in drop fn
}
/// Sets [`TempDatabase`] new pre transaction creation hook.
pub fn set_pre_transaction_hook(&self, hook: Box<dyn Fn() + Send + Sync>) {
let mut db_hook = self.pre_tx_hook.write();
*db_hook = hook;
}
/// Sets [`TempDatabase`] new post transaction creation hook.
pub fn set_post_transaction_hook(&self, hook: Box<dyn Fn() + Send + Sync>) {
let mut db_hook = self.post_tx_hook.write();
*db_hook = hook;
}
}
impl<DB: Database> Database for TempDatabase<DB> {
type TX = <DB as Database>::TX;
type TXMut = <DB as Database>::TXMut;
fn tx(&self) -> Result<Self::TX, DatabaseError> {
self.db().tx()
self.pre_tx_hook.read()();
let tx = self.db().tx()?;
self.post_tx_hook.read()();
Ok(tx)
}
fn tx_mut(&self) -> Result<Self::TXMut, DatabaseError> {
@ -150,7 +186,7 @@ pub mod test_utils {
)
.expect(&emsg);
Arc::new(TempDatabase { db: Some(db), path })
Arc::new(TempDatabase::new(db, path))
}
/// Create read/write database for testing
@ -162,7 +198,7 @@ pub mod test_utils {
.with_max_read_transaction_duration(Some(MaxReadTransactionDuration::Unbounded)),
)
.expect(ERROR_DB_CREATION);
Arc::new(TempDatabase { db: Some(db), path })
Arc::new(TempDatabase::new(db, path))
}
/// Create read only database for testing
@ -175,7 +211,7 @@ pub mod test_utils {
init_db(path.as_path(), args.clone()).expect(ERROR_DB_CREATION);
}
let db = open_db_read_only(path.as_path(), args).expect(ERROR_DB_OPEN);
Arc::new(TempDatabase { db: Some(db), path })
Arc::new(TempDatabase::new(db, path))
}
}