#[cfg(feature = "std-time")]
mod std_time_sync_tests {
use rate_guard::{ Millis, StdTimeSource, RateLimit};
use rate_guard::limits::TokenBucketBuilder;
use std::time::Duration;
#[test]
fn test_token_bucket_with_std_time_sync() {
let bucket = TokenBucketBuilder::builder()
.capacity(100)
.refill_amount(10)
.refill_every(Duration::from_millis(100))
.with_time(StdTimeSource::new())
.with_precision::<Millis>()
.build()
.unwrap();
assert!(bucket.try_acquire(50).is_ok());
assert_eq!(bucket.capacity_remaining().unwrap(), 50);
std::thread::sleep(Duration::from_millis(150));
let remaining = bucket.capacity_remaining().unwrap();
assert!(remaining > 50, "Expected refill, got {} tokens", remaining);
}
#[test]
fn test_concurrent_usage_with_threads() {
use std::sync::Arc;
use std::thread;
let bucket = Arc::new(
TokenBucketBuilder::builder()
.capacity(100)
.refill_amount(20)
.refill_every(Duration::from_millis(100))
.with_time(StdTimeSource::new())
.with_precision::<Millis>()
.build()
.unwrap()
);
let mut handles = vec![];
for _ in 0..3 {
let bucket_clone = Arc::clone(&bucket);
let handle = thread::spawn(move || {
let mut acquired = 0;
for _ in 0..5 {
if bucket_clone.try_acquire(5).is_ok() {
acquired += 1;
}
thread::sleep(Duration::from_millis(50));
}
acquired
});
handles.push(handle);
}
let total: usize = handles.into_iter().map(|h| h.join().unwrap()).sum();
assert!(total > 0);
}
}