eventsourcing 9.3.3__py3-none-any.whl → 9.3.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of eventsourcing might be problematic. Click here for more details.
- eventsourcing/application.py +0 -15
- eventsourcing/system.py +25 -2
- {eventsourcing-9.3.3.dist-info → eventsourcing-9.3.5.dist-info}/METADATA +1 -1
- eventsourcing-9.3.5.dist-info/RECORD +24 -0
- eventsourcing/examples/__init__.py +0 -0
- eventsourcing/examples/aggregate1/__init__.py +0 -0
- eventsourcing/examples/aggregate1/application.py +0 -27
- eventsourcing/examples/aggregate1/domainmodel.py +0 -16
- eventsourcing/examples/aggregate1/test_application.py +0 -37
- eventsourcing/examples/aggregate2/__init__.py +0 -0
- eventsourcing/examples/aggregate2/application.py +0 -27
- eventsourcing/examples/aggregate2/domainmodel.py +0 -22
- eventsourcing/examples/aggregate2/test_application.py +0 -37
- eventsourcing/examples/aggregate3/__init__.py +0 -0
- eventsourcing/examples/aggregate3/application.py +0 -27
- eventsourcing/examples/aggregate3/domainmodel.py +0 -38
- eventsourcing/examples/aggregate3/test_application.py +0 -37
- eventsourcing/examples/aggregate4/__init__.py +0 -0
- eventsourcing/examples/aggregate4/application.py +0 -27
- eventsourcing/examples/aggregate4/domainmodel.py +0 -114
- eventsourcing/examples/aggregate4/test_application.py +0 -38
- eventsourcing/examples/aggregate5/__init__.py +0 -0
- eventsourcing/examples/aggregate5/application.py +0 -27
- eventsourcing/examples/aggregate5/domainmodel.py +0 -131
- eventsourcing/examples/aggregate5/test_application.py +0 -38
- eventsourcing/examples/aggregate6/__init__.py +0 -0
- eventsourcing/examples/aggregate6/application.py +0 -30
- eventsourcing/examples/aggregate6/domainmodel.py +0 -123
- eventsourcing/examples/aggregate6/test_application.py +0 -38
- eventsourcing/examples/aggregate6a/__init__.py +0 -0
- eventsourcing/examples/aggregate6a/application.py +0 -40
- eventsourcing/examples/aggregate6a/domainmodel.py +0 -149
- eventsourcing/examples/aggregate6a/test_application.py +0 -45
- eventsourcing/examples/aggregate7/__init__.py +0 -0
- eventsourcing/examples/aggregate7/application.py +0 -53
- eventsourcing/examples/aggregate7/domainmodel.py +0 -142
- eventsourcing/examples/aggregate7/persistence.py +0 -57
- eventsourcing/examples/aggregate7/test_application.py +0 -45
- eventsourcing/examples/aggregate7/test_compression_and_encryption.py +0 -45
- eventsourcing/examples/aggregate7/test_snapshotting_intervals.py +0 -67
- eventsourcing/examples/aggregate7a/__init__.py +0 -0
- eventsourcing/examples/aggregate7a/application.py +0 -56
- eventsourcing/examples/aggregate7a/domainmodel.py +0 -168
- eventsourcing/examples/aggregate7a/test_application.py +0 -46
- eventsourcing/examples/aggregate7a/test_compression_and_encryption.py +0 -45
- eventsourcing/examples/aggregate8/__init__.py +0 -0
- eventsourcing/examples/aggregate8/application.py +0 -47
- eventsourcing/examples/aggregate8/domainmodel.py +0 -71
- eventsourcing/examples/aggregate8/persistence.py +0 -57
- eventsourcing/examples/aggregate8/test_application.py +0 -44
- eventsourcing/examples/aggregate8/test_compression_and_encryption.py +0 -44
- eventsourcing/examples/aggregate8/test_snapshotting_intervals.py +0 -38
- eventsourcing/examples/bankaccounts/__init__.py +0 -0
- eventsourcing/examples/bankaccounts/application.py +0 -70
- eventsourcing/examples/bankaccounts/domainmodel.py +0 -56
- eventsourcing/examples/bankaccounts/test.py +0 -173
- eventsourcing/examples/cargoshipping/__init__.py +0 -0
- eventsourcing/examples/cargoshipping/application.py +0 -126
- eventsourcing/examples/cargoshipping/domainmodel.py +0 -330
- eventsourcing/examples/cargoshipping/interface.py +0 -143
- eventsourcing/examples/cargoshipping/test.py +0 -231
- eventsourcing/examples/contentmanagement/__init__.py +0 -0
- eventsourcing/examples/contentmanagement/application.py +0 -118
- eventsourcing/examples/contentmanagement/domainmodel.py +0 -69
- eventsourcing/examples/contentmanagement/test.py +0 -180
- eventsourcing/examples/contentmanagement/utils.py +0 -26
- eventsourcing/examples/contentmanagementsystem/__init__.py +0 -0
- eventsourcing/examples/contentmanagementsystem/application.py +0 -54
- eventsourcing/examples/contentmanagementsystem/postgres.py +0 -17
- eventsourcing/examples/contentmanagementsystem/sqlite.py +0 -17
- eventsourcing/examples/contentmanagementsystem/system.py +0 -14
- eventsourcing/examples/contentmanagementsystem/test_system.py +0 -180
- eventsourcing/examples/searchablecontent/__init__.py +0 -0
- eventsourcing/examples/searchablecontent/application.py +0 -45
- eventsourcing/examples/searchablecontent/persistence.py +0 -23
- eventsourcing/examples/searchablecontent/postgres.py +0 -118
- eventsourcing/examples/searchablecontent/sqlite.py +0 -136
- eventsourcing/examples/searchablecontent/test_application.py +0 -110
- eventsourcing/examples/searchablecontent/test_recorder.py +0 -68
- eventsourcing/examples/searchabletimestamps/__init__.py +0 -0
- eventsourcing/examples/searchabletimestamps/application.py +0 -32
- eventsourcing/examples/searchabletimestamps/persistence.py +0 -20
- eventsourcing/examples/searchabletimestamps/postgres.py +0 -110
- eventsourcing/examples/searchabletimestamps/sqlite.py +0 -99
- eventsourcing/examples/searchabletimestamps/test_searchabletimestamps.py +0 -94
- eventsourcing/examples/test_invoice.py +0 -176
- eventsourcing/examples/test_parking_lot.py +0 -206
- eventsourcing/tests/application_tests/__init__.py +0 -0
- eventsourcing/tests/application_tests/test_application_with_automatic_snapshotting.py +0 -55
- eventsourcing/tests/application_tests/test_application_with_popo.py +0 -22
- eventsourcing/tests/application_tests/test_application_with_postgres.py +0 -75
- eventsourcing/tests/application_tests/test_application_with_sqlite.py +0 -72
- eventsourcing/tests/application_tests/test_cache.py +0 -134
- eventsourcing/tests/application_tests/test_event_sourced_log.py +0 -162
- eventsourcing/tests/application_tests/test_notificationlog.py +0 -232
- eventsourcing/tests/application_tests/test_notificationlogreader.py +0 -126
- eventsourcing/tests/application_tests/test_processapplication.py +0 -110
- eventsourcing/tests/application_tests/test_processingpolicy.py +0 -109
- eventsourcing/tests/application_tests/test_repository.py +0 -504
- eventsourcing/tests/application_tests/test_snapshotting.py +0 -68
- eventsourcing/tests/application_tests/test_upcasting.py +0 -459
- eventsourcing/tests/docs_tests/__init__.py +0 -0
- eventsourcing/tests/docs_tests/test_docs.py +0 -293
- eventsourcing/tests/domain_tests/__init__.py +0 -0
- eventsourcing/tests/domain_tests/test_aggregate.py +0 -1200
- eventsourcing/tests/domain_tests/test_aggregate_decorators.py +0 -1604
- eventsourcing/tests/domain_tests/test_domainevent.py +0 -80
- eventsourcing/tests/interface_tests/__init__.py +0 -0
- eventsourcing/tests/interface_tests/test_remotenotificationlog.py +0 -258
- eventsourcing/tests/persistence_tests/__init__.py +0 -0
- eventsourcing/tests/persistence_tests/test_aes.py +0 -93
- eventsourcing/tests/persistence_tests/test_connection_pool.py +0 -722
- eventsourcing/tests/persistence_tests/test_eventstore.py +0 -72
- eventsourcing/tests/persistence_tests/test_infrastructure_factory.py +0 -21
- eventsourcing/tests/persistence_tests/test_mapper.py +0 -113
- eventsourcing/tests/persistence_tests/test_noninterleaving_notification_ids.py +0 -69
- eventsourcing/tests/persistence_tests/test_popo.py +0 -124
- eventsourcing/tests/persistence_tests/test_postgres.py +0 -1120
- eventsourcing/tests/persistence_tests/test_sqlite.py +0 -348
- eventsourcing/tests/persistence_tests/test_transcoder.py +0 -44
- eventsourcing/tests/system_tests/__init__.py +0 -0
- eventsourcing/tests/system_tests/test_runner.py +0 -935
- eventsourcing/tests/system_tests/test_system.py +0 -284
- eventsourcing/tests/utils_tests/__init__.py +0 -0
- eventsourcing/tests/utils_tests/test_utils.py +0 -226
- eventsourcing-9.3.3.dist-info/RECORD +0 -145
- {eventsourcing-9.3.3.dist-info → eventsourcing-9.3.5.dist-info}/AUTHORS +0 -0
- {eventsourcing-9.3.3.dist-info → eventsourcing-9.3.5.dist-info}/LICENSE +0 -0
- {eventsourcing-9.3.3.dist-info → eventsourcing-9.3.5.dist-info}/WHEEL +0 -0
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
After Ed Blackburn's https://github.com/edblackburn/parking-lot/.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from __future__ import annotations
|
|
6
|
-
|
|
7
|
-
import re
|
|
8
|
-
from dataclasses import dataclass
|
|
9
|
-
from datetime import datetime, timedelta
|
|
10
|
-
from typing import List, Type, cast
|
|
11
|
-
from unittest import TestCase
|
|
12
|
-
from uuid import NAMESPACE_URL, UUID, uuid5
|
|
13
|
-
|
|
14
|
-
from eventsourcing.application import AggregateNotFoundError, Application
|
|
15
|
-
from eventsourcing.domain import Aggregate, triggers
|
|
16
|
-
from eventsourcing.system import NotificationLogReader
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@dataclass
|
|
20
|
-
class LicencePlate:
|
|
21
|
-
number: str
|
|
22
|
-
regex = re.compile("^[0-9]{3}-[0-9]{3}$")
|
|
23
|
-
|
|
24
|
-
def __post_init__(self) -> None:
|
|
25
|
-
if not bool(self.regex.match(self.number)):
|
|
26
|
-
raise ValueError
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@dataclass
|
|
30
|
-
class Booking:
|
|
31
|
-
start: datetime
|
|
32
|
-
finish: datetime
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class Product:
|
|
36
|
-
delta = timedelta()
|
|
37
|
-
|
|
38
|
-
@classmethod
|
|
39
|
-
def calc_finish(cls, start: datetime) -> datetime:
|
|
40
|
-
return start + cls.delta
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class EndOfDay(Product):
|
|
44
|
-
delta = timedelta(days=1, seconds=-1)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class EndOfWeek(Product):
|
|
48
|
-
delta = timedelta(days=7, seconds=-1)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class Vehicle(Aggregate):
|
|
52
|
-
class Event(Aggregate.Event):
|
|
53
|
-
pass
|
|
54
|
-
|
|
55
|
-
class Registered(Event, Aggregate.Created):
|
|
56
|
-
licence_plate_number: str
|
|
57
|
-
|
|
58
|
-
class Booked(Event):
|
|
59
|
-
start: datetime
|
|
60
|
-
finish: datetime
|
|
61
|
-
|
|
62
|
-
class Unbooked(Event):
|
|
63
|
-
when: datetime
|
|
64
|
-
|
|
65
|
-
@triggers(Registered)
|
|
66
|
-
def __init__(self, licence_plate_number: str):
|
|
67
|
-
self.licence_plate_number = licence_plate_number
|
|
68
|
-
self.bookings: List[Booking] = []
|
|
69
|
-
self.inspection_failures: List[datetime] = []
|
|
70
|
-
|
|
71
|
-
@triggers(Booked)
|
|
72
|
-
def book(self, start: datetime, finish: datetime) -> None:
|
|
73
|
-
self.bookings.append(Booking(start, finish))
|
|
74
|
-
|
|
75
|
-
@triggers(Unbooked)
|
|
76
|
-
def fail_inspection(self, when: datetime) -> None:
|
|
77
|
-
self.inspection_failures.append(when)
|
|
78
|
-
|
|
79
|
-
@property
|
|
80
|
-
def licence_plate(self) -> LicencePlate:
|
|
81
|
-
return LicencePlate(self.licence_plate_number)
|
|
82
|
-
|
|
83
|
-
def inspect(self, when: datetime) -> None:
|
|
84
|
-
for booking in self.bookings:
|
|
85
|
-
if booking.start < when < booking.finish:
|
|
86
|
-
break
|
|
87
|
-
else:
|
|
88
|
-
self.fail_inspection(when)
|
|
89
|
-
|
|
90
|
-
@staticmethod
|
|
91
|
-
def create_id(licence_plate_number: str) -> UUID:
|
|
92
|
-
return uuid5(NAMESPACE_URL, f"/licence_plate_numbers/{licence_plate_number}")
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
class ParkingLot(Application):
|
|
96
|
-
def book(self, licence_plate: LicencePlate, product: Type[Product]) -> None:
|
|
97
|
-
try:
|
|
98
|
-
vehicle = self.get_vehicle(licence_plate)
|
|
99
|
-
except AggregateNotFoundError:
|
|
100
|
-
vehicle = Vehicle(licence_plate.number)
|
|
101
|
-
start = Vehicle.Event.create_timestamp()
|
|
102
|
-
finish = product.calc_finish(start)
|
|
103
|
-
vehicle.book(start=start, finish=finish)
|
|
104
|
-
self.save(vehicle)
|
|
105
|
-
|
|
106
|
-
def inspect(self, licence_plate: LicencePlate, when: datetime) -> None:
|
|
107
|
-
vehicle = self.get_vehicle(licence_plate)
|
|
108
|
-
vehicle.inspect(when)
|
|
109
|
-
self.save(vehicle)
|
|
110
|
-
|
|
111
|
-
def get_vehicle(self, licence_plate: LicencePlate) -> Vehicle:
|
|
112
|
-
return cast(
|
|
113
|
-
Vehicle, self.repository.get(Vehicle.create_id(licence_plate.number))
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class TestParkingLot(TestCase):
|
|
118
|
-
def test_licence_plate(self) -> None:
|
|
119
|
-
# Valid.
|
|
120
|
-
licence_plate = LicencePlate("123-123")
|
|
121
|
-
self.assertIsInstance(licence_plate, LicencePlate)
|
|
122
|
-
self.assertEqual(licence_plate.number, "123-123")
|
|
123
|
-
|
|
124
|
-
# Invalid.
|
|
125
|
-
with self.assertRaises(ValueError):
|
|
126
|
-
LicencePlate("abcdef")
|
|
127
|
-
|
|
128
|
-
def test_parking_lot(self) -> None:
|
|
129
|
-
# Construct the application object to use an SQLite database.
|
|
130
|
-
app = ParkingLot(
|
|
131
|
-
env={
|
|
132
|
-
"PERSISTENCE_MODULE": "eventsourcing.sqlite",
|
|
133
|
-
"SQLITE_DBNAME": ":memory:",
|
|
134
|
-
}
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
# Create a valid licence plate.
|
|
138
|
-
licence_plate = LicencePlate("123-123")
|
|
139
|
-
|
|
140
|
-
# Book unregistered vehicle.
|
|
141
|
-
app.book(licence_plate, EndOfDay)
|
|
142
|
-
|
|
143
|
-
# Check vehicle state.
|
|
144
|
-
vehicle = app.get_vehicle(licence_plate)
|
|
145
|
-
self.assertEqual(vehicle.licence_plate, licence_plate)
|
|
146
|
-
self.assertEqual(len(vehicle.bookings), 1)
|
|
147
|
-
self.assertEqual(len(vehicle.inspection_failures), 0)
|
|
148
|
-
booking1 = vehicle.bookings[-1]
|
|
149
|
-
|
|
150
|
-
# Book registered vehicle.
|
|
151
|
-
app.book(licence_plate, EndOfWeek)
|
|
152
|
-
|
|
153
|
-
# Check vehicle state.
|
|
154
|
-
vehicle = app.get_vehicle(licence_plate)
|
|
155
|
-
self.assertEqual(len(vehicle.bookings), 2)
|
|
156
|
-
self.assertEqual(len(vehicle.inspection_failures), 0)
|
|
157
|
-
booking2 = vehicle.bookings[-1]
|
|
158
|
-
|
|
159
|
-
# Inspect whilst has booking.
|
|
160
|
-
app.inspect(licence_plate, Vehicle.Event.create_timestamp())
|
|
161
|
-
|
|
162
|
-
# Check vehicle state.
|
|
163
|
-
vehicle = app.get_vehicle(licence_plate)
|
|
164
|
-
self.assertEqual(len(vehicle.bookings), 2)
|
|
165
|
-
self.assertEqual(len(vehicle.inspection_failures), 0)
|
|
166
|
-
|
|
167
|
-
# Inspect after bookings expired.
|
|
168
|
-
inspected_on = Vehicle.Event.create_timestamp() + timedelta(days=10)
|
|
169
|
-
app.inspect(licence_plate, inspected_on)
|
|
170
|
-
|
|
171
|
-
# Check vehicle state.
|
|
172
|
-
vehicle = app.get_vehicle(licence_plate)
|
|
173
|
-
self.assertEqual(len(vehicle.bookings), 2)
|
|
174
|
-
self.assertEqual(len(vehicle.inspection_failures), 1)
|
|
175
|
-
|
|
176
|
-
# Check all domain events in bounded context.
|
|
177
|
-
notifications = NotificationLogReader(app.notification_log).read(start=1)
|
|
178
|
-
domain_events = [app.mapper.to_domain_event(n) for n in notifications]
|
|
179
|
-
self.assertEqual(len(domain_events), 4)
|
|
180
|
-
|
|
181
|
-
vehicle1_id = Vehicle.create_id("123-123")
|
|
182
|
-
event0 = domain_events[0]
|
|
183
|
-
assert isinstance(event0, Vehicle.Registered)
|
|
184
|
-
self.assertEqual(event0.originator_id, vehicle1_id)
|
|
185
|
-
self.assertEqual(event0.originator_version, 1)
|
|
186
|
-
self.assertEqual(event0.licence_plate_number, "123-123")
|
|
187
|
-
|
|
188
|
-
event1 = domain_events[1]
|
|
189
|
-
assert isinstance(event1, Vehicle.Booked)
|
|
190
|
-
self.assertEqual(event1.originator_id, vehicle1_id)
|
|
191
|
-
self.assertEqual(event1.originator_version, 2)
|
|
192
|
-
self.assertEqual(event1.start, booking1.start)
|
|
193
|
-
self.assertEqual(event1.finish, booking1.finish)
|
|
194
|
-
|
|
195
|
-
event2 = domain_events[2]
|
|
196
|
-
assert isinstance(event2, Vehicle.Booked)
|
|
197
|
-
self.assertEqual(event2.originator_id, vehicle1_id)
|
|
198
|
-
self.assertEqual(event2.originator_version, 3)
|
|
199
|
-
self.assertEqual(event2.start, booking2.start)
|
|
200
|
-
self.assertEqual(event2.finish, booking2.finish)
|
|
201
|
-
|
|
202
|
-
event3 = domain_events[3]
|
|
203
|
-
assert isinstance(event3, Vehicle.Unbooked)
|
|
204
|
-
self.assertEqual(event3.originator_id, vehicle1_id)
|
|
205
|
-
self.assertEqual(event3.originator_version, 4)
|
|
206
|
-
self.assertEqual(event3.when, inspected_on)
|
|
File without changes
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from decimal import Decimal
|
|
4
|
-
from typing import ClassVar, Dict, Type
|
|
5
|
-
from unittest import TestCase
|
|
6
|
-
|
|
7
|
-
from eventsourcing.domain import Aggregate, MutableOrImmutableAggregate
|
|
8
|
-
from eventsourcing.tests.application import BankAccounts
|
|
9
|
-
from eventsourcing.tests.domain import BankAccount
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class BankAccountsWithAutomaticSnapshotting(BankAccounts):
|
|
13
|
-
is_snapshotting_enabled = False
|
|
14
|
-
snapshotting_intervals: ClassVar[
|
|
15
|
-
Dict[Type[MutableOrImmutableAggregate], int] | None
|
|
16
|
-
] = {BankAccount: 5}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class TestApplicationWithAutomaticSnapshotting(TestCase):
|
|
20
|
-
def test(self):
|
|
21
|
-
app = BankAccountsWithAutomaticSnapshotting()
|
|
22
|
-
|
|
23
|
-
# Check snapshotting is enabled by setting snapshotting_intervals only.
|
|
24
|
-
self.assertTrue(app.snapshots)
|
|
25
|
-
|
|
26
|
-
# Open an account.
|
|
27
|
-
account_id = app.open_account("Alice", "alice@example.com")
|
|
28
|
-
|
|
29
|
-
# Check there are no snapshots.
|
|
30
|
-
snapshots = list(app.snapshots.get(account_id))
|
|
31
|
-
self.assertEqual(len(snapshots), 0)
|
|
32
|
-
|
|
33
|
-
# Trigger twelve more events.
|
|
34
|
-
for _ in range(12):
|
|
35
|
-
app.credit_account(account_id, Decimal("10.00"))
|
|
36
|
-
|
|
37
|
-
# Check the account is at version 13.
|
|
38
|
-
account = app.get_account(account_id)
|
|
39
|
-
self.assertEqual(account.version, 13)
|
|
40
|
-
|
|
41
|
-
# Check snapshots have been taken at regular intervals.
|
|
42
|
-
snapshots = list(app.snapshots.get(account_id))
|
|
43
|
-
self.assertEqual(len(snapshots), 2)
|
|
44
|
-
self.assertEqual(snapshots[0].originator_version, 5)
|
|
45
|
-
self.assertEqual(snapshots[1].originator_version, 10)
|
|
46
|
-
|
|
47
|
-
# Check another type of aggregate is not snapshotted.
|
|
48
|
-
aggregate = Aggregate()
|
|
49
|
-
for _ in range(10):
|
|
50
|
-
aggregate.trigger_event(Aggregate.Event)
|
|
51
|
-
app.save(aggregate)
|
|
52
|
-
|
|
53
|
-
# Check snapshots have not been taken at regular intervals.
|
|
54
|
-
snapshots = list(app.snapshots.get(aggregate.id))
|
|
55
|
-
self.assertEqual(len(snapshots), 0)
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
from eventsourcing.tests.application import (
|
|
2
|
-
TIMEIT_FACTOR,
|
|
3
|
-
ApplicationTestCase,
|
|
4
|
-
ExampleApplicationTestCase,
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class TestApplicationWithPOPO(ApplicationTestCase):
|
|
9
|
-
def test_application_fastforward_skipping_during_contention(self):
|
|
10
|
-
self.skipTest("POPO is too fast for this test to work")
|
|
11
|
-
|
|
12
|
-
def test_application_fastforward_blocking_during_contention(self):
|
|
13
|
-
self.skipTest("POPO is too fast for this test to make sense")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class TestExampleApplicationWithPOPO(ExampleApplicationTestCase):
|
|
17
|
-
timeit_number = 100 * TIMEIT_FACTOR
|
|
18
|
-
expected_factory_topic = "eventsourcing.popo:Factory"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
del ApplicationTestCase
|
|
22
|
-
del ExampleApplicationTestCase
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from unittest import TestCase
|
|
3
|
-
|
|
4
|
-
from eventsourcing.postgres import PostgresDatastore
|
|
5
|
-
from eventsourcing.tests.application import (
|
|
6
|
-
TIMEIT_FACTOR,
|
|
7
|
-
ApplicationTestCase,
|
|
8
|
-
ExampleApplicationTestCase,
|
|
9
|
-
)
|
|
10
|
-
from eventsourcing.tests.postgres_utils import drop_postgres_table
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class WithPostgres(TestCase):
|
|
14
|
-
timeit_number = 5 * TIMEIT_FACTOR
|
|
15
|
-
expected_factory_topic = "eventsourcing.postgres:Factory"
|
|
16
|
-
|
|
17
|
-
def setUp(self) -> None:
|
|
18
|
-
super().setUp()
|
|
19
|
-
|
|
20
|
-
os.environ["PERSISTENCE_MODULE"] = "eventsourcing.postgres"
|
|
21
|
-
os.environ["CREATE_TABLE"] = "y"
|
|
22
|
-
os.environ["POSTGRES_DBNAME"] = "eventsourcing"
|
|
23
|
-
os.environ["POSTGRES_HOST"] = "127.0.0.1"
|
|
24
|
-
os.environ["POSTGRES_PORT"] = "5432"
|
|
25
|
-
os.environ["POSTGRES_USER"] = "eventsourcing"
|
|
26
|
-
os.environ["POSTGRES_PASSWORD"] = "eventsourcing" # noqa: S105
|
|
27
|
-
os.environ["POSTGRES_SCHEMA"] = "public"
|
|
28
|
-
|
|
29
|
-
db = PostgresDatastore(
|
|
30
|
-
os.getenv("POSTGRES_DBNAME"),
|
|
31
|
-
os.getenv("POSTGRES_HOST"),
|
|
32
|
-
os.getenv("POSTGRES_PORT"),
|
|
33
|
-
os.getenv("POSTGRES_USER"),
|
|
34
|
-
os.getenv("POSTGRES_PASSWORD"),
|
|
35
|
-
)
|
|
36
|
-
drop_postgres_table(db, "public.bankaccounts_events")
|
|
37
|
-
drop_postgres_table(db, "public.bankaccounts_snapshots")
|
|
38
|
-
db.close()
|
|
39
|
-
|
|
40
|
-
def tearDown(self) -> None:
|
|
41
|
-
db = PostgresDatastore(
|
|
42
|
-
os.getenv("POSTGRES_DBNAME"),
|
|
43
|
-
os.getenv("POSTGRES_HOST"),
|
|
44
|
-
os.getenv("POSTGRES_PORT"),
|
|
45
|
-
os.getenv("POSTGRES_USER"),
|
|
46
|
-
os.getenv("POSTGRES_PASSWORD"),
|
|
47
|
-
)
|
|
48
|
-
drop_postgres_table(db, "public.bankaccounts_events")
|
|
49
|
-
drop_postgres_table(db, "public.bankaccounts_snapshots")
|
|
50
|
-
|
|
51
|
-
del os.environ["PERSISTENCE_MODULE"]
|
|
52
|
-
del os.environ["CREATE_TABLE"]
|
|
53
|
-
del os.environ["POSTGRES_DBNAME"]
|
|
54
|
-
del os.environ["POSTGRES_HOST"]
|
|
55
|
-
del os.environ["POSTGRES_PORT"]
|
|
56
|
-
del os.environ["POSTGRES_USER"]
|
|
57
|
-
del os.environ["POSTGRES_PASSWORD"]
|
|
58
|
-
del os.environ["POSTGRES_SCHEMA"]
|
|
59
|
-
db.close()
|
|
60
|
-
|
|
61
|
-
super().tearDown()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class TestApplicationWithPostgres(ApplicationTestCase, WithPostgres):
|
|
65
|
-
pass
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
class TestExampleApplicationWithPostgres(ExampleApplicationTestCase, WithPostgres):
|
|
69
|
-
timeit_number = 5 * TIMEIT_FACTOR
|
|
70
|
-
expected_factory_topic = "eventsourcing.postgres:Factory"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
del ApplicationTestCase
|
|
74
|
-
del ExampleApplicationTestCase
|
|
75
|
-
del WithPostgres
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from unittest import TestCase
|
|
3
|
-
|
|
4
|
-
from eventsourcing.tests.application import (
|
|
5
|
-
TIMEIT_FACTOR,
|
|
6
|
-
ApplicationTestCase,
|
|
7
|
-
ExampleApplicationTestCase,
|
|
8
|
-
)
|
|
9
|
-
from eventsourcing.tests.persistence import tmpfile_uris
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class WithSQLiteFile(TestCase):
|
|
13
|
-
timeit_number = 30 * TIMEIT_FACTOR
|
|
14
|
-
expected_factory_topic = "eventsourcing.sqlite:Factory"
|
|
15
|
-
|
|
16
|
-
def setUp(self) -> None:
|
|
17
|
-
super().setUp()
|
|
18
|
-
self.uris = tmpfile_uris()
|
|
19
|
-
# self.db_uri = next(self.uris)
|
|
20
|
-
|
|
21
|
-
os.environ["PERSISTENCE_MODULE"] = "eventsourcing.sqlite"
|
|
22
|
-
os.environ["CREATE_TABLE"] = "y"
|
|
23
|
-
os.environ["SQLITE_DBNAME"] = next(self.uris)
|
|
24
|
-
|
|
25
|
-
def tearDown(self) -> None:
|
|
26
|
-
del os.environ["PERSISTENCE_MODULE"]
|
|
27
|
-
del os.environ["CREATE_TABLE"]
|
|
28
|
-
del os.environ["SQLITE_DBNAME"]
|
|
29
|
-
super().tearDown()
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class WithSQLiteInMemory(TestCase):
|
|
33
|
-
timeit_number = 30 * TIMEIT_FACTOR
|
|
34
|
-
expected_factory_topic = "eventsourcing.sqlite:Factory"
|
|
35
|
-
|
|
36
|
-
def setUp(self) -> None:
|
|
37
|
-
super().setUp()
|
|
38
|
-
os.environ["PERSISTENCE_MODULE"] = "eventsourcing.sqlite"
|
|
39
|
-
os.environ["CREATE_TABLE"] = "y"
|
|
40
|
-
os.environ["SQLITE_DBNAME"] = "file:memory:?mode=memory&cache=shared"
|
|
41
|
-
|
|
42
|
-
def tearDown(self) -> None:
|
|
43
|
-
del os.environ["PERSISTENCE_MODULE"]
|
|
44
|
-
del os.environ["CREATE_TABLE"]
|
|
45
|
-
del os.environ["SQLITE_DBNAME"]
|
|
46
|
-
super().tearDown()
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class TestApplicationWithSQLiteFile(ApplicationTestCase, WithSQLiteFile):
|
|
50
|
-
pass
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
# class TestApplicationWithSQLiteInMemory(TestApplication, WithSQLiteInMemory):
|
|
54
|
-
# pass
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class TestExampleApplicationWithSQLiteFile(ExampleApplicationTestCase, WithSQLiteFile):
|
|
58
|
-
timeit_number = 30 * TIMEIT_FACTOR
|
|
59
|
-
expected_factory_topic = "eventsourcing.sqlite:Factory"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class TestExampleApplicationWithSQLiteInMemory(
|
|
63
|
-
ExampleApplicationTestCase, WithSQLiteInMemory
|
|
64
|
-
):
|
|
65
|
-
timeit_number = 30 * TIMEIT_FACTOR
|
|
66
|
-
expected_factory_topic = "eventsourcing.sqlite:Factory"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
del ApplicationTestCase
|
|
70
|
-
del ExampleApplicationTestCase
|
|
71
|
-
del WithSQLiteFile
|
|
72
|
-
del WithSQLiteInMemory
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
from unittest import TestCase
|
|
2
|
-
|
|
3
|
-
from eventsourcing.application import Cache, LRUCache
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class TestCache(TestCase):
|
|
7
|
-
def test_put_get(self):
|
|
8
|
-
cache = Cache()
|
|
9
|
-
|
|
10
|
-
with self.assertRaises(KeyError):
|
|
11
|
-
cache.get(1)
|
|
12
|
-
|
|
13
|
-
cache.put(1, 1)
|
|
14
|
-
self.assertEqual(cache.get(1), 1)
|
|
15
|
-
|
|
16
|
-
cache.put(2, 2)
|
|
17
|
-
self.assertEqual(1, cache.get(1))
|
|
18
|
-
self.assertEqual(2, cache.get(2))
|
|
19
|
-
|
|
20
|
-
cache.put(3, 3)
|
|
21
|
-
self.assertEqual(3, cache.get(3))
|
|
22
|
-
self.assertEqual(2, cache.get(2))
|
|
23
|
-
self.assertEqual(1, cache.get(1))
|
|
24
|
-
|
|
25
|
-
cache.put(1, 2)
|
|
26
|
-
self.assertEqual(2, cache.get(1))
|
|
27
|
-
cache.put(1, 3)
|
|
28
|
-
self.assertEqual(3, cache.get(1))
|
|
29
|
-
|
|
30
|
-
cache.get(1, evict=True)
|
|
31
|
-
with self.assertRaises(KeyError):
|
|
32
|
-
cache.get(1)
|
|
33
|
-
|
|
34
|
-
cache.put(1, None)
|
|
35
|
-
with self.assertRaises(KeyError):
|
|
36
|
-
cache.get(1)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class TestLRUCache(TestCase):
|
|
40
|
-
def test_put_get(self):
|
|
41
|
-
cache = LRUCache(maxsize=2)
|
|
42
|
-
|
|
43
|
-
with self.assertRaises(KeyError):
|
|
44
|
-
cache.get(1)
|
|
45
|
-
|
|
46
|
-
evicted = cache.put(1, 1)
|
|
47
|
-
self.assertEqual(evicted, (None, None))
|
|
48
|
-
self.assertEqual(cache.get(1), 1)
|
|
49
|
-
|
|
50
|
-
evicted = cache.put(2, 2)
|
|
51
|
-
self.assertEqual(evicted, (None, None))
|
|
52
|
-
self.assertEqual(1, cache.get(1))
|
|
53
|
-
self.assertEqual(2, cache.get(2))
|
|
54
|
-
|
|
55
|
-
evicted = cache.put(3, 3)
|
|
56
|
-
self.assertEqual(evicted, (1, 1))
|
|
57
|
-
|
|
58
|
-
self.assertEqual(3, cache.get(3))
|
|
59
|
-
self.assertEqual(2, cache.get(2))
|
|
60
|
-
|
|
61
|
-
cache.put(1, 1)
|
|
62
|
-
self.assertEqual(1, cache.get(1))
|
|
63
|
-
cache.put(1, 2)
|
|
64
|
-
self.assertEqual(2, cache.get(1))
|
|
65
|
-
cache.put(1, 3)
|
|
66
|
-
self.assertEqual(3, cache.get(1))
|
|
67
|
-
|
|
68
|
-
def test_put_get_evict_recent(self):
|
|
69
|
-
cache = LRUCache(maxsize=3)
|
|
70
|
-
|
|
71
|
-
cache.put(1, 1)
|
|
72
|
-
self.assertEqual(1, cache.get(1))
|
|
73
|
-
self.assertEqual(1, cache.get(1))
|
|
74
|
-
self.assertEqual(1, cache.get(1, evict=True))
|
|
75
|
-
|
|
76
|
-
with self.assertRaises(KeyError):
|
|
77
|
-
self.assertEqual(1, cache.get(1))
|
|
78
|
-
|
|
79
|
-
cache.put(1, 1)
|
|
80
|
-
cache.put(2, 2)
|
|
81
|
-
cache.put(3, 3)
|
|
82
|
-
evicted = cache.put(4, 4)
|
|
83
|
-
self.assertEqual(evicted, (1, 1))
|
|
84
|
-
|
|
85
|
-
self.assertEqual(3, cache.get(3, evict=True))
|
|
86
|
-
|
|
87
|
-
evicted = cache.put(5, 5)
|
|
88
|
-
self.assertEqual(evicted, (None, None))
|
|
89
|
-
|
|
90
|
-
evicted = cache.put(6, 6)
|
|
91
|
-
self.assertEqual(evicted, (2, 2))
|
|
92
|
-
|
|
93
|
-
evicted = cache.put(7, 7)
|
|
94
|
-
self.assertEqual(evicted, (4, 4))
|
|
95
|
-
|
|
96
|
-
def test_put_get_evict_oldest(self):
|
|
97
|
-
cache = LRUCache(maxsize=3)
|
|
98
|
-
|
|
99
|
-
cache.put(1, 1)
|
|
100
|
-
cache.put(2, 2)
|
|
101
|
-
cache.put(3, 3)
|
|
102
|
-
self.assertEqual(1, cache.get(1, evict=True))
|
|
103
|
-
|
|
104
|
-
evicted = cache.put(4, 4)
|
|
105
|
-
self.assertEqual(evicted, (None, None))
|
|
106
|
-
|
|
107
|
-
evicted = cache.put(5, 5)
|
|
108
|
-
self.assertEqual(evicted, (2, 2))
|
|
109
|
-
|
|
110
|
-
evicted = cache.put(6, 6)
|
|
111
|
-
self.assertEqual(evicted, (3, 3))
|
|
112
|
-
|
|
113
|
-
evicted = cache.put(7, 7)
|
|
114
|
-
self.assertEqual(evicted, (4, 4))
|
|
115
|
-
|
|
116
|
-
def test_put_get_evict_newest(self):
|
|
117
|
-
cache = LRUCache(maxsize=3)
|
|
118
|
-
|
|
119
|
-
cache.put(1, 1)
|
|
120
|
-
cache.put(2, 2)
|
|
121
|
-
cache.put(3, 3)
|
|
122
|
-
self.assertEqual(3, cache.get(3, evict=True))
|
|
123
|
-
|
|
124
|
-
evicted = cache.put(4, 4)
|
|
125
|
-
self.assertEqual(evicted, (None, None))
|
|
126
|
-
|
|
127
|
-
evicted = cache.put(5, 5)
|
|
128
|
-
self.assertEqual(evicted, (1, 1))
|
|
129
|
-
|
|
130
|
-
evicted = cache.put(6, 6)
|
|
131
|
-
self.assertEqual(evicted, (2, 2))
|
|
132
|
-
|
|
133
|
-
evicted = cache.put(7, 7)
|
|
134
|
-
self.assertEqual(evicted, (4, 4))
|