setup.py test -> pytest / tox

This commit is contained in:
tecnovert 2021-01-10 20:30:07 +02:00
parent bce20d1e59
commit a3ba5cf7e6
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
20 changed files with 332 additions and 227 deletions

View file

@ -7,40 +7,42 @@ lint_task:
- pip install codespell - pip install codespell
script: script:
- flake8 --version - flake8 --version
- PYTHONWARNINGS="ignore" flake8 --ignore=E501,F841,W503 --exclude=basicswap/contrib,messages_pb2.py,.eggs - PYTHONWARNINGS="ignore" flake8 --ignore=E501,F841,W503 --exclude=basicswap/contrib,messages_pb2.py,.eggs,.tox
- codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=tests/lint/spelling.ignore-words.txt -S .git,.eggs,gitianpubkeys,*.pyc,*basicswap/contrib,*mnemonics.py - codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=tests/lint/spelling.ignore-words.txt -S .git,.eggs,.tox,gitianpubkeys,*.pyc,*basicswap/contrib,*mnemonics.py
test_task: test_task:
environment: environment:
- PART_VERSION: 0.19.1.2 - TEST_PREPARE_PATH: $HOME/test_basicswap-prepare
- BTC_VERSION: 0.20.1 - TEST_RELOAD_PATH: $HOME/test_basicswap1
- LTC_VERSION: 0.18.1 - TEST_DIR: $HOME/test_basicswap2
- XMR_VERSION: 0.17.1.9 - BIN_DIR: /tmp/cached_bin
- TEST_RELOAD_PATH: $HOME/test_basicswap1/ - PARTICL_BINDIR: ${BIN_DIR}/particl
- TEST_DIR: $HOME/test_basicswap2/ - BITCOIN_BINDIR: ${BIN_DIR}/bitcoin
- BIN_DIRS: $HOME/binaries - LITECOIN_BINDIR: ${BIN_DIR}/litecoin
- PARTICL_BINDIR: ${BIN_DIRS}/particl-${PART_VERSION}/bin - XMR_BINDIR: ${BIN_DIR}/monero
- BITCOIN_BINDIR: ${BIN_DIRS}/bitcoin-${BTC_VERSION}/bin
- LITECOIN_BINDIR: ${BIN_DIRS}/litecoin-${LTC_VERSION}/bin
- MONERO_BINDIR: ${BIN_DIRS}/monero-${XMR_VERSION}/bin
setup_script: setup_script:
- apt-get update - apt-get update
- apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config - apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config
- if [ ! -d "$BIN_DIRS" ]; then mkdir -p "$BIN_DIRS" ; fi - pip install tox
- if [ ! -d "$PARTICL_BINDIR" ]; then cd "$BIN_DIRS" && wget https://github.com/tecnovert/particl-core/releases/download/v${PART_VERSION}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz; fi - python3 setup.py install
- if [ ! -d "$BITCOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://bitcoincore.org/bin/bitcoin-core-${BTC_VERSION}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz; fi
- if [ ! -d "$LITECOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://download.litecoin.org/litecoin-${LTC_VERSION}/linux/litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
- wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/anonswap.zip - wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/anonswap.zip
- unzip coincurve-anonswap.zip - unzip coincurve-anonswap.zip
- cd coincurve-anonswap - cd coincurve-anonswap
- python3 setup.py install --force - python3 setup.py install --force
bins_cache:
folder: /tmp/cached_bin
reupload_on_changes: false
fingerprint_script:
- basicswap-prepare -v
populate_script:
- basicswap-prepare --bindir=/tmp/cached_bin --preparebinonly --withcoins=particl,bitcoin,litecoin,monero
script: script:
- cd "${CIRRUS_WORKING_DIR}" - cd "${CIRRUS_WORKING_DIR}"
- export DATADIRS="${TEST_DIR}" - export DATADIRS="${TEST_DIR}"
- mkdir -p ${DATADIRS}/bin/{particl,bitcoin,monero} - mkdir -p "${DATADIRS}/bin"
- cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/bitcoin" - cp -r ${BIN_DIR} "${DATADIRS}/bin"
- cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/particl" - mkdir -p "${TEST_RELOAD_PATH}/bin"
- mkdir -p ${TEST_RELOAD_PATH}/bin/{particl,bitcoin,monero} - cp -r ${BIN_DIR} "${TEST_RELOAD_PATH}/bin"
- cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/particl" - mkdir -p "${TEST_PREPARE_PATH}/bin"
- cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/bitcoin" - cp -r ${BIN_DIR} "${TEST_PREPARE_PATH}/bin"
- python setup.py test - tox

2
.gitignore vendored
View file

@ -5,3 +5,5 @@ __pycache__
/*.egg-info /*.egg-info
/*.egg /*.egg
/*.eggs /*.eggs
.tox
.eggs

View file

@ -7,40 +7,37 @@ stages:
- test - test
env: env:
global: global:
- PART_VERSION=0.19.1.2 - TEST_PREPARE_PATH: ~/test_basicswap-prepare
- BTC_VERSION=0.20.1 - TEST_DIR=~/test_basicswap2
- LTC_VERSION=0.18.1 - TEST_RELOAD_PATH=~/test_basicswap1
- XMR_VERSION=0.17.1.9 - BIN_DIRS=~/cached_bin
- TEST_DIR=~/test_basicswap2/ - PARTICL_BINDIR=${BIN_DIRS}/particl
- TEST_RELOAD_PATH=~/test_basicswap1/ - BITCOIN_BINDIR=${BIN_DIRS}/bitcoin
- BIN_DIRS=~/binaries - LITECOIN_BINDIR=${BIN_DIRS}/litecoin
- PARTICL_BINDIR=${BIN_DIRS}/particl-${PART_VERSION}/bin/ - XMR_BINDIR=${BIN_DIRS}/monero
- BITCOIN_BINDIR=${BIN_DIRS}/bitcoin-${BTC_VERSION}/bin/
- LITECOIN_BINDIR=${BIN_DIRS}/litecoin-${LTC_VERSION}/bin/
- MONERO_BINDIR=${BIN_DIRS}/monero-${XMR_VERSION}/bin/
cache: cache:
directories: directories:
- "$BIN_DIRS" - "$BIN_DIRS"
before_install: before_install:
- sudo apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config - sudo apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config
install:
- travis_retry pip install tox
before_script: before_script:
- if [ ! -d "$BIN_DIRS" ]; then mkdir -p "$BIN_DIRS" ; fi
- if [ ! -d "$PARTICL_BINDIR" ]; then cd "$BIN_DIRS" && wget https://github.com/tecnovert/particl-core/releases/download/v${PART_VERSION}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz ; fi
- if [ ! -d "$BITCOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://bitcoincore.org/bin/bitcoin-core-${BTC_VERSION}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
- if [ ! -d "$LITECOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://download.litecoin.org/litecoin-${LTC_VERSION}/linux/litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
- wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/anonswap.zip - wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/anonswap.zip
- unzip coincurve-anonswap.zip - unzip coincurve-anonswap.zip
- cd coincurve-anonswap - cd coincurve-anonswap
- python3 setup.py install --force - python3 setup.py install --force
script: script:
- cd $TRAVIS_BUILD_DIR - cd $TRAVIS_BUILD_DIR
- basicswap-prepare --bindir=${BIN_DIRS} --preparebinonly --withcoins=particl,bitcoin,litecoin,monero
- export DATADIRS="${TEST_DIR}" - export DATADIRS="${TEST_DIR}"
- mkdir -p ${DATADIRS}/bin/{particl,bitcoin,monero} - mkdir -p "${DATADIRS}/bin"
- cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/bitcoin" - cp -r ${BIN_DIR} "${DATADIRS}/bin"
- mkdir -p ${TEST_RELOAD_PATH}/bin/{particl,bitcoin,monero} - mkdir -p "${TEST_RELOAD_PATH}/bin"
- cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/particl" - cp -r ${BIN_DIR} "${TEST_RELOAD_PATH}/bin"
- cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/bitcoin" - mkdir -p "${TEST_PREPARE_PATH}/bin"
- python setup.py test - cp -r ${BIN_DIR} "${TEST_PREPARE_PATH}/bin"
- tox
after_success: after_success:
- echo "End test" - echo "End test"
jobs: jobs:
@ -53,8 +50,8 @@ jobs:
- travis_retry pip install codespell==1.15.0 - travis_retry pip install codespell==1.15.0
before_script: before_script:
script: script:
- PYTHONWARNINGS="ignore" flake8 --ignore=E501,F841,W503 --exclude=basicswap/contrib,messages_pb2.py,.eggs - PYTHONWARNINGS="ignore" flake8 --ignore=E501,F841,W503 --exclude=basicswap/contrib,messages_pb2.py,.eggs,.tox
- codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=tests/lint/spelling.ignore-words.txt -S .git,.eggs,gitianpubkeys,*.pyc,*basicswap/contrib,*mnemonics.py - codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=tests/lint/spelling.ignore-words.txt -S .git,.eggs,.tox,gitianpubkeys,*.pyc,*basicswap/contrib,*mnemonics.py
after_success: after_success:
- echo "End lint" - echo "End lint"
- stage: test - stage: test

View file

@ -383,32 +383,35 @@ class HttpHandler(BaseHTTPRequestHandler):
page_data['autoaccept'] = True if b'autoaccept' in form_data else False page_data['autoaccept'] = True if b'autoaccept' in form_data else False
parsed_data['autoaccept'] = page_data['autoaccept'] parsed_data['autoaccept'] = page_data['autoaccept']
if len(errors) == 0 and page_data['swap_style'] == 'xmr': try:
if b'fee_rate_from' in form_data: if len(errors) == 0 and page_data['swap_style'] == 'xmr':
page_data['from_fee_override'] = form_data[b'fee_rate_from'][0].decode('utf-8') if b'fee_rate_from' in form_data:
parsed_data['from_fee_override'] = page_data['from_fee_override'] page_data['from_fee_override'] = form_data[b'fee_rate_from'][0].decode('utf-8')
else: parsed_data['from_fee_override'] = page_data['from_fee_override']
from_fee_override, page_data['from_fee_src'] = swap_client.getFeeRateForCoin(parsed_data['coin_from'], page_data['fee_from_conf'])
if page_data['fee_from_extra'] > 0:
from_fee_override += from_fee_override * (float(page_data['fee_from_extra']) / 100.0)
page_data['from_fee_override'] = ci_from.format_amount(ci_from.make_int(from_fee_override, r=1))
parsed_data['from_fee_override'] = page_data['from_fee_override']
lock_spend_tx_vsize = ci_from.xmr_swap_alock_spend_tx_vsize()
lock_spend_tx_fee = ci_from.make_int(ci_from.make_int(from_fee_override, r=1) * lock_spend_tx_vsize / 1000, r=1)
page_data['amt_from_lock_spend_tx_fee'] = ci_from.format_amount(lock_spend_tx_fee // ci_from.COIN())
page_data['tla_from'] = ci_from.ticker()
if coin_to == Coins.XMR:
if b'fee_rate_to' in form_data:
page_data['to_fee_override'] = form_data[b'fee_rate_to'][0].decode('utf-8')
parsed_data['to_fee_override'] = page_data['to_fee_override']
else: else:
to_fee_override, page_data['to_fee_src'] = swap_client.getFeeRateForCoin(parsed_data['coin_to'], page_data['fee_to_conf']) from_fee_override, page_data['from_fee_src'] = swap_client.getFeeRateForCoin(parsed_data['coin_from'], page_data['fee_from_conf'])
if page_data['fee_to_extra'] > 0: if page_data['fee_from_extra'] > 0:
to_fee_override += to_fee_override * (float(page_data['fee_to_extra']) / 100.0) from_fee_override += from_fee_override * (float(page_data['fee_from_extra']) / 100.0)
page_data['to_fee_override'] = ci_to.format_amount(ci_to.make_int(to_fee_override, r=1)) page_data['from_fee_override'] = ci_from.format_amount(ci_from.make_int(from_fee_override, r=1))
parsed_data['to_fee_override'] = page_data['to_fee_override'] parsed_data['from_fee_override'] = page_data['from_fee_override']
lock_spend_tx_vsize = ci_from.xmr_swap_alock_spend_tx_vsize()
lock_spend_tx_fee = ci_from.make_int(ci_from.make_int(from_fee_override, r=1) * lock_spend_tx_vsize / 1000, r=1)
page_data['amt_from_lock_spend_tx_fee'] = ci_from.format_amount(lock_spend_tx_fee // ci_from.COIN())
page_data['tla_from'] = ci_from.ticker()
if coin_to == Coins.XMR:
if b'fee_rate_to' in form_data:
page_data['to_fee_override'] = form_data[b'fee_rate_to'][0].decode('utf-8')
parsed_data['to_fee_override'] = page_data['to_fee_override']
else:
to_fee_override, page_data['to_fee_src'] = swap_client.getFeeRateForCoin(parsed_data['coin_to'], page_data['fee_to_conf'])
if page_data['fee_to_extra'] > 0:
to_fee_override += to_fee_override * (float(page_data['fee_to_extra']) / 100.0)
page_data['to_fee_override'] = ci_to.format_amount(ci_to.make_int(to_fee_override, r=1))
parsed_data['to_fee_override'] = page_data['to_fee_override']
except Exception as e:
print('Error setting fee', str(e)) # Expected if missing fields
return parsed_data, errors return parsed_data, errors
@ -456,7 +459,9 @@ class HttpHandler(BaseHTTPRequestHandler):
def postNewOffer(self, form_data): def postNewOffer(self, form_data):
page_data = {} page_data = {}
parsed_data = self.parseOfferFormData(form_data, page_data) parsed_data, errors = self.parseOfferFormData(form_data, page_data)
if len(errors) > 0:
raise ValueError('Parse errors: ' + ' '.join(errors))
return self.postNewOfferFromParsed(parsed_data) return self.postNewOfferFromParsed(parsed_data)
def page_newoffer(self, url_split, post_string): def page_newoffer(self, url_split, post_string):

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2020 tecnovert # Copyright (c) 2020-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -117,7 +117,8 @@ class BTCInterface(CoinInterface):
def __init__(self, coin_settings, network): def __init__(self, coin_settings, network):
super().__init__() super().__init__()
self.rpc_callback = make_rpc_func(coin_settings['rpcport'], coin_settings['rpcauth'], host=coin_settings['rpchost']) rpc_host = coin_settings.get('rpchost', 'localhost')
self.rpc_callback = make_rpc_func(coin_settings['rpcport'], coin_settings['rpcauth'], host=rpc_host)
self.txoType = CTxOut self.txoType = CTxOut
self._network = network self._network = network
self.blocks_confirmed = coin_settings['blocks_confirmed'] self.blocks_confirmed = coin_settings['blocks_confirmed']

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2020 tecnovert # Copyright (c) 2020-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -36,7 +36,8 @@ class PARTInterface(BTCInterface):
return 213 return 213
def __init__(self, coin_settings, network): def __init__(self, coin_settings, network):
self.rpc_callback = make_rpc_func(coin_settings['rpcport'], coin_settings['rpcauth'], host=coin_settings['rpchost']) rpc_host = coin_settings.get('rpchost', 'localhost')
self.rpc_callback = make_rpc_func(coin_settings['rpcport'], coin_settings['rpcauth'], host=rpc_host)
self.txoType = CTxOutPart self.txoType = CTxOutPart
self._network = network self._network = network
self.blocks_confirmed = coin_settings['blocks_confirmed'] self.blocks_confirmed = coin_settings['blocks_confirmed']

View file

@ -123,6 +123,7 @@ class XMRInterface(CoinInterface):
def getWalletInfo(self): def getWalletInfo(self):
self.rpc_wallet_cb('open_wallet', {'filename': self._wallet_filename}) self.rpc_wallet_cb('open_wallet', {'filename': self._wallet_filename})
rv = {} rv = {}
self.rpc_wallet_cb('refresh')
balance_info = self.rpc_wallet_cb('get_balance') balance_info = self.rpc_wallet_cb('get_balance')
rv['balance'] = format_amount(balance_info['unlocked_balance'], XMRInterface.exp()) rv['balance'] = format_amount(balance_info['unlocked_balance'], XMRInterface.exp())
rv['unconfirmed_balance'] = format_amount(balance_info['balance'] - balance_info['unlocked_balance'], XMRInterface.exp()) rv['unconfirmed_balance'] = format_amount(balance_info['balance'] - balance_info['unlocked_balance'], XMRInterface.exp())

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2019-2020 tecnovert # Copyright (c) 2019-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -31,11 +31,14 @@ from bin.basicswap_run import startDaemon, startXmrWalletDaemon
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
BIN_ARCH = 'osx64.tar.gz' BIN_ARCH = 'osx64'
FILE_EXT = 'tar.gz'
elif platform.system() == 'Windows': elif platform.system() == 'Windows':
BIN_ARCH = 'win64.zip' BIN_ARCH = 'win64'
FILE_EXT = 'zip'
else: else:
BIN_ARCH = 'x86_64-linux-gnu.tar.gz' BIN_ARCH = 'x86_64-linux-gnu'
FILE_EXT = 'tar.gz'
known_coins = { known_coins = {
'particl': '0.19.1.2', 'particl': '0.19.1.2',
@ -67,6 +70,8 @@ LTC_RPC_HOST = os.getenv('LTC_RPC_HOST', 'localhost')
BTC_RPC_HOST = os.getenv('BTC_RPC_HOST', 'localhost') BTC_RPC_HOST = os.getenv('BTC_RPC_HOST', 'localhost')
NMC_RPC_HOST = os.getenv('NMC_RPC_HOST', 'localhost') NMC_RPC_HOST = os.getenv('NMC_RPC_HOST', 'localhost')
extract_core_overwrite = True
def make_reporthook(): def make_reporthook():
read = 0 # Number of bytes read so far read = 0 # Number of bytes read so far
@ -88,6 +93,7 @@ def make_reporthook():
def downloadFile(url, path): def downloadFile(url, path):
logger.info('Downloading file %s', url) logger.info('Downloading file %s', url)
logger.info('To %s', path)
opener = urllib.request.build_opener() opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')] opener.addheaders = [('User-agent', 'Mozilla/5.0')]
urllib.request.install_opener(opener) urllib.request.install_opener(opener)
@ -97,19 +103,31 @@ def downloadFile(url, path):
def extractCore(coin, version, settings, bin_dir, release_path): def extractCore(coin, version, settings, bin_dir, release_path):
logger.info('extractCore %s v%s', coin, version) logger.info('extractCore %s v%s', coin, version)
bins = [coin + 'd', coin + '-cli', coin + '-tx']
if coin == 'monero': if coin == 'monero':
bins = ['monerod', 'monero-wallet-rpc']
num_exist = 0
for b in bins:
out_path = os.path.join(bin_dir, b)
if os.path.exists(out_path):
num_exist += 1
if not extract_core_overwrite and num_exist == len(bins):
logger.info('Skipping extract, files exist.')
return
with tarfile.open(release_path) as ft: with tarfile.open(release_path) as ft:
for member in ft.getmembers(): for member in ft.getmembers():
if member.isdir(): if member.isdir():
continue continue
out_path = os.path.join(bin_dir, os.path.basename(member.name)) bin_name = os.path.basename(member.name)
fi = ft.extractfile(member) if bin_name not in bins:
with open(out_path, 'wb') as fout: continue
fout.write(fi.read()) out_path = os.path.join(bin_dir, bin_name)
fi.close() if (not os.path.exists(out_path)) or extract_core_overwrite:
os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH) fi = ft.extractfile(member)
with open(out_path, 'wb') as fout:
fout.write(fi.read())
fi.close()
os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH)
return return
bins = [coin + 'd', coin + '-cli', coin + '-tx'] bins = [coin + 'd', coin + '-cli', coin + '-tx']
@ -121,18 +139,20 @@ def extractCore(coin, version, settings, bin_dir, release_path):
for b in bins: for b in bins:
b += '.exe' b += '.exe'
out_path = os.path.join(bin_dir, b) out_path = os.path.join(bin_dir, b)
with open(out_path, 'wb') as fout: if (not os.path.exists(out_path)) or extract_core_overwrite:
fout.write(fz.read('{}-{}/bin/{}'.format(coin, version, b))) with open(out_path, 'wb') as fout:
os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH) fout.write(fz.read('{}-{}/bin/{}'.format(coin, version, b)))
os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH)
else: else:
with tarfile.open(release_path) as ft: with tarfile.open(release_path) as ft:
for b in bins: for b in bins:
out_path = os.path.join(bin_dir, b) out_path = os.path.join(bin_dir, b)
fi = ft.extractfile('{}-{}/bin/{}'.format(coin, version, b)) if not os.path.exists(out_path) or extract_core_overwrite:
with open(out_path, 'wb') as fout: fi = ft.extractfile('{}-{}/bin/{}'.format(coin, version, b))
fout.write(fi.read()) with open(out_path, 'wb') as fout:
fi.close() fout.write(fi.read())
os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH) fi.close()
os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH)
def prepareCore(coin, version, settings, data_dir): def prepareCore(coin, version, settings, data_dir):
@ -152,11 +172,12 @@ def prepareCore(coin, version, settings, data_dir):
os_dir_name = 'linux' os_dir_name = 'linux'
os_name = 'linux' os_name = 'linux'
release_filename = '{}-{}-{}'.format(coin, version, BIN_ARCH)
if coin == 'monero': if coin == 'monero':
use_file_ext = 'tar.bz2' if FILE_EXT == 'tar.gz' else FILE_EXT
release_filename = '{}-{}-{}.{}'.format(coin, version, BIN_ARCH, use_file_ext)
if os_name == 'osx': if os_name == 'osx':
os_name = 'mac' os_name = 'mac'
release_url = 'https://downloads.getmonero.org/cli/monero-{}-x64-v{}.tar.bz2'.format(os_name, version) release_url = 'https://downloads.getmonero.org/cli/monero-{}-x64-v{}.{}'.format(os_name, version, use_file_ext)
release_path = os.path.join(bin_dir, release_filename) release_path = os.path.join(bin_dir, release_filename)
if not os.path.exists(release_path): if not os.path.exists(release_path):
downloadFile(release_url, release_path) downloadFile(release_url, release_path)
@ -168,7 +189,7 @@ def prepareCore(coin, version, settings, data_dir):
if not os.path.exists(assert_path): if not os.path.exists(assert_path):
downloadFile(assert_url, assert_path) downloadFile(assert_url, assert_path)
else: else:
release_filename = '{}-{}-{}'.format(coin, version, BIN_ARCH) release_filename = '{}-{}-{}.{}'.format(coin, version, BIN_ARCH, FILE_EXT)
if coin == 'particl': if coin == 'particl':
signing_key_name = 'tecnovert' signing_key_name = 'tecnovert'
release_url = 'https://github.com/tecnovert/particl-core/releases/download/v{}/{}'.format(version, release_filename) release_url = 'https://github.com/tecnovert/particl-core/releases/download/v{}/{}'.format(version, release_filename)
@ -284,16 +305,17 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic):
fp.write('regtest=1\n') fp.write('regtest=1\n')
fp.write('keep-fakechain=1\n') fp.write('keep-fakechain=1\n')
fp.write('fixed-difficulty=1\n') fp.write('fixed-difficulty=1\n')
elif chain == 'testnet': else:
fp.write('bootstrap-daemon-address=auto\n')
fp.write('restricted-rpc=1\n')
if chain == 'testnet':
fp.write('testnet=1\n') fp.write('testnet=1\n')
fp.write('data-dir={}\n'.format(data_dir)) fp.write('data-dir={}\n'.format(data_dir))
fp.write('rpc-bind-port={}\n'.format(core_settings['rpcport'])) fp.write('rpc-bind-port={}\n'.format(core_settings['rpcport']))
fp.write('rpc-bind-ip=127.0.0.1\n') fp.write('rpc-bind-ip=127.0.0.1\n')
fp.write('zmq-rpc-bind-port={}\n'.format(core_settings['zmqport'])) fp.write('zmq-rpc-bind-port={}\n'.format(core_settings['zmqport']))
fp.write('zmq-rpc-bind-ip=127.0.0.1\n') fp.write('zmq-rpc-bind-ip=127.0.0.1\n')
fp.write('prune-blockchain=1') fp.write('prune-blockchain=1\n')
fp.write('restricted-rpc=1')
fp.write('bootstrap-daemon-address=auto')
wallet_conf_path = os.path.join(data_dir, coin + '_wallet.conf') wallet_conf_path = os.path.join(data_dir, coin + '_wallet.conf')
if os.path.exists(wallet_conf_path): if os.path.exists(wallet_conf_path):
@ -346,7 +368,11 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic):
def printVersion(): def printVersion():
from basicswap import __version__ from basicswap import __version__
logger.info('Basicswap version:', __version__) logger.info('Basicswap version: %s', __version__)
logger.info('Core versions:')
for coin, version in known_coins.items():
logger.info('\t%s: %s', coin, version)
def printHelp(): def printHelp():
@ -369,6 +395,7 @@ def printHelp():
logger.info('--portoffset=n Raise all ports by n.') logger.info('--portoffset=n Raise all ports by n.')
logger.info('--htmlhost= Interface to host on, default:localhost.') logger.info('--htmlhost= Interface to host on, default:localhost.')
logger.info('--xmrrestoreheight=n Block height to restore Monero wallet from, default:{}.'.format(DEFAULT_XMR_RESTORE_HEIGHT)) logger.info('--xmrrestoreheight=n Block height to restore Monero wallet from, default:{}.'.format(DEFAULT_XMR_RESTORE_HEIGHT))
logger.info('--noextractover Prevent extracting cores if files exist. Speeds up tests')
logger.info('\n' + 'Known coins: %s', ', '.join(known_coins.keys())) logger.info('\n' + 'Known coins: %s', ', '.join(known_coins.keys()))
@ -393,6 +420,7 @@ def exitWithError(error_msg):
def main(): def main():
global extract_core_overwrite
data_dir = None data_dir = None
bin_dir = None bin_dir = None
port_offset = None port_offset = None
@ -437,6 +465,9 @@ def main():
if name == 'nocores': if name == 'nocores':
no_cores = True no_cores = True
continue continue
if name == 'noextractover':
extract_core_overwrite = False
continue
if len(s) == 2: if len(s) == 2:
if name == 'datadir': if name == 'datadir':
data_dir = os.path.expanduser(s[1].strip('"')) data_dir = os.path.expanduser(s[1].strip('"'))
@ -489,7 +520,8 @@ def main():
if bin_dir is None: if bin_dir is None:
bin_dir = os.path.join(data_dir, 'bin') bin_dir = os.path.join(data_dir, 'bin')
logger.info('Using datadir: %s', data_dir) logger.info('datadir: %s', data_dir)
logger.info('bindir: %s', bin_dir)
logger.info('Chain: %s', chain) logger.info('Chain: %s', chain)
if port_offset is None: if port_offset is None:

View file

@ -184,7 +184,7 @@ def runClient(fp, data_dir, chain):
def printVersion(): def printVersion():
logger.info('Basicswap version:', __version__) logger.info('Basicswap version: %s', __version__)
def printHelp(): def printHelp():

View file

@ -2,7 +2,7 @@
## Run One Test ## Run One Test
``` ```
python setup.py test -s tests.basicswap.test_xmr.Test.test_02_leader_recover_a_lock_tx pytest -v -s tests/basicswap/test_xmr.py::Test::test_02_leader_recover_a_lock_tx
``` ```
## TODO ## TODO

View file

@ -12,7 +12,7 @@ setuptools.setup(
version=__version__, version=__version__,
author="tecnovert", author="tecnovert",
author_email="tecnovert@tecnovert.net", author_email="tecnovert@tecnovert.net",
description="Simple atomic swap demo", description="Simple atomic swap system",
long_description=open("README.md").read(), long_description=open("README.md").read(),
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
url="https://github.com/tecnovert/basicswap", url="https://github.com/tecnovert/basicswap",
@ -23,6 +23,13 @@ setuptools.setup(
"License :: OSI Approved :: MIT License", "License :: OSI Approved :: MIT License",
"Operating System :: Linux", "Operating System :: Linux",
], ],
keywords=[
"crypto",
"cryptocurrency",
"particl",
"bitcoin",
"monero",
],
install_requires=[ install_requires=[
"wheel", "wheel",
"pyzmq", "pyzmq",
@ -38,6 +45,5 @@ setuptools.setup(
"basicswap-run=bin.basicswap_run:main", "basicswap-run=bin.basicswap_run:main",
"basicswap-prepare=bin.basicswap_prepare:main", "basicswap-prepare=bin.basicswap_prepare:main",
] ]
}, }
test_suite="tests.basicswap.test_suite"
) )

View file

@ -1,17 +0,0 @@
import unittest
import tests.basicswap.test_other as test_other
import tests.basicswap.test_prepare as test_prepare
import tests.basicswap.test_run as test_run
import tests.basicswap.test_reload as test_reload
def test_suite():
loader = unittest.TestLoader()
suite = loader.loadTestsFromModule(test_other)
suite.addTests(loader.loadTestsFromModule(test_prepare))
suite.addTests(loader.loadTestsFromModule(test_run))
suite.addTests(loader.loadTestsFromModule(test_reload))
# TODO: Add to ci scripts suite.addTests(loader.loadTestsFromModule(test_xmr))
return suite

View file

@ -1,23 +1,23 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2019-2020 tecnovert # Copyright (c) 2019-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
""" """
basicswap]$ python tests/test_nmc.py basicswap]$ python tests/basicswap/extended/test_nmc.py
""" """
import os import os
import sys import sys
import unittest
import json import json
import logging
import shutil
import time import time
import shutil
import signal import signal
import logging
import unittest
import threading import threading
from urllib.request import urlopen from urllib.request import urlopen

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2020 tecnovert # Copyright (c) 2020-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -9,10 +9,10 @@
export TEST_PATH=/tmp/test_basicswap_wallet_init export TEST_PATH=/tmp/test_basicswap_wallet_init
mkdir -p ${TEST_PATH}/bin/{particl,monero,bitcoin} mkdir -p ${TEST_PATH}/bin/{particl,monero,bitcoin}
cp ~/tmp/particl-0.19.1.2-x86_64-linux-gnu.tar.gz ${TEST_PATH}/bin/particl cp ~/tmp/particl-0.19.1.2-x86_64-linux-gnu.tar.gz ${TEST_PATH}/bin/particl
cp ~/tmp/monero-0.17.1.9-x86_64-linux-gnu.tar.gz ${TEST_PATH}/bin/monero cp ~/tmp/monero-linux-x64-v0.17.1.9.tar.bz2 ${TEST_PATH}/bin/monero/monero-0.17.1.9-x86_64-linux-gnu.tar.bz2
cp ~/tmp/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz ${TEST_PATH}/bin/bitcoin cp ~/tmp/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz ${TEST_PATH}/bin/bitcoin
export PYTHONPATH=$(pwd) export PYTHONPATH=$(pwd)
python tests/basicswap/test_wallet_init.py python tests/basicswap/extended/test_wallet_init.py
""" """
@ -61,33 +61,6 @@ def waitForServer(port):
traceback.print_exc() traceback.print_exc()
def waitForNumOffers(port, offers):
for i in range(20):
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
if summary['num_network_offers'] >= offers:
return
time.sleep(1)
raise ValueError('waitForNumOffers failed')
def waitForNumBids(port, bids):
for i in range(20):
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
if summary['num_recv_bids'] >= bids:
return
time.sleep(1)
raise ValueError('waitForNumBids failed')
def waitForNumSwapping(port, bids):
for i in range(20):
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
if summary['num_swapping'] >= bids:
return
time.sleep(1)
raise ValueError('waitForNumSwapping failed')
class Test(unittest.TestCase): class Test(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
@ -106,7 +79,10 @@ class Test(unittest.TestCase):
'-bindir="{}"'.format(os.path.join(test_path, 'bin')), '-bindir="{}"'.format(os.path.join(test_path, 'bin')),
'-portoffset={}'.format(i), '-portoffset={}'.format(i),
'-particl_mnemonic="{}"'.format(mnemonics[0]), '-particl_mnemonic="{}"'.format(mnemonics[0]),
'-regtest', '-withcoin=monero,bitcoin'] '-regtest',
'-withcoin=monero,bitcoin',
'-noextractover',
'-xmrrestoreheight=0']
with patch.object(sys, 'argv', testargs): with patch.object(sys, 'argv', testargs):
prepareSystem.main() prepareSystem.main()

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2019 tecnovert # Copyright (c) 2019-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -13,7 +13,6 @@ cp ~/tmp/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz ${TEST_RELOAD_PATH}/bin/bitcoin
export PYTHONPATH=$(pwd) export PYTHONPATH=$(pwd)
python tests/basicswap/test_reload.py python tests/basicswap/test_reload.py
""" """
import os import os
@ -61,9 +60,10 @@ def waitForServer(port):
try: try:
time.sleep(1) time.sleep(1)
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read()) summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
break return
except Exception: except Exception:
traceback.print_exc() traceback.print_exc()
raise ValueError('waitForServer failed')
def waitForNumOffers(port, offers): def waitForNumOffers(port, offers):

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2020 tecnovert # Copyright (c) 2020-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -9,7 +9,7 @@
export TEST_RELOAD_PATH=/tmp/test_basicswap export TEST_RELOAD_PATH=/tmp/test_basicswap
mkdir -p ${TEST_RELOAD_PATH}/bin/{particl,monero} mkdir -p ${TEST_RELOAD_PATH}/bin/{particl,monero}
cp ~/tmp/particl-0.19.1.2-x86_64-linux-gnu.tar.gz ${TEST_RELOAD_PATH}/bin/particl cp ~/tmp/particl-0.19.1.2-x86_64-linux-gnu.tar.gz ${TEST_RELOAD_PATH}/bin/particl
cp ~/tmp/monero-0.17.1.9-x86_64-linux-gnu.tar.gz ${TEST_RELOAD_PATH}/bin/monero cp ~/tmp/monero-linux-x64-v0.17.1.9.tar.bz2 ${TEST_RELOAD_PATH}/bin/monero/monero-0.17.1.9-x86_64-linux-gnu.tar.bz2
export PYTHONPATH=$(pwd) export PYTHONPATH=$(pwd)
python tests/basicswap/test_reload_xmr.py python tests/basicswap/test_reload_xmr.py
@ -19,8 +19,8 @@ python tests/basicswap/test_reload_xmr.py
import os import os
import sys import sys
import json import json
import time
import shutil import shutil
import signal
import logging import logging
import unittest import unittest
import traceback import traceback
@ -46,7 +46,7 @@ XMR_BASE_P2P_PORT = 17792
XMR_BASE_RPC_PORT = 29798 XMR_BASE_RPC_PORT = 29798
XMR_BASE_WALLET_RPC_PORT = 29998 XMR_BASE_WALLET_RPC_PORT = 29998
stop_test = False delay_event = threading.Event()
logger = logging.getLogger() logger = logging.getLogger()
logger.level = logging.DEBUG logger.level = logging.DEBUG
@ -54,47 +54,64 @@ if not len(logger.handlers):
logger.addHandler(logging.StreamHandler(sys.stdout)) logger.addHandler(logging.StreamHandler(sys.stdout))
def waitForServer(port): def waitForServer(port, wait_for=20):
for i in range(20): for i in range(wait_for):
if delay_event.is_set():
raise ValueError('Test stopped.')
try: try:
time.sleep(1) delay_event.wait(1)
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read()) summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
break return
except Exception: except Exception:
traceback.print_exc() traceback.print_exc()
raise ValueError('waitForServer failed')
def waitForNumOffers(port, offers): def waitForNumOffers(port, offers, wait_for=20):
for i in range(20): for i in range(wait_for):
if delay_event.is_set():
raise ValueError('Test stopped.')
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read()) summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
if summary['num_network_offers'] >= offers: if summary['num_network_offers'] >= offers:
return return
time.sleep(1) delay_event.wait(1)
raise ValueError('waitForNumOffers failed') raise ValueError('waitForNumOffers failed')
def waitForNumBids(port, bids): def waitForNumBids(port, bids, wait_for=20):
for i in range(20): for i in range(wait_for):
if delay_event.is_set():
raise ValueError('Test stopped.')
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read()) summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
if summary['num_recv_bids'] >= bids: if summary['num_recv_bids'] >= bids:
return return
time.sleep(1) delay_event.wait(1)
raise ValueError('waitForNumBids failed') raise ValueError('waitForNumBids failed')
def waitForNumSwapping(port, bids): def waitForNumSwapping(port, bids, wait_for=60):
for i in range(20): for i in range(wait_for):
if delay_event.is_set():
raise ValueError('Test stopped.')
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read()) summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
if summary['num_swapping'] >= bids: if summary['num_swapping'] >= bids:
return return
time.sleep(1) delay_event.wait(1)
raise ValueError('waitForNumSwapping failed') raise ValueError('waitForNumSwapping failed')
def updateThread(xmr_addr): def updateThread(xmr_addr):
while not stop_test: while not delay_event.is_set():
callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr, 'amount_of_blocks': 1}) try:
time.sleep(5) callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr, 'amount_of_blocks': 1})
except Exception as e:
print('updateThread error', str(e))
delay_event.wait(2)
def signal_handler(sig, frame):
logging.info('signal {} detected.'.format(sig))
delay_event.set()
class Test(unittest.TestCase): class Test(unittest.TestCase):
@ -102,6 +119,9 @@ class Test(unittest.TestCase):
def setUpClass(cls): def setUpClass(cls):
super(Test, cls).setUpClass() super(Test, cls).setUpClass()
cls.update_thread = None
cls.processes = []
for i in range(3): for i in range(3):
client_path = os.path.join(test_path, 'client{}'.format(i)) client_path = os.path.join(test_path, 'client{}'.format(i))
config_path = os.path.join(client_path, cfg.CONFIG_FILENAME) config_path = os.path.join(client_path, cfg.CONFIG_FILENAME)
@ -115,7 +135,10 @@ class Test(unittest.TestCase):
'-bindir="{}"'.format(os.path.join(test_path, 'bin')), '-bindir="{}"'.format(os.path.join(test_path, 'bin')),
'-portoffset={}'.format(i), '-portoffset={}'.format(i),
'-particl_mnemonic="{}"'.format(mnemonics[i]), '-particl_mnemonic="{}"'.format(mnemonics[i]),
'-regtest', '-withcoin=monero'] '-regtest',
'-withcoin=monero',
'-noextractover',
'-xmrrestoreheight=0']
with patch.object(sys, 'argv', testargs): with patch.object(sys, 'argv', testargs):
prepareSystem.main() prepareSystem.main()
@ -140,7 +163,22 @@ class Test(unittest.TestCase):
if ip != i: if ip != i:
fp.write('add-exclusive-node=127.0.0.1:{}\n'.format(XMR_BASE_P2P_PORT + ip)) fp.write('add-exclusive-node=127.0.0.1:{}\n'.format(XMR_BASE_P2P_PORT + ip))
assert(os.path.exists(config_path)) with open(config_path) as fs:
settings = json.load(fs)
settings['min_delay_event'] = 1
settings['max_delay_event'] = 4
settings['check_progress_seconds'] = 5
settings['check_watched_seconds'] = 5
settings['check_expired_seconds'] = 60
settings['check_events_seconds'] = 5
settings['check_xmr_swaps_seconds'] = 5
with open(config_path, 'w') as fp:
json.dump(settings, fp, indent=4)
signal.signal(signal.SIGINT, signal_handler)
def run_thread(self, client_id): def run_thread(self, client_id):
client_path = os.path.join(test_path, 'client{}'.format(client_id)) client_path = os.path.join(test_path, 'client{}'.format(client_id))
@ -148,14 +186,12 @@ class Test(unittest.TestCase):
with patch.object(sys, 'argv', testargs): with patch.object(sys, 'argv', testargs):
runSystem.main() runSystem.main()
def test_reload(self): def start_processes(self):
global stop_test delay_event.clear()
update_thread = None
processes = []
for i in range(3): for i in range(3):
processes.append(multiprocessing.Process(target=self.run_thread, args=(i,))) self.processes.append(multiprocessing.Process(target=self.run_thread, args=(i,)))
processes[-1].start() self.processes[-1].start()
try: try:
waitForServer(12701) waitForServer(12701)
@ -163,12 +199,38 @@ class Test(unittest.TestCase):
wallets = json.loads(urlopen('http://localhost:12701/json/wallets').read()) wallets = json.loads(urlopen('http://localhost:12701/json/wallets').read())
xmr_addr1 = wallets['6']['deposit_address'] xmr_addr1 = wallets['6']['deposit_address']
num_blocks = 500 num_blocks = 100
logging.info('Mining %d Monero blocks.', num_blocks) if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks:
callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr1, 'amount_of_blocks': num_blocks}) logging.info('Mining {} Monero blocks to {}.'.format(num_blocks, xmr_addr1))
rv = callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count') callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr1, 'amount_of_blocks': num_blocks})
logging.info('XMR blocks: %d', rv['count']) logging.info('XMR blocks: %d', callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'])
self.update_thread = threading.Thread(target=updateThread, args=(xmr_addr1,))
self.update_thread.start()
except Exception:
traceback.print_exc()
def stop_processes(self):
logger.info('Stopping test')
delay_event.set()
if self.update_thread:
self.update_thread.join()
for p in self.processes:
p.terminate()
for p in self.processes:
p.join()
self.update_thread = None
self.processes = []
def test_01_reload(self):
self.start_processes()
try:
waitForServer(12700)
waitForServer(12701)
wallets1 = json.loads(urlopen('http://localhost:12701/json/wallets').read())
assert(float(wallets1['6']['balance']) > 0.0)
data = parse.urlencode({ data = parse.urlencode({
'addr_from': '-1', 'addr_from': '-1',
@ -201,7 +263,7 @@ class Test(unittest.TestCase):
bid = bids[0] bid = bids[0]
if bid['bid_state'] == 'Received': if bid['bid_state'] == 'Received':
break break
time.sleep(1) delay_event.wait(1)
data = parse.urlencode({ data = parse.urlencode({
'accept': True 'accept': True
@ -212,39 +274,48 @@ class Test(unittest.TestCase):
waitForNumSwapping(12701, 1) waitForNumSwapping(12701, 1)
logger.info('Restarting client') logger.info('Restarting client')
c1 = processes[1] c1 = self.processes[1]
c1.terminate() c1.terminate()
c1.join() c1.join()
processes[1] = multiprocessing.Process(target=self.run_thread, args=(1,)) self.processes[1] = multiprocessing.Process(target=self.run_thread, args=(1,))
processes[1].start() self.processes[1].start()
waitForServer(12701) waitForServer(12701)
rv = json.loads(urlopen('http://localhost:12701/json').read()) rv = json.loads(urlopen('http://localhost:12701/json').read())
assert(rv['num_swapping'] == 1) assert(rv['num_swapping'] == 1)
update_thread = threading.Thread(target=updateThread, args=(xmr_addr1,))
update_thread.start()
logger.info('Completing swap') logger.info('Completing swap')
for i in range(240): for i in range(240):
time.sleep(5) if delay_event.is_set():
raise ValueError('Test stopped.')
delay_event.wait(4)
rv = json.loads(urlopen('http://localhost:12700/json/bids/{}'.format(bid['bid_id'])).read()) rv = json.loads(urlopen('http://localhost:12700/json/bids/{}'.format(bid['bid_id'])).read())
print(rv)
if rv['bid_state'] == 'Completed': if rv['bid_state'] == 'Completed':
break break
assert(rv['bid_state'] == 'Completed') assert(rv['bid_state'] == 'Completed')
except Exception: except Exception as e:
traceback.print_exc() traceback.print_exc()
raise(e)
finally:
self.stop_processes()
logger.info('Stopping test') def test_02_bids_offline(self):
stop_test = True # Start multiple bids while offering node is offline
if update_thread: self.start_processes()
update_thread.join()
for p in processes: try:
p.terminate() waitForServer(12700)
for p in processes: waitForServer(12701)
p.join() wallets1 = json.loads(urlopen('http://localhost:12701/json/wallets').read())
print('wallets 1', json.dumps(wallets1, indent=4))
assert(float(wallets1['6']['balance']) > 0.0)
except Exception as e:
traceback.print_exc()
raise(e)
finally:
self.stop_processes()
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -1,15 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2019 tecnovert # Copyright (c) 2019-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
""" """
basicswap]$ python setup.py test basicswap]$ pytest
Run one test: Run one test:
$ python setup.py test -s tests.basicswap.test_run.Test.test_04_ltc_btc $ pytest -v -s tests/basicswap/test_run.py::Test::test_04_ltc_btc
""" """

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2020 tecnovert # Copyright (c) 2020-2021 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -103,7 +103,7 @@ def prepareXmrDataDir(datadir, node_id, conf_file):
fp.write('rpc-bind-port={}\n'.format(XMR_BASE_RPC_PORT + node_id)) fp.write('rpc-bind-port={}\n'.format(XMR_BASE_RPC_PORT + node_id))
fp.write('p2p-bind-ip=127.0.0.1\n') fp.write('p2p-bind-ip=127.0.0.1\n')
fp.write('rpc-bind-ip=127.0.0.1\n') fp.write('rpc-bind-ip=127.0.0.1\n')
fp.write('prune-blockchain=1\n')
fp.write('zmq-rpc-bind-port={}\n'.format(XMR_BASE_ZMQ_PORT + node_id)) fp.write('zmq-rpc-bind-port={}\n'.format(XMR_BASE_ZMQ_PORT + node_id))
fp.write('zmq-rpc-bind-ip=127.0.0.1\n') fp.write('zmq-rpc-bind-ip=127.0.0.1\n')
@ -118,6 +118,7 @@ def startXmrWalletRPC(node_dir, bin_dir, wallet_bin, node_id, opts=[]):
data_dir = os.path.expanduser(node_dir) data_dir = os.path.expanduser(node_dir)
args = [daemon_bin] args = [daemon_bin]
args += ['--non-interactive']
args += ['--daemon-address=localhost:{}'.format(XMR_BASE_RPC_PORT + node_id)] args += ['--daemon-address=localhost:{}'.format(XMR_BASE_RPC_PORT + node_id)]
args += ['--no-dns'] args += ['--no-dns']
args += ['--rpc-bind-port={}'.format(XMR_BASE_WALLET_RPC_PORT + node_id)] args += ['--rpc-bind-port={}'.format(XMR_BASE_WALLET_RPC_PORT + node_id)]
@ -370,17 +371,17 @@ class Test(unittest.TestCase):
cls.btc_addr = callnoderpc(0, 'getnewaddress', ['mining_addr', 'bech32'], base_rpc_port=BTC_BASE_RPC_PORT) cls.btc_addr = callnoderpc(0, 'getnewaddress', ['mining_addr', 'bech32'], base_rpc_port=BTC_BASE_RPC_PORT)
cls.xmr_addr = cls.callxmrnodewallet(cls, 1, 'get_address')['address'] cls.xmr_addr = cls.callxmrnodewallet(cls, 1, 'get_address')['address']
num_blocks = 500 num_blocks = 500 # Mine enough to activate segwit
logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr) logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr)
callnoderpc(0, 'generatetoaddress', [num_blocks, cls.btc_addr], base_rpc_port=BTC_BASE_RPC_PORT) callnoderpc(0, 'generatetoaddress', [num_blocks, cls.btc_addr], base_rpc_port=BTC_BASE_RPC_PORT)
checkForks(callnoderpc(0, 'getblockchaininfo', base_rpc_port=BTC_BASE_RPC_PORT)) checkForks(callnoderpc(0, 'getblockchaininfo', base_rpc_port=BTC_BASE_RPC_PORT))
num_blocks = 100
if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks:
logging.info('Mining %d Monero blocks.', num_blocks) logging.info('Mining %d Monero blocks to %s.', num_blocks, cls.xmr_addr)
callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': num_blocks}) callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': num_blocks})
rv = callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count') logging.info('XMR blocks: %d', callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'])
logging.info('XMR blocks: %d', rv['count'])
logging.info('Starting update thread.') logging.info('Starting update thread.')
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGINT, signal_handler)
@ -629,8 +630,12 @@ class Test(unittest.TestCase):
logging.info('---------- Test xmr withdrawals') logging.info('---------- Test xmr withdrawals')
swap_clients = self.swap_clients swap_clients = self.swap_clients
js_0 = json.loads(urlopen('http://localhost:1800/json/wallets').read()) js_0 = json.loads(urlopen('http://localhost:1800/json/wallets').read())
print('js_0 debug', js_0)
address_to = js_0[str(int(Coins.XMR))]['deposit_address'] address_to = js_0[str(int(Coins.XMR))]['deposit_address']
js_1 = json.loads(urlopen('http://localhost:1801/json/wallets').read())
assert(float(js_1[str(int(Coins.XMR))]['balance']) > 0.0)
swap_clients[1].withdrawCoin(Coins.XMR, 1.1, address_to, False) swap_clients[1].withdrawCoin(Coins.XMR, 1.1, address_to, False)
def test_09_auto_accept(self): def test_09_auto_accept(self):

23
tox.ini Normal file
View file

@ -0,0 +1,23 @@
[tox]
envlist = py3
[testenv]
setenv =
COINCURVE_IGNORE_SYSTEM_LIB = 1
passenv =
PARTICL_BINDIR
BITCOIN_BINDIR
LITECOIN_BINDIR
XMR_BINDIR
deps =
pytest
-rrequirements.txt
git+https://github.com/tecnovert/coincurve.git@anonswap#egg=coincurve
commands =
pytest
[pytest]
addopts = -v -s
norecursedirs = tests/basicswap/extended
testpaths =
tests