Skip to main content

netstack3_base/testutil/
misc.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Miscellaneous test utilities used in netstack3.
6//!
7//! # Note to developers
8//!
9//! Please refrain from adding types to this module, keep this only to
10//! freestanding functions. If you require a new type, create a module for it.
11
12// The crate is `no_std`, but test utilities are allowed to print to stdout.
13extern crate std;
14
15use alloc::vec::Vec;
16use core::fmt::Debug;
17use core::sync::atomic::{self, AtomicBool};
18
19/// Install a logger for tests.
20///
21/// Call this method at the beginning of the test for which logging is desired.
22/// This function sets global program state, so all tests that run after this
23/// function is called will use the logger.
24pub fn set_logger_for_test() {
25    struct Logger;
26
27    impl log::Log for Logger {
28        fn enabled(&self, _metadata: &log::Metadata<'_>) -> bool {
29            true
30        }
31
32        fn log(&self, record: &log::Record<'_>) {
33            std::println!("[{}] ({}) {}", record.level(), record.target(), record.args())
34        }
35
36        fn flush(&self) {}
37    }
38
39    static LOGGER_ONCE: AtomicBool = AtomicBool::new(true);
40
41    // log::set_logger will panic if called multiple times.
42    if LOGGER_ONCE.swap(false, atomic::Ordering::AcqRel) {
43        log::set_logger(&Logger).unwrap();
44        log::set_max_level(log::LevelFilter::Trace);
45    }
46}
47
48/// Asserts that an iterable object produces zero items.
49///
50/// `assert_empty` drains `into_iter.into_iter()` and asserts that zero
51/// items are produced. It panics with a message which includes the produced
52/// items if this assertion fails.
53#[track_caller]
54pub fn assert_empty<I: IntoIterator>(into_iter: I)
55where
56    I::Item: Debug,
57{
58    // NOTE: Collecting into a `Vec` is cheap in the happy path because
59    // zero-capacity vectors are guaranteed not to allocate.
60    let vec = into_iter.into_iter().collect::<Vec<_>>();
61    assert!(vec.is_empty(), "vec={vec:?}");
62}