From 8bc47eeb4f36865be8895097d7e247abef8a4b44 Mon Sep 17 00:00:00 2001 From: dd di cesare Date: Fri, 28 Jul 2023 16:43:27 +0200 Subject: [PATCH] [test] Testing update function with multi-threading case --- .../src/storage/atomic_expiring_value.rs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/limitador/src/storage/atomic_expiring_value.rs b/limitador/src/storage/atomic_expiring_value.rs index ddda7938..dc2d5ed6 100644 --- a/limitador/src/storage/atomic_expiring_value.rs +++ b/limitador/src/storage/atomic_expiring_value.rs @@ -84,8 +84,10 @@ impl Clone for AtomicExpiringValue { #[cfg(test)] mod tests { - use super::AtomicExpiringValue; + use super::*; use std::time::{Duration, SystemTime}; + use std::sync::{Arc, Barrier}; + use std::thread; #[test] fn returns_value_when_valid() { @@ -124,4 +126,33 @@ mod tests { val.update(3, 10, now); assert_eq!(val.value_at(now - Duration::from_secs(1)), 3); } + + #[test] + fn test_overlapping_updates() { + let now = SystemTime::now(); + let atomic_expiring_value = Arc::new(AtomicExpiringValue::new(42, now + Duration::from_secs(10))); + + let barrier = Arc::new(Barrier::new(2)); + + let atomic_expiring_value_clone = Arc::clone(&atomic_expiring_value); + let barrier_clone = Arc::clone(&barrier); + let thread1 = thread::spawn(move || { + barrier_clone.wait(); + atomic_expiring_value_clone.update(2, 1, now + Duration::from_secs(11)); + }); + + let atomic_expiring_value_clone2 = Arc::clone(&atomic_expiring_value); + let barrier_clone2 = Arc::clone(&barrier); + let thread2 = thread::spawn(move || { + barrier_clone2.wait(); + atomic_expiring_value_clone2.update(1, 1, now); + }); + + assert_eq!(atomic_expiring_value.value.load(Ordering::SeqCst), 42); + + thread2.join().unwrap(); + thread1.join().unwrap(); + + assert_eq!(atomic_expiring_value.value.load(Ordering::SeqCst), 3); + } }