def test_exception_bubbling(): # do propagate cfg['reactors']['propagate_exceptions'] = True brq = Baroque() brq.config = cfg def reaction_raising_error(evt): raise FileNotFoundError() r = Reactor(reaction_raising_error) brq.on(GenericEventType()).run(r) with pytest.raises(FileNotFoundError): brq.publish(Event(GenericEventType())) pytest.fail() # do not propagate cfg['reactors']['propagate_exceptions'] = False brq = Baroque() brq.config = cfg brq.on(GenericEventType()).run(r) try: brq.publish(Event(GenericEventType())) except FileNotFoundError: pytest.fail()
def test_touch(): e = Event(GenericEventType(), payload=dict(a=1, b=2), description='hello', owner=1234) ts1 = e.timestamp e = Event(GenericEventType(), payload=dict(a=1, b=2), description='hello', owner=1234) ts2 = e.timestamp assert ts2 > ts1
def test_add(): bag = EventTypesBag() assert len(bag.types) == 0 ets = [GenericEventType(), MetricEventType()] bag.add(ets) assert len(bag.types) == 2 bag.add([GenericEventType()]) assert len(bag.types) == 2 bag.add([DataOperationEventType()]) assert len(bag.types) == 3
def test_constructor_with_type_objects(): e1 = Event(GenericEventType(), payload=dict(a=1, b=2), description='hello', owner=1234) e2 = Event(GenericEventType, payload=dict(a=1, b=2), description='hello', owner=1234) assert isinstance(e1.type, GenericEventType) assert isinstance(e2.type, GenericEventType)
def test_magic_methods(): bck = DictBackend() evt1 = Event(GenericEventType(), dict(foo='bar')) evt2 = Event(MetricEventType(), dict(bar='baz')) bck.create(evt1) bck.create(evt2) assert len(bck) == 2 assert evt1 in bck assert evt2 in bck for event_id in bck: assert isinstance(bck[event_id], Event) keys = bck.keys() assert len(keys) == 2 assert evt1.id in keys assert evt2.id in keys values = bck.values() assert len(values) == 2 assert evt1 in values assert evt2 in values bck.clear() assert len(bck) == 0
def test_react(): r = Reactor(greet) evt = Event(GenericEventType()) r.react(evt) assert r.count_reactions() == 1 assert r.last_event_reacted() is not None assert r.last_reacted_on() is not None
def test_persist_event(): brq = Baroque() assert len(brq._persistance_backend) == 0 evt = Event(GenericEventType(), payload=dict(test=123)) brq._persist_event(evt) assert len(brq._persistance_backend) == 1 assert evt in brq._persistance_backend
def test_update_event_status(): eventtype = GenericEventType() evt = Event(eventtype, payload=dict()) assert evt.status == EventStatus.UNPUBLISHED brq = Baroque() brq._update_event_status(evt) assert evt.status == EventStatus.PUBLISHED
def test_validate(): jsonschema = '''{ "type": "object", "properties": { "payload": { "type": "object", "properties": { "foo": { "type": "string" }, "bar": { "type": "number" } }, "required": ["foo", "bar"] } }, "required": ["payload"] }''' eventtype = EventType(jsonschema) # event is conforming to JSON schema of its type event = Event(eventtype, payload=dict(foo='value', bar=123)) assert EventType.validate(event, eventtype) # event is of another type event = Event(GenericEventType(), payload=dict(foo='value', bar=123)) assert not EventType.validate(event, eventtype) # event is of the same type but not conforming event = Event(eventtype, payload=dict(x=1, y=2)) assert not EventType.validate(event, eventtype)
def test_update(): bck = DictBackend() evt = Event(GenericEventType(), dict(foo='bar')) bck.create(evt) assert len(bck._db) == 1 # updating nothing leads to an exception with pytest.raises(AssertionError): bck.update(None) pytest.fail() # updating events with null id is idempotent former_evt0_id = evt.id evt.id = None bck.update(evt) assert len(bck._db) == 1 result = bck.read(former_evt0_id) assert result == evt # event was unchanged assert result.owner is None # actual update evt.owner = 'me' bck.update(evt) assert len(bck._db) == 1 result = bck.read(former_evt0_id) assert result.owner == 'me'
def test_dont_count_twice_eventtypes(): eventtype = GenericEventType() same_eventtype = GenericEventType() c = EventCounter() assert c.count_all() == 0 assert c.count(eventtype) == c.count(same_eventtype) == 0 c.increment_counting(Event(eventtype)) assert c.count_all() == 1 assert c.count(eventtype) == 1 assert c.count(same_eventtype) == 1 c.increment_counting(Event(same_eventtype)) assert c.count_all() == 2 assert c.count(eventtype) == 2 assert c.count(same_eventtype) == 2
def test_remove_all(): reg = EventTypesRegistry() reg.register(GenericEventType()) reg.register(MetricEventType()) reg.register(DataOperationEventType()) assert reg.count() == 3 reg.remove_all() assert reg.count() == 0
def test_magic_methods(): bag = EventTypesBag() assert len(bag) == 0 et = GenericEventType() bag.add([et]) assert len(bag) == 1 assert et in bag for _ in bag: pass
def test_constructor(): e = Event(GenericEventType(), payload=dict(a=1, b=2), description='hello', owner=1234) assert isinstance(e.type, GenericEventType) assert e.id is not None assert not e.links assert not e.tags assert e.status == EventStatus.UNPUBLISHED assert e.timestamp is not None
def test_count_event(): brq = Baroque() eventtype = GenericEventType() evt = Event(eventtype, payload=dict()) assert brq.events.count(eventtype) == 0 assert brq.events.count_all() == 0 brq._count_event(evt) assert brq.events.count(eventtype) == 1 assert brq.events.count_all() == 1
def test_on(): brq = Baroque() eventtype = GenericEventType() result = brq.on(eventtype) assert isinstance(result, ReactorsBag) brq.reactors.registered_types[type(eventtype)] = ReactorsBag() result = brq.on(eventtype) assert isinstance(result, ReactorsBag)
def test_read(): bck = DictBackend() evt = Event(GenericEventType(), dict(foo='bar')) bck.create(evt) result = bck.read(evt.id) assert result == evt # reading nothing assert bck.read('unexistent') is None
def test_publish_on_topic(): reg = TopicsRegistry() t = Topic('test', eventtypes=[GenericEventType(), MetricEventType()]) evt = Event(MetricEventType()) # failures with pytest.raises(AssertionError): reg.publish_on_topic(None, t) with pytest.raises(AssertionError): reg.publish_on_topic(123, t) with pytest.raises(AssertionError): reg.publish_on_topic(evt, None) with pytest.raises(AssertionError): reg.publish_on_topic(evt, 123) # using a databox class to keep state and make assertions class Box: def __init__(self): self.called = False def mark_called(self): self.called = True # publish an event on a topic that doesn't have its eventtype registered t = Topic('aaa', eventtypes=[GenericEventType()]) evt = Event(MetricEventType()) box = Box() r = ReactorFactory.call_function(box, 'mark_called') reg.register(t) reg.on_topic_run(t, r) reg.publish_on_topic(evt, t) assert not box.called # publish an event on a topic that has its eventtype registered reg = TopicsRegistry() t = Topic('aaa', eventtypes=[MetricEventType()]) box = Box() r = ReactorFactory.call_function(box, 'mark_called') reg.register(t) reg.on_topic_run(t, r) evt = Event(MetricEventType()) reg.publish_on_topic(evt, t) assert box.called
def test_register(): reg = EventTypesRegistry() assert reg.count() == 0 reg.register(GenericEventType()) # with a concrete instance assert reg.count() == 1 reg.register(GenericEventType) # with a type object assert reg.count() == 1 reg.register(MetricEventType()) assert reg.count() == 2 with pytest.raises(AssertionError): reg.register('not-a-reactor') pytest.fail()
def test_add_failing(): bag = EventTypesBag() with pytest.raises(AssertionError): bag.add('string') pytest.fail() with pytest.raises(AssertionError): bag.add(123) pytest.fail() with pytest.raises(AssertionError): ets = [GenericEventType(), dict()] bag.add(ets) pytest.fail()
def test_constructor_failures(): with pytest.raises(TypeError): Event() pytest.fail() with pytest.raises(AssertionError): Event(None) pytest.fail() with pytest.raises(AssertionError): Event(123) pytest.fail() with pytest.raises(AssertionError): Event(GenericEventType(), payload=123) pytest.fail()
def test_get_or_create_bag_when_bag_already_exists(): reg = ReactorsRegistry() # with concrete instances et1 = MetricEventType() et2 = GenericEventType() reg.get_or_create_bag(et1) assert len(reg.registered_types) == 1 assert type(et1) in reg.registered_types assert type(et2) not in reg.registered_types result = reg.get_or_create_bag(et2) assert type(et2) in reg.registered_types assert len(reg.registered_types) == 2 assert isinstance(result, ReactorsBag) assert result == reg.registered_types[type(et2)]
def test_constructor(): t = Topic('test', description='this is a test topic', owner='me') assert t.id is not None assert len(t.eventtypes) == 0 assert t.owner is not None assert len(t.tags) == 0 assert t.timestamp is not None ets = [GenericEventType(), DataOperationEventType()] t = Topic('test', eventtypes=ets, description='this is a test topic', owner='me', tags=['x', 'y']) assert len(t.eventtypes) == 2 assert len(t.tags) == 2
def test_remove_all(): reg = ReactorsRegistry() et1 = MetricEventType() et2 = GenericEventType() et3 = DataOperationEventType() reg.get_or_create_bag(et1) reg.get_or_create_bag(et2) reg.get_or_create_bag(et3) reg.get_jolly_bag().run(ReactorFactory.stdout()) assert len(reg.registered_types) == 3 assert len(reg.jolly_bag) == 1 reg.remove_all() assert len(reg.registered_types) == 0 assert len(reg.jolly_bag) == 0
def test_create(): bck = DictBackend() assert len(bck._db) == 0 # adding nothing leads to an exception with pytest.raises(AssertionError): bck.create(None) pytest.fail() # adding events with null id evt0 = Event(GenericEventType(), dict(foo='bar')) evt0.id = None bck.create(evt0) assert len(bck._db) == 0 # fresh add evt1 = Event(GenericEventType(), dict(foo='bar')) bck.create(evt1) assert len(bck._db) == 1 # adding twice the same event is idempotent bck.create(evt1) assert len(bck._db) == 1
def test_condition_met(): r = Reactor(greet) evt = Event(GenericEventType(), payload=dict()) # no condition set is_met = r._condition_met(evt) assert is_met # condition is not met r.only_if(only_test_events) is_met = r._condition_met(evt) assert not is_met # condition is met evt.payload['test'] = 'value' is_met = r._condition_met(evt) assert is_met
def test_react_conditionally(): r = Reactor(greet, condition=only_test_events) evt = Event(GenericEventType()) # condition is not met r.react_conditionally(evt) assert r.count_reactions() == 0 assert r.last_event_reacted() is None assert r.last_reacted_on() is None # condition is met evt.payload = {'test': 'value'} r.react_conditionally(evt) assert r.count_reactions() == 1 assert r.last_event_reacted() is not None assert r.last_reacted_on() is not None
def test_persistence_backend(): brq = Baroque() # test we're actually using the claimed persistence backend cfg['events']['persist'] = True cfg['events'][ 'persistence_backend'] = 'tests.test_configuration.FakePersistenceBackend' brq.config = cfg pb = brq._persistance_backend assert len(pb) == 0 evt = Event(GenericEventType()) brq.publish(evt) assert len(pb) == 1 assert evt in pb
def test_remove(): reg = EventTypesRegistry() reg.register(GenericEventType()) reg.register(MetricEventType()) reg.register(DataOperationEventType()) assert reg.count() == 3 reg.remove(DataOperationEventType()) # with a concrete instance assert reg.count() == 2 assert DataOperationEventType() not in reg.registered_types reg.remove(GenericEventType) # with a type object assert reg.count() == 1 assert DataOperationEventType() not in reg.registered_types with pytest.raises(AssertionError): reg.remove(123) pytest.fail()
def test_new(): r = TopicsRegistry() topic = r.new('test', eventtypes=[GenericEventType(), MetricEventType()], description='this is a test topic', owner='me', tags=['aaa', 'bbb', 'ccc']) assert isinstance(topic, Topic) assert topic.name == 'test' assert isinstance(topic.eventtypes, EventTypesBag) assert topic.description == 'this is a test topic' assert topic.owner == 'me' assert 'aaa' in topic.tags assert 'bbb' in topic.tags assert 'ccc' in topic.tags assert topic in r