mirror of
https://github.com/Blockstream/satellite-api.git
synced 2025-02-23 14:00:26 +01:00
- Preserve the SQLite database and use SQLAlchemy to wrap db interactions. - Use Alembic for database migrations. - Organize all the python modules on the new server/ directory. - Use pytest for unit tests and organize test modules at server/tests/.
143 lines
5 KiB
Python
143 lines
5 KiB
Python
from datetime import datetime, timedelta
|
|
import os
|
|
import pytest
|
|
from unittest.mock import patch
|
|
|
|
from common import generate_test_order
|
|
from constants import InvoiceStatus, OrderStatus
|
|
import daemon
|
|
from database import db
|
|
from models import Order, Invoice
|
|
from invoice_helpers import pay_invoice
|
|
import constants
|
|
import server
|
|
|
|
|
|
@pytest.fixture
|
|
def tx_engine(mocker):
|
|
tx_engine = daemon.TxEngine()
|
|
yield tx_engine
|
|
|
|
|
|
@pytest.fixture
|
|
def mockredis(mocker):
|
|
_mr = mocker.Mock(name="mockredis")
|
|
mocker.patch("transmitter.redis", return_value=_mr)
|
|
mocker.patch("transmitter.redis.from_url", return_value=_mr)
|
|
return _mr
|
|
|
|
|
|
@pytest.fixture
|
|
def client(mockredis):
|
|
app = server.create_app(from_test=True)
|
|
app.app_context().push()
|
|
with app.test_client() as client:
|
|
yield client
|
|
server.teardown_app(app)
|
|
|
|
|
|
@pytest.fixture
|
|
def daemon_app():
|
|
app = daemon.create_app()
|
|
yield app
|
|
|
|
|
|
@patch('orders.new_invoice')
|
|
def test_tx_engine(mock_new_invoice, client, tx_engine):
|
|
# prepare test env
|
|
|
|
# create an old transmitted order
|
|
completed_order_uuid = generate_test_order(
|
|
mock_new_invoice,
|
|
client,
|
|
invoice_status=InvoiceStatus.paid,
|
|
order_status=OrderStatus.transmitting)['uuid']
|
|
|
|
# create two sendable orders
|
|
first_sendable_order_uuid = generate_test_order(mock_new_invoice,
|
|
client,
|
|
order_id=5,
|
|
bid=1000)['uuid']
|
|
first_sendable_db_order = \
|
|
Order.query.filter_by(uuid=first_sendable_order_uuid).first()
|
|
pay_invoice(first_sendable_db_order.invoices[0])
|
|
db.session.commit()
|
|
|
|
second_sendable_order_uuid = generate_test_order(mock_new_invoice,
|
|
client,
|
|
order_id=6,
|
|
bid=2000)['uuid']
|
|
second_sendable_db_order = \
|
|
Order.query.filter_by(uuid=second_sendable_order_uuid).first()
|
|
pay_invoice(second_sendable_db_order.invoices[0])
|
|
db.session.commit()
|
|
|
|
tx_engine.start(2)
|
|
|
|
completed_db_order = \
|
|
Order.query.filter_by(uuid=completed_order_uuid).first()
|
|
assert completed_db_order.status == OrderStatus.sent.value
|
|
assert completed_db_order.ended_transmission_at is not None
|
|
|
|
first_sendable_db_order = \
|
|
Order.query.filter_by(uuid=first_sendable_order_uuid).first()
|
|
second_sendable_db_order = \
|
|
Order.query.filter_by(uuid=second_sendable_order_uuid).first()
|
|
assert first_sendable_db_order.status == constants.OrderStatus.sent.value
|
|
assert second_sendable_db_order.status == constants.OrderStatus.sent.value
|
|
# The second order has a higher bid_per_byte, so it should be sent first
|
|
assert first_sendable_db_order.tx_seq_num == 2
|
|
assert second_sendable_db_order.tx_seq_num == 1
|
|
assert second_sendable_db_order.ended_transmission_at \
|
|
< first_sendable_db_order.ended_transmission_at
|
|
|
|
|
|
@patch('orders.new_invoice')
|
|
def test_cleanup_database(mock_new_invoice, client, tx_engine, daemon_app):
|
|
# prepare test env
|
|
|
|
# create an invoice that must get expired
|
|
pending_invoice_lid = generate_test_order(
|
|
mock_new_invoice, client, order_id=2)['lightning_invoice']['id']
|
|
pending_db_invoice = \
|
|
Invoice.query.filter_by(lid=pending_invoice_lid).first()
|
|
pending_db_invoice.expires_at = datetime.utcnow() - timedelta(days=1)
|
|
db.session.commit()
|
|
|
|
# create an order that must get expired
|
|
pending_order_uuid = generate_test_order(mock_new_invoice,
|
|
client,
|
|
order_id=3)['uuid']
|
|
pending_db_order = Order.query.filter_by(uuid=pending_order_uuid).first()
|
|
pending_db_order.created_at = datetime.utcnow() - \
|
|
timedelta(days=constants.EXPIRE_PENDING_ORDERS_AFTER_DAYS
|
|
+ 1)
|
|
db.session.commit()
|
|
|
|
# Create an order whose transmission ended a long time ago. The
|
|
# corresponding message file should be deleted.
|
|
sent_order_uuid = generate_test_order(
|
|
mock_new_invoice,
|
|
client,
|
|
order_id=4,
|
|
invoice_status=InvoiceStatus.paid)['uuid']
|
|
sent_db_order = Order.query.filter_by(uuid=sent_order_uuid).first()
|
|
sent_db_order.ended_transmission_at = datetime.utcnow() -\
|
|
timedelta(days=constants.MESSAGE_FILE_RETENTION_TIME_DAYS
|
|
+ 1)
|
|
db.session.commit()
|
|
|
|
daemon.cleanup_database(daemon_app)
|
|
|
|
pending_db_invoice = \
|
|
Invoice.query.filter_by(lid=pending_invoice_lid).first()
|
|
assert pending_db_invoice.status == InvoiceStatus.expired.value
|
|
|
|
pending_db_order = Order.query.filter_by(uuid=pending_order_uuid).first()
|
|
assert pending_db_order.status == OrderStatus.expired.value
|
|
|
|
message_path = os.path.join(constants.MSG_STORE_PATH, pending_order_uuid)
|
|
assert not os.path.exists(message_path)
|
|
|
|
message_path = os.path.join(constants.MSG_STORE_PATH, sent_order_uuid)
|
|
assert not os.path.exists(message_path)
|