From aceccc72f2f4727946a0114c0526adc95b029272 Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Sun, 26 May 2019 21:12:44 +0000 Subject: [PATCH] WIP: Add tests for Executor. --- src/context.rs | 3 ++- src/executor.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/context.rs b/src/context.rs index 776605a..13257f6 100644 --- a/src/context.rs +++ b/src/context.rs @@ -9,6 +9,7 @@ use crate::user::UserMap; /// Contains all the different bits of client state. /// /// Implements `Sync`. +#[derive(Debug)] pub struct Context { pub rooms: Mutex, pub users: Mutex, @@ -26,8 +27,8 @@ impl Context { #[cfg(test)] mod tests { - use std::thread; use std::sync::Arc; + use std::thread; use super::Context; diff --git a/src/executor.rs b/src/executor.rs index 710508d..df32058 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -50,8 +50,61 @@ impl Executor { }) } - /// Blocks until all scheduled jobs are executed. - pub fn join(self) { - self.pool.join() + /// Blocks until all scheduled jobs are executed, then returns the context. + pub fn join(self) -> Context { + self.pool.join(); + + // Once the pool is joined, no-one should be holding on to copies of + // `self.context` anymore, so we unwrap() here. + Arc::try_unwrap(self.context).unwrap() + } +} + +#[cfg(test)] +mod tests { + use std::io; + use std::sync::{Arc, Barrier, Mutex}; + + use super::{Context, Executor, Job}; + + #[test] + fn immediate_join_returns_empty_context() { + let context = Executor::new().join(); + assert_eq!(context.users.lock().get_list(), vec![]); + assert_eq!(context.rooms.lock().get_room_list(), vec![]); + } + + struct Waiter { + pub barrier: Arc, + } + + impl Job for Waiter { + fn execute(self: Box, context: &Context) -> io::Result<()> { + self.barrier.wait(); + Ok(()) + } } + + #[test] + fn join_waits_for_all_jobs() { + let executor = Executor::new(); + + let barrier = Arc::new(Barrier::new(2)); + + let waiter1 = Box::new(Waiter { + barrier: barrier.clone(), + }); + let waiter2 = Box::new(Waiter { + barrier: barrier.clone(), + }); + + executor.schedule(waiter1); + executor.schedule(waiter2); + + let context = executor.join(); + assert_eq!(context.users.lock().get_list(), vec![]); + assert_eq!(context.rooms.lock().get_room_list(), vec![]); + } + + // TODO: Add a test that exercises modifying Context. }