Skip to content

Commit

Permalink
[WIP] Add a test to reproduce error
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed Mar 21, 2024
1 parent 281f1aa commit 1b3247b
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
5 changes: 5 additions & 0 deletions spdlog/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ tracing-appender = "=0.2.2"
[build-dependencies]
rustc_version = "0.4.0"

[[test]]
name = "global_async_pool_sink"
harness = false
required-features = ["multi-thread"]

[[bench]]
name = "compare_with_cpp_spdlog"
harness = false
Expand Down
106 changes: 106 additions & 0 deletions spdlog/tests/global_async_pool_sink.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use std::{
env,
os::raw::c_int,
process,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
};

use spdlog::{
formatter::Formatter,
prelude::*,
sink::{AsyncPoolSink, Sink},
ErrorHandler,
};

static IS_FLUSHED: AtomicBool = AtomicBool::new(false);

struct SetFlagSink;

impl Sink for SetFlagSink {
fn log(&self, _record: &spdlog::Record) -> error::Result<()> {
Ok(())
}

fn flush(&self) -> error::Result<()> {
IS_FLUSHED.store(true, Ordering::SeqCst);
Ok(())
}

fn level_filter(&self) -> LevelFilter {
LevelFilter::All
}

fn set_level_filter(&self, _level_filter: LevelFilter) {
unimplemented!()
}

fn set_formatter(&self, _formatter: Box<dyn Formatter>) {
unimplemented!()
}

fn set_error_handler(&self, _handler: Option<ErrorHandler>) {
unimplemented!()
}
}

fn run_test() {
{
extern "C" fn check() {
assert!(IS_FLUSHED.load(Ordering::SeqCst));
}
// Setup `atexit`` to check the flag at the end of the program
extern "C" {
fn atexit(cb: extern "C" fn()) -> c_int;
}
assert_eq!(unsafe { atexit(check) }, 0);

let async_pool_sink = Arc::new(
AsyncPoolSink::builder()
.sink(Arc::new(SetFlagSink))
.build()
.unwrap(),
);

let logger = Arc::new(Logger::builder().sink(async_pool_sink).build().unwrap());
logger.set_flush_level_filter(LevelFilter::All);
spdlog::set_default_logger(logger);
}

info!("hello async_pool_sink");

// Workaround, adding these 2 lines at the end of `main` function
//
// std::thread::sleep(std::time::Duration::from_millis(100));
// spdlog::default_logger().flush();
}

fn main() {
// https://github.com/SpriteOvO/spdlog-rs/issues/64

// This is a flaky test, it only has a certain probability of failing, so we run
// it multiple times to make sure it's really working properly.
{
let args = env::args().collect::<Vec<_>>();
// If this is the parent process (no additional arguments)
if args.len() == 1 {
for _ in 0..1000 {
let status = process::Command::new(&args[0])
.arg("child")
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(status.success());
}
return;
}

// Run the test after leaving the scope, so the main function ends
// without dropping additional variables, thus exiting faster. This
// should increase the probability of reproducing the error.
}
run_test();
}

0 comments on commit 1b3247b

Please sign in to comment.