def bus(sqlite_session_factory): return messagebus.MessageBus( uow=unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory), notifications=notifications.EmailNotifications( smtp_host=cfg['host'], port=cfg['port'], ), publish=lambda *_, **__: None)
def test_rolls_back_uncommitted_work_by_default(sqlite_session_factory): uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) with uow: insert_batch(uow.session, 'batch1', 'MEDIUM-PLINTH', 100, None) new_session = sqlite_session_factory() rows = list(new_session.execute('SELECT * FROM "batches"')) assert rows == []
def get_bus(): uow = unit_of_work.SqlAlchemyUnitOfWork() bus = messagebus.MessageBus( uow=uow, notifications=notifications.EmailNotifications(), publish=publish) uow.set_bus(bus) return bus
def sqlite_bus(sqlite_session_factory): uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) bus = messagebus.MessageBus( uow=uow, notifications=mock.Mock(), publish=mock.Mock(), ) uow.set_bus(bus) return bus
def try_to_allocate(orderid, sku, exceptions, session_factory): line = model.OrderLine(orderid, sku, 10) try: with unit_of_work.SqlAlchemyUnitOfWork(session_factory) as uow: product = uow.products.get(sku=sku) product.allocate(line) time.sleep(0.2) uow.commit() except Exception as e: # pylint: disable=broad-except print(traceback.format_exc()) exceptions.append(e)
def test_rolls_back_on_error(sqlite_session_factory): class MyException(Exception): pass uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) with pytest.raises(MyException): with uow: insert_batch(uow.session, 'batch1', 'LARGE-FORK', 100, None) raise MyException() new_session = sqlite_session_factory() rows = list(new_session.execute('SELECT * FROM "batches"')) assert rows == []
def test_uow_can_retrieve_a_batch_and_allocate_to_it(sqlite_session_factory): session = sqlite_session_factory() insert_batch(session, 'batch1', 'HIPSTER-WORKBENCH', 100, None) session.commit() uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) with uow: product = uow.products.get(sku='HIPSTER-WORKBENCH') line = model.OrderLine('o1', 'HIPSTER-WORKBENCH', 10) product.allocate(line) uow.commit() batchref = get_allocated_batch_ref(session, 'o1', 'HIPSTER-WORKBENCH') assert batchref == 'batch1'
def test_concurrent_updates_to_version_are_not_allowed( postgres_session_factory): sku, batch = random_ref('s'), random_ref('b') session = postgres_session_factory() insert_batch(session, batch, sku, 100, eta=None, product_version=3) session.commit() exceptions = [] # type: List[Exception] o1, o2 = random_ref('o1'), random_ref('o2') target1 = lambda: try_to_allocate(o1, sku, exceptions, postgres_session_factory) target2 = lambda: try_to_allocate(o2, sku, exceptions, postgres_session_factory) t1 = threading.Thread(target=target1) t2 = threading.Thread(target=target2) t1.start() t2.start() t1.join() t2.join() [[version]] = session.execute( "SELECT version_number FROM products WHERE sku=:sku", dict(sku=sku), ) assert version == 4 exception = [exceptions] assert 'could not serialize access due to concurrent update' in str( exception) orders = list( session.execute( "SELECT orderid FROM allocations" " JOIN batches ON allocations.batch_id = batches.id" " JOIN order_lines ON allocations.orderline_id = order_lines.id" " WHERE order_lines.sku=:sku", dict(sku=sku), )) assert len(orders) == 1 with unit_of_work.SqlAlchemyUnitOfWork(postgres_session_factory) as uow: uow.session.execute('select 1')
from datetime import datetime from flask import Flask, jsonify, request from allocation import ( commands, exceptions, messagebus, notifications, orm, redis_pubsub, unit_of_work, views, ) app = Flask(__name__) orm.start_mappers() bus = messagebus.MessageBus(uow=unit_of_work.SqlAlchemyUnitOfWork(), notifications=notifications.EmailNotifications(), publish=redis_pubsub.publish) @app.route("/add_batch", methods=['POST']) def add_batch(): eta = request.json['eta'] if eta is not None: eta = datetime.fromisoformat(eta).date() command = commands.CreateBatch( request.json['ref'], request.json['sku'], request.json['qty'], eta, )
def get_bus(): return messagebus.MessageBus(uow=unit_of_work.SqlAlchemyUnitOfWork(), send_mail=email.send, publish=publish)
def get_bus(): return messagebus.MessageBus( uow=unit_of_work.SqlAlchemyUnitOfWork(), notifications=notifications.EmailNotifications(), publish=publish)
from datetime import datetime from flask import Flask, jsonify, request from allocation import ( commands, exceptions, messagebus, notifications, orm, redis_pubsub, unit_of_work, views, ) app = Flask(__name__) orm.start_mappers() uow = unit_of_work.SqlAlchemyUnitOfWork() bus = messagebus.MessageBus(uow=uow, notifications=notifications.EmailNotifications(), publish=redis_pubsub.publish) uow.bus = bus @app.route("/add_batch", methods=['POST']) def add_batch(): eta = request.json['eta'] if eta is not None: eta = datetime.fromisoformat(eta).date() cmd = commands.CreateBatch( request.json['ref'], request.json['sku'], request.json['qty'],
def sqlite_bus(sqlite_session_factory): return messagebus.MessageBus( uow=unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory), send_mail=mock.Mock(), publish=mock.Mock(), )