Files
nutshell/tests/helpers.py
callebtc f74f18c9ca Github CI with Postgres (#417)
* with postgres

* postgres test explicit

* make format

* start postgres only if needed

* remove if again

* print db

* db in matrix

* delete schema

* use new env var MINT_TEST_DATABASE for tests

* add db path to regtest
2024-02-11 15:52:02 +01:00

187 lines
4.9 KiB
Python

import hashlib
import importlib
import json
import os
import random
import string
import time
from subprocess import PIPE, Popen, TimeoutExpired
from typing import Tuple
from loguru import logger
from cashu.core.settings import settings
def get_random_string(N: int = 10):
return "".join(
random.SystemRandom().choice(string.ascii_uppercase + string.digits)
for _ in range(N)
)
async def get_random_invoice_data():
return {"out": False, "amount": 10, "memo": f"test_memo_{get_random_string(10)}"}
wallets_module = importlib.import_module("cashu.lightning")
wallet_class = getattr(wallets_module, settings.mint_lightning_backend)
WALLET = wallet_class()
is_fake: bool = WALLET.__class__.__name__ == "FakeWallet"
is_regtest: bool = not is_fake
is_deprecated_api_only = settings.debug_mint_only_deprecated
is_github_actions = os.getenv("GITHUB_ACTIONS") == "true"
is_postgres = settings.mint_database.startswith("postgres")
docker_lightning_cli = [
"docker",
"exec",
"cashu-lnd-1-1",
"lncli",
"--network",
"regtest",
"--rpcserver=lnd-1",
]
docker_bitcoin_cli = [
"docker",
"exec",
"cashu-bitcoind-1-1bitcoin-cli",
"-rpcuser=lnbits",
"-rpcpassword=lnbits",
"-regtest",
]
docker_lightning_unconnected_cli = [
"docker",
"exec",
"cashu-lnd-2-1",
"lncli",
"--network",
"regtest",
"--rpcserver=lnd-2",
]
def run_cmd(cmd: list) -> str:
timeout = 20
process = Popen(cmd, stdout=PIPE, stderr=PIPE)
def process_communication(comm):
stdout, stderr = comm
output = stdout.decode("utf-8").strip()
error = stderr.decode("utf-8").strip()
return output, error
try:
now = time.time()
output, error = process_communication(process.communicate(timeout=timeout))
took = time.time() - now
logger.debug(f"ran command output: {output}, error: {error}, took: {took}s")
return output
except TimeoutExpired:
process.kill()
output, error = process_communication(process.communicate())
logger.error(f"timeout command: {cmd}, output: {output}, error: {error}")
raise
def run_cmd_json(cmd: list) -> dict:
output = run_cmd(cmd)
try:
return json.loads(output) if output else {}
except json.decoder.JSONDecodeError:
logger.error(f"failed to decode json from cmd `{cmd}`: {output}")
raise
def get_hold_invoice(sats: int) -> Tuple[str, dict]:
preimage = os.urandom(32)
preimage_hash = hashlib.sha256(preimage).hexdigest()
cmd = docker_lightning_cli.copy()
cmd.extend(["addholdinvoice", preimage_hash, str(sats)])
json = run_cmd_json(cmd)
return preimage.hex(), json
def settle_invoice(preimage: str) -> str:
cmd = docker_lightning_cli.copy()
cmd.extend(["settleinvoice", preimage])
return run_cmd(cmd)
def cancel_invoice(preimage_hash: str) -> str:
cmd = docker_lightning_cli.copy()
cmd.extend(["cancelinvoice", preimage_hash])
return run_cmd(cmd)
def get_real_invoice(sats: int) -> dict:
cmd = docker_lightning_cli.copy()
cmd.extend(["addinvoice", str(sats)])
return run_cmd_json(cmd)
def pay_real_invoice(invoice: str) -> str:
cmd = docker_lightning_cli.copy()
cmd.extend(["payinvoice", "--force", invoice])
return run_cmd(cmd)
def mine_blocks(blocks: int = 1) -> str:
cmd = docker_bitcoin_cli.copy()
cmd.extend(["-generate", str(blocks)])
return run_cmd(cmd)
def get_unconnected_node_uri() -> str:
cmd = docker_lightning_unconnected_cli.copy()
cmd.append("getinfo")
info = run_cmd_json(cmd)
pubkey = info["identity_pubkey"]
return f"{pubkey}@lnd-2:9735"
def create_onchain_address(address_type: str = "bech32") -> str:
cmd = docker_bitcoin_cli.copy()
cmd.extend(["getnewaddress", address_type])
return run_cmd(cmd)
def pay_onchain(address: str, sats: int) -> str:
btc = sats * 0.00000001
cmd = docker_bitcoin_cli.copy()
cmd.extend(["sendtoaddress", address, str(btc)])
return run_cmd(cmd)
# def clean_database(settings):
# if DB_TYPE == POSTGRES:
# db_url = make_url(settings.lnbits_database_url)
# conn = psycopg2.connect(settings.lnbits_database_url)
# conn.autocommit = True
# with conn.cursor() as cur:
# try:
# cur.execute("DROP DATABASE lnbits_test")
# except psycopg2.errors.InvalidCatalogName:
# pass
# cur.execute("CREATE DATABASE lnbits_test")
# db_url.database = "lnbits_test"
# settings.lnbits_database_url = str(db_url)
# core.db.__init__("database")
# conn.close()
# else:
# # FIXME: do this once mock data is removed from test data folder
# # os.remove(settings.lnbits_data_folder + "/database.sqlite3")
# pass
def pay_if_regtest(bolt11: str):
if is_regtest:
pay_real_invoice(bolt11)