fmt
This commit is contained in:
parent
8b0a6ca5c8
commit
4c4273992d
@ -3,8 +3,8 @@
|
|||||||
pub mod stats;
|
pub mod stats;
|
||||||
pub use stats::*;
|
pub use stats::*;
|
||||||
|
|
||||||
use crate::llmp::LlmpReceiver;
|
|
||||||
use crate::llmp::LlmpSender;
|
use crate::llmp::LlmpSender;
|
||||||
|
use crate::{llmp::LlmpReceiver, utils::deserialize_state_mgr};
|
||||||
use alloc::{
|
use alloc::{
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
@ -46,18 +46,10 @@ pub enum LogSeverity {
|
|||||||
impl fmt::Display for LogSeverity {
|
impl fmt::Display for LogSeverity {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
LogSeverity::Debug => {
|
LogSeverity::Debug => write!(f, "Debug"),
|
||||||
write!(f, "Debug")
|
LogSeverity::Info => write!(f, "Info"),
|
||||||
}
|
LogSeverity::Warn => write!(f, "Warn"),
|
||||||
LogSeverity::Info => {
|
LogSeverity::Error => write!(f, "Error"),
|
||||||
write!(f, "Info")
|
|
||||||
}
|
|
||||||
LogSeverity::Warn => {
|
|
||||||
write!(f, "Warn")
|
|
||||||
}
|
|
||||||
LogSeverity::Error => {
|
|
||||||
write!(f, "Error")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,10 +196,15 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Send off an event to the broker
|
/// Send off an event to the broker
|
||||||
fn fire<C, FT, R>(&mut self, _state: &mut State<C, I, R, FT>, event: Event<I>) -> Result<(), AflError> where
|
fn fire<C, FT, R>(
|
||||||
C: Corpus<I, R>,
|
&mut self,
|
||||||
FT: FeedbacksTuple<I>,
|
_state: &mut State<C, I, R, FT>,
|
||||||
R: Rand;
|
event: Event<I>,
|
||||||
|
) -> Result<(), AflError>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
||||||
@ -228,10 +225,16 @@ where
|
|||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire<C, FT, R>(&mut self, _state: &mut State<C, I, R, FT>, _event: Event<I>) -> Result<(), AflError> where
|
fn fire<C, FT, R>(
|
||||||
C: Corpus<I, R>,
|
&mut self,
|
||||||
FT: FeedbacksTuple<I>,
|
_state: &mut State<C, I, R, FT>,
|
||||||
R: Rand {
|
_event: Event<I>,
|
||||||
|
) -> Result<(), AflError>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,10 +271,16 @@ where
|
|||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire<C, FT, R>(&mut self, _state: &mut State<C, I, R, FT>, event: Event<I>) -> Result<(), AflError> where
|
fn fire<C, FT, R>(
|
||||||
C: Corpus<I, R>,
|
&mut self,
|
||||||
FT: FeedbacksTuple<I>,
|
_state: &mut State<C, I, R, FT>,
|
||||||
R: Rand, {
|
event: Event<I>,
|
||||||
|
) -> Result<(), AflError>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
match Self::handle_in_broker(&mut self.stats, 0, &event)? {
|
match Self::handle_in_broker(&mut self.stats, 0, &event)? {
|
||||||
BrokerEventResult::Forward => self.events.push(event),
|
BrokerEventResult::Forward => self.events.push(event),
|
||||||
BrokerEventResult::Handled => (),
|
BrokerEventResult::Handled => (),
|
||||||
@ -367,6 +376,9 @@ const _LLMP_TAG_EVENT_TO_BROKER: llmp::Tag = 0x2B80438;
|
|||||||
///
|
///
|
||||||
const LLMP_TAG_EVENT_TO_BOTH: llmp::Tag = 0x2B0741;
|
const LLMP_TAG_EVENT_TO_BOTH: llmp::Tag = 0x2B0741;
|
||||||
|
|
||||||
|
const _LLMP_TAG_RESTART: llmp::Tag = 0x8357A87;
|
||||||
|
const _LLMP_TAG_NO_RESTART: llmp::Tag = 0x57A7EE71;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LlmpEventManager<I, SH, ST>
|
pub struct LlmpEventManager<I, SH, ST>
|
||||||
where
|
where
|
||||||
@ -640,7 +652,11 @@ where
|
|||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire<C, FT, R>(&mut self, _state: &mut State<C, I, R, FT>, event: Event<I>) -> Result<(), AflError>
|
fn fire<C, FT, R>(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut State<C, I, R, FT>,
|
||||||
|
event: Event<I>,
|
||||||
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -672,7 +688,7 @@ where
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// A manager that can restart on the fly
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LlmpRestartingEventManager<I, SH, ST>
|
pub struct LlmpRestartingEventManager<I, SH, ST>
|
||||||
where
|
where
|
||||||
@ -681,12 +697,12 @@ where
|
|||||||
ST: Stats,
|
ST: Stats,
|
||||||
//CE: CustomEvent<I>,
|
//CE: CustomEvent<I>,
|
||||||
{
|
{
|
||||||
|
/// The embedded llmp event manager
|
||||||
llmp_mgr: LlmpEventManager<I, SH, ST>,
|
llmp_mgr: LlmpEventManager<I, SH, ST>,
|
||||||
|
/// The sender to serialize the state for the next runner
|
||||||
sender: LlmpSender<SH>,
|
sender: LlmpSender<SH>,
|
||||||
receiver: LlmpReceiver<SH>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<I, SH, ST> EventManager<I> for LlmpRestartingEventManager<I, SH, ST>
|
impl<I, SH, ST> EventManager<I> for LlmpRestartingEventManager<I, SH, ST>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -702,23 +718,27 @@ where
|
|||||||
self.llmp_mgr.process(state)
|
self.llmp_mgr.process(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire<C, FT, R>(&mut self, state: &mut State<C, I, R, FT>, event: Event<I>) -> Result<(), AflError> where
|
fn fire<C, FT, R>(
|
||||||
|
&mut self,
|
||||||
|
state: &mut State<C, I, R, FT>,
|
||||||
|
event: Event<I>,
|
||||||
|
) -> Result<(), AflError>
|
||||||
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
|
// Check if we are going to crash in the event, in which case we store our current state for the next runner
|
||||||
match &event {
|
match &event {
|
||||||
Event::Crash { input: _ } => {
|
Event::Crash { input: _ } | Event::Timeout { input: _ } => {
|
||||||
|
// First, reset the page to 0 so the next iteration can read read from the beginning of this page
|
||||||
|
unsafe { sender.reset_last_page() };
|
||||||
let buf = postcard::to_allocvec(&(&state, &self.llmp_mgr.describe()?))?;
|
let buf = postcard::to_allocvec(&(&state, &self.llmp_mgr.describe()?))?;
|
||||||
self.sender.send_buf(0x1, &buf).unwrap();
|
self.sender.send_buf(_LLMP_TAG_RESTART, &buf).unwrap();
|
||||||
},
|
}
|
||||||
Event::Timeout { input: _ } => {
|
_ => (),
|
||||||
let buf = postcard::to_allocvec(&(&state, &self.llmp_mgr.describe()?))?;
|
|
||||||
self.sender.send_buf(0x1, &buf).unwrap();
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
};
|
};
|
||||||
self.llmp_mgr.fire(state, event)
|
self.llmp_mgr.fire(state, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,37 +748,32 @@ const ENV_FUZZER_RECEIVER: &str = &"_AFL_ENV_FUZZER_RECEIVER";
|
|||||||
/// The llmp (2 way) connection from a fuzzer to the broker (broadcasting all other fuzzer messages)
|
/// The llmp (2 way) connection from a fuzzer to the broker (broadcasting all other fuzzer messages)
|
||||||
const ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = &"_AFL_ENV_FUZZER_BROKER_CLIENT";
|
const ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = &"_AFL_ENV_FUZZER_BROKER_CLIENT";
|
||||||
|
|
||||||
|
|
||||||
impl<I, SH, ST> LlmpRestartingEventManager<I, SH, ST>
|
impl<I, SH, ST> LlmpRestartingEventManager<I, SH, ST>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SH: ShMem,
|
SH: ShMem,
|
||||||
ST: Stats, //CE: CustomEvent<I>,
|
ST: Stats, //CE: CustomEvent<I>,
|
||||||
{
|
{
|
||||||
|
|
||||||
/// Create a new runner, the executed child doing the actual fuzzing.
|
/// Create a new runner, the executed child doing the actual fuzzing.
|
||||||
pub fn new(llmp_mgr: LlmpEventManager<I, SH, ST>, receiver: LlmpReceiver<SH>, sender: LlmpSender<SH>) -> Self {
|
pub fn new(llmp_mgr: LlmpEventManager<I, SH, ST>, sender: LlmpSender<SH>) -> Self {
|
||||||
Self {
|
Self { llmp_mgr, sender }
|
||||||
llmp_mgr,
|
|
||||||
sender,
|
|
||||||
receiver,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn temp<C, FT, R>(stats: ST, broker_port: u16) -> Result<(Self, Option<State<C, I, R, FT>>), AflError>
|
pub fn temp<C, FT, R>(
|
||||||
|
stats: ST,
|
||||||
|
broker_port: u16,
|
||||||
|
) -> Result<(Self, Option<State<C, I, R, FT>>), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
|
|
||||||
let mut mgr;
|
let mut mgr;
|
||||||
|
|
||||||
// We start ourself as child process to actually fuzz
|
// We start ourself as child process to actually fuzz
|
||||||
if std::env::var(ENV_FUZZER_SENDER).is_err() {
|
if std::env::var(ENV_FUZZER_SENDER).is_err() {
|
||||||
|
|
||||||
// We are either the broker, or the parent of the fuzzing instance
|
// We are either the broker, or the parent of the fuzzing instance
|
||||||
mgr = LlmpEventManager::new_on_port( stats, broker_port)?;
|
mgr = LlmpEventManager::new_on_port(stats, broker_port)?;
|
||||||
if mgr.is_broker() {
|
if mgr.is_broker() {
|
||||||
// Yep, broker. Just loop here.
|
// Yep, broker. Just loop here.
|
||||||
println!("Doing broker things. Run this tool again to start fuzzing in a client.");
|
println!("Doing broker things. Run this tool again to start fuzzing in a client.");
|
||||||
@ -807,9 +822,7 @@ where
|
|||||||
None => {
|
None => {
|
||||||
println!("First run. Let's set it all up");
|
println!("First run. Let's set it all up");
|
||||||
// Mgr to send and receive msgs from/to all other fuzzer instances
|
// Mgr to send and receive msgs from/to all other fuzzer instances
|
||||||
mgr = LlmpEventManager::existing_client_from_env(
|
mgr = LlmpEventManager::existing_client_from_env(ENV_FUZZER_BROKER_CLIENT_INITIAL)?;
|
||||||
ENV_FUZZER_BROKER_CLIENT_INITIAL,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
(mgr, None)
|
(mgr, None)
|
||||||
}
|
}
|
||||||
@ -824,80 +837,82 @@ where
|
|||||||
|
|
||||||
Ok(mgr)
|
Ok(mgr)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A restarting state is a combination of restarter and runner, that can be used on systems without `fork`.
|
/// A restarting state is a combination of restarter and runner, that can be used on systems without `fork`.
|
||||||
/// The restarter will start a new process each time the child crashes or timeouts.
|
/// The restarter will start a new process each time the child crashes or timeouts.
|
||||||
pub fn setup_restarting_state<I, C, FT, R, SH, ST, >(mgr: &mut LlmpEventManager<I, SH, ST>) -> Result<Option<State<C, I, R, FT>>, AflError>
|
pub fn setup_restarting_state<I, C, FT, R, SH, ST>(
|
||||||
where
|
mgr: &mut LlmpEventManager<I, SH, ST>,
|
||||||
I: Input,
|
) -> Result<Option<State<C, I, R, FT>>, AflError>
|
||||||
C: Corpus<I, R>,
|
where
|
||||||
FT: FeedbacksTuple<I>,
|
I: Input,
|
||||||
R: Rand,
|
C: Corpus<I, R>,
|
||||||
SH: ShMem,
|
FT: FeedbacksTuple<I>,
|
||||||
ST: Stats,
|
R: Rand,
|
||||||
|
SH: ShMem,
|
||||||
|
ST: Stats,
|
||||||
{
|
{
|
||||||
|
// We start ourself as child process to actually fuzz
|
||||||
|
if std::env::var(ENV_FUZZER_SENDER).is_err() {
|
||||||
|
mgr.to_env(ENV_FUZZER_BROKER_CLIENT_INITIAL);
|
||||||
|
|
||||||
// We start ourself as child process to actually fuzz
|
// First, create a channel from the fuzzer (sender) to us (receiver) to report its state for restarts.
|
||||||
if std::env::var(ENV_FUZZER_SENDER).is_err() {
|
let sender = LlmpSender::new(0, false)?;
|
||||||
|
let receiver = LlmpReceiver::on_existing_map(
|
||||||
|
AflShmem::clone_ref(&sender.out_maps.last().unwrap().shmem)?,
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
// Store the information to a map.
|
||||||
|
sender.to_env(ENV_FUZZER_SENDER)?;
|
||||||
|
receiver.to_env(ENV_FUZZER_RECEIVER)?;
|
||||||
|
|
||||||
mgr.to_env(ENV_FUZZER_BROKER_CLIENT_INITIAL);
|
let mut ctr = 0;
|
||||||
|
// Client->parent loop
|
||||||
// First, create a channel from the fuzzer (sender) to us (receiver) to report its state for restarts.
|
loop {
|
||||||
let sender = LlmpSender::new(0, false)?;
|
dbg!("Spawning next client");
|
||||||
let receiver = LlmpReceiver::on_existing_map(
|
Command::new(env::current_exe()?)
|
||||||
AflShmem::clone_ref(&sender.out_maps.last().unwrap().shmem)?,
|
.current_dir(env::current_dir()?)
|
||||||
None,
|
.args(env::args())
|
||||||
)?;
|
.status()?;
|
||||||
// Store the information to a map.
|
ctr += 1;
|
||||||
sender.to_env(ENV_FUZZER_SENDER)?;
|
if ctr == 10 {
|
||||||
receiver.to_env(ENV_FUZZER_RECEIVER)?;
|
return Ok(());
|
||||||
|
|
||||||
let mut ctr = 0;
|
|
||||||
// Client->parent loop
|
|
||||||
loop {
|
|
||||||
dbg!("Spawning next client");
|
|
||||||
Command::new(env::current_exe()?)
|
|
||||||
.current_dir(env::current_dir()?)
|
|
||||||
.args(env::args())
|
|
||||||
.status()?;
|
|
||||||
ctr += 1;
|
|
||||||
if ctr == 10 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
println!("We're a client, let's fuzz :)");
|
|
||||||
|
|
||||||
// We are the fuzzing instance, first, connect to our own restore map.
|
println!("We're a client, let's fuzz :)");
|
||||||
// A sender and a receiver for single communication
|
|
||||||
let mut receiver = LlmpReceiver::<AflShmem>::on_existing_from_env(ENV_FUZZER_RECEIVER)?;
|
|
||||||
let mut sender = LlmpSender::<AflShmem>::on_existing_from_env(ENV_FUZZER_SENDER)?;
|
|
||||||
|
|
||||||
// If we're restarting, deserialize the old state.
|
// We are the fuzzing instance, first, connect to our own restore map.
|
||||||
let (mut state, mut mgr) = match receiver.recv_buf()? {
|
// A sender and a receiver for single communication
|
||||||
None => {
|
let mut receiver = LlmpReceiver::<AflShmem>::on_existing_from_env(ENV_FUZZER_RECEIVER)?;
|
||||||
println!("First run. Let's set it all up");
|
let mut sender = LlmpSender::<AflShmem>::on_existing_from_env(ENV_FUZZER_SENDER)?;
|
||||||
// Mgr to send and receive msgs from/to all other fuzzer instances
|
|
||||||
let client_mgr = LlmpEventManager::existing_client_from_env(
|
|
||||||
ENV_FUZZER_BROKER_CLIENT_INITIAL,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
(LlmpRestartingEventManager::new(client_mgr, sender, receiver), receiver: LlmpReceiver<SH>, sender: LlmpSender<SH>), None)
|
// If we're restarting, deserialize the old state.
|
||||||
}
|
let (mut state, mut mgr) = match receiver.recv_buf()? {
|
||||||
// Restoring from a previous run, deserialize state and corpus.
|
None => {
|
||||||
Some((_sender, _tag, msg)) => {
|
println!("First run. Let's set it all up");
|
||||||
println!("Subsequent run. Let's load all data from shmem (received {} bytes from previous instance)", msg.len());
|
// Mgr to send and receive msgs from/to all other fuzzer instances
|
||||||
deserialize_state_mgr(&msg, stats)?
|
let client_mgr =
|
||||||
}
|
LlmpEventManager::existing_client_from_env(ENV_FUZZER_BROKER_CLIENT_INITIAL)?;
|
||||||
};
|
|
||||||
// We reset the sender, the next sender and receiver (after crash) will reuse the page from the initial message.
|
(LlmpRestartingEventManager::new(client_mgr, sender), None)
|
||||||
unsafe { sender.reset_last_page() };
|
}
|
||||||
|
// Restoring from a previous run, deserialize state and corpus.
|
||||||
|
Some((_sender, _tag, msg)) => {
|
||||||
|
println!("Subsequent run. Let's load all data from shmem (received {} bytes from previous instance)", msg.len());
|
||||||
|
deserialize_state_mgr(&msg)?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// We reset the sender, the next sender and receiver (after crash) will reuse the page from the initial message.
|
||||||
|
unsafe { sender.reset_last_page() };
|
||||||
|
/* TODO: Not sure if this is needed
|
||||||
|
// We commit an empty NO_RESTART message to this buf, against infinite loops,
|
||||||
|
// in case something crashes in the fuzzer.
|
||||||
|
sender.send_buf(_LLMP_TAG_NO_RESTART, []);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
@ -86,11 +86,14 @@ where
|
|||||||
let cur = current_milliseconds();
|
let cur = current_milliseconds();
|
||||||
if cur - last > 60 * 100 {
|
if cur - last > 60 * 100 {
|
||||||
last = cur;
|
last = cur;
|
||||||
manager.fire(state, Event::UpdateStats {
|
manager.fire(
|
||||||
executions: state.executions(),
|
state,
|
||||||
execs_over_sec: state.executions_over_seconds(),
|
Event::UpdateStats {
|
||||||
phantom: PhantomData,
|
executions: state.executions(),
|
||||||
})?
|
execs_over_sec: state.executions_over_seconds(),
|
||||||
|
phantom: PhantomData,
|
||||||
|
},
|
||||||
|
)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,11 +143,14 @@ where
|
|||||||
for in_dir in in_dirs {
|
for in_dir in in_dirs {
|
||||||
self.load_from_directory(executor, generator, manager, in_dir)?;
|
self.load_from_directory(executor, generator, manager, in_dir)?;
|
||||||
}
|
}
|
||||||
manager.fire(self, Event::Log {
|
manager.fire(
|
||||||
severity_level: LogSeverity::Debug,
|
self,
|
||||||
message: format!("Loaded {} initial testcases.", self.corpus().count()), // get corpus count
|
Event::Log {
|
||||||
phantom: PhantomData,
|
severity_level: LogSeverity::Debug,
|
||||||
})?;
|
message: format!("Loaded {} initial testcases.", self.corpus().count()), // get corpus count
|
||||||
|
phantom: PhantomData,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
manager.process(self)?;
|
manager.process(self)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -351,11 +354,14 @@ where
|
|||||||
added += 1;
|
added += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
manager.fire(self, Event::Log {
|
manager.fire(
|
||||||
severity_level: LogSeverity::Debug,
|
self,
|
||||||
message: format!("Loaded {} over {} initial testcases", added, num),
|
Event::Log {
|
||||||
phantom: PhantomData,
|
severity_level: LogSeverity::Debug,
|
||||||
})?;
|
message: format!("Loaded {} over {} initial testcases", added, num),
|
||||||
|
phantom: PhantomData,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
manager.process(self)?;
|
manager.process(self)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user