/* Astrolog, a logging framework for Rust Copyright (C) 2019 Alessandro Pellizzari This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #[macro_use] extern crate lazy_static; extern crate astrolog; #[cfg(test)] mod tests { use astrolog; use std::sync::Mutex; // This is to avoid tests being run in parallel, as we are testing a global // object lazy_static! { static ref TEST_MUTEX: Mutex<()> = Mutex::new(()); } #[test] fn test_basic_global_logger() { let _guard = TEST_MUTEX.lock().unwrap(); astrolog::reset_global_logger(); astrolog::debug("Some debug message"); } #[test] fn test_global_logger_config() { use astrolog::handler::LevelAware; let _guard = TEST_MUTEX.lock().unwrap(); astrolog::reset_global_logger(); astrolog::debug("Some debug message"); astrolog::config(|l| { l.push_handler(astrolog::handler::vec::VecHandler::new()) .make_async() .set_levels_range(astrolog::Level::Warning, astrolog::Level::Critical); }); } #[test] fn test_global_logger_string() { let _guard = TEST_MUTEX.lock().unwrap(); astrolog::reset_global_logger(); use astrolog::{errors::HandlerError, handler::Handler, Level, Record}; use std::sync::{Arc, RwLock}; let s = Arc::new(RwLock::new(String::new())); struct StringHandler { s: Arc>, }; impl Handler for StringHandler { fn is_handling(&self, _: &Level) -> bool { true } fn handle(&self, s: &Record) -> Result { let mut m = self.s.write().unwrap(); (*m).push_str(&s.msg); Ok(true) } } let h = StringHandler { s: s.clone() }; astrolog::config(|l| { l.push_handler(h); }); astrolog::debug("Some debug message"); assert_eq!("Some debug message", &*s.read().unwrap()); } #[test] fn test_global_logger_string_mt() { let _guard = TEST_MUTEX.lock().unwrap(); astrolog::reset_global_logger(); use astrolog::{errors::HandlerError, handler::Handler, Level, Record}; use std::sync::{Arc, RwLock}; use std::thread; let s = Arc::new(RwLock::new(String::new())); struct StringHandler { s: Arc>, }; impl Handler for StringHandler { fn is_handling(&self, _: &Level) -> bool { true } fn handle(&self, s: &Record) -> Result { let mut m = self.s.write().unwrap(); (*m).push_str(&s.msg); Ok(true) } } let h = StringHandler { s: s.clone() }; astrolog::config(|l| { l.push_handler(h); }); let mut ts = vec![]; for i in 0..10 { ts.push(thread::spawn(move || { astrolog::debug(&format!("{}", &i)); })) } for t in ts { t.join().expect("Failed to join test threads"); } assert_eq!(10, s.read().unwrap().len()); } #[test] fn test_global_logger_string_async() { let _guard = TEST_MUTEX.lock().unwrap(); astrolog::reset_global_logger(); use astrolog::{errors::HandlerError, handler::Handler, Level, Record}; use std::sync::{Arc, RwLock}; use std::thread; use std::time::Duration; let s = Arc::new(RwLock::new(String::new())); struct StringHandler { s: Arc>, }; impl Handler for StringHandler { fn is_handling(&self, _: &Level) -> bool { true } fn handle(&self, s: &Record) -> Result { let mut m = self.s.write().unwrap(); (*m).push_str(&s.msg); Ok(true) } } let h = StringHandler { s: s.clone() }; astrolog::config(|l| { l.make_async().push_handler(h); }); astrolog::debug("Some debug message"); // Wait for the thread to write to the handler thread::sleep(Duration::from_millis(64)); assert_eq!("Some debug message", &*s.read().unwrap()); } #[test] fn test_global_logger_string_async_mt() { let _guard = TEST_MUTEX.lock().unwrap(); astrolog::reset_global_logger(); use astrolog::{errors::HandlerError, handler::Handler, Level, Record}; use std::sync::{Arc, RwLock}; use std::thread; use std::time::Duration; let s = Arc::new(RwLock::new(String::new())); struct StringHandler { s: Arc>, }; impl Handler for StringHandler { fn is_handling(&self, _: &Level) -> bool { true } fn handle(&self, s: &Record) -> Result { let mut m = self.s.write().unwrap(); (*m).push_str(&s.msg); Ok(true) } } let h = StringHandler { s: s.clone() }; astrolog::config(|l| { l.make_async().push_handler(h); }); let mut ts = vec![]; for i in 0..10 { ts.push(thread::spawn(move || { astrolog::debug(&format!("{}", &i)); })) } for t in ts { t.join().expect("Failed to join test threads"); } // Wait for the thread to write to the handler thread::sleep(Duration::from_millis(200)); assert_eq!(10, s.read().unwrap().len()); } }