def test_sliding_last_window_to_halt(self): timestamp_lower = EpochNSClock.generate_timestamp() sleep(0.5) timestamp_upper = EpochNSClock.generate_timestamp() window_range_ns = timestamp_upper - timestamp_lower timestamp_a = timestamp_lower timestamp_b = timestamp_a + window_range_ns timestamp_c = timestamp_b + window_range_ns + 1 predicate_a = BoboPredicateCallable(predicate_key_a_value_a) predicate_b = BoboPredicateCallable(predicate_key_a_value_b) predicate_c = BoboPredicateCallable(predicate_key_a_value_c) predicate_first_window = WindowSlidingLast(window_range_ns) event_a = PrimitiveEvent(timestamp_a, {KEY: VAL_1}) event_b = PrimitiveEvent(timestamp_b, {KEY: VAL_2}) event_c = PrimitiveEvent(timestamp_c, {KEY: VAL_3}) pattern_a = BoboPattern() \ .followed_by(LABEL_LAYER_A, predicate_a) \ .followed_by(LABEL_LAYER_B, predicate_b) \ .followed_by(LABEL_LAYER_C, predicate_c) \ .precondition(predicate_first_window) handler = BoboNFAHandler(BoboRuleBuilder.nfa(NFA_NAME_A, pattern_a), SharedVersionedMatchBuffer()) handlersub = NFAHandlerSubscriber() handler.subscribe(handlersub) handler.process(event_a) handler.process(event_b) handler.process(event_c) self.assertEqual(len(handlersub.final), 1)
def test_sliding_first_window_to_halt(self): predicate_a = BoboPredicateCallable(predicate_key_a_value_a) predicate_b = BoboPredicateCallable(predicate_key_a_value_b) predicate_c = BoboPredicateCallable(predicate_key_a_value_c) predicate_first_window = WindowSlidingFirst( interval_sec=range_sec) event_a = PrimitiveEvent(timestamp_low, {KEY: VAL_1}) event_b = PrimitiveEvent(timestamp_mid, {KEY: VAL_2}) event_c = PrimitiveEvent(timestamp_upp, {KEY: VAL_3}) pattern_a = BoboPattern() \ .followed_by(LABEL_LAYER_A, predicate_a) \ .followed_by(LABEL_LAYER_B, predicate_b) \ .followed_by(LABEL_LAYER_C, predicate_c) \ .precondition(predicate_first_window) handler = BoboNFAHandler( BoboRuleBuilder.nfa(NFA_NAME_A, pattern_a), SharedVersionedMatchBuffer()) handlersub = NFAHandlerSubscriber() handler.subscribe(handlersub) handler.process(event_a) handler.process(event_b) handler.process(event_c) self.assertEqual(len(handlersub.final), 1)
def test_to_dict(self): # Create primitive event p_timestamp = EpochNSClock.generate_timestamp() p_event = PrimitiveEvent(timestamp=p_timestamp, data=P_DATA) p_hist = "p_hist" # Create composite event c_timestamp = EpochNSClock.generate_timestamp() c_history = BoboHistory() c_event = CompositeEvent(timestamp=c_timestamp, name=C_NAME, history=c_history, data=C_DATA) c_hist = "c_hist" # Create list of events for history events = {p_hist: [p_event], c_hist: [c_event]} # Create history and add events history = BoboHistory(events=events) self.assertDictEqual(history.to_dict(), { p_hist: [p_event.to_dict()], c_hist: [c_event.to_dict()] })
def test_invalid_min_0(self): validator = StrDictValidator(min_length=0) self.assertFalse(validator.validate(None)) self.assertFalse(validator.validate("")) self.assertFalse(validator.validate(123)) self.assertFalse(validator.validate(123.456)) self.assertFalse(validator.validate(True)) self.assertFalse(validator.validate(False)) self.assertFalse(validator.validate(BoboHistory())) self.assertFalse( validator.validate( PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()))) # as a dict self.assertFalse(validator.validate({KEY_A: None})) self.assertFalse(validator.validate({KEY_A: 123})) self.assertFalse(validator.validate({KEY_A: 123.456})) self.assertFalse(validator.validate({KEY_A: True})) self.assertFalse(validator.validate({KEY_A: False})) self.assertFalse(validator.validate({KEY_A: BoboHistory()})) self.assertFalse( validator.validate({ KEY_A: PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) }))
def test_nondeterministic_loop_success(self): pattern_loop = BoboPattern() \ .followed_by(LABEL_LAYER_A, BoboPredicateCallable(predicate_key_a_value_a)) \ .followed_by(LABEL_LAYER_B, BoboPredicateCallable(predicate_key_a_value_b), loop=True) \ .followed_by(LABEL_LAYER_C, BoboPredicateCallable(predicate_key_a_value_c)) \ .followed_by(LABEL_LAYER_D, BoboPredicateCallable(predicate_key_a_value_d)) nfa, buffer, handler, handlersub = handler_setup(nfa_name=NFA_NAME_A, pattern=pattern_loop) event_b1 = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data=event_b.data) event_b2 = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data=event_b.data) event_c1 = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data=event_c.data) event_c2 = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data=event_c.data) # first run cloned handler.process(event_a) handler.process(event_b) self.assertEqual(1, len(handler.runs.values())) run = list(handler.runs.values())[0] # first run loops handler.process(event_b1) self.assertEqual(1, len(handler.runs.values())) # second run cloned handler.process(event_c1) self.assertEqual(2, len(handler.runs.values())) # first run increments handler.process(event_b2) self.assertEqual(2, len(handler.runs.values())) # third run cloned handler.process(event_c2) self.assertEqual(3, len(handler.runs.values())) # second and third run reach final state handler.process(event_d) self.assertEqual(1, len(handler.runs.values())) # first run is the only run left self.assertEqual(run, list(handler.runs.values())[0])
def test_to_dict(self): p_timestamp = EpochNSClock.generate_timestamp() p_data = {"p_key": "p_value"} p_event = PrimitiveEvent(timestamp=p_timestamp, data=p_data) self.assertDictEqual( p_event.to_dict(), { PrimitiveEvent.TIMESTAMP: p_timestamp, PrimitiveEvent.DATA: p_data, PrimitiveEvent.EVENT_ID: p_event.event_id })
def test_1_level_10_increments_1_event_per_increment(self): buffer = SharedVersionedMatchBuffer() run_id = generate_unique_string() events = [ PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) for _ in range(10) ] version = RunVersion() version.add_level(run_id) version_current = version.get_version_as_str() for event in events: version.increment_level(generate_unique_string()) version_next = version.get_version_as_str() buffer.put_event(nfa_name=NFA_NAME_A, run_id=run_id, version=version_current, state_label=LABEL_LAYER_A, event=event, new_version=version_next) version_current = version_next history_events = buffer.get_all_events( nfa_name=NFA_NAME_A, run_id=run_id, version=version).events[LABEL_LAYER_A] self.assertEqual(10, len(history_events)) for event in events: self.assertTrue(event in history_events)
def primitive(d: dict) -> PrimitiveEvent: """Creates a PrimitiveEvent instance from serialized representation of one. :param d: A dict representation of a PrimitiveEvent instance. :type d: dict :raises RuntimeError: Timestamp not found in dict. :raises RuntimeError: Data not found in dict. :return: A PrimitiveEvent instance. """ timestamp = d.get(PrimitiveEvent.TIMESTAMP) if timestamp is None: raise RuntimeError("Timestamp not found in dict.") data = d.get(PrimitiveEvent.DATA) if data is None: raise RuntimeError("Data not found in dict.") event_id = d.get(PrimitiveEvent.EVENT_ID) if event_id is None: raise RuntimeError("Event ID not found in dict.") return PrimitiveEvent(timestamp=timestamp, data=data, event_id=event_id)
def test_add_recent(self): nfa, buffer, handler, handlersub = handler_setup( nfa_name=NFA_NAME_A, pattern=pattern_relaxed, max_recent=2) p_event = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data={}) sleep(0.1) c_event = CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name=EVENT_NAME_A, history=BoboHistory(), data={}) sleep(0.1) a_event = ActionEvent(timestamp=EpochNSClock.generate_timestamp(), name=EVENT_NAME_B, success=True, for_event=c_event) handler.add_recent(p_event) handler.add_recent(c_event) self.assertTrue(p_event in handler._recent) self.assertTrue(c_event in handler._recent) handler.add_recent(a_event) self.assertFalse(p_event in handler._recent) self.assertTrue(c_event in handler._recent) self.assertTrue(a_event in handler._recent)
def format(self, data) -> PrimitiveEvent: """ :param data: The data to format. :return: A new PrimitiveEvent instance containing the data. """ return PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data=data)
def test_remove_all_pointers_two_match_events(self): event_a = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) event_b = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) match_a = MatchEvent(nfa_name=NFA_NAME_A, label=LABEL_LAYER_A, event=event_a) match_b = MatchEvent(nfa_name=NFA_NAME_A, label=LABEL_LAYER_B, event=event_b) version = RunVersion() version.add_level( BoboRun._generate_id(nfa_name=NFA_NAME_A, start_event_id=event_a.event_id)) version_str = version.get_version_as_str() # match events should start with no pointers self.assertFalse(match_a.has_pointers()) self.assertFalse(match_b.has_pointers()) # match a --next--> match b match_a.add_pointer_next(version=version_str, event_id=match_b.event.event_id) # match a <--previous-- match b match_b.add_pointer_previous(version=version_str, event_id=match_a.event.event_id) # match events both have pointers self.assertTrue(match_a.has_pointers()) self.assertTrue(match_b.has_pointers()) # removing pointers from one match event match_a.remove_all_pointers(version=version_str) self.assertFalse(match_a.has_pointers()) self.assertTrue(match_b.has_pointers()) # all pointers removed match_b.remove_all_pointers(version=version_str) self.assertFalse(match_a.has_pointers()) self.assertFalse(match_b.has_pointers())
def test_valid_function(self): f = BoboPredicateCallable(valid_function) history = BoboHistory() recent = [] self.assertTrue( f.evaluate(event=PrimitiveEvent(EpochNSClock.generate_timestamp(), KEY_VALUE), history=history, recent=recent))
def test_fixed_window_to_final(self): timestamp_lower = EpochNSClock.generate_timestamp() sleep(0.1) timestamp_a = EpochNSClock.generate_timestamp() sleep(0.1) timestamp_b = EpochNSClock.generate_timestamp() sleep(0.1) timestamp_c = EpochNSClock.generate_timestamp() sleep(0.1) timestamp_upper = EpochNSClock.generate_timestamp() sleep(0.1) predicate_a = BoboPredicateCallable(predicate_key_a_value_a) predicate_b = BoboPredicateCallable(predicate_key_a_value_b) predicate_c = BoboPredicateCallable(predicate_key_a_value_c) predicate_fixed_window = WindowFixed(timestamp_lower, timestamp_upper) event_a = PrimitiveEvent(timestamp_a, {KEY: VAL_1}) event_b = PrimitiveEvent(timestamp_b, {KEY: VAL_2}) event_c = PrimitiveEvent(timestamp_c, {KEY: VAL_3}) pattern_a = BoboPattern() \ .followed_by(LABEL_LAYER_A, predicate_a) \ .followed_by(LABEL_LAYER_B, predicate_b) \ .followed_by(LABEL_LAYER_C, predicate_c) \ .precondition(predicate_fixed_window) handler = BoboNFAHandler( BoboRuleBuilder.nfa(NFA_NAME_A, pattern_a), SharedVersionedMatchBuffer()) handlersub = NFAHandlerSubscriber() handler.subscribe(handlersub) handler.process(event_a) handler.process(event_b) handler.process(event_c) self.assertEqual(len(handlersub.final_history), 1) self.assertDictEqual(handlersub.final_history[0].events, {LABEL_LAYER_A: [event_a], LABEL_LAYER_B: [event_b], LABEL_LAYER_C: [event_c]})
def test_nondeterministic_success(self): pattern_nondet = BoboPattern() \ .followed_by(LABEL_LAYER_A, BoboPredicateCallable(predicate_key_a_value_a)) \ .followed_by_any(LABEL_LAYER_B_C, [BoboPredicateCallable(predicate_key_a_value_b), BoboPredicateCallable( predicate_key_a_value_c)]) \ .next(LABEL_LAYER_D, BoboPredicateCallable(predicate_key_a_value_d)) nfa, buffer, handler, handlersub = handler_setup( nfa_name=NFA_NAME_A, pattern=pattern_nondet) event_d1 = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data=event_d.data) event_d2 = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data=event_d.data) handler.process(event_a) handler.process(event_b) handler.process(event_d1) self.assertEqual(len(handlersub.final_history), 1) self.assertDictEqual( handlersub.final_history[0].events, { LABEL_LAYER_A: [event_a], LABEL_LAYER_B_C: [event_b], LABEL_LAYER_D: [event_d1] }) handler.process(event_c) handler.process(event_d2) self.assertEqual(len(handlersub.final_history), 2) self.assertDictEqual( handlersub.final_history[1].events, { LABEL_LAYER_A: [event_a], LABEL_LAYER_B_C: [event_c], LABEL_LAYER_D: [event_d2] })
def test_valid_method(self): obj = TestBoboPredicateCallableMethods() f = BoboPredicateCallable(obj.valid_method) history = BoboHistory() recent = [] self.assertTrue( f.evaluate(event=PrimitiveEvent(EpochNSClock.generate_timestamp(), KEY_VALUE), history=history, recent=recent))
def test_to_dict_two_match_events(self): event_a = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) event_b = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) match_a = MatchEvent(nfa_name=NFA_NAME_A, label=LABEL_LAYER_A, event=event_a) match_b = MatchEvent(nfa_name=NFA_NAME_A, label=LABEL_LAYER_B, event=event_b) version = RunVersion() version.add_level( BoboRun._generate_id(nfa_name=NFA_NAME_A, start_event_id=event_a.event_id)) version_str = version.get_version_as_str() # match a --next--> match b match_a.add_pointer_next(version=version_str, label=match_b.label, event_id=match_b.event.event_id) # match a dict self.assertDictEqual( match_a.to_dict(), { MatchEvent.NFA_NAME: NFA_NAME_A, MatchEvent.LABEL: LABEL_LAYER_A, MatchEvent.EVENT: event_a.to_dict(), MatchEvent.NEXT_IDS: { version_str: (match_b.label, match_b.event.event_id) }, MatchEvent.PREVIOUS_IDS: {} }) # match a <--previous-- match b match_b.add_pointer_previous(version=version_str, label=match_a.label, event_id=match_a.event.event_id) # match b dict self.assertDictEqual( match_b.to_dict(), { MatchEvent.NFA_NAME: NFA_NAME_A, MatchEvent.LABEL: LABEL_LAYER_B, MatchEvent.EVENT: event_b.to_dict(), MatchEvent.NEXT_IDS: {}, MatchEvent.PREVIOUS_IDS: { version_str: (match_a.label, match_a.event.event_id) } })
def test_match_event_points_to_itself(self): event_a = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) match_a = MatchEvent(nfa_name=NFA_NAME_A, label=LABEL_LAYER_A, event=event_a) version = RunVersion() version.add_level( BoboRun._generate_id(nfa_name=NFA_NAME_A, start_event_id=event_a.event_id)) version_str = version.get_version_as_str() with self.assertRaises(RuntimeError): match_a.add_pointer_next(version=version_str, label=LABEL_LAYER_A, event_id=event_a.event_id) with self.assertRaises(RuntimeError): match_a.add_pointer_previous(version=version_str, label=LABEL_LAYER_A, event_id=event_a.event_id)
stub_pattern_4 = BoboPattern() \ .followed_by( label=LABEL_A, predicate=stub_predicate_true ).followed_by( label=LABEL_B, predicate=stub_predicate_true ).followed_by( label=LABEL_C, predicate=stub_predicate_true ).followed_by( label=LABEL_D, predicate=stub_predicate_true ) event_a = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) event_b = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) event_c = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) event_d = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp()) credentials = PlainCredentials('guest', 'guest') parameters = ConnectionParameters("127.0.0.1", 5672, '/', credentials) class StubSubscriberSetup(IReceiverSubscriber, IDeciderSubscriber, IProducerSubscriber, IForwarderSubscriber): def __init__(self) -> None: super().__init__() self.receiver_event = [] self.invalid_data = []
def predicate_key_a_value_b(event: BoboEvent, history: BoboHistory, recent: List[BoboEvent]): return event.data[KEY_A] == VALUE_B def predicate_key_a_value_c(event: BoboEvent, history: BoboHistory, recent: List[BoboEvent]): return event.data[KEY_A] == VALUE_C def predicate_key_a_value_d(event: BoboEvent, history: BoboHistory, recent: List[BoboEvent]): return event.data[KEY_A] == VALUE_D event_a = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data={KEY_A: VALUE_A}) event_b = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data={KEY_A: VALUE_B}) event_c = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data={KEY_A: VALUE_C}) event_d = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data={KEY_A: VALUE_D}) event_e = PrimitiveEvent(timestamp=EpochNSClock.generate_timestamp(), data={KEY_A: VALUE_E}) pattern_relaxed = BoboPattern() \ .followed_by(LABEL_LAYER_A,