From a5d067457863bd698d9f4171cbae0f37e59cc746 Mon Sep 17 00:00:00 2001 From: Tatsuya Kawano Date: Tue, 9 Jan 2024 18:35:43 +0800 Subject: [PATCH] Compute API - Update the tests to ensure the internal waiter map is empty at the end --- src/future/cache.rs | 42 +++++++++++++++++++++++++++++---- src/future/value_initializer.rs | 7 ++++++ src/sync/cache.rs | 41 ++++++++++++++++++++++++++++---- src/sync/segment.rs | 15 ++++++++++++ src/sync/value_initializer.rs | 7 ++++++ 5 files changed, 104 insertions(+), 8 deletions(-) diff --git a/src/future/cache.rs b/src/future/cache.rs index 6a683b7e..84d1c615 100644 --- a/src/future/cache.rs +++ b/src/future/cache.rs @@ -2045,7 +2045,19 @@ where } } +// For unit tests. // For unit tests. +#[cfg(test)] +impl Cache { + pub(crate) fn is_table_empty(&self) -> bool { + self.entry_count() == 0 + } + + pub(crate) fn is_waiter_map_empty(&self) -> bool { + self.value_initializer.waiter_count() == 0 + } +} + #[cfg(test)] impl Cache where @@ -2053,10 +2065,6 @@ where V: Clone + Send + Sync + 'static, S: BuildHasher + Clone + Send + Sync + 'static, { - fn is_table_empty(&self) -> bool { - self.entry_count() == 0 - } - fn invalidation_predicate_count(&self) -> usize { self.base.invalidation_predicate_count() } @@ -3439,6 +3447,8 @@ mod tests { }; futures_util::join!(task1, task2, task3, task4, task5); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -3519,6 +3529,8 @@ mod tests { }; futures_util::join!(task1, task2, task3, task4, task5); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -3653,6 +3665,8 @@ mod tests { }; futures_util::join!(task1, task2, task3, task4, task5, task6, task7); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -3787,6 +3801,8 @@ mod tests { }; futures_util::join!(task1, task2, task3, task4, task5, task6, task7); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -3922,6 +3938,8 @@ mod tests { }; futures_util::join!(task1, task2, task3, task4, task5, task6, task7, task8); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -4063,6 +4081,8 @@ mod tests { }; futures_util::join!(task1, task2, task3, task4, task5, task6, task7, task8); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -4329,6 +4349,8 @@ mod tests { }; futures_util::join!(task1, task2, task3, task4, task5, task6, task7, task8); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -4401,6 +4423,8 @@ mod tests { assert_eq!(ent3.into_value(), 3); assert_eq!(cache.get(&KEY).await, Some(3)); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -4566,6 +4590,8 @@ mod tests { panic!("Expected `Unchanged`. Got {res6:?}") }; assert_eq!(*entry.into_value().read().await, vec![5]); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -4687,6 +4713,8 @@ mod tests { *entry.into_value().read().await, vec![1, 2] // Removed value. ); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -4738,6 +4766,8 @@ mod tests { cache.try_get_with(1, async { Ok(5) }).await as Result<_, Arc>, Ok(5) ); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -4768,6 +4798,8 @@ mod tests { handle.abort(); assert_eq!(cache.get_with(1, async { 5 }).await, 5); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] @@ -4801,6 +4833,8 @@ mod tests { cache.try_get_with(1, async { Ok(5) }).await as Result<_, Arc>, Ok(5) ); + + assert!(cache.is_waiter_map_empty()); } #[tokio::test] diff --git a/src/future/value_initializer.rs b/src/future/value_initializer.rs index b7392750..1af827da 100644 --- a/src/future/value_initializer.rs +++ b/src/future/value_initializer.rs @@ -477,6 +477,13 @@ where } } +#[cfg(test)] +impl ValueInitializer { + pub(crate) fn waiter_count(&self) -> usize { + self.waiters.len() + } +} + #[inline] fn remove_waiter(waiter_map: &WaiterMap, w_key: (Arc, TypeId), w_hash: u64) where diff --git a/src/sync/cache.rs b/src/sync/cache.rs index b8f430ad..4a154bdb 100644 --- a/src/sync/cache.rs +++ b/src/sync/cache.rs @@ -1864,6 +1864,17 @@ where } // For unit tests. +#[cfg(test)] +impl Cache { + pub(crate) fn is_table_empty(&self) -> bool { + self.entry_count() == 0 + } + + pub(crate) fn is_waiter_map_empty(&self) -> bool { + self.value_initializer.waiter_count() == 0 + } +} + #[cfg(test)] impl Cache where @@ -1871,10 +1882,6 @@ where V: Clone + Send + Sync + 'static, S: BuildHasher + Clone + Send + Sync + 'static, { - pub(crate) fn is_table_empty(&self) -> bool { - self.entry_count() == 0 - } - pub(crate) fn invalidation_predicate_count(&self) -> usize { self.base.invalidation_predicate_count() } @@ -3070,6 +3077,8 @@ mod tests { for t in [thread1, thread2, thread3, thread4, thread5] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -3153,6 +3162,8 @@ mod tests { for t in [thread1, thread2, thread3, thread4, thread5] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -3290,6 +3301,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -3429,6 +3442,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -3568,6 +3583,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -3707,6 +3724,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -3836,6 +3855,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -3965,6 +3986,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -4032,6 +4055,8 @@ mod tests { assert_eq!(ent3.into_value(), 3); assert_eq!(cache.get(&KEY), Some(3)); + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -4185,6 +4210,8 @@ mod tests { panic!("Expected `Unchanged`. Got {res6:?}") }; assert_eq!(*entry.into_value().read().unwrap(), vec![5]); + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -4302,6 +4329,8 @@ mod tests { *entry.into_value().read().unwrap(), vec![1, 2] // Removed value. ); + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -4325,6 +4354,8 @@ mod tests { barrier.wait(); assert_eq!(cache.get_with(1, || 5), 5); + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -4351,6 +4382,8 @@ mod tests { cache.try_get_with(1, || Ok(5)) as Result<_, Arc>, Ok(5) ); + + assert!(cache.is_waiter_map_empty()); } #[test] diff --git a/src/sync/segment.rs b/src/sync/segment.rs index aafdc777..53251ae9 100644 --- a/src/sync/segment.rs +++ b/src/sync/segment.rs @@ -638,6 +638,13 @@ where } // For unit tests. +#[cfg(test)] +impl SegmentedCache { + fn is_waiter_map_empty(&self) -> bool { + self.inner.segments.iter().all(Cache::is_waiter_map_empty) + } +} + #[cfg(test)] impl SegmentedCache where @@ -1419,6 +1426,8 @@ mod tests { for t in [thread1, thread2, thread3, thread4, thread5] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -1548,6 +1557,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -1686,6 +1697,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } #[test] @@ -1815,6 +1828,8 @@ mod tests { ] { t.join().expect("Failed to join"); } + + assert!(cache.is_waiter_map_empty()); } // This test ensures that the `contains_key`, `get` and `invalidate` can use diff --git a/src/sync/value_initializer.rs b/src/sync/value_initializer.rs index e802317a..ca7c8b3a 100644 --- a/src/sync/value_initializer.rs +++ b/src/sync/value_initializer.rs @@ -393,3 +393,10 @@ where (w_key, w_hash) } } + +#[cfg(test)] +impl ValueInitializer { + pub(crate) fn waiter_count(&self) -> usize { + self.waiters.len() + } +}