mirror of
https://framagit.org/ppom/reaction
synced 2026-03-14 12:45:47 +01:00
Test existing FilterManager tests for each Duplicate enum
This commit is contained in:
parent
81e5fb4c42
commit
6f346ff371
3 changed files with 439 additions and 414 deletions
|
|
@ -354,6 +354,7 @@ impl Filter {
|
|||
retry_period: Option<&str>,
|
||||
stream_name: &str,
|
||||
name: &str,
|
||||
duplicate: Duplicate,
|
||||
config_patterns: &Patterns,
|
||||
) -> Self {
|
||||
let mut filter = Self {
|
||||
|
|
@ -361,6 +362,7 @@ impl Filter {
|
|||
regex: regex.into_iter().map(|s| s.into()).collect(),
|
||||
retry,
|
||||
retry_period: retry_period.map(|s| s.into()),
|
||||
duplicate,
|
||||
..Default::default()
|
||||
};
|
||||
filter.setup(stream_name, name, config_patterns).unwrap();
|
||||
|
|
@ -374,6 +376,7 @@ impl Filter {
|
|||
retry_period: Option<&str>,
|
||||
stream_name: &str,
|
||||
name: &str,
|
||||
duplicate: Duplicate,
|
||||
config_patterns: &Patterns,
|
||||
) -> &'static Self {
|
||||
Box::leak(Box::new(Self::new(
|
||||
|
|
@ -383,6 +386,7 @@ impl Filter {
|
|||
retry_period,
|
||||
stream_name,
|
||||
name,
|
||||
duplicate,
|
||||
config_patterns,
|
||||
)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ mod tests {
|
|||
use chrono::{DateTime, Local, TimeDelta};
|
||||
|
||||
use crate::{
|
||||
concepts::{filter_tests::ok_filter, Action, Filter, Pattern},
|
||||
concepts::{filter_tests::ok_filter, Action, Duplicate, Filter, Pattern},
|
||||
daemon::filter::state::State,
|
||||
tests::TempDatabase,
|
||||
};
|
||||
|
|
@ -256,6 +256,7 @@ mod tests {
|
|||
Some("2s"),
|
||||
"s1",
|
||||
"f1",
|
||||
Duplicate::default(),
|
||||
&patterns,
|
||||
);
|
||||
|
||||
|
|
@ -384,6 +385,7 @@ mod tests {
|
|||
Some("2s"),
|
||||
"s1",
|
||||
"f1",
|
||||
Duplicate::default(),
|
||||
&patterns,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use tokio::sync::Semaphore;
|
|||
|
||||
use super::{state::filter_ordered_times_db_name, FilterManager, React};
|
||||
use crate::{
|
||||
concepts::{Action, Filter, Pattern, Patterns, Time},
|
||||
concepts::{Action, Duplicate, Filter, Pattern, Patterns, Time},
|
||||
daemon::shutdown::ShutdownController,
|
||||
tests::TempDatabase,
|
||||
};
|
||||
|
|
@ -83,10 +83,142 @@ impl TestBed2 {
|
|||
|
||||
#[tokio::test]
|
||||
async fn three_matches_then_action_then_delayed_action() {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![
|
||||
Action::new(
|
||||
for dup in [Duplicate::Rerun, Duplicate::Extend, Duplicate::Ignore] {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a2 <az> >> {}", &bed.out_file)],
|
||||
Some("100ms"),
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a2",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
],
|
||||
vec!["test <az>"],
|
||||
Some(3),
|
||||
Some("2s"),
|
||||
"test",
|
||||
"test",
|
||||
dup,
|
||||
&bed.az_patterns,
|
||||
);
|
||||
|
||||
let bed = bed.part2(filter, Local::now(), None).await;
|
||||
|
||||
let now = bed.now;
|
||||
let now1s = bed.now + TimeDelta::seconds(1);
|
||||
let now2s = bed.now + TimeDelta::seconds(2);
|
||||
|
||||
// No match
|
||||
assert_eq!(bed.manager.handle_line("test 131", now), React::NoMatch);
|
||||
bed.assert_empty_trees();
|
||||
|
||||
// First match
|
||||
let one = vec!["one".to_string()];
|
||||
assert_eq!(bed.manager.handle_line("test one", now), React::Match);
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert_eq!(
|
||||
state.matches,
|
||||
BTreeMap::from([(one.clone(), BTreeSet::from([now]))]),
|
||||
"the match has been added to matches"
|
||||
);
|
||||
assert_eq!(
|
||||
state.ordered_times.tree(),
|
||||
&BTreeMap::from([(now, one.clone())]),
|
||||
"the match has been added to ordered_times"
|
||||
);
|
||||
assert!(state.triggers.is_empty(), "triggers is still empty");
|
||||
}
|
||||
|
||||
// Second match
|
||||
assert_eq!(bed.manager.handle_line("test one", now1s), React::Match);
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert_eq!(
|
||||
state.matches,
|
||||
BTreeMap::from([(one.clone(), BTreeSet::from([now, now1s]))]),
|
||||
"a second match is present in matches"
|
||||
);
|
||||
assert_eq!(
|
||||
state.ordered_times.tree(),
|
||||
&BTreeMap::from([(now, one.clone()), (now1s, one.clone())]),
|
||||
"a second match is present in ordered_times"
|
||||
);
|
||||
assert!(state.triggers.is_empty(), "triggers is still empty");
|
||||
}
|
||||
|
||||
// Third match, exec
|
||||
let _block = bed.semaphore.acquire().await.unwrap();
|
||||
assert_eq!(bed.manager.handle_line("test one", now2s), React::Trigger);
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert!(
|
||||
state.matches.is_empty(),
|
||||
"matches are emptied after trigger"
|
||||
);
|
||||
assert!(
|
||||
state.ordered_times.is_empty(),
|
||||
"ordered_times are emptied after trigger"
|
||||
);
|
||||
assert_eq!(
|
||||
state.triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now2s, 1)]))]),
|
||||
// 1 and not 2 because the decrement_trigger() doesn't wait for the semaphore
|
||||
"triggers now contain the triggered match with 1 action left"
|
||||
);
|
||||
}
|
||||
drop(_block);
|
||||
|
||||
// Now the first action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
// Check first action
|
||||
assert_eq!(
|
||||
bed.manager.state.lock().unwrap().triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now2s, 1)]))]),
|
||||
"triggers still contain the triggered match with 1 action left"
|
||||
);
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the first action"
|
||||
);
|
||||
|
||||
// Now the second action executes
|
||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||
// Check second action
|
||||
assert!(
|
||||
bed.manager.state.lock().unwrap().triggers.is_empty(),
|
||||
"triggers are empty again"
|
||||
);
|
||||
assert_eq!(
|
||||
"a1 one\na2 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the 2 actions"
|
||||
);
|
||||
|
||||
bed.assert_empty_trees();
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn one_match_one_action() {
|
||||
for dup in [Duplicate::Rerun, Duplicate::Extend, Duplicate::Ignore] {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
|
|
@ -94,326 +226,209 @@ async fn three_matches_then_action_then_delayed_action() {
|
|||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a2 <az> >> {}", &bed.out_file)],
|
||||
Some("100ms"),
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a2",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
],
|
||||
vec!["test <az>"],
|
||||
Some(3),
|
||||
Some("2s"),
|
||||
"test",
|
||||
"test",
|
||||
&bed.az_patterns,
|
||||
);
|
||||
|
||||
let bed = bed.part2(filter, Local::now(), None).await;
|
||||
|
||||
let now = bed.now;
|
||||
let now1s = bed.now + TimeDelta::seconds(1);
|
||||
let now2s = bed.now + TimeDelta::seconds(2);
|
||||
|
||||
// No match
|
||||
assert_eq!(bed.manager.handle_line("test 131", now), React::NoMatch);
|
||||
bed.assert_empty_trees();
|
||||
|
||||
// First match
|
||||
let one = vec!["one".to_string()];
|
||||
assert_eq!(bed.manager.handle_line("test one", now), React::Match);
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert_eq!(
|
||||
state.matches,
|
||||
BTreeMap::from([(one.clone(), BTreeSet::from([now]))]),
|
||||
"the match has been added to matches"
|
||||
);
|
||||
assert_eq!(
|
||||
state.ordered_times.tree(),
|
||||
&BTreeMap::from([(now, one.clone())]),
|
||||
"the match has been added to ordered_times"
|
||||
);
|
||||
assert!(state.triggers.is_empty(), "triggers is still empty");
|
||||
}
|
||||
|
||||
// Second match
|
||||
assert_eq!(bed.manager.handle_line("test one", now1s), React::Match);
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert_eq!(
|
||||
state.matches,
|
||||
BTreeMap::from([(one.clone(), BTreeSet::from([now, now1s]))]),
|
||||
"a second match is present in matches"
|
||||
);
|
||||
assert_eq!(
|
||||
state.ordered_times.tree(),
|
||||
&BTreeMap::from([(now, one.clone()), (now1s, one.clone())]),
|
||||
"a second match is present in ordered_times"
|
||||
);
|
||||
assert!(state.triggers.is_empty(), "triggers is still empty");
|
||||
}
|
||||
|
||||
// Third match, exec
|
||||
let _block = bed.semaphore.acquire().await.unwrap();
|
||||
assert_eq!(bed.manager.handle_line("test one", now2s), React::Trigger);
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert!(
|
||||
state.matches.is_empty(),
|
||||
"matches are emptied after trigger"
|
||||
);
|
||||
assert!(
|
||||
state.ordered_times.is_empty(),
|
||||
"ordered_times are emptied after trigger"
|
||||
);
|
||||
assert_eq!(
|
||||
state.triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now2s, 1)]))]),
|
||||
// 1 and not 2 because the decrement_trigger() doesn't wait for the semaphore
|
||||
"triggers now contain the triggered match with 1 action left"
|
||||
);
|
||||
}
|
||||
drop(_block);
|
||||
|
||||
// Now the first action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
// Check first action
|
||||
assert_eq!(
|
||||
bed.manager.state.lock().unwrap().triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now2s, 1)]))]),
|
||||
"triggers still contain the triggered match with 1 action left"
|
||||
);
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the first action"
|
||||
);
|
||||
|
||||
// Now the second action executes
|
||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||
// Check second action
|
||||
assert!(
|
||||
bed.manager.state.lock().unwrap().triggers.is_empty(),
|
||||
"triggers are empty again"
|
||||
);
|
||||
assert_eq!(
|
||||
"a1 one\na2 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the 2 actions"
|
||||
);
|
||||
|
||||
bed.assert_empty_trees();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn one_match_one_action() {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
)],
|
||||
vec!["test <az>"],
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
dup,
|
||||
&bed.az_patterns,
|
||||
)],
|
||||
vec!["test <az>"],
|
||||
None,
|
||||
None,
|
||||
"test",
|
||||
"test",
|
||||
&bed.az_patterns,
|
||||
);
|
||||
);
|
||||
|
||||
let bed = bed.part2(filter, Local::now(), None).await;
|
||||
let now = bed.now;
|
||||
let bed = bed.part2(filter, Local::now(), None).await;
|
||||
let now = bed.now;
|
||||
|
||||
// No match
|
||||
assert_eq!(bed.manager.handle_line("test 131", now), React::NoMatch);
|
||||
bed.assert_empty_trees();
|
||||
// No match
|
||||
assert_eq!(bed.manager.handle_line("test 131", now), React::NoMatch);
|
||||
bed.assert_empty_trees();
|
||||
|
||||
// match
|
||||
assert_eq!(bed.manager.handle_line("test one", now), React::Trigger);
|
||||
bed.assert_empty_trees();
|
||||
// match
|
||||
assert_eq!(bed.manager.handle_line("test one", now), React::Trigger);
|
||||
bed.assert_empty_trees();
|
||||
|
||||
// the action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the first action"
|
||||
);
|
||||
// the action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the first action"
|
||||
);
|
||||
|
||||
bed.assert_empty_trees();
|
||||
bed.assert_empty_trees();
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn one_match_one_delayed_action() {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
Some("100ms"),
|
||||
false,
|
||||
for dup in [Duplicate::Rerun, Duplicate::Extend, Duplicate::Ignore] {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
Some("100ms"),
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
)],
|
||||
vec!["test <az>"],
|
||||
None,
|
||||
None,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
dup,
|
||||
&bed.az_patterns,
|
||||
)],
|
||||
vec!["test <az>"],
|
||||
None,
|
||||
None,
|
||||
"test",
|
||||
"test",
|
||||
&bed.az_patterns,
|
||||
);
|
||||
|
||||
let bed = bed.part2(filter, Local::now(), None).await;
|
||||
let now = bed.now;
|
||||
|
||||
// No match
|
||||
assert_eq!(bed.manager.handle_line("test 131", now), React::NoMatch);
|
||||
bed.assert_empty_trees();
|
||||
|
||||
// Match
|
||||
let one = vec!["one".to_string()];
|
||||
assert_eq!(bed.manager.handle_line("test one", now), React::Trigger);
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert!(state.matches.is_empty(), "matches stay empty");
|
||||
assert!(state.ordered_times.is_empty(), "ordered_times stay empty");
|
||||
assert_eq!(
|
||||
state.triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now, 1)]))]),
|
||||
"triggers still contain the triggered match with 1 action left"
|
||||
);
|
||||
|
||||
let bed = bed.part2(filter, Local::now(), None).await;
|
||||
let now = bed.now;
|
||||
|
||||
// No match
|
||||
assert_eq!(bed.manager.handle_line("test 131", now), React::NoMatch);
|
||||
bed.assert_empty_trees();
|
||||
|
||||
// Match
|
||||
let one = vec!["one".to_string()];
|
||||
assert_eq!(bed.manager.handle_line("test one", now), React::Trigger);
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert!(state.matches.is_empty(), "matches stay empty");
|
||||
assert!(state.ordered_times.is_empty(), "ordered_times stay empty");
|
||||
assert_eq!(
|
||||
state.triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now, 1)]))]),
|
||||
"triggers still contain the triggered match with 1 action left"
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
"",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file is empty"
|
||||
);
|
||||
|
||||
// The action executes
|
||||
tokio::time::sleep(Duration::from_millis(140)).await;
|
||||
assert!(
|
||||
bed.manager.state.lock().unwrap().triggers.is_empty(),
|
||||
"triggers are empty again"
|
||||
);
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the action"
|
||||
);
|
||||
|
||||
bed.assert_empty_trees();
|
||||
}
|
||||
assert_eq!(
|
||||
"",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file is empty"
|
||||
);
|
||||
|
||||
// The action executes
|
||||
tokio::time::sleep(Duration::from_millis(140)).await;
|
||||
assert!(
|
||||
bed.manager.state.lock().unwrap().triggers.is_empty(),
|
||||
"triggers are empty again"
|
||||
);
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the action"
|
||||
);
|
||||
|
||||
bed.assert_empty_trees();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn one_db_match_one_runtime_match_one_action() {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
for dup in [Duplicate::Rerun, Duplicate::Extend, Duplicate::Ignore] {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
)],
|
||||
vec!["test <az>"],
|
||||
Some(2),
|
||||
Some("2s"),
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
dup,
|
||||
&bed.az_patterns,
|
||||
)],
|
||||
vec!["test <az>"],
|
||||
Some(2),
|
||||
Some("2s"),
|
||||
"test",
|
||||
"test",
|
||||
&bed.az_patterns,
|
||||
);
|
||||
|
||||
let mut db = TempDatabase::default().await;
|
||||
|
||||
// Pre-add match
|
||||
let now = Local::now();
|
||||
let one = vec!["one".to_string()];
|
||||
let now1s = now - TimeDelta::seconds(1);
|
||||
|
||||
db.set_loaded_db(HashMap::from([(
|
||||
filter_ordered_times_db_name(filter),
|
||||
HashMap::from([(now1s.to_rfc3339().into(), one.clone().into())]),
|
||||
)]));
|
||||
|
||||
// Finish setup
|
||||
let bed = bed.part2(filter, now, Some(db)).await;
|
||||
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert_eq!(
|
||||
state.matches,
|
||||
BTreeMap::from([(one.clone(), BTreeSet::from([now1s]))]),
|
||||
"the match previously added to matches"
|
||||
);
|
||||
|
||||
let mut db = TempDatabase::default().await;
|
||||
|
||||
// Pre-add match
|
||||
let now = Local::now();
|
||||
let one = vec!["one".to_string()];
|
||||
let now1s = now - TimeDelta::seconds(1);
|
||||
|
||||
db.set_loaded_db(HashMap::from([(
|
||||
filter_ordered_times_db_name(filter),
|
||||
HashMap::from([(now1s.to_rfc3339().into(), one.clone().into())]),
|
||||
)]));
|
||||
|
||||
// Finish setup
|
||||
let bed = bed.part2(filter, now, Some(db)).await;
|
||||
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert_eq!(
|
||||
state.matches,
|
||||
BTreeMap::from([(one.clone(), BTreeSet::from([now1s]))]),
|
||||
"the match previously added to matches"
|
||||
);
|
||||
assert_eq!(
|
||||
state.ordered_times.tree(),
|
||||
&BTreeMap::from([(now1s, one.clone())]),
|
||||
"the match previously added to matches"
|
||||
);
|
||||
assert!(state.triggers.is_empty(), "triggers stay empty");
|
||||
}
|
||||
|
||||
// match
|
||||
assert_eq!(bed.manager.handle_line("test one", now), React::Trigger);
|
||||
bed.assert_empty_trees();
|
||||
// the action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
assert_eq!(
|
||||
state.ordered_times.tree(),
|
||||
&BTreeMap::from([(now1s, one.clone())]),
|
||||
"the match previously added to matches"
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the action"
|
||||
);
|
||||
assert!(state.triggers.is_empty(), "triggers stay empty");
|
||||
}
|
||||
|
||||
// match
|
||||
assert_eq!(bed.manager.handle_line("test one", now), React::Trigger);
|
||||
bed.assert_empty_trees();
|
||||
// the action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the action"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn one_outdated_db_match() {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
for dup in [Duplicate::Rerun, Duplicate::Extend, Duplicate::Ignore] {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
)],
|
||||
vec!["test <az>"],
|
||||
Some(2),
|
||||
Some("1s"),
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
dup,
|
||||
&bed.az_patterns,
|
||||
)],
|
||||
vec!["test <az>"],
|
||||
Some(2),
|
||||
Some("1s"),
|
||||
"test",
|
||||
"test",
|
||||
&bed.az_patterns,
|
||||
);
|
||||
);
|
||||
|
||||
let mut db = TempDatabase::default().await;
|
||||
let mut db = TempDatabase::default().await;
|
||||
|
||||
// Pre-add match
|
||||
let now = Local::now();
|
||||
let one = vec!["one".to_string()];
|
||||
let now1s = now - TimeDelta::milliseconds(1001);
|
||||
// Pre-add match
|
||||
let now = Local::now();
|
||||
let one = vec!["one".to_string()];
|
||||
let now1s = now - TimeDelta::milliseconds(1001);
|
||||
|
||||
db.set_loaded_db(HashMap::from([(
|
||||
filter_ordered_times_db_name(filter),
|
||||
HashMap::from([(now1s.to_rfc3339().into(), one.clone().into())]),
|
||||
)]));
|
||||
db.set_loaded_db(HashMap::from([(
|
||||
filter_ordered_times_db_name(filter),
|
||||
HashMap::from([(now1s.to_rfc3339().into(), one.clone().into())]),
|
||||
)]));
|
||||
|
||||
// Finish setup
|
||||
let bed = bed.part2(filter, now, Some(db)).await;
|
||||
bed.assert_empty_trees();
|
||||
// Finish setup
|
||||
let bed = bed.part2(filter, now, Some(db)).await;
|
||||
bed.assert_empty_trees();
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
|
@ -423,145 +438,149 @@ async fn flush() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn trigger_unmatched_pattern() {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a2 <az> >> {}", &bed.out_file)],
|
||||
Some("200ms"),
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a2",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
],
|
||||
vec!["test <az>"],
|
||||
Some(2),
|
||||
Some("1s"),
|
||||
"test",
|
||||
"test",
|
||||
&bed.az_patterns,
|
||||
);
|
||||
for dup in [Duplicate::Rerun, Duplicate::Extend, Duplicate::Ignore] {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a2 <az> >> {}", &bed.out_file)],
|
||||
Some("200ms"),
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a2",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
],
|
||||
vec!["test <az>"],
|
||||
Some(2),
|
||||
Some("1s"),
|
||||
"test",
|
||||
"test",
|
||||
dup,
|
||||
&bed.az_patterns,
|
||||
);
|
||||
|
||||
let now = Local::now();
|
||||
let one = vec!["one".to_string()];
|
||||
let bed = bed.part2(filter, now, None).await;
|
||||
let now = Local::now();
|
||||
let one = vec!["one".to_string()];
|
||||
let bed = bed.part2(filter, now, None).await;
|
||||
|
||||
bed.manager
|
||||
.handle_trigger(
|
||||
// az_pattern: "one"
|
||||
bed.az_patterns
|
||||
.values()
|
||||
.cloned()
|
||||
.map(|pattern| (pattern, one[0].clone()))
|
||||
.collect(),
|
||||
now,
|
||||
)
|
||||
.unwrap();
|
||||
bed.manager
|
||||
.handle_trigger(
|
||||
// az_pattern: "one"
|
||||
bed.az_patterns
|
||||
.values()
|
||||
.cloned()
|
||||
.map(|pattern| (pattern, one[0].clone()))
|
||||
.collect(),
|
||||
now,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// the action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
// the action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
|
||||
// No matches, one action registered
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert!(state.matches.is_empty());
|
||||
assert!(state.ordered_times.is_empty());
|
||||
// No matches, one action registered
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert!(state.matches.is_empty());
|
||||
assert!(state.ordered_times.is_empty());
|
||||
assert_eq!(
|
||||
state.triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now, 1)]))]),
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
state.triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now, 1)]))]),
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the action"
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the action"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn trigger_matched_pattern() {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a2 <az> >> {}", &bed.out_file)],
|
||||
Some("200ms"),
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a2",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
],
|
||||
vec!["test <az>"],
|
||||
Some(2),
|
||||
Some("1s"),
|
||||
"test",
|
||||
"test",
|
||||
&bed.az_patterns,
|
||||
);
|
||||
for dup in [Duplicate::Rerun, Duplicate::Extend, Duplicate::Ignore] {
|
||||
let bed = TestBed::new();
|
||||
let filter = Filter::new_static(
|
||||
vec![
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a1 <az> >> {}", &bed.out_file)],
|
||||
None,
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a1",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
Action::new(
|
||||
vec!["sh", "-c", &format!("echo a2 <az> >> {}", &bed.out_file)],
|
||||
Some("200ms"),
|
||||
false,
|
||||
"test",
|
||||
"test",
|
||||
"a2",
|
||||
&bed.az_patterns,
|
||||
),
|
||||
],
|
||||
vec!["test <az>"],
|
||||
Some(2),
|
||||
Some("1s"),
|
||||
"test",
|
||||
"test",
|
||||
dup,
|
||||
&bed.az_patterns,
|
||||
);
|
||||
|
||||
let now = Local::now();
|
||||
let now1s = now - TimeDelta::milliseconds(10);
|
||||
let one = vec!["one".to_string()];
|
||||
let now = Local::now();
|
||||
let now1s = now - TimeDelta::milliseconds(10);
|
||||
let one = vec!["one".to_string()];
|
||||
|
||||
let mut db = TempDatabase::default().await;
|
||||
db.set_loaded_db(HashMap::from([(
|
||||
filter_ordered_times_db_name(filter),
|
||||
HashMap::from([(now1s.to_rfc3339().into(), one.clone().into())]),
|
||||
)]));
|
||||
let bed = bed.part2(filter, now, Some(db)).await;
|
||||
let mut db = TempDatabase::default().await;
|
||||
db.set_loaded_db(HashMap::from([(
|
||||
filter_ordered_times_db_name(filter),
|
||||
HashMap::from([(now1s.to_rfc3339().into(), one.clone().into())]),
|
||||
)]));
|
||||
let bed = bed.part2(filter, now, Some(db)).await;
|
||||
|
||||
bed.manager
|
||||
.handle_trigger(
|
||||
// az_pattern: "one"
|
||||
bed.az_patterns
|
||||
.values()
|
||||
.cloned()
|
||||
.map(|pattern| (pattern, one[0].clone()))
|
||||
.collect(),
|
||||
now,
|
||||
)
|
||||
.unwrap();
|
||||
bed.manager
|
||||
.handle_trigger(
|
||||
// az_pattern: "one"
|
||||
bed.az_patterns
|
||||
.values()
|
||||
.cloned()
|
||||
.map(|pattern| (pattern, one[0].clone()))
|
||||
.collect(),
|
||||
now,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// the action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
// the action executes
|
||||
tokio::time::sleep(Duration::from_millis(40)).await;
|
||||
|
||||
// No matches, one action registered
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert!(state.matches.is_empty());
|
||||
assert!(state.ordered_times.is_empty());
|
||||
// No matches, one action registered
|
||||
{
|
||||
let state = bed.manager.state.lock().unwrap();
|
||||
assert!(state.matches.is_empty());
|
||||
assert!(state.ordered_times.is_empty());
|
||||
assert_eq!(
|
||||
state.triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now, 1)]))]),
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
state.triggers.tree(),
|
||||
&BTreeMap::from([(one.clone(), BTreeMap::from([(now, 1)]))]),
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the action"
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
"a1 one\n",
|
||||
&read_to_string(&bed.out_file).unwrap(),
|
||||
"the output file contains the result of the action"
|
||||
);
|
||||
}
|
||||
|
||||
// TODO test State functions
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue