Ejemplo n.º 1
0
 def setUp(self):
     assert_event_handlers_empty()
     # Setup the repo, and a persistence subscriber.
     stored_event_repo = PythonObjectsStoredEventRepository()
     event_store = EventStore(stored_event_repo=stored_event_repo)
     self.repo = CollectionRepo(event_store=event_store)
     self.ps = PersistenceSubscriber(event_store=event_store)
Ejemplo n.º 2
0
 def setUp(self):
     self.es = EventStore(
         stored_event_repo=PythonObjectsStoredEventRepository())
     self.ps = PersistenceSubscriber(self.es)
     self.call_dependencies_repo = CallDependenciesRepo(self.es)
     self.call_dependents_repo = CallDependentsRepo(self.es)
     self.call_leafs_repo = CallLeafsRepo(self.es)
     self.call_requirement_repo = CallRequirementRepo(self.es)
Ejemplo n.º 3
0
 def setUp(self):
     assert_event_handlers_empty()
     self.es = EventStore(PythonObjectsStoredEventRepository())
     self.ps = PersistenceSubscriber(self.es)
     # self.call_result_repo = CallResultRepo(self.es)
     self.call_result_repo = {}
     self.call_dependencies_repo = CallDependenciesRepo(self.es)
     self.call_dependents_repo = CallDependentsRepo(self.es)
     self.call_requirement_repo = CallRequirementRepo(self.es)
     self.policy = CallResultPolicy(call_result_repo=self.call_result_repo)
Ejemplo n.º 4
0
class TestCollectionRepo(TestCase):
    def setUp(self):
        assert_event_handlers_empty()
        # Setup the repo, and a persistence subscriber.
        stored_event_repo = PythonObjectsStoredEventRepository()
        event_store = EventStore(stored_event_repo=stored_event_repo)
        self.repo = CollectionRepo(event_store=event_store)
        self.ps = PersistenceSubscriber(event_store=event_store)

    def tearDown(self):
        self.ps.close()
        assert_event_handlers_empty()

    def test(self):
        # Check the collection is not in the repo.
        with self.assertRaises(RepositoryKeyError):
            _ = self.repo['none']

        # Register a new collection.
        collection_id = register_new_collection().id

        # Check the collection is in the repo.
        collection = self.repo[collection_id]
        self.assertIsInstance(collection, Collection)
        self.assertEqual(collection.id, collection_id)
        # Check the collection has zero items.
        self.assertEqual(len(collection.items), 0)

        # Add item.
        item1 = 'item1'
        collection.add_item(item1)

        # Check the collection is in the repo.
        collection = self.repo[collection_id]
        self.assertIsInstance(collection, Collection)
        self.assertEqual(collection.id, collection_id)
        # Check the collection has one item.
        self.assertEqual(len(collection.items), 1)

        # Remove item.
        collection.remove_item(item1)

        # Check the collection is in the repo.
        collection = self.repo[collection_id]
        self.assertIsInstance(collection, Collection)
        self.assertEqual(collection.id, collection_id)
        # Check the collection has zero items.
        self.assertEqual(len(collection.items), 0)

        # Discard the collection.
        collection.discard()

        # Check the collection is not in the repo.
        with self.assertRaises(RepositoryKeyError):
            _ = self.repo['none']
Ejemplo n.º 5
0
class TestExampleEntity(unittest.TestCase):

    def setUp(self):
        # Setup the persistence subscriber.
        self.event_store = EventStore(PythonObjectsStoredEventRepository())
        self.persistence_subscriber = PersistenceSubscriber(event_store=self.event_store)

    def tearDown(self):
        self.persistence_subscriber.close()

    def test_entity_lifecycle(self):
        # Check the factory creates an instance.
        example1 = register_new_example(a=1, b=2)
        self.assertIsInstance(example1, Example)
        self.assertEqual(1, example1.a)
        self.assertEqual(2, example1.b)

        # Check a second instance with the same values is not "equal" to the first.
        example2 = register_new_example(a=1, b=2)
        self.assertNotEqual(example1, example2)

        # Setup the repo.
        repo = ExampleRepository(self.event_store)

        # Check the example entities can be retrieved from the example repository.
        entity1 = repo[example1.id]
        self.assertIsInstance(entity1, Example)
        self.assertEqual(1, entity1.a)
        self.assertEqual(2, entity1.b)

        entity2 = repo[example2.id]
        self.assertIsInstance(entity2, Example)
        self.assertEqual(1, entity2.a)
        self.assertEqual(2, entity2.b)

        # Check the entity can be updated.
        entity1.a = 100
        self.assertEqual(100, repo[entity1.id].a)
        entity1.b = -200
        self.assertEqual(-200, repo[entity1.id].b)

        self.assertEqual(0, entity1.count_heartbeats())
        entity1.beat_heart()
        entity1.beat_heart()
        entity1.beat_heart()
        self.assertEqual(3, entity1.count_heartbeats())
        self.assertEqual(3, repo[entity1.id].count_heartbeats())

        # Check the entity can be discarded.
        entity1.discard()
        self.assertRaises(KeyError, repo.__getitem__, entity1.id)

    def test_mutator_not_implemented_error(self):
        class UnsupportedEvent(DomainEvent): pass
        self.assertRaises(NotImplementedError, Example.mutator, Example, UnsupportedEvent('1', '0'))
Ejemplo n.º 6
0
    def setUp(self):
        super(LogTestCase, self).setUp()

        # Check we're starting clean, event handler-wise.
        assert_event_handlers_empty()

        # Setup the persistence subscriber.
        self.event_store = EventStore(self.stored_event_repo)
        self.persistence_subscriber = PersistenceSubscriber(
            event_store=self.event_store)

        self.log_repo = LogRepo(self.event_store)
class TestPersistenceSubscriber(unittest.TestCase):

    def setUp(self):
        self.mock_event_store = mock.Mock(spec=EventStore)
        self.persistence_subscriber = PersistenceSubscriber(event_store=self.mock_event_store)

    def tearDown(self):
        self.persistence_subscriber.close()

    def test(self):
        # Check the publishing a domain event causes 'append' to be called on the event store.
        self.assertEqual(0, self.mock_event_store.append.call_count)
        publish(mock.Mock(spec=DomainEvent))
        self.assertEqual(1, self.mock_event_store.append.call_count)
Ejemplo n.º 8
0
 def is_domain_event(event):
     return PersistenceSubscriber.is_domain_event(event) and \
         not isinstance(event, (
             CallResult.Created,
             CallResult.Discarded,
             SimulatedPrice.Created,
         ))
Ejemplo n.º 9
0
 def setUp(self):
     self.es = EventStore(stored_event_repo=PythonObjectsStoredEventRepository())
     self.ps = PersistenceSubscriber(self.es)
     self.call_dependencies_repo = CallDependenciesRepo(self.es)
     self.call_dependents_repo = CallDependentsRepo(self.es)
     self.call_leafs_repo = CallLeafsRepo(self.es)
     self.call_requirement_repo = CallRequirementRepo(self.es)
class TestPersistenceSubscriber(unittest.TestCase):
    def setUp(self):
        # Set up a persistence subscriber with a (mock) event store.
        self.event_store = mock.Mock(spec=EventStore)
        self.persistence_subscriber = PersistenceSubscriber(
            event_store=self.event_store)

    def tearDown(self):
        # Close the persistence subscriber.
        self.persistence_subscriber.close()

    def test_published_events_are_appended_to_event_store(self):
        # Check the event store's append method has NOT been called.
        self.assertEqual(0, self.event_store.append.call_count)

        # Publish a (mock) domain event.
        domain_event = mock.Mock(spec=DomainEvent)
        publish(domain_event)

        # Check the append method HAS been called once with the domain event.
        self.event_store.append.assert_called_once_with(domain_event)
Ejemplo n.º 11
0
    def test_with_snapshots(self):
        # Check the EventPlayer's take_snapshot() method.
        stored_event_repo = PythonObjectsStoredEventRepository()
        event_store = EventStore(stored_event_repo)
        self.ps = PersistenceSubscriber(event_store)
        event_player = EventPlayer(
            event_store=event_store,
            id_prefix='Example',
            mutate_func=Example.mutate,
            snapshot_strategy=EventSourcedSnapshotStrategy(event_store=event_store)
        )

        # Check the method returns None when there are no events.
        snapshot = event_player.take_snapshot('wrong')
        self.assertIsNone(snapshot)

        # Create a new entity.
        example = register_new_example(a=123, b=234)

        # Take a snapshot with the entity.
        snapshot1 = event_player.take_snapshot(example.id)
        self.assertIsInstance(snapshot1, Snapshot)

        # Take another snapshot with the entity.
        snapshot2 = event_player.take_snapshot(example.id)
        # - should return the previous snapshot
        self.assertIsInstance(snapshot2, Snapshot)
        self.assertEqual(snapshot2.at_event_id, snapshot1.at_event_id)

        # Generate a domain event.
        example.beat_heart()

        # Take another snapshot with the entity.
        # - should use the previous snapshot and the heartbeat event
        snapshot3 = event_player.take_snapshot(example.id)
        self.assertNotEqual(snapshot3.at_event_id, snapshot1.at_event_id)
Ejemplo n.º 12
0
 def setUp(self):
     # Setup the persistence subscriber.
     self.event_store = EventStore(PythonObjectsStoredEventRepository())
     self.persistence_subscriber = PersistenceSubscriber(
         event_store=self.event_store)
Ejemplo n.º 13
0
class TestExampleEntity(unittest.TestCase):
    def setUp(self):
        # Setup the persistence subscriber.
        self.event_store = EventStore(PythonObjectsStoredEventRepository())
        self.persistence_subscriber = PersistenceSubscriber(
            event_store=self.event_store)

    def tearDown(self):
        self.persistence_subscriber.close()
        assert_event_handlers_empty()

    def test_entity_lifecycle(self):
        # Check the factory creates an instance.
        example1 = register_new_example(a=1, b=2)
        self.assertIsInstance(example1, Example)

        # Check the properties of the Example class.
        self.assertEqual(1, example1.a)
        self.assertEqual(2, example1.b)

        # Check the properties of the EventSourcedEntity class.
        self.assertTrue(example1.id)
        self.assertEqual(1, example1.version)
        self.assertTrue(example1.created_on)

        # Check a second instance with the same values is not "equal" to the first.
        example2 = register_new_example(a=1, b=2)
        self.assertNotEqual(example1, example2)

        # Setup the repo.
        repo = ExampleRepo(self.event_store)

        # Check the example entities can be retrieved from the example repository.
        entity1 = repo[example1.id]
        self.assertIsInstance(entity1, Example)
        self.assertEqual(1, entity1.a)
        self.assertEqual(2, entity1.b)

        entity2 = repo[example2.id]
        self.assertIsInstance(entity2, Example)
        self.assertEqual(1, entity2.a)
        self.assertEqual(2, entity2.b)

        # Check the entity can be updated.
        entity1.a = 100
        self.assertEqual(100, repo[entity1.id].a)
        entity1.b = -200
        self.assertEqual(-200, repo[entity1.id].b)

        self.assertEqual(0, entity1.count_heartbeats())
        entity1.beat_heart()
        entity1.beat_heart()
        entity1.beat_heart()
        self.assertEqual(3, entity1.count_heartbeats())
        self.assertEqual(3, repo[entity1.id].count_heartbeats())

        # Check the entity can be discarded.
        entity1.discard()

        # Check the repo now raises a KeyError.
        self.assertRaises(RepositoryKeyError, repo.__getitem__, entity1.id)

        # Check the entity can't be discarded twice.
        self.assertRaises(AssertionError, entity1.discard)

        # Should fail to validate event with wrong entity ID.
        self.assertRaises(
            EntityIDConsistencyError, entity2._validate_originator,
            DomainEvent(entity_id=entity2.id + 'wrong', entity_version=0))
        # Should fail to validate event with wrong entity version.
        self.assertRaises(EntityVersionConsistencyError,
                          entity2._validate_originator,
                          DomainEvent(entity_id=entity2.id, entity_version=0))
        # Should validate event with correct entity ID and version.
        entity2._validate_originator(
            DomainEvent(entity_id=entity2.id, entity_version=entity2.version))

        # Check an entity can be reregistered with the same ID.
        replacement_event = Example.Created(entity_id=entity1.id, a=11, b=12)
        # replacement = Example.mutate(event=replacement_event)
        publish(event=replacement_event)

        # Check the replacement entity can be retrieved from the example repository.
        replacement = repo[entity1.id]
        assert isinstance(replacement, Example)
        self.assertEqual(replacement.a, 11)
        self.assertEqual(replacement.b, 12)

    def test_not_implemented_error(self):
        # Define an event class.
        class UnsupportedEvent(DomainEvent):
            pass

        # Check we get an error when attempting to mutate on the event.
        self.assertRaises(NotImplementedError, Example.mutate, Example,
                          UnsupportedEvent('1', '0'))

    def test_mutableproperty(self):
        # Check we get an error when called with something other than a function.
        self.assertRaises(ProgrammingError, mutableproperty, 'not a getter')
        self.assertRaises(ProgrammingError, mutableproperty, 123)
        self.assertRaises(ProgrammingError, mutableproperty, None)

        # Call the decorator with a function.
        getter = lambda: None
        p = mutableproperty(getter)

        # Check we got a property object.
        self.assertIsInstance(p, property)

        # Check the property object has both setter and getter functions.
        self.assertTrue(p.fset)
        self.assertTrue(p.fget)

        # Pretend we decorated an object.
        o = EventSourcedEntity(entity_id='1',
                               entity_version=0,
                               domain_event_id=1)
        o.__dict__['_<lambda>'] = 'value1'

        # Call the property's getter function.
        value = p.fget(o)
        self.assertEqual(value, 'value1')

        # Call the property's setter function.
        p.fset(o, 'value2')

        # Check the attribute has changed.
        value = p.fget(o)
        self.assertEqual(value, 'value2')

        # Check the property's getter function isn't the getter function we passed in.
        self.assertNotEqual(p.fget, getter)

        # Define a class that uses the decorator.
        class Aaa(EventSourcedEntity):
            "An event sourced entity."

            def __init__(self, a, *args, **kwargs):
                super(Aaa, self).__init__(*args, **kwargs)
                self._a = a

            @mutableproperty
            def a(self):
                "A mutable event sourced property."

        # Instantiate the class and check assigning to the property publishes an event and updates the object state.
        published_events = []
        subscription = (lambda x: True, lambda x: published_events.append(x))
        subscribe(*subscription)
        entity_id = '1'
        try:
            aaa = Aaa(entity_id=entity_id,
                      entity_version=None,
                      domain_event_id='0',
                      a=1)
            self.assertEqual(aaa.a, 1)
            aaa.a = 'value1'
            self.assertEqual(aaa.a, 'value1')
        finally:
            unsubscribe(*subscription)

        # Check an event was published.
        self.assertEqual(len(published_events), 1)

        # Check the published event was an AttributeChanged event, with the expected attribute values.
        published_event = published_events[0]
        self.assertIsInstance(published_event, Aaa.AttributeChanged)
        self.assertEqual(published_event.name, '_a')
        self.assertEqual(published_event.value, 'value1')
        self.assertTrue(published_event.domain_event_id)
        self.assertEqual(published_event.entity_id, entity_id)

    def test_static_mutator_method(self):
        self.assertRaises(NotImplementedError, EventSourcedEntity._mutator, 1,
                          2)

    def test_created_mutator_error(self):
        self.assertRaises(CreatedMutatorRequiresTypeNotInstance,
                          created_mutator, mock.Mock(spec=DomainEvent),
                          'not a class')
 def setUp(self):
     # Setup the persistence subscriber.
     self.event_store = EventStore(PythonObjectsStoredEventRepository())
     self.persistence_subscriber = PersistenceSubscriber(event_store=self.event_store)
class TestInstanceEntity(unittest.TestCase):
    def setUp(self):
        # Setup the persistence subscriber.
        self.event_store = EventStore(PythonObjectsStoredEventRepository())
        self.persistence_subscriber = PersistenceSubscriber(event_store=self.event_store)

    def tearDown(self):
        self.persistence_subscriber.close()
        assert_event_handlers_empty()

    def test_entity_lifecycle(self):
        # Check the factory creates an instance.
        instance1 = register_new_instance(atmo_id=27216, name='Ubuntu 14.04.2 XFCE Base', username='******')
        self.assertIsInstance(instance1, Instance)

        # Check the properties of the Instance class.
        self.assertEqual(27216, instance1.atmo_id)
        self.assertEqual('Ubuntu 14.04.2 XFCE Base', instance1.name)
        self.assertEqual('amitj', instance1.username)
        self.assertEqual('unknown', instance1.status)
        self.assertEqual('', instance1.activity)
        self.assertEqual({-1, -1, -1}, instance1.size)

        # Check the properties of the Instance class.
        self.assertTrue(instance1.id)
        self.assertEqual(1, instance1.version)
        self.assertTrue(instance1.created_on)

        # Check a second instance with the same values is not "equal" to the first.
        # TODO: Actually, maybe it will be, and more importantly, _should_ be.
        instance2 = register_new_instance(atmo_id=27216, name='Ubuntu 14.04.2 XFCE Base', username='******')
        self.assertNotEqual(instance1, instance2)

        # Setup the repo.
        repo = InstanceRepo(self.event_store)

        # Check the allocation source entities can be retrieved from the allocation source repository.
        entity1 = repo[instance1.id]
        self.assertIsInstance(entity1, Instance)
        self.assertEqual(27216, entity1.atmo_id)
        self.assertEqual('Ubuntu 14.04.2 XFCE Base', entity1.name)

        entity2 = repo[instance2.id]
        self.assertIsInstance(entity2, Instance)
        self.assertEqual(27216, entity2.atmo_id)
        self.assertEqual('Ubuntu 14.04.2 XFCE Base', entity2.name)

        # Check the mutable properties can be updated, but not the immutable ones:
        # Immutable:
        # - atmo_id
        # - username
        #
        # Mutable:
        # - name
        # - status
        # - activity
        # - size
        with self.assertRaises(AttributeError):
            # noinspection PyPropertyAccess
            entity1.atmo_id = 27217
        self.assertEqual(27216, repo[entity1.id].atmo_id)
        with self.assertRaises(AttributeError):
            # noinspection PyPropertyAccess
            entity1.username = '******'
        self.assertEqual('amitj', repo[entity1.id].username)

        entity1.name = 'Ubuntu 16.04.1 XFCE Base'
        self.assertEqual('Ubuntu 16.04.1 XFCE Base', repo[entity1.id].name)
        entity1.status = 'pending'
        self.assertEqual('pending', repo[entity1.id].status)
        entity1.activity = 'networking'
        self.assertEqual('networking', repo[entity1.id].activity)
        entity1.size = {'mem': '65536', 'disk': '0', 'cpu': '16'}
        self.assertEqual({'mem': '65536', 'disk': '0', 'cpu': '16'}, repo[entity1.id].size)

        self.assertEqual(0, entity1.count_heartbeats())
        entity1.beat_heart()
        entity1.beat_heart()
        entity1.beat_heart()
        self.assertEqual(3, entity1.count_heartbeats())
        self.assertEqual(3, repo[entity1.id].count_heartbeats())

        # Check the entity can be discarded.
        entity1.discard()

        # Check the repo now raises a KeyError.
        self.assertRaises(KeyError, repo.__getitem__, entity1.id)

        # Check the entity can't be discarded twice.
        self.assertRaises(AssertionError, entity1.discard)

        # Should fail to validate event with wrong entity ID.
        self.assertRaises(EntityIDConsistencyError,
                          entity2._validate_originator,
                          DomainEvent(entity_id=entity2.id + 'wrong', entity_version=0)
                          )
        # Should fail to validate event with wrong entity version.
        self.assertRaises(EntityVersionConsistencyError,
                          entity2._validate_originator,
                          DomainEvent(entity_id=entity2.id, entity_version=0)
                          )
        # Should validate event with correct entity ID and version.
        entity2._validate_originator(
            DomainEvent(entity_id=entity2.id, entity_version=entity2.version)
        )

    def test_entity_created_date(self):
        instance_created_timestamp = datetime_to_timestamp(datetime.datetime(2016, 1, 1, tzinfo=utc_timezone))
        domain_event_id = uuid_from_timestamp(instance_created_timestamp)
        event = Instance.Created(entity_id='instance1', atmo_id=27216, name='Ubuntu 14.04.2 XFCE Base',
                                 username='******', domain_event_id=domain_event_id)
        instance1 = Instance.mutate(event=event)
        publish(event=event)

        self.assertIsInstance(instance1, Instance)

        # Check the properties of the Instance class.
        self.assertEqual(27216, instance1.atmo_id)
        self.assertEqual('Ubuntu 14.04.2 XFCE Base', instance1.name)

        # Check the properties of the Instance class.
        self.assertTrue(instance1.id)
        self.assertEqual(1, instance1.version)
        self.assertTrue(instance1.created_on)
        self.assertAlmostEqual(instance_created_timestamp, instance1.created_on)

    def test_not_implemented_error(self):
        # Define an event class.
        class UnsupportedEvent(DomainEvent):
            pass

        # Check we get an error when attempting to mutate on the event.
        self.assertRaises(NotImplementedError, Instance.mutate, Instance, UnsupportedEvent('1', '0'))
Ejemplo n.º 16
0
class TestDependencyGraph(unittest.TestCase):
    def setUp(self):
        self.es = EventStore(
            stored_event_repo=PythonObjectsStoredEventRepository())
        self.ps = PersistenceSubscriber(self.es)
        self.call_dependencies_repo = CallDependenciesRepo(self.es)
        self.call_dependents_repo = CallDependentsRepo(self.es)
        self.call_leafs_repo = CallLeafsRepo(self.es)
        self.call_requirement_repo = CallRequirementRepo(self.es)

    def tearDown(self):
        self.ps.close()

    def test_generate_dependency_graph_with_function_call(self):
        contract_specification = register_contract_specification(
            specification="""
def double(x):
    return x * 2

double(1 + 1)
""")

        generate_dependency_graph(
            contract_specification=contract_specification,
            call_dependencies_repo=self.call_dependencies_repo,
            call_dependents_repo=self.call_dependents_repo,
            call_leafs_repo=self.call_leafs_repo,
            call_requirement_repo=self.call_requirement_repo,
        )

        root_dependencies = self.call_dependencies_repo[
            contract_specification.id]
        assert isinstance(root_dependencies, CallDependencies)
        self.assertEqual(len(root_dependencies.dependencies), 1)

        root_dependency = root_dependencies.dependencies[0]
        call_dependencies = self.call_dependencies_repo[root_dependency]
        self.assertEqual(len(call_dependencies.dependencies), 0)

        dependency = self.call_dependents_repo[root_dependency]
        assert isinstance(dependency, CallDependents)
        self.assertEqual(len(dependency.dependents), 1)

        self.assertEqual(dependency.dependents[0], contract_specification.id)


#     def test_generate_dependency_graph_recursive_functional_call(self):
#         contract_specification = self.app.register_contract_specification(specification="""
# def inc(x):
#     if x < 10:
#         return inc(x+1) + inc(x+2)
#     else:
#         return 100
#
# inc(1 + 2)
# """)
#
#         dependency_graph = self.app.generate_dependency_graph(contract_specification=contract_specification)
#
#         call_dependencies = self.app.call_dependencies_repo[dependency_graph.id]
#         self.assertEqual(len(call_dependencies.requirements), 1)
#         dependency_id = call_dependencies.requirements[0]
#         dependents = self.app.call_dependents_repo[dependency_id].dependents
#         self.assertEqual(len(dependents), 1)
#         self.assertIn(dependency_graph.id, dependents)
#         # A circular dependency...
#         self.assertIn(dependency_id, dependents)

    def test_generate_execution_order(self):

        # Dependencies:
        # 1 -> 2
        # 1 -> 3
        # 3 -> 2

        # Therefore dependents:
        # 1 = []
        # 2 = [1, 3]
        # 3 = [1]

        # 2 depends on nothing, so 2 is a leaf.
        # 1 depends on 3 and 2, so 1 is not next.
        # 3 depends only on 2, so is next.
        # Therefore 1 is last.
        # Hence evaluation order: 2, 3, 1

        call_dependencies_repo = MagicMock(spec=CallDependenciesRepository,
                                           __getitem__=lambda self, x: {
                                               1: [2, 3],
                                               2: [],
                                               3: [2]
                                           }[x])
        call_dependents_repo = MagicMock(spec=CallDependentsRepository,
                                         __getitem__=lambda self, x: {
                                             1: [],
                                             2: [1, 3],
                                             3: [1]
                                         }[x])

        leaf_call_ids = [2]
        execution_order_gen = generate_execution_order(leaf_call_ids,
                                                       call_dependents_repo,
                                                       call_dependencies_repo)
        execution_order = list(execution_order_gen)
        self.assertEqual(execution_order, [2, 3, 1])

    def test_get_dependency_values(self):
        call_dependencies_repo = MagicMock(
            spec=CallDependenciesRepository,
            __getitem__=lambda self, x: {
                '1':
                CallDependencies(dependencies=['2', '3'],
                                 entity_id=123,
                                 entity_version=0,
                                 timestamp=1),
            }[x])
        call_result_repo = MagicMock(
            spec=CallResultRepository,
            __getitem__=lambda self, x: {
                'valuation2':
                Mock(spec=CallResult, result_value=12, perturbed_values={}),
                'valuation3':
                Mock(spec=CallResult, result_value=13, perturbed_values={}),
            }[x])
        values = get_dependency_results('valuation', '1',
                                        call_dependencies_repo,
                                        call_result_repo)
        self.assertEqual(values, {'2': (12, {}), '3': (13, {})})
Ejemplo n.º 17
0
class TestCallResultPolicy(TestCase):
    def setUp(self):
        assert_event_handlers_empty()
        self.es = EventStore(PythonObjectsStoredEventRepository())
        self.ps = PersistenceSubscriber(self.es)
        # self.call_result_repo = CallResultRepo(self.es)
        self.call_result_repo = {}
        self.call_dependencies_repo = CallDependenciesRepo(self.es)
        self.call_dependents_repo = CallDependentsRepo(self.es)
        self.call_requirement_repo = CallRequirementRepo(self.es)
        self.policy = CallResultPolicy(call_result_repo=self.call_result_repo)

    def tearDown(self):
        self.ps.close()
        self.policy.close()
        assert_event_handlers_empty()

    def test_delete_result(self):
        # In this test, there are two "calls": call1 and call2.
        # It is supposed that call1 happens first, and call2 uses the result of call1.
        # Therefore call2 depends upon call1, call1 is a dependency of call2, and call2 is a dependent of call1.
        call1_id = 'call1'
        call2_id = 'call2'
        contract_valuation_id = 'val1'
        contract_specification_id = 'spec1'
        # call1_id = uuid4().hex
        # call2_id = uuid4().hex
        # contract_valuation_id = uuid4().hex
        # contract_specification_id = uuid4().hex

        register_call_dependencies(call2_id, [call1_id])

        # Check the policy has the dependencies for call2.
        self.assertEqual(self.policy.dependencies[call2_id], [call1_id])

        # Register dependents of call1, as call2.
        register_call_dependents(call1_id, [call2_id])

        # Check the policy has the dependencies for call2.
        self.assertEqual(self.policy.dependents[call1_id], [call2_id])

        # Register call result for call1.
        # - this should trigger deletion of call2 result
        call1_result = register_call_result(call1_id, 1.0, {}, contract_valuation_id, contract_specification_id, [])

        # Check the policy has the result for call1.
        self.assertTrue(call1_result.id in self.policy.result)

        # Check the result for call1 exists.
        self.assertTrue(call1_result.id in self.call_result_repo)

        # Register call result for call2.
        call2_result = register_call_result(call2_id, 1.0, {}, contract_valuation_id, contract_specification_id, [])

        # Check the policy has the result for call2.
        self.assertTrue(call2_result.id in self.policy.result)

        # Check the result for call2 exists.
        self.assertTrue(call2_result.id in self.call_result_repo)

        # Check the policy does not have the result for call1.
        self.assertFalse(call1_result.id in self.policy.result)

        # Check the result for call1 doesn't exist (because it's dependents have results).
        self.assertFalse(call1_result.id in self.call_result_repo)
Ejemplo n.º 18
0
 def setUp(self):
     self.es = EventStore(stored_event_repo=InMemoryStoredEventRepository())
     self.ps = PersistenceSubscriber(self.es)
     self.call_dependencies_repo = CallDependenciesRepo(self.es)
     self.call_dependents_repo = CallDependentsRepo(self.es)
class TestAllocationSourceEntity(unittest.TestCase):
    def setUp(self):
        # Setup the persistence subscriber.
        self.event_store = EventStore(PythonObjectsStoredEventRepository())
        self.persistence_subscriber = PersistenceSubscriber(event_store=self.event_store)

    def tearDown(self):
        self.persistence_subscriber.close()
        assert_event_handlers_empty()

    def test_entity_lifecycle(self):
        # Check the factory creates an instance.
        allocation_source1 = register_new_allocation_source(a=1, b=2)
        self.assertIsInstance(allocation_source1, AllocationSource)

        # Check the properties of the AllocationSource class.
        self.assertEqual(1, allocation_source1.a)
        self.assertEqual(2, allocation_source1.b)

        # Check the properties of the EventSourcedEntity class.
        self.assertTrue(allocation_source1.id)
        self.assertEqual(1, allocation_source1.version)
        self.assertTrue(allocation_source1.created_on)

        # Check a second instance with the same values is not "equal" to the first.
        allocation_source2 = register_new_allocation_source(a=1, b=2)
        self.assertNotEqual(allocation_source1, allocation_source2)

        # Setup the repo.
        repo = AllocationSourceRepo(self.event_store)

        # Check the allocation source entities can be retrieved from the allocation source repository.
        entity1 = repo[allocation_source1.id]
        self.assertIsInstance(entity1, AllocationSource)
        self.assertEqual(1, entity1.a)
        self.assertEqual(2, entity1.b)

        entity2 = repo[allocation_source2.id]
        self.assertIsInstance(entity2, AllocationSource)
        self.assertEqual(1, entity2.a)
        self.assertEqual(2, entity2.b)

        # Check the entity can be updated.
        entity1.a = 100
        self.assertEqual(100, repo[entity1.id].a)
        entity1.b = -200
        self.assertEqual(-200, repo[entity1.id].b)

        self.assertEqual(0, entity1.count_heartbeats())
        entity1.beat_heart()
        entity1.beat_heart()
        entity1.beat_heart()
        self.assertEqual(3, entity1.count_heartbeats())
        self.assertEqual(3, repo[entity1.id].count_heartbeats())

        # Check the entity can be discarded.
        entity1.discard()

        # Check the repo now raises a KeyError.
        self.assertRaises(KeyError, repo.__getitem__, entity1.id)

        # Check the entity can't be discarded twice.
        self.assertRaises(AssertionError, entity1.discard)

        # Should fail to validate event with wrong entity ID.
        self.assertRaises(EntityIDConsistencyError,
                          entity2._validate_originator,
                          DomainEvent(entity_id=entity2.id + 'wrong', entity_version=0)
                          )
        # Should fail to validate event with wrong entity version.
        self.assertRaises(EntityVersionConsistencyError,
                          entity2._validate_originator,
                          DomainEvent(entity_id=entity2.id, entity_version=0)
                          )
        # Should validate event with correct entity ID and version.
        entity2._validate_originator(
            DomainEvent(entity_id=entity2.id, entity_version=entity2.version)
        )

    def test_not_implemented_error(self):
        # Define an event class.
        class UnsupportedEvent(DomainEvent):
            pass

        # Check we get an error when attempting to mutate on the event.
        self.assertRaises(NotImplementedError, AllocationSource.mutate, AllocationSource, UnsupportedEvent('1', '0'))
 def setUp(self):
     self.mock_event_store = mock.Mock(spec=EventStore)
     self.persistence_subscriber = PersistenceSubscriber(event_store=self.mock_event_store)
Ejemplo n.º 21
0
class LogTestCase(AbstractTestCase):
    @property
    def stored_event_repo(self):
        """
        Returns a stored event repository.

        Concrete log test cases will provide this method.
        """
        raise NotImplementedError

    def setUp(self):
        super(LogTestCase, self).setUp()

        # Check we're starting clean, event handler-wise.
        assert_event_handlers_empty()

        # Setup the persistence subscriber.
        self.event_store = EventStore(self.stored_event_repo)
        self.persistence_subscriber = PersistenceSubscriber(
            event_store=self.event_store)

        self.log_repo = LogRepo(self.event_store)

    def tearDown(self):
        # Close the persistence subscriber.
        self.persistence_subscriber.close()

        super(LogTestCase, self).tearDown()

        # Check we finished clean, event handler-wise.
        assert_event_handlers_empty()

    def test_entity_lifecycle(self):
        log = self.log_repo.get_or_create(log_name='log1', bucket_size='year')
        self.assertIsInstance(log, Log)
        self.assertEqual(log.name, 'log1')
        self.assertEqual(log.bucket_size, 'year')

        # Test get_logger and get_log_reader().
        logger = get_logger(log)
        self.assertIsInstance(logger, Logger)
        message1 = 'This is message 1'
        message2 = 'This is message 2'
        message3 = 'This is message 3'
        message4 = 'This is message 4'
        message5 = 'This is message 5'
        message6 = 'This is message 6'
        event1 = logger.info(message1)
        event2 = logger.info(message2)
        event3 = logger.info(message3)
        halfway = uuid1().hex
        event4 = logger.info(message4)
        event5 = logger.info(message5)
        event6 = logger.info(message6)

        # Check we can get all the messages (query running in descending order).
        log_reader = get_log_reader(log, event_store=self.event_store)
        messages = list(log_reader.get_messages(is_ascending=False))
        self.assertEqual(len(messages), 6)
        self.assertEqual(messages[0], message6)
        self.assertEqual(messages[1], message5)
        self.assertEqual(messages[2], message4)
        self.assertEqual(messages[3], message3)
        self.assertEqual(messages[4], message2)
        self.assertEqual(messages[5], message1)

        # Check we can get all the messages (query running in ascending order).
        messages = list(log_reader.get_messages(is_ascending=True))
        self.assertEqual(len(messages), 6)
        self.assertEqual(messages[0], message1)
        self.assertEqual(messages[1], message2)
        self.assertEqual(messages[2], message3)
        self.assertEqual(messages[3], message4)
        self.assertEqual(messages[4], message5)
        self.assertEqual(messages[5], message6)

        # Check we can get messages after halfway (query running in descending order).
        messages = list(
            log_reader.get_messages(after=halfway, is_ascending=False))
        self.assertEqual(len(messages), 3)
        self.assertEqual(messages[0], message6)
        self.assertEqual(messages[1], message5)
        self.assertEqual(messages[2], message4)

        # Check we can get messages until halfway (query running in descending order).
        messages = list(
            log_reader.get_messages(until=halfway, is_ascending=False))
        self.assertEqual(len(messages), 3)
        self.assertEqual(messages[0], message3)
        self.assertEqual(messages[1], message2)
        self.assertEqual(messages[2], message1)

        # Check we can get messages until halfway (query running in ascending order).
        messages = list(
            log_reader.get_messages(until=halfway, is_ascending=True))
        self.assertEqual(len(messages), 3)
        self.assertEqual(messages[0], message1)
        self.assertEqual(messages[1], message2)
        self.assertEqual(messages[2], message3)

        # Check we can get messages after halfway (query running in ascending order).
        messages = list(
            log_reader.get_messages(after=halfway, is_ascending=True))
        self.assertEqual(len(messages), 3)
        self.assertEqual(messages[0], message4)
        self.assertEqual(messages[1], message5)
        self.assertEqual(messages[2], message6)

        # Check we can get last three messages (query running in descending order).
        messages = list(log_reader.get_messages(limit=3, is_ascending=False))
        self.assertEqual(len(messages), 3)
        self.assertEqual(messages[0], message6)
        self.assertEqual(messages[1], message5)
        self.assertEqual(messages[2], message4)

        # Check we can get first three messages (query running in ascending order).
        messages = list(log_reader.get_messages(limit=3, is_ascending=True))
        self.assertEqual(len(messages), 3)
        self.assertEqual(messages[0], message1)
        self.assertEqual(messages[1], message2)
        self.assertEqual(messages[2], message3)

        # Check we can get last line (query running in descending order).
        messages = list(
            log_reader.get_messages(limit=1, after=halfway,
                                    is_ascending=False))
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0], message6)

        # Check we can get the first line after halfway (query running in ascending order).
        messages = list(
            log_reader.get_messages(limit=1, after=halfway, is_ascending=True))
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0], message4)

        # Check we can get the first line before halfway (query running in descending order).
        messages = list(
            log_reader.get_messages(limit=1, until=halfway,
                                    is_ascending=False))
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0], message3)

        # Check we can get the first line (query running in ascending order).
        messages = list(
            log_reader.get_messages(limit=1, until=halfway, is_ascending=True))
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0], message1)

        # Check there isn't a line after the last line (query running in ascending order).
        messages = list(
            log_reader.get_messages(limit=1,
                                    after=event6.domain_event_id,
                                    is_ascending=True))
        self.assertEqual(len(messages), 0)

        # Check there is nothing somehow both after and until halfway.
        messages = list(log_reader.get_messages(after=halfway, until=halfway))
        self.assertEqual(len(messages), 0)

    def test_buckets(self):
        # Start new log.
        log = start_new_log(name='log1', bucket_size='second')

        # Write messages across the time interval
        start = datetime.datetime.now()
        logger = get_logger(log)
        number_of_messages = 300
        events = []
        for i in range(number_of_messages):
            message_logged = logger.info(str(i))
            events.append(message_logged)
            sleep(0.01)
        self.assertGreater(datetime.datetime.now() - start,
                           datetime.timedelta(seconds=1))

        # Get the messages in descending order.
        reader = get_log_reader(log, self.event_store)
        messages = list(reader.get_messages(is_ascending=False, page_size=10))
        self.assertEqual(len(messages), number_of_messages)

        # Expect the order of the messages is the reverse of the created order.
        self.assertEqual(
            messages,
            list(reversed([str(i) for i in range(number_of_messages)])))

        # Get the messages in ascending order.
        messages = list(reader.get_messages(is_ascending=True, page_size=10))
        self.assertEqual(len(messages), number_of_messages)

        # Expect the order of the messages is the same as the created order.
        self.assertEqual(messages, [str(i) for i in range(number_of_messages)])

        # Get a limited number of messages in descending order.
        limit = 150
        messages = list(
            reader.get_messages(is_ascending=False, page_size=10, limit=limit))
        self.assertLess(limit, number_of_messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the reverse of the created order.
        self.assertEqual(
            messages,
            list(reversed([str(i)
                           for i in range(number_of_messages)]))[:limit])

        # Get a limited number of messages in ascending order.
        limit = 150
        messages = list(
            reader.get_messages(is_ascending=True, page_size=10, limit=limit))
        self.assertLess(limit, number_of_messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the same as the created order.
        self.assertEqual(messages, [str(i) for i in range(limit)])

        # Get a limited number of messages in descending order from the midpoint down.
        limit = 110
        midpoint = events[150].domain_event_id
        messages = list(
            reader.get_messages(is_ascending=False,
                                page_size=10,
                                limit=limit,
                                until=midpoint))
        self.assertLess(limit, number_of_messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the reverse of the created order.
        self.assertEqual(
            messages,
            list(reversed([str(i) for i in range(150 - limit, 150)])))

        # Get a limited number of messages in ascending order from the midpoint up.
        limit = 110
        midpoint = events[149].domain_event_id
        messages = list(
            reader.get_messages(is_ascending=True,
                                page_size=10,
                                limit=limit,
                                after=midpoint))
        self.assertLess(limit, number_of_messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the same as the created order.
        self.assertEqual(messages, [str(i) for i in range(150, 150 + limit)])

        # Get a limited number of messages in descending order above the midpoint down.
        limit = 200
        midpoint = events[150].domain_event_id
        messages = list(
            reader.get_messages(is_ascending=False,
                                page_size=10,
                                limit=limit,
                                after=midpoint))
        self.assertLess(limit, number_of_messages)
        self.assertEqual(len(messages), 150)

        # Expect the order of the messages is the reverse of the created order.
        self.assertEqual(messages,
                         list(reversed([str(i) for i in range(150, 300)])))

        # Get a limited number of messages in ascending order below the midpoint up.
        limit = 200
        midpoint = events[149].domain_event_id
        messages = list(
            reader.get_messages(is_ascending=True,
                                page_size=10,
                                limit=limit,
                                until=midpoint))
        self.assertLess(limit, number_of_messages)
        self.assertEqual(len(messages), 150)

        # Expect the order of the messages is the same as the created order.
        self.assertEqual(messages, [str(i) for i in range(150)])

        #
        # Use the last position to start part way through.
        limit = 20
        last_position = reader.position
        messages = reader.get_messages(is_ascending=True,
                                       page_size=10,
                                       limit=limit,
                                       after=last_position)
        messages = list(messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the same as the created order.
        self.assertEqual(messages, [str(i) for i in range(150, 150 + limit)])

        # Do it again.
        last_position = reader.position
        messages = reader.get_messages(is_ascending=True,
                                       page_size=10,
                                       limit=limit,
                                       after=last_position)
        messages = list(messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the same as the created order.
        self.assertEqual(messages,
                         [str(i) for i in range(150 + limit, 150 + limit * 2)])

        # Go back.
        last_position = reader.position
        messages = reader.get_messages(is_ascending=False,
                                       page_size=10,
                                       limit=limit,
                                       until=last_position)
        messages = list(messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the reverse of the created order.
        self.assertEqual(
            messages,
            [str(i) for i in range(148 + limit * 2, 148 + limit, -1)])

        # Go back.
        last_position = reader.position
        messages = reader.get_messages(is_ascending=False,
                                       page_size=10,
                                       limit=limit,
                                       until=last_position)
        messages = list(messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the reverse of the created order.
        self.assertEqual(
            messages,
            [str(i) for i in range(128 + limit * 2, 128 + limit, -1)])

        # Go back.
        last_position = reader.position
        messages = reader.get_messages(is_ascending=False,
                                       page_size=10,
                                       limit=limit,
                                       until=last_position)
        messages = list(messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the reverse of the created order.
        self.assertEqual(
            messages,
            [str(i) for i in range(108 + limit * 2, 108 + limit, -1)])

        # Repeat.
        messages = reader.get_messages(is_ascending=False,
                                       page_size=10,
                                       limit=limit,
                                       until=last_position)
        messages = list(messages)
        self.assertEqual(len(messages), limit)

        # Expect the order of the messages is the reverse of the created order.
        self.assertEqual(
            messages,
            [str(i) for i in range(108 + limit * 2, 108 + limit, -1)])
Ejemplo n.º 22
0
 def setUp(self):
     self.es = EventStore(stored_event_repo=InMemoryStoredEventRepository())
     self.ps = PersistenceSubscriber(self.es)
     self.call_dependencies_repo = CallDependenciesRepo(self.es)
     self.call_dependents_repo = CallDependentsRepo(self.es)
Ejemplo n.º 23
0
class TestDependencyGraph(unittest.TestCase):
    def setUp(self):
        self.es = EventStore(stored_event_repo=PythonObjectsStoredEventRepository())
        self.ps = PersistenceSubscriber(self.es)
        self.call_dependencies_repo = CallDependenciesRepo(self.es)
        self.call_dependents_repo = CallDependentsRepo(self.es)
        self.call_leafs_repo = CallLeafsRepo(self.es)
        self.call_requirement_repo = CallRequirementRepo(self.es)

    def tearDown(self):
        self.ps.close()

    def test_generate_dependency_graph_with_function_call(self):
        contract_specification = register_contract_specification(source_code="""
def double(x):
    return x * 2

double(1 + 1)
""")

        generate_dependency_graph(
            contract_specification=contract_specification,
            call_dependencies_repo=self.call_dependencies_repo,
            call_dependents_repo=self.call_dependents_repo,
            call_requirement_repo=self.call_requirement_repo,
        )

        root_dependencies = self.call_dependencies_repo[contract_specification.id]
        assert isinstance(root_dependencies, CallDependencies)
        self.assertEqual(len(root_dependencies.dependencies), 1)

        root_dependency = root_dependencies.dependencies[0]
        call_dependencies = self.call_dependencies_repo[root_dependency]
        self.assertEqual(len(call_dependencies.dependencies), 0)

        dependency = self.call_dependents_repo[root_dependency]
        assert isinstance(dependency, CallDependents)
        self.assertEqual(len(dependency.dependents), 1)

        self.assertEqual(dependency.dependents[0], contract_specification.id)

    #     def test_generate_dependency_graph_recursive_functional_call(self):
    #         contract_specification = self.app.register_contract_specification(specification="""
    # def inc(x):
    #     if x < 10:
    #         return inc(x+1) + inc(x+2)
    #     else:
    #         return 100
    #
    # inc(1 + 2)
    # """)
    #
    #         dependency_graph = self.app.generate_dependency_graph(contract_specification=contract_specification)
    #
    #         call_dependencies = self.app.call_dependencies_repo[dependency_graph.id]
    #         self.assertEqual(len(call_dependencies.requirements), 1)
    #         dependency_id = call_dependencies.requirements[0]
    #         dependents = self.app.call_dependents_repo[dependency_id].dependents
    #         self.assertEqual(len(dependents), 1)
    #         self.assertIn(dependency_graph.id, dependents)
    #         # A circular dependency...
    #         self.assertIn(dependency_id, dependents)



    def test_generate_execution_order(self):
        # Dependencies:
        # 1 -> 2
        # 1 -> 3
        # 3 -> 2

        # Therefore dependents:
        # 1 = []
        # 2 = [1, 3]
        # 3 = [1]

        # 2 depends on nothing, so 2 is a leaf.
        # 1 depends on 3 and 2, so 1 is not next.
        # 3 depends only on 2, so is next.
        # Therefore 1 is last.
        # Hence evaluation order: 2, 3, 1

        call_dependencies_repo = MagicMock(spec=CallDependenciesRepository,
                                           __getitem__=lambda self, x: {
                                               1: [2, 3],
                                               2: [],
                                               3: [2]
                                           }[x])
        call_dependents_repo = MagicMock(spec=CallDependentsRepository,
                                         __getitem__=lambda self, x: {
                                             1: [],
                                             2: [1, 3],
                                             3: [1]
                                         }[x])

        leaf_call_ids = [2]
        execution_order_gen = generate_execution_order(leaf_call_ids, call_dependents_repo, call_dependencies_repo)
        execution_order = list(execution_order_gen)
        self.assertEqual(execution_order, [2, 3, 1])

    def test_get_dependency_values(self):
        call_dependencies_repo = MagicMock(spec=CallDependenciesRepository,
                                           __getitem__=lambda self, x: {
                                               '1': CallDependencies(dependencies=['2', '3'], entity_id=123,
                                                                     entity_version=0, timestamp=1),
                                           }[x])
        call_result1 = Mock(spec=CallResult, result_value=12, perturbed_values={})
        call_result2 = Mock(spec=CallResult, result_value=13, perturbed_values={})
        call_result_repo = MagicMock(spec=CallResultRepository,
                                     __getitem__=lambda self, x: {
                                         'valuation2': call_result1,
                                         'valuation3': call_result2,
                                     }[x])
        values = get_dependency_results('valuation', '1', call_dependencies_repo, call_result_repo)
        self.assertEqual(len(values), 2)
        self.assertEqual(values['2'].result_value, 12)
        self.assertEqual(values['3'].result_value, 13)
Ejemplo n.º 24
0
    def test_snapshots(self):
        stored_event_repo = PythonObjectsStoredEventRepository()
        event_store = EventStore(stored_event_repo)
        self.ps = PersistenceSubscriber(event_store)
        event_player = EventPlayer(event_store=event_store, id_prefix='Example', mutate_func=Example.mutate)

        # Create a new entity.
        registered_example = register_new_example(a=123, b=234)

        # Take a snapshot.
        snapshot = take_snapshot(registered_example, uuid1().hex)

        # Replay from this snapshot.
        after = snapshot.at_event_id
        initial_state = entity_from_snapshot(snapshot)
        retrieved_example = event_player.replay_events(registered_example.id, initial_state=initial_state, after=after)

        # Check the attributes are correct.
        self.assertEqual(retrieved_example.a, 123)

        # Remember the time now.
        timecheck1 = uuid1().hex

        # Change attribute value.
        retrieved_example.a = 999

        # Check the initial state doesn't move.
        self.assertEqual(initial_state.a, 123)

        # Remember the time now.
        timecheck2 = uuid1().hex

        # Change attribute value.
        retrieved_example.a = 9999

        # Remember the time now.
        timecheck3 = uuid1().hex

        # Check the event sourced entities are correct.
        assert initial_state.a == 123
        retrieved_example = event_player.replay_events(registered_example.id)
        self.assertEqual(retrieved_example.a, 9999)

        # Take another snapshot.
        snapshot2 = take_snapshot(retrieved_example, uuid1().hex)

        # Check we can replay from this snapshot.
        initial_state2 = entity_from_snapshot(snapshot2)
        after2 = snapshot2.domain_event_id
        retrieved_example = event_player.replay_events(registered_example.id, initial_state=initial_state2, after=after2)
        # Check the attributes are correct.
        self.assertEqual(retrieved_example.a, 9999)

        # Check we can get historical state at timecheck1.
        retrieved_example = event_player.replay_events(registered_example.id, until=timecheck1)
        self.assertEqual(retrieved_example.a, 123)

        # Check we can get historical state at timecheck2.
        retrieved_example = event_player.replay_events(registered_example.id, until=timecheck2)
        self.assertEqual(retrieved_example.a, 999)

        # Check we can get historical state at timecheck3.
        retrieved_example = event_player.replay_events(registered_example.id, until=timecheck3)
        self.assertEqual(retrieved_example.a, 9999)

        # Similarly, check we can get historical state using a snapshot
        retrieved_example = event_player.replay_events(registered_example.id, initial_state=initial_state, after=after, until=timecheck2)
        self.assertEqual(retrieved_example.a, 999)
 def setUp(self):
     # Set up a persistence subscriber with a (mock) event store.
     self.event_store = mock.Mock(spec=EventStore)
     self.persistence_subscriber = PersistenceSubscriber(
         event_store=self.event_store)
Ejemplo n.º 26
0
 def create_persistence_subscriber(self):
     if self.persist_events and self.event_store:
         return PersistenceSubscriber(self.event_store)