def test_subscribe_producer_composite_rejected(self): setup = BoboSetup() sub = StubSubscriberSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) # this rejects all events passed to Producer setup.config_producer(NoAction(bool_return=False)) setup.subscribe_producer(NAME_NFA_A, sub) setup.configure() producer = setup.get_producer() producer.setup() c_event = CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name=NAME_NFA_A, history=BoboHistory(), data={}) producer.on_decider_complex_event(c_event) producer.loop() self.assertEqual(c_event, sub.rejected_producer_event[0])
def test_subscribe_forward_action_failure(self): setup = BoboSetup() sub = StubSubscriberSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) # this rejects all events passed to Forwarder setup.config_forwarder(NoAction(bool_return=False)) setup.subscribe_forwarder(sub) setup.configure() forwarder = setup.get_forwarder() forwarder.setup() a_event = NoAction().execute( CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name=NAME_NFA_A, history=BoboHistory(), data={})) forwarder.on_producer_action(a_event) forwarder.loop() self.assertEqual(a_event, sub.forwarder_failure_event[0])
def test_producer_action_event_triggers_forward(self): forward = ActionForwarder(NoAction(bool_return=True)) sub = StubForwarderSubscriber() forward.subscribe(sub) c_event = generate_composite_event(NAME_A) a_event = NoAction(bool_return=True).execute(c_event) forward.on_producer_action(a_event) forward.setup() forward.loop() self.assertListEqual([a_event], sub.success)
def test_forward_failure(self): comp_event = generate_composite_event(NAME_A) action_event = NoAction().execute(comp_event) forward = ActionForwarder(NoAction(bool_return=False)) sub = StubForwarderSubscriber() forward.subscribe(sub) forward.on_producer_action(action_event) forward.setup() forward.loop() self.assertListEqual([action_event], sub.failure)
def test_multi_composite_from_decider_to_producer_recursive(self): setup = BoboSetup(recursive=True, max_recent=2) nfa_names = [NAME_NFA_A, NAME_NFA_B, NAME_NFA_C] for nfa_name in nfa_names: setup.add_complex_event(event_def=BoboComplexEvent( name=nfa_name, pattern=stub_pattern_1, action=NoAction())) setup.config_receiver(StrDictValidator()) setup.configure() decider = setup.get_decider() decider.setup() handlers = decider.get_all_handlers() self.assertEqual(3, len(handlers)) producer = setup.get_producer() producer.setup() decider.on_receiver_event(event_a) for _ in range(len(nfa_names)): decider.loop() producer.loop() for handler in handlers: self.assertEqual(2, len(handler.get_all_recent()))
def test_action_from_producer_to_decider_not_recursive(self): setup = BoboSetup(recursive=False) setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_4)) setup.config_receiver(StrDictValidator()) setup.configure() decider = setup.get_decider() decider.setup() producer = setup.get_producer() producer.setup() a_event = NoAction().execute( CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name=NAME_NFA_A, history=BoboHistory(), data={})) producer.on_action_attempt(a_event) producer.loop() handler = decider.get_all_handlers()[0] self.assertEqual(0, len(handler.get_all_recent()))
def test_setup_after_cancel(self): setup = BoboSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.config_null_data(delay_sec=NULL_DATA_DELAY, null_data=BoboNullDataStatic(DATA_DICT_A)) setup.configure() setup.start() sleep(SLEEP_WAIT) setup.cancel() self.assertFalse(setup.is_ready()) self.assertFalse(setup.is_active()) self.assertFalse(setup.is_inactive()) self.assertTrue(setup.is_cancelled()) self.assertTrue(setup.is_configured()) self.assertFalse(setup.get_receiver().is_active()) self.assertFalse(setup.get_decider().is_active()) self.assertFalse(setup.get_producer().is_active()) self.assertFalse(setup.get_forwarder().is_active()) self.assertFalse(setup.get_null_data_generator().is_active())
def test_on_sync(self): setup = BoboSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_4, action=NoAction())) setup.config_null_data(delay_sec=NULL_DATA_DELAY, null_data=BoboNullDataStatic(DATA_DICT_A)) setup.config_distributed(exchange_name=EXCHANGE_NAME, user_name=USER_NAME, parameters=parameters) setup.configure() self.assertFalse(setup.get_receiver().is_active()) self.assertFalse(setup.get_decider().is_active()) self.assertFalse(setup.get_producer().is_active()) self.assertFalse(setup.get_forwarder().is_active()) self.assertFalse(setup.get_null_data_generator().is_active()) setup.on_sync() self.assertTrue(setup.get_receiver().is_active()) self.assertTrue(setup.get_decider().is_active()) self.assertTrue(setup.get_producer().is_active()) self.assertTrue(setup.get_forwarder().is_active()) self.assertTrue(setup.get_null_data_generator().is_active())
def test_subscribe_unsubscribe(self): forward = ActionForwarder(NoAction(bool_return=True)) sub = StubForwarderSubscriber() forward.subscribe(sub) self.assertListEqual([sub], forward._subs) forward.unsubscribe(sub) self.assertListEqual([], forward._subs)
def test_get_distributed_configured_but_not_distributed(self): setup = BoboSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.configure() with self.assertRaises(RuntimeError): setup.get_distributed()
def test_constructor(self): name = "evdef_name" pattern = BoboPattern() action = NoAction() evdef = BoboComplexEvent(name=name, pattern=pattern, action=action) self.assertEqual(name, evdef.name) self.assertEqual(pattern, evdef.pattern) self.assertEqual(action, evdef.action)
def _config_forwarder(self) -> None: if self._action_forwarder is None: self._action_forwarder = NoAction() self._forwarder = ActionForwarder(action=self._action_forwarder, max_queue_size=self._max_queue_size, active=(not self._distributed)) self._forwarder_thread = BoboTaskThread(task=self._forwarder, delay=self._delay)
def test_configure_when_cancelled(self): setup = BoboSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.cancel() with self.assertRaises(RuntimeError): setup.configure() self.assertFalse(setup.is_configured())
def test_action_subscribe_unsubscribe(self): action = NoAction(bool_return=True) actionsub = StubBoboActionSubscriber() # subscribe action.subscribe(actionsub) c_event_a = generate_composite_event(NAME_A) action.execute(c_event_a) # event should cause ActionEvent to be passed to sub self.assertEqual(1, len(actionsub.events)) self.assertIsInstance(actionsub.events[0], ActionEvent) self.assertEqual(c_event_a, actionsub.events[0].for_event) # unsubscribe action.unsubscribe(actionsub) action.execute(generate_composite_event(NAME_B)) # no new ActionEvent self.assertEqual(1, len(actionsub.events))
def test_action_false(self): event_a = generate_composite_event(NAME_A) prod = ActionProducer(NoAction(bool_return=False)) sub = StubProducerSubscriber() prod.subscribe(NAME_A, sub) prod.on_decider_complex_event(event_a) prod.setup() prod.loop() self.assertListEqual([event_a], sub.reject)
def test_true(self): timestamp = EpochNSClock.generate_timestamp() name = "c_name" history = BoboHistory() data = {"c_key": "c_value"} c_event = CompositeEvent(timestamp=timestamp, name=name, history=history, data=data) self.assertTrue(NoAction().execute(c_event).success)
def test_start_when_active(self): setup = BoboSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.start() sleep(SLEEP_WAIT) with self.assertRaises(RuntimeError): setup.start() setup.cancel()
def test_composite_event_triggers_action_execution(self): event_a = generate_composite_event(NAME_A) prod = ActionProducer(NoAction(bool_return=True)) action = NoAction(bool_return=True) # sub subscribes to prod sub = StubProducerSubscriber() prod.subscribe(NAME_A, sub) # prod subscribes to action prod.subscribe(event_a.name, action) # action subscribes to prod action.subscribe(prod) prod.setup() prod.on_decider_complex_event(event_a) prod.loop() self.assertEqual(1, len(sub.action)) self.assertIsInstance(sub.action[0], ActionEvent) self.assertEqual(event_a, sub.action[0].for_event)
def test_setup_before_configure(self): setup = BoboSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.config_null_data(delay_sec=NULL_DATA_DELAY, null_data=BoboNullDataStatic(DATA_DICT_A)) self.assertFalse(setup.is_ready()) self.assertFalse(setup.is_active()) self.assertTrue(setup.is_inactive()) self.assertFalse(setup.is_cancelled()) self.assertFalse(setup.is_configured())
def test_subscribe_producer_action(self): setup = BoboSetup() sub = StubSubscriberSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.subscribe_producer(NAME_NFA_A, sub) setup.configure() producer = setup.get_producer() producer.setup() a_event = NoAction().execute( CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name=NAME_NFA_A, history=BoboHistory(), data={})) producer.on_action_attempt(a_event) producer.loop() self.assertEqual(a_event, sub.producer_action[0])
def test_subscribe_unsubscribe(self): prod = ActionProducer(NoAction()) sub = StubProducerSubscriber() # subscribe prod.subscribe(NAME_A, sub) self.assertDictEqual(prod._subs, { NAME_A: [sub] }) # unsubscribe prod.unsubscribe(NAME_A, sub) self.assertDictEqual(prod._subs, { NAME_A: [] })
def test_action_event_from_subscribed_action(self): event_a = generate_composite_event(NAME_A) prod = ActionProducer(NoAction(bool_return=True)) # sub subscribes to prod sub = StubProducerSubscriber() prod.subscribe(NAME_A, sub) # action subscribes to prod action = NoAction(bool_return=True) action.subscribe(prod) action.execute(event_a) self.assertEqual(1, len(sub.action)) self.assertIsInstance(sub.action[0], ActionEvent) self.assertEqual(event_a, sub.action[0].for_event)
def test_subscribe_receiver_valid_data(self): setup = BoboSetup() sub = StubSubscriberSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.config_receiver(StrDictValidator()) setup.subscribe_receiver(sub) setup.configure() receiver = setup.get_receiver() receiver.setup() receiver.add_data(DATA_DICT_A) receiver.loop() self.assertIsInstance(sub.receiver_event[0], PrimitiveEvent)
def test_subscribe_receiver_invalid_data(self): setup = BoboSetup() sub = StubSubscriberSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.config_receiver(StrDictValidator()) setup.subscribe_receiver(sub) setup.configure() receiver = setup.get_receiver() receiver.setup() receiver.add_data(VALUE_A) receiver.loop() self.assertEqual(VALUE_A, sub.invalid_data[0])
def test_config_arguments(self): setup = BoboSetup() event_def = BoboComplexEvent(NAME_NFA_A, stub_pattern_1) validator = StrDictValidator() action_producer = RateLimitAction() action_forwarder = NoAction() null_data = BoboNullDataStatic(DATA_DICT_A) setup.add_complex_event(event_def) setup.config_receiver(validator) setup.config_producer(action_producer) setup.config_forwarder(action_forwarder) setup.config_null_data(NULL_DATA_DELAY, null_data) setup.config_distributed(EXCHANGE_NAME, USER_NAME, parameters) setup.configure() receiver = setup.get_receiver() decider = setup.get_decider() producer = setup.get_producer() forwarder = setup.get_forwarder() nullgen = setup.get_null_data_generator() manager = setup.get_distributed() self.assertEqual(validator, receiver.get_validator()) self.assertEqual(NAME_NFA_A, decider.get_all_handlers()[0].nfa.name) self.assertEqual(action_producer, producer._action) self.assertEqual(action_forwarder, forwarder._action) self.assertEqual(null_data, nullgen.null_data) self.assertEqual(receiver, nullgen.receiver) self.assertEqual(manager.outgoing.decider, decider) self.assertEqual(manager.outgoing.exchange_name, EXCHANGE_NAME) self.assertTrue(manager.outgoing.user_id.find(USER_NAME) != -1) self.assertEqual(manager.outgoing.parameters, parameters) self.assertEqual(manager.incoming.decider, decider) self.assertEqual(manager.incoming.exchange_name, EXCHANGE_NAME) self.assertTrue(manager.incoming.user_id.find(USER_NAME) != -1) self.assertEqual(manager.incoming.parameters, parameters)
def test_subscribe_decider_composite(self): setup = BoboSetup() sub = StubSubscriberSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.subscribe_decider(NAME_NFA_A, sub) setup.configure() decider = setup.get_decider() decider.setup() c_event = CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name=NAME_NFA_A, history=BoboHistory(), data={}) decider.on_handler_final(NAME_NFA_A, RUN_ID_A, c_event) self.assertEqual(c_event, sub.decider_complex_event[0])
def test_subscribe_forward_composite_success(self): setup = BoboSetup() sub = StubSubscriberSetup() setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_1, action=NoAction())) setup.subscribe_forwarder(sub) setup.configure() forwarder = setup.get_forwarder() forwarder.setup() c_event = CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name=NAME_NFA_A, history=BoboHistory(), data={}) forwarder.on_accepted_producer_event(c_event) forwarder.loop() self.assertEqual(c_event, sub.forwarder_success_event[0])
def test_action_from_producer_to_forwarder(self): setup = BoboSetup(recursive=True) setup.add_complex_event(event_def=BoboComplexEvent( name=NAME_NFA_A, pattern=stub_pattern_4)) setup.config_receiver(StrDictValidator()) setup.configure() producer = setup.get_producer() producer.setup() forwarder = setup.get_forwarder() forwarder.setup() a_event = NoAction().execute( CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name=NAME_NFA_A, history=BoboHistory(), data={})) producer.on_action_attempt(a_event) producer.loop() self.assertEqual(a_event, forwarder._event_queue.get_nowait())
import unittest from bobocep.receiver.clocks.epoch_ns_clock import EpochNSClock from bobocep.rules.actions.multi.sequential_action import SequentialAction from bobocep.rules.actions.no_action import NoAction from bobocep.rules.events.composite_event import CompositeEvent from bobocep.rules.events.histories.bobo_history import BoboHistory ACTION_TRUE = NoAction(bool_return=True) ACTION_FALSE = NoAction(bool_return=False) def generate_composite_event() -> CompositeEvent: return CompositeEvent(timestamp=EpochNSClock.generate_timestamp(), name="name", history=BoboHistory(), data={}) class TestSequentialAction(unittest.TestCase): def test_any_success_all_pass(self): seq = SequentialAction(actions=[ACTION_TRUE, ACTION_TRUE, ACTION_TRUE], all_success=False, early_stop=False) self.assertTrue(seq.execute(generate_composite_event()).success) def test_any_success_some_pass(self): seq = SequentialAction( actions=[ACTION_FALSE, ACTION_TRUE, ACTION_TRUE], all_success=False,