apache_avro_test_helper/
logger.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#![cfg(not(target_arch = "wasm32"))]
19
20use crate::LOG_MESSAGES;
21use log::{LevelFilter, Log, Metadata};
22use std::sync::OnceLock;
23
24struct TestLogger {
25    delegate: env_logger::Logger,
26}
27
28impl Log for TestLogger {
29    #[inline]
30    fn enabled(&self, _metadata: &Metadata) -> bool {
31        true
32    }
33
34    fn log(&self, record: &log::Record) {
35        if self.enabled(record.metadata()) {
36            LOG_MESSAGES.with(|msgs| msgs.borrow_mut().push(format!("{}", record.args())));
37
38            self.delegate.log(record);
39        }
40    }
41
42    fn flush(&self) {}
43}
44
45fn test_logger() -> &'static TestLogger {
46    // Lazy static because the Logger has to be 'static
47    static TEST_LOGGER_ONCE: OnceLock<TestLogger> = OnceLock::new();
48    TEST_LOGGER_ONCE.get_or_init(|| TestLogger {
49        delegate: env_logger::Builder::from_default_env()
50            .filter_level(LevelFilter::Off)
51            .parse_default_env()
52            .build(),
53    })
54}
55
56pub fn clear_log_messages() {
57    LOG_MESSAGES.with(|msgs| match msgs.try_borrow_mut() {
58        Ok(mut log_messages) => log_messages.clear(),
59        Err(err) => panic!("Failed to clear log messages: {err:?}"),
60    });
61}
62
63pub fn assert_not_logged(unexpected_message: &str) {
64    LOG_MESSAGES.with(|msgs| match msgs.borrow().last() {
65        Some(last_log) if last_log == unexpected_message => {
66            panic!("The following log message should not have been logged: '{unexpected_message}'")
67        }
68        _ => (),
69    });
70}
71
72pub fn assert_logged(expected_message: &str) {
73    let mut deleted = false;
74    LOG_MESSAGES.with(|msgs| {
75        msgs.borrow_mut().retain(|msg| {
76            if msg == expected_message {
77                deleted = true;
78                false
79            } else {
80                true
81            }
82        })
83    });
84
85    if !deleted {
86        panic!("Expected log message has not been logged: '{expected_message}'");
87    }
88}
89
90pub(crate) fn install() {
91    log::set_logger(test_logger())
92        .map(|_| log::set_max_level(LevelFilter::Trace))
93        .map_err(|err| {
94            eprintln!("Failed to set the custom logger: {err:?}");
95        })
96        .unwrap();
97}