setup.py test -> pytest / tox

2024-05-20_merge
tecnovert 4 years ago
parent bce20d1e59
commit a3ba5cf7e6
No known key found for this signature in database
GPG Key ID: 8ED6D8750C4E3F93
  1. 50
      .cirrus.yml
  2. 2
      .gitignore
  3. 43
      .travis.yml
  4. 7
      basicswap/http_server.py
  5. 5
      basicswap/interface_btc.py
  6. 5
      basicswap/interface_part.py
  7. 1
      basicswap/interface_xmr.py
  8. 64
      bin/basicswap_prepare.py
  9. 2
      bin/basicswap_run.py
  10. 2
      doc/notes.md
  11. 12
      setup.py
  12. 17
      tests/basicswap/__init__.py
  13. 0
      tests/basicswap/extended/test_network.py
  14. 10
      tests/basicswap/extended/test_nmc.py
  15. 38
      tests/basicswap/extended/test_wallet_init.py
  16. 6
      tests/basicswap/test_reload.py
  17. 169
      tests/basicswap/test_reload_xmr.py
  18. 6
      tests/basicswap/test_run.py
  19. 17
      tests/basicswap/test_xmr.py
  20. 23
      tox.ini

@ -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

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

@ -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

@ -383,6 +383,7 @@ 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']
try:
if len(errors) == 0 and page_data['swap_style'] == 'xmr': if len(errors) == 0 and page_data['swap_style'] == 'xmr':
if b'fee_rate_from' in form_data: if b'fee_rate_from' in form_data:
page_data['from_fee_override'] = form_data[b'fee_rate_from'][0].decode('utf-8') page_data['from_fee_override'] = form_data[b'fee_rate_from'][0].decode('utf-8')
@ -409,6 +410,8 @@ class HttpHandler(BaseHTTPRequestHandler):
to_fee_override += to_fee_override * (float(page_data['fee_to_extra']) / 100.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)) 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'] 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):

@ -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']

@ -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']

@ -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())

@ -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,14 +103,26 @@ 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)
if bin_name not in bins:
continue
out_path = os.path.join(bin_dir, bin_name)
if (not os.path.exists(out_path)) or extract_core_overwrite:
fi = ft.extractfile(member) fi = ft.extractfile(member)
with open(out_path, 'wb') as fout: with open(out_path, 'wb') as fout:
fout.write(fi.read()) fout.write(fi.read())
@ -121,6 +139,7 @@ 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)
if (not os.path.exists(out_path)) or extract_core_overwrite:
with open(out_path, 'wb') as fout: with open(out_path, 'wb') as fout:
fout.write(fz.read('{}-{}/bin/{}'.format(coin, version, b))) fout.write(fz.read('{}-{}/bin/{}'.format(coin, version, b)))
os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH) os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH)
@ -128,6 +147,7 @@ def extractCore(coin, version, settings, bin_dir, release_path):
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)
if not os.path.exists(out_path) or extract_core_overwrite:
fi = ft.extractfile('{}-{}/bin/{}'.format(coin, version, b)) fi = ft.extractfile('{}-{}/bin/{}'.format(coin, version, b))
with open(out_path, 'wb') as fout: with open(out_path, 'wb') as fout:
fout.write(fi.read()) fout.write(fi.read())
@ -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:

@ -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():

@ -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

@ -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"
) )

@ -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

@ -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

@ -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()

@ -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):

@ -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():
try:
callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr, 'amount_of_blocks': 1}) callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr, 'amount_of_blocks': 1})
time.sleep(5) 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:
logging.info('Mining {} Monero blocks to {}.'.format(num_blocks, xmr_addr1))
callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr1, 'amount_of_blocks': num_blocks}) callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr1, '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'])
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__':

@ -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
""" """

@ -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):

@ -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
Loading…
Cancel
Save