Skip to content

Commit

Permalink
skip on github?
Browse files Browse the repository at this point in the history
  • Loading branch information
callebtc committed Nov 5, 2024
1 parent bae748d commit a1deda8
Showing 1 changed file with 128 additions and 104 deletions.
232 changes: 128 additions & 104 deletions tests/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ async def get_connection():


@pytest.mark.asyncio
@pytest.mark.skipif(
is_github_actions and not is_postgres,
reason=(
"Fails on GitHub Actions for some inexplicable reason, but only for SQLite"
),
)
async def test_db_verify_spent_proofs_and_set_pending_race_condition(
wallet: Wallet, ledger: Ledger
):
Expand All @@ -211,107 +217,125 @@ async def test_db_verify_spent_proofs_and_set_pending_race_condition(
)


# @pytest.mark.asyncio
# async def test_db_verify_spent_proofs_and_set_pending_delayed_no_race_condition(
# wallet: Wallet, ledger: Ledger
# ):
# # fill wallet
# mint_quote = await wallet.request_mint(64)
# await pay_if_regtest(mint_quote.request)
# await wallet.mint(64, quote_id=mint_quote.quote)
# assert wallet.balance == 64

# async def delayed_verify_spent_proofs_and_set_pending():
# await asyncio.sleep(0.1)
# await ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs)

# await assert_err(
# asyncio.gather(
# ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs),
# delayed_verify_spent_proofs_and_set_pending(),
# ),
# "proofs are pending",
# )


# @pytest.mark.asyncio
# async def test_db_verify_spent_proofs_and_set_pending_no_race_condition_different_proofs(
# wallet: Wallet, ledger: Ledger
# ):
# # fill wallet
# mint_quote = await wallet.request_mint(64)
# await pay_if_regtest(mint_quote.request)
# await wallet.mint(64, quote_id=mint_quote.quote, split=[32, 32])
# assert wallet.balance == 64
# assert len(wallet.proofs) == 2

# asyncio.gather(
# ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs[:1]),
# ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs[1:]),
# )


# @pytest.mark.asyncio
# @pytest.mark.skipif(
# not settings.mint_database.startswith("postgres"),
# reason="SQLite does not support row locking",
# )
# async def test_db_get_connection_lock_different_row(wallet: Wallet, ledger: Ledger):
# if ledger.db.type == db.SQLITE:
# pytest.skip("SQLite does not support row locking")
# # this should work since we lock two different rows
# mint_quote = await wallet.request_mint(64)
# mint_quote_2 = await wallet.request_mint(64)

# async def get_connection2():
# """This code makes sure that only the error of the second connection is raised (which we check in the assert_err)"""
# try:
# async with ledger.db.get_connection(
# lock_table="mint_quotes",
# lock_select_statement=f"quote='{mint_quote.quote}'",
# lock_timeout=0.1,
# ):
# try:
# async with ledger.db.get_connection(
# lock_table="mint_quotes",
# lock_select_statement=f"quote='{mint_quote_2.quote}'",
# lock_timeout=0.1,
# ) as conn2:
# # write something with conn1, this time we should reach this block with postgres
# quote = await ledger.crud.get_mint_quote(
# quote_id=mint_quote_2.quote, db=ledger.db, conn=conn2
# )
# assert quote is not None
# quote.amount = 100
# await ledger.crud.update_mint_quote(
# quote=quote, db=ledger.db, conn=conn2
# )

# except Exception as exc:
# # this is expected to raise
# raise Exception(f"conn2: {exc}")

# except Exception as exc:
# if "conn2" in str(exc):
# raise exc
# else:
# raise Exception(f"not expected to happen: {exc}")

# await get_connection2()


# @pytest.mark.asyncio
# async def test_db_lock_table(wallet: Wallet, ledger: Ledger):
# # fill wallet
# mint_quote = await wallet.request_mint(64)
# await pay_if_regtest(mint_quote.request)

# await wallet.mint(64, quote_id=mint_quote.quote)
# assert wallet.balance == 64

# async with ledger.db.connect(lock_table="proofs_pending", lock_timeout=0.1) as conn:
# assert isinstance(conn, Connection)
# await assert_err(
# ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs),
# "failed to acquire database lock",
# )
@pytest.mark.asyncio
@pytest.mark.skipif(
is_github_actions and not is_postgres,
reason=(
"Fails on GitHub Actions for some inexplicable reason, but only for SQLite"
),
)
async def test_db_verify_spent_proofs_and_set_pending_delayed_no_race_condition(
wallet: Wallet, ledger: Ledger
):
# fill wallet
mint_quote = await wallet.request_mint(64)
await pay_if_regtest(mint_quote.request)
await wallet.mint(64, quote_id=mint_quote.quote)
assert wallet.balance == 64

async def delayed_verify_spent_proofs_and_set_pending():
await asyncio.sleep(0.1)
await ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs)

await assert_err(
asyncio.gather(
ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs),
delayed_verify_spent_proofs_and_set_pending(),
),
"proofs are pending",
)


@pytest.mark.asyncio
@pytest.mark.skipif(
is_github_actions and not is_postgres,
reason=(
"Fails on GitHub Actions for some inexplicable reason, but only for SQLite"
),
)
async def test_db_verify_spent_proofs_and_set_pending_no_race_condition_different_proofs(
wallet: Wallet, ledger: Ledger
):
# fill wallet
mint_quote = await wallet.request_mint(64)
await pay_if_regtest(mint_quote.request)
await wallet.mint(64, quote_id=mint_quote.quote, split=[32, 32])
assert wallet.balance == 64
assert len(wallet.proofs) == 2

asyncio.gather(
ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs[:1]),
ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs[1:]),
)


@pytest.mark.asyncio
@pytest.mark.skipif(
not settings.mint_database.startswith("postgres"),
reason="SQLite does not support row locking",
)
async def test_db_get_connection_lock_different_row(wallet: Wallet, ledger: Ledger):
if ledger.db.type == db.SQLITE:
pytest.skip("SQLite does not support row locking")
# this should work since we lock two different rows
mint_quote = await wallet.request_mint(64)
mint_quote_2 = await wallet.request_mint(64)

async def get_connection2():
"""This code makes sure that only the error of the second connection is raised (which we check in the assert_err)"""
try:
async with ledger.db.get_connection(
lock_table="mint_quotes",
lock_select_statement=f"quote='{mint_quote.quote}'",
lock_timeout=0.1,
):
try:
async with ledger.db.get_connection(
lock_table="mint_quotes",
lock_select_statement=f"quote='{mint_quote_2.quote}'",
lock_timeout=0.1,
) as conn2:
# write something with conn1, this time we should reach this block with postgres
quote = await ledger.crud.get_mint_quote(
quote_id=mint_quote_2.quote, db=ledger.db, conn=conn2
)
assert quote is not None
quote.amount = 100
await ledger.crud.update_mint_quote(
quote=quote, db=ledger.db, conn=conn2
)

except Exception as exc:
# this is expected to raise
raise Exception(f"conn2: {exc}")

except Exception as exc:
if "conn2" in str(exc):
raise exc
else:
raise Exception(f"not expected to happen: {exc}")

await get_connection2()


@pytest.mark.asyncio
@pytest.mark.skipif(
is_github_actions and not is_postgres,
reason=(
"Fails on GitHub Actions for some inexplicable reason, but only for SQLite"
),
)
async def test_db_lock_table(wallet: Wallet, ledger: Ledger):
# fill wallet
mint_quote = await wallet.request_mint(64)
await pay_if_regtest(mint_quote.request)

await wallet.mint(64, quote_id=mint_quote.quote)
assert wallet.balance == 64

async with ledger.db.connect(lock_table="proofs_pending", lock_timeout=0.1) as conn:
assert isinstance(conn, Connection)
await assert_err(
ledger.db_write._verify_spent_proofs_and_set_pending(wallet.proofs),
"failed to acquire database lock",
)

0 comments on commit a1deda8

Please sign in to comment.