Skip to content

Commit

Permalink
Intoduce timeout as a feature
Browse files Browse the repository at this point in the history
Signed-off-by: Heinz N. Gies <heinz@licenser.net>
  • Loading branch information
Licenser committed Jun 29, 2022
1 parent 714def9 commit 4e23a8b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 18 deletions.
18 changes: 12 additions & 6 deletions serial_test/Cargo.toml
Expand Up @@ -14,28 +14,34 @@ keywords = ["sequential"]
lazy_static = "1.2"
parking_lot = "^0.12"
serial_test_derive = { version = "~0.8.0", path = "../serial_test_derive" }
fslock = {version = "0.2", optional = true}
document-features = {version = "0.2", optional=true}
log = {version = "0.4", optional = true}
futures = {version = "^0.3", default_features = false, features = ["executor"] }
fslock = { version = "0.2", optional = true }
document-features = { version = "0.2", optional = true }
log = { version = "0.4", optional = true }
futures = { version = "^0.3", default_features = false, features = [
"executor",
] }

[dev-dependencies]
itertools = "0.10"
tokio = { version = "^1.17", features = ["macros", "rt"] }

[features]
default = ["logging"]
default = ["logging", "timeout"]

## Switches on debug logging (and requires the `log` package)
logging = ["log"]

## The file_locks feature unlocks the `file_serial`/`file_parallel` macros
file_locks = ["fslock"]

## The `timeout` feature lets tests time out after a certain amount of time
## if not enabled tests will wait indefinetly to be started
timeout = []

docsrs = ["document-features"]

# docs.rs-specific configuration
[package.metadata.docs.rs]
all-features = true
# defines the configuration attribute `docsrs`
rustdoc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
32 changes: 20 additions & 12 deletions serial_test/src/code_lock.rs
@@ -1,10 +1,9 @@
use crate::rwlock::{Locks, MutexGuardWrapper};
use lazy_static::lazy_static;
#[cfg(feature = "logging")]
use log::debug;
use parking_lot::{Mutex, RwLock};
use log::{debug, warn};
use parking_lot::RwLock;
use std::{
cell::RefCell,
collections::HashMap,
ops::{Deref, DerefMut},
sync::{atomic::AtomicU32, Arc},
Expand Down Expand Up @@ -46,11 +45,14 @@ impl UniqueReentrantMutex {
lazy_static! {
pub(crate) static ref LOCKS: Arc<RwLock<HashMap<String, UniqueReentrantMutex>>> =
Arc::new(RwLock::new(HashMap::new()));
static ref MAX_WAIT: Arc<Mutex<RefCell<Duration>>> =
Arc::new(Mutex::new(RefCell::new(Duration::from_secs(60))));
static ref MUTEX_ID: Arc<AtomicU32> = Arc::new(AtomicU32::new(1));
}

#[cfg(feature = "timeout")]
lazy_static! {
static ref MAX_WAIT: Arc<RwLock<Duration>> = Arc::new(RwLock::new(Duration::from_secs(60)));
}

impl Default for UniqueReentrantMutex {
fn default() -> Self {
Self {
Expand All @@ -67,20 +69,23 @@ impl Default for UniqueReentrantMutex {
///
/// However, sometimes if you've got a *lot* of serial tests it might theoretically not be enough,
/// hence this method.
///
/// This function is only available when the `timeout` feature is enabled.
#[cfg(feature = "timeout")]
pub fn set_max_wait(max_wait: Duration) {
MAX_WAIT.lock().replace(max_wait);
*MAX_WAIT.write() = max_wait;
}

pub(crate) fn wait_duration() -> Duration {
*MAX_WAIT.lock().borrow()
*MAX_WAIT.read()
}

pub(crate) fn check_new_key(name: &str) {
let start = Instant::now();
loop {
#[cfg(feature = "logging")]
{
let duration = Instant::now() - start;
if wait_duration().is_some() {
let duration = start.elapsed();
debug!("Waiting for '{}' {:?}", name, duration);
}
// Check if a new key is needed. Just need a read lock, which can be done in sync with everyone else
Expand All @@ -105,9 +110,12 @@ pub(crate) fn check_new_key(name: &str) {
// If the try_lock fails, then go around the loop again
// Odds are another test was also locking on the write and has now written the key

let duration = Instant::now() - start;
if duration >= wait_duration() {
panic!("check_new_key timed out!");
#[cfg(feature = "timeout")]
if let Some(wait) = wait_duration() {
let duration = start.elapsed();
if duration > wait {
panic!("Timeout waiting for '{}' {:?}", name, duration);
}
}
}
}

0 comments on commit 4e23a8b

Please sign in to comment.