[FEAT] Improve tests (#296)

* test cli arent async tests

* unused SERVER_ENDPOINT var

* async test werent marked async

* make test didnt use correct ports

* enable more verbose test logging

* refactor conftest variable

* not needed anymore are set in conftest

* using test_data now for conftest

* formatting

* comment out invalid hex

* remove test dir before creating it to be sure

* keep data from altest testrun and ad test_data to ignore

* ignore error for CI

* add duplicate env var

* fix confest

* Update pyproject.toml

* fix up tests

* short p2pk locktimes for faster tests

---------

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
This commit is contained in:
dni ⚡
2023-08-06 18:35:34 +02:00
committed by GitHub
parent ca2b8e7bd6
commit 0a5beb75a2
11 changed files with 85 additions and 97 deletions

View File

@@ -16,42 +16,36 @@ from cashu.lightning.fake import FakeWallet
from cashu.mint import migrations as migrations_mint
from cashu.mint.ledger import Ledger
SERVER_ENDPOINT = "http://localhost:3337"
SERVER_PORT = 3337
SERVER_ENDPOINT = f"http://localhost:{SERVER_PORT}"
settings.cashu_dir = "./test_data/"
settings.mint_host = "localhost"
settings.mint_port = SERVER_PORT
settings.mint_host = "0.0.0.0"
settings.mint_listen_port = SERVER_PORT
settings.mint_url = SERVER_ENDPOINT
settings.lightning = False
settings.tor = False
settings.mint_lightning_backend = "FakeWallet"
settings.mint_database = "./test_data/test_mint"
settings.mint_derivation_path = "0/0/0/0"
settings.mint_private_key = "TEST_PRIVATE_KEY"
shutil.rmtree(settings.cashu_dir, ignore_errors=True)
Path(settings.cashu_dir).mkdir(parents=True, exist_ok=True)
class UvicornServer(multiprocessing.Process):
def __init__(self, config: Config, private_key: str = "TEST_PRIVATE_KEY"):
def __init__(self, config: Config):
super().__init__()
self.server = Server(config=config)
self.config = config
self.private_key = private_key
def stop(self):
self.terminate()
def run(self, *args, **kwargs):
settings.lightning = False
settings.mint_lightning_backend = "FakeWallet"
settings.mint_database = "data/test_mint"
settings.mint_private_key = self.private_key
settings.mint_derivation_path = "0/0/0/0"
dirpath = Path(settings.mint_database)
if dirpath.exists() and dirpath.is_dir():
shutil.rmtree(dirpath)
dirpath = Path("data/wallet1")
if dirpath.exists() and dirpath.is_dir():
shutil.rmtree(dirpath)
dirpath = Path("data/wallet2")
if dirpath.exists() and dirpath.is_dir():
shutil.rmtree(dirpath)
dirpath = Path("data/wallet3")
if dirpath.exists() and dirpath.is_dir():
shutil.rmtree(dirpath)
self.server.run()
@@ -62,13 +56,13 @@ async def ledger():
await ledger.load_used_proofs()
await ledger.init_keysets()
db_file = "data/mint/test.sqlite3"
db_file = "test_data/mint/test.sqlite3"
if os.path.exists(db_file):
os.remove(db_file)
ledger = Ledger(
db=Database("test", "data/mint"),
seed="TEST_PRIVATE_KEY",
derivation_path="0/0/0/0",
db=Database("test", "test_data/mint"),
seed=settings.mint_private_key,
derivation_path=settings.mint_derivation_path,
lightning=FakeWallet(),
)
await start_mint_init(ledger)
@@ -77,12 +71,10 @@ async def ledger():
@pytest.fixture(autouse=True, scope="session")
def mint():
settings.mint_listen_port = 3337
settings.mint_url = "http://localhost:3337"
config = uvicorn.Config(
"cashu.mint.app:app",
port=settings.mint_listen_port,
host="127.0.0.1",
host=settings.mint_listen_host,
)
server = UvicornServer(config=config)

View File

@@ -16,14 +16,13 @@ def cli_prefix():
async def init_wallet():
wallet = await Wallet.with_db(
url=settings.mint_host,
db="data/test_cli_wallet",
db="test_data/test_cli_wallet",
name="wallet",
)
await wallet.load_proofs()
return wallet
@pytest.mark.asyncio
def test_info(cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -37,7 +36,6 @@ def test_info(cli_prefix):
assert result.exit_code == 0
@pytest.mark.asyncio
def test_info_with_mint(cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -51,7 +49,6 @@ def test_info_with_mint(cli_prefix):
assert result.exit_code == 0
@pytest.mark.asyncio
def test_info_with_mnemonic(cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -65,7 +62,6 @@ def test_info_with_mnemonic(cli_prefix):
assert result.exit_code == 0
@pytest.mark.asyncio
def test_balance(cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -80,7 +76,6 @@ def test_balance(cli_prefix):
assert result.exit_code == 0
@pytest.mark.asyncio
def test_invoice(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -96,7 +91,6 @@ def test_invoice(mint, cli_prefix):
assert result.exit_code == 0
@pytest.mark.asyncio
def test_invoice_with_split(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -108,7 +102,6 @@ def test_invoice_with_split(mint, cli_prefix):
# assert wallet.proof_amounts.count(1) >= 10
@pytest.mark.asyncio
def test_wallets(cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -123,7 +116,6 @@ def test_wallets(cli_prefix):
assert result.exit_code == 0
@pytest.mark.asyncio
def test_send(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -136,7 +128,6 @@ def test_send(mint, cli_prefix):
assert "cashuA" in result.output, "output does not have a token"
@pytest.mark.asyncio
def test_send_without_split(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -149,7 +140,6 @@ def test_send_without_split(mint, cli_prefix):
assert "cashuA" in result.output, "output does not have a token"
@pytest.mark.asyncio
def test_send_without_split_but_wrong_amount(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(
@@ -159,7 +149,6 @@ def test_send_without_split_but_wrong_amount(mint, cli_prefix):
assert "No proof with this amount found" in str(result.exception)
@pytest.mark.asyncio
def test_receive_tokenv3(mint, cli_prefix):
runner = CliRunner()
token = (
@@ -181,10 +170,10 @@ def test_receive_tokenv3(mint, cli_prefix):
print(result.output)
@pytest.mark.asyncio
def test_receive_tokenv3_no_mint(mint, cli_prefix):
# this test works only if the previous test succeeds because we simulate the case where the mint URL is not in the token
# therefore, we need to know the mint keyset already and have the mint URL in the db
# this test works only if the previous test succeeds because we simulate the case
# where the mint URL is not in the token therefore, we need to know the mint keyset
# already and have the mint URL in the db
runner = CliRunner()
token = (
"cashuAeyJ0b2tlbiI6IFt7InByb29mcyI6IFt7ImlkIjogIjFjQ05JQVoyWC93MSIsICJhbW91bnQiOiAyLCAic2VjcmV0IjogIi1oM0ZXMFFoX1FYLW9ac1V2c0RuNlEiLC"
@@ -205,7 +194,6 @@ def test_receive_tokenv3_no_mint(mint, cli_prefix):
print(result.output)
@pytest.mark.asyncio
def test_receive_tokenv2(mint, cli_prefix):
runner = CliRunner()
token = (
@@ -223,7 +211,6 @@ def test_receive_tokenv2(mint, cli_prefix):
print(result.output)
@pytest.mark.asyncio
def test_receive_tokenv1(mint, cli_prefix):
runner = CliRunner()
token = (
@@ -240,7 +227,6 @@ def test_receive_tokenv1(mint, cli_prefix):
print(result.output)
@pytest.mark.asyncio()
def test_nostr_send(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(

View File

@@ -8,8 +8,6 @@ from cashu.core.helpers import calculate_number_of_blank_outputs
from cashu.core.settings import settings
from cashu.mint.ledger import Ledger
SERVER_ENDPOINT = "http://localhost:3338"
async def assert_err(f, msg):
"""Compute f() and expect an error message 'msg'."""

View File

@@ -50,7 +50,7 @@ async def reset_wallet_db(wallet: Wallet):
async def wallet1(mint):
wallet1 = await Wallet1.with_db(
url=SERVER_ENDPOINT,
db="data/wallet1",
db="test_data/wallet1",
name="wallet1",
)
await wallet1.load_mint()
@@ -62,7 +62,7 @@ async def wallet1(mint):
async def wallet2(mint):
wallet2 = await Wallet2.with_db(
url=SERVER_ENDPOINT,
db="data/wallet2",
db="test_data/wallet2",
name="wallet2",
)
await wallet2.load_mint()
@@ -72,13 +72,13 @@ async def wallet2(mint):
@pytest_asyncio.fixture(scope="function")
async def wallet3(mint):
dirpath = Path("data/wallet3")
dirpath = Path("test_data/wallet3")
if dirpath.exists() and dirpath.is_dir():
shutil.rmtree(dirpath)
wallet3 = await Wallet1.with_db(
url=SERVER_ENDPOINT,
db="data/wallet3",
db="test_data/wallet3",
name="wallet3",
)
await wallet3.db.execute("DELETE FROM proofs")
@@ -313,6 +313,7 @@ async def test_p2sh_receive_with_wrong_wallet(wallet1: Wallet, wallet2: Wallet):
await assert_err(wallet2.redeem(send_proofs), "lock not found.") # wrong receiver
@pytest.mark.asyncio
async def test_token_state(wallet1: Wallet):
await wallet1.mint(64)
assert wallet1.balance == 64
@@ -321,6 +322,7 @@ async def test_token_state(wallet1: Wallet):
assert resp.dict()["pending"]
@pytest.mark.asyncio
async def test_bump_secret_derivation(wallet3: Wallet):
await wallet3._init_private_key(
"half depart obvious quality work element tank gorilla view sugar picture humble"

View File

@@ -12,8 +12,8 @@ from tests.conftest import SERVER_ENDPOINT
async def wallet(mint):
wallet = await Wallet.with_db(
url=SERVER_ENDPOINT,
db="data/test_wallet_api",
name="wallet_api",
db="test_data/wallet",
name="wallet",
)
await wallet.load_mint()
wallet.status()
@@ -89,7 +89,7 @@ async def test_receive_all(wallet: Wallet):
with TestClient(app) as client:
response = client.post("/receive?all=true")
assert response.status_code == 200
assert response.json()["initial_balance"]
assert response.json()["initial_balance"] == 0
assert response.json()["balance"]
@@ -100,7 +100,7 @@ async def test_burn_all(wallet: Wallet):
assert response.status_code == 200
response = client.post("/burn?all=true")
assert response.status_code == 200
assert response.json()["balance"]
assert response.json()["balance"] == 0
@pytest.mark.asyncio

View File

@@ -34,7 +34,9 @@ def assert_amt(proofs: List[Proof], expected: int):
@pytest_asyncio.fixture(scope="function")
async def wallet1(mint):
wallet1 = await Wallet1.with_db(SERVER_ENDPOINT, "data/wallet_p2pk_1", "wallet1")
wallet1 = await Wallet1.with_db(
SERVER_ENDPOINT, "test_data/wallet_p2pk_1", "wallet1"
)
await migrate_databases(wallet1.db, migrations)
await wallet1.load_mint()
wallet1.status()
@@ -43,7 +45,9 @@ async def wallet1(mint):
@pytest_asyncio.fixture(scope="function")
async def wallet2(mint):
wallet2 = await Wallet2.with_db(SERVER_ENDPOINT, "data/wallet_p2pk_2", "wallet2")
wallet2 = await Wallet2.with_db(
SERVER_ENDPOINT, "test_data/wallet_p2pk_2", "wallet2"
)
await migrate_databases(wallet2.db, migrations)
wallet2.private_key = PrivateKey(secrets.token_bytes(32), raw=True)
await wallet2.load_mint()
@@ -95,7 +99,7 @@ async def test_p2pk_short_locktime_receive_with_wrong_private_key(
pubkey_wallet2 = await wallet2.create_p2pk_pubkey() # receiver side
# sender side
secret_lock = await wallet1.create_p2pk_lock(
pubkey_wallet2, locktime_seconds=4
pubkey_wallet2, locktime_seconds=2
) # sender side
_, send_proofs = await wallet1.split_to_send(
wallet1.proofs, 8, secret_lock=secret_lock
@@ -107,7 +111,7 @@ async def test_p2pk_short_locktime_receive_with_wrong_private_key(
wallet2.redeem(send_proofs),
"Mint Error: no valid signature provided for input.",
)
await asyncio.sleep(6)
await asyncio.sleep(2)
# should succeed because even with the wrong private key we
# can redeem the tokens after the locktime
await wallet2.redeem(send_proofs_copy)
@@ -122,7 +126,7 @@ async def test_p2pk_locktime_with_refund_pubkey(wallet1: Wallet, wallet2: Wallet
assert garbage_pubkey
secret_lock = await wallet1.create_p2pk_lock(
garbage_pubkey.serialize().hex(), # create lock to unspendable pubkey
locktime_seconds=4, # locktime
locktime_seconds=2, # locktime
tags=Tags([["refund", pubkey_wallet2]]), # refund pubkey
) # sender side
_, send_proofs = await wallet1.split_to_send(
@@ -134,7 +138,7 @@ async def test_p2pk_locktime_with_refund_pubkey(wallet1: Wallet, wallet2: Wallet
wallet2.redeem(send_proofs),
"Mint Error: no valid signature provided for input.",
)
await asyncio.sleep(6)
await asyncio.sleep(2)
# we can now redeem because of the refund locktime
await wallet2.redeem(send_proofs_copy)
@@ -150,7 +154,7 @@ async def test_p2pk_locktime_with_wrong_refund_pubkey(wallet1: Wallet, wallet2:
assert garbage_pubkey_2
secret_lock = await wallet1.create_p2pk_lock(
garbage_pubkey.serialize().hex(), # create lock to unspendable pubkey
locktime_seconds=4, # locktime
locktime_seconds=2, # locktime
tags=Tags([["refund", garbage_pubkey_2.serialize().hex()]]), # refund pubkey
) # sender side
_, send_proofs = await wallet1.split_to_send(
@@ -162,7 +166,7 @@ async def test_p2pk_locktime_with_wrong_refund_pubkey(wallet1: Wallet, wallet2:
wallet2.redeem(send_proofs),
"Mint Error: no valid signature provided for input.",
)
await asyncio.sleep(6)
await asyncio.sleep(2)
# we still can't redeem it because we used garbage_pubkey_2 as a refund pubkey
await assert_err(
wallet2.redeem(send_proofs_copy),

View File

@@ -33,7 +33,9 @@ def assert_amt(proofs: List[Proof], expected: int):
@pytest_asyncio.fixture(scope="function")
async def wallet1(mint):
wallet1 = await Wallet1.with_db(SERVER_ENDPOINT, "data/wallet_p2sh_1", "wallet1")
wallet1 = await Wallet1.with_db(
SERVER_ENDPOINT, "test_data/wallet_p2sh_1", "wallet1"
)
await migrate_databases(wallet1.db, migrations)
await wallet1.load_mint()
wallet1.status()
@@ -42,7 +44,9 @@ async def wallet1(mint):
@pytest_asyncio.fixture(scope="function")
async def wallet2(mint):
wallet2 = await Wallet2.with_db(SERVER_ENDPOINT, "data/wallet_p2sh_2", "wallet2")
wallet2 = await Wallet2.with_db(
SERVER_ENDPOINT, "test_data/wallet_p2sh_2", "wallet2"
)
await migrate_databases(wallet2.db, migrations)
wallet2.private_key = PrivateKey(secrets.token_bytes(32), raw=True)
await wallet2.load_mint()