List observer and feedback (#553)
This commit is contained in:
parent
ef01009f30
commit
5ffddcfd4a
@ -32,7 +32,7 @@ use crate::{
|
|||||||
events::EventFirer,
|
events::EventFirer,
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
observers::{ObserversTuple, TimeObserver},
|
observers::{ListObserver, ObserversTuple, TimeObserver},
|
||||||
state::HasClientPerfMonitor,
|
state::HasClientPerfMonitor,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -913,3 +913,74 @@ impl TimeFeedback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consider interesting a testcase if the list in ListObserver is not empty.
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
pub struct ListFeedback<T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
name: String,
|
||||||
|
phantom: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, S, T> Feedback<I, S> for ListFeedback<T>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
S: HasClientPerfMonitor,
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
#[allow(clippy::wrong_self_convention)]
|
||||||
|
fn is_interesting<EM, OT>(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut S,
|
||||||
|
_manager: &mut EM,
|
||||||
|
_input: &I,
|
||||||
|
observers: &OT,
|
||||||
|
_exit_kind: &ExitKind,
|
||||||
|
) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
EM: EventFirer<I>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
|
{
|
||||||
|
// TODO Replace with match_name_type when stable
|
||||||
|
let observer = observers
|
||||||
|
.match_name::<ListObserver<T>>(self.name())
|
||||||
|
.unwrap();
|
||||||
|
// TODO register the list content in a testcase metadata
|
||||||
|
Ok(!observer.list().is_empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Named for ListFeedback<T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
self.name.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ListFeedback<T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
/// Creates a new [`ListFeedback`], deciding if the value of a [`ListObserver`] with the given `name` of a run is interesting.
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(name: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.to_string(),
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`TimeFeedback`], deciding if the given [`ListObserver`] value of a run is interesting.
|
||||||
|
#[must_use]
|
||||||
|
pub fn new_with_observer(observer: &ListObserver<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
name: observer.name().to_string(),
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -30,6 +30,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
bolts::{
|
bolts::{
|
||||||
current_time,
|
current_time,
|
||||||
|
ownedref::OwnedRefMut,
|
||||||
tuples::{MatchName, Named},
|
tuples::{MatchName, Named},
|
||||||
},
|
},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
@ -229,6 +230,61 @@ impl Named for TimeObserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A simple observer with a list of things.
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
||||||
|
pub struct ListObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
name: String,
|
||||||
|
/// The list
|
||||||
|
list: OwnedRefMut<'a, Vec<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> ListObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
/// Creates a new [`ListObserver`] with the given name.
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(name: &'static str, list: &'a mut Vec<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.to_string(),
|
||||||
|
list: OwnedRefMut::Ref(list),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list ref
|
||||||
|
pub fn list(&self) -> &Vec<T> {
|
||||||
|
self.list.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list mut
|
||||||
|
pub fn list_mut(&mut self) -> &mut Vec<T> {
|
||||||
|
self.list.as_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, I, S, T> Observer<I, S> for ListObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
|
self.list.as_mut().clear();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Named for ListObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user