From 0c2176371f395d7770ca7e06c03dce9a3494d6db Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Thu, 29 Aug 2024 11:17:23 +0000 Subject: [PATCH] test suite: minor fixes and cleanups --- test/cmdtest_py_d/ct_automount_eth.py | 1 + test/cmdtest_py_d/ct_autosign.py | 30 ++++++++------ test/cmdtest_py_d/ct_base.py | 3 ++ test/cmdtest_py_d/ct_xmr_autosign.py | 56 ++++++++++++++++++++------- test/cmdtest_py_d/ct_xmrwallet.py | 36 ++++++++++++----- test/include/common.py | 4 +- test/unit_tests_d/ut_dep.py | 7 ++-- 7 files changed, 97 insertions(+), 40 deletions(-) diff --git a/test/cmdtest_py_d/ct_automount_eth.py b/test/cmdtest_py_d/ct_automount_eth.py index 5c12fd53..c616cc38 100755 --- a/test/cmdtest_py_d/ct_automount_eth.py +++ b/test/cmdtest_py_d/ct_automount_eth.py @@ -100,6 +100,7 @@ class CmdTestAutosignETH(CmdTestAutosignThreaded, CmdTestEthdev): t.expect('(y/N): ', 'n') self._do_confirm_send(t, quiet=True) t.written_to_file('Sent automount transaction') + t.read() self.remove_device_online() return t diff --git a/test/cmdtest_py_d/ct_autosign.py b/test/cmdtest_py_d/ct_autosign.py index d1e5303c..05349543 100755 --- a/test/cmdtest_py_d/ct_autosign.py +++ b/test/cmdtest_py_d/ct_autosign.py @@ -86,9 +86,10 @@ class CmdTestAutosignBase(CmdTestBase): def __del__(self): if hasattr(self,'have_dummy_control_files'): LEDControl.delete_dummy_control_files() - if sys.platform == 'darwin' and not cfg.no_daemon_stop: - for label in (self.asi.dev_label, self.asi.ramdisk.label): - self._macOS_eject_disk(label) + if not cfg.no_daemon_stop: + if sys.platform == 'darwin': + for label in (self.asi.dev_label, self.asi.ramdisk.label): + self._macOS_eject_disk(label) def _create_autosign_instances(self,create_dirs): d = {'offline': {'name':'asi'}} @@ -121,16 +122,22 @@ class CmdTestAutosignBase(CmdTestBase): setattr(self, data['name'], asi) def _create_removable_device(self): - img = self.asi.fs_image_path if sys.platform == 'linux': + run(['truncate', '--size=10M', str(self.asi.fs_image_path)], check=True) + cmd = [ + '/sbin/mkfs.ext2', + '-E', 'root_owner={}:{}'.format(os.getuid(), os.getgid()), + '-L', self.asi.dev_label, + str(self.asi.fs_image_path)] redir = DEVNULL - run(f'truncate --size=10M {img}'.split(), check=True) - run(f'/sbin/mkfs.ext2 -E root_owner={os.getuid()}:{os.getgid()} {img}'.split(), - stdout=redir, stderr=redir, check=True) + run(cmd, stdout=redir, stderr=redir, check=True) elif sys.platform == 'darwin': + cmd = [ + 'hdiutil', 'create', '-size', '10M', '-fs', 'exFAT', + '-volname', self.asi.dev_label, + str(self.asi.fs_image_path)] redir = None if cfg.exact_output or cfg.verbose else DEVNULL - run(f'hdiutil create -size 10M -fs exFAT -volname {self.asi.dev_label} {img}'.split(), - stdout=redir, check=True) + run(cmd, stdout=redir, check=True) def _macOS_mount_fs_image(self, loc): time.sleep(0.2) @@ -231,7 +238,7 @@ class CmdTestAutosignBase(CmdTestBase): if loc.dev_label_path.exists(): loc.dev_label_path.unlink() elif sys.platform == 'darwin': - loc.do_umount(silent=True) + self._macOS_eject_disk(loc.dev_label) def _mount_ops(self, loc, cmd, *args, **kwargs): return getattr(getattr(self,loc),cmd)(*args, silent=self.silent_mount, **kwargs) @@ -418,7 +425,8 @@ class CmdTestAutosignThreaded(CmdTestAutosignBase): def _wait_signed(self,desc): oqmsg_r(gray(f'→ offline wallet{"s" if desc.endswith("s") else ""} waiting for {desc}')) - assert not self.asi.device_inserted, f'‘{self.asi.dev_label_path}’ is inserted!' + assert not self.asi.device_inserted, ( + f'‘{getattr(self.asi, "dev_label_path", self.asi.dev_label)}’ is inserted!') assert not self.asi.mountpoint.is_mount(), f'‘{self.asi.mountpoint}’ is mounted!' self.insert_device() while True: diff --git a/test/cmdtest_py_d/ct_base.py b/test/cmdtest_py_d/ct_base.py index bd5cbc1e..0dc3d71c 100755 --- a/test/cmdtest_py_d/ct_base.py +++ b/test/cmdtest_py_d/ct_base.py @@ -111,3 +111,6 @@ class CmdTestBase: t.ok() t.skip_ok = True return t + + def noop(self): + return 'ok' diff --git a/test/cmdtest_py_d/ct_xmr_autosign.py b/test/cmdtest_py_d/ct_xmr_autosign.py index 5c5a9490..91a66cd0 100755 --- a/test/cmdtest_py_d/ct_xmr_autosign.py +++ b/test/cmdtest_py_d/ct_xmr_autosign.py @@ -41,6 +41,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): # ct_xmrwallet attrs: tx_relay_user = 'miner' + # user sid autosign shift kal_range add_coind_args user_data = ( ('miner', '98831F3A', False, 130, '1', []), ('alice', 'FE3C6545', True, 150, '1-2', []), @@ -51,6 +52,9 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): cmd_group = ( ('daemon_version', 'checking daemon version'), + ('gen_kafile_miner', 'generating key-address file for Miner'), + ('create_wallet_miner', 'creating Monero wallet for Miner'), + ('mine_initial_coins', 'mining initial coins'), ('create_tmp_wallets', 'creating temporary online wallets for Alice'), ('new_account_alice', 'adding an account to Alice’s tmp wallet'), ('new_address_alice', 'adding an address to Alice’s tmp wallet'), @@ -59,13 +63,12 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): ('delete_tmp_wallets', 'deleting Alice’s tmp wallets'), ('autosign_setup', 'autosign setup with Alice’s seed'), ('autosign_xmr_setup', 'autosign setup (creation of Monero signing wallets)'), - ('create_watchonly_wallets', 'creating online (watch-only) wallets for Alice'), + ('create_watchonly_wallets', 'creating watch-only wallets from Alice’s wallet dumps'), ('delete_tmp_dump_files', 'deleting Alice’s dump files'), - ('gen_kafiles', 'generating key-address files for Miner'), - ('create_wallets_miner', 'creating Monero wallets for Miner'), - ('mine_initial_coins', 'mining initial coins'), ('fund_alice1', 'sending funds to Alice (wallet #1)'), + ('check_bal_alice1', 'mining, checking balance (wallet #1)'), ('fund_alice2', 'sending funds to Alice (wallet #2)'), + ('check_bal_alice2', 'mining, checking balance (wallet #2)'), ('autosign_start_thread', 'starting autosign wait loop'), ('export_outputs1', 'exporting outputs from Alice’s watch-only wallet #1'), ('create_transfer_tx1', 'creating a transfer TX'), @@ -185,6 +188,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): + ['dump'] + ([] if autosign else [get_file_with_ext(data.udir,'akeys')]) ) t.expect('2 wallets dumped') + t.read() self.remove_device_online() return t @@ -204,15 +208,27 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): def delete_tmp_dump_files(self): return self._delete_files( '.dump' ) + def gen_kafile_miner(self): + return self.gen_kafiles(['miner']) + + def create_wallet_miner(self): + return self.create_wallets_miner() + def delete_dump_files(self): return self._delete_files( '.dump' ) def fund_alice1(self): - return self.fund_alice(wallet=1,check_bal=False) + return self.fund_alice(wallet=1) + + def check_bal_alice1(self): + return self.check_bal_alice(wallet=1) def fund_alice2(self): return self.fund_alice(wallet=2) + def check_bal_alice2(self): + return self.check_bal_alice(wallet=2) + def autosign_setup(self): return self.run_setup( mn_type = 'mmgen', @@ -221,25 +237,30 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): expect_args = ['Continue with Monero setup? (Y/n): ', 'n']) def autosign_xmr_setup(self): + self.insert_device_online() self.do_mount_online() self.asi_online.xmr_dir.mkdir(exist_ok=True) (self.asi_online.xmr_dir / 'old.vkeys').touch() self.do_umount_online() + self.remove_device_online() + self.insert_device() t = self.spawn('mmgen-autosign', self.opts + ['xmr_setup'], no_passthru_opts=True) t.written_to_file('View keys') + t.read() + self.remove_device() return t def create_watchonly_wallets(self): + return self.restore_wallets() + + def restore_wallets(self): self.insert_device_online() t = self.create_wallets('alice', op='restore') t.read() # required! self.remove_device_online() return t - def restore_wallets(self): - return self.create_watchonly_wallets() - def _create_transfer_tx(self, amt, add_opts=[]): self.insert_device_online() t = self.do_op( @@ -299,6 +320,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): + ([wallet_arg] if wallet_arg else []) ) desc_pfx = f'{desc}, ' if desc else '' + self.insert_device_online() # device must be removed by calling method return self.spawn( 'mmgen-xmrwallet', args, extra_desc=f'({desc_pfx}Alice)' ) def _sync_chkbal(self,wallet_arg,bal_chk_func): @@ -341,7 +363,6 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): return self._submit_transfer_tx( relay_parm=self.tx_relay_daemon_parm ) def _submit_transfer_tx(self,relay_parm=None,ext=None,op='submit',check_bal=True): - self.insert_device_online() t = self._xmr_autosign_op( op = op, add_opts = [f'--tx-relay-daemon={relay_parm}'] if relay_parm else [], @@ -350,7 +371,8 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): wait_signed = op == 'submit') t.expect( f'{op.capitalize()} transaction? (y/N): ', 'y' ) t.written_to_file('Submitted transaction') - self.remove_device_online() + t.read() + self.remove_device_online() # device was inserted by _xmr_autosign_op() if check_bal: t.ok() return self._mine_chk('unlocked') @@ -358,13 +380,13 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): return t def _export_outputs(self, wallet_arg, op, add_opts=[]): - self.insert_device_online() t = self._xmr_autosign_op( op = op, wallet_arg = wallet_arg, add_opts = add_opts) t.written_to_file('Wallet outputs') - self.remove_device_online() + t.read() + self.remove_device_online() # device was inserted by _xmr_autosign_op() return t def export_outputs1(self): @@ -377,14 +399,13 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): return self._export_outputs('1-2', op='export-outputs-sign') def _import_key_images(self,wallet_arg): - self.insert_device_online() t = self._xmr_autosign_op( op = 'import-key-images', wallet_arg = wallet_arg, signable_desc = 'wallet outputs', wait_signed = True) t.read() - self.remove_device_online() + self.remove_device_online() # device was inserted by _xmr_autosign_op() return t def import_key_images1(self): @@ -402,6 +423,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): 'transfer 1:0','-> ext', 'transfer 1:0','-> ext' ]) + t.read() self.remove_device_online() return t @@ -414,6 +436,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): def txview_all(self): t = self.spawn('', msg_only=True) + self.insert_device() self.do_mount() imsg(blue('Opening transaction directory: ') + cyan(f'{self.asi.xmr_tx_dir}')) for fn in self.asi.xmr_tx_dir.iterdir(): @@ -421,6 +444,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): self.spawn('mmgen-xmrwallet', ['txview', str(fn)], no_msg=True).read() imsg('') self.do_umount() + self.remove_device() return 'ok' def check_tx_dirs(self): @@ -429,10 +453,14 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): self.do_mount() before = '\n'.join(self._gen_listing()) self.do_umount() + self.remove_device() + self.insert_device() t = self.spawn('mmgen-autosign', self.opts + ['clean']) t.read() + self.remove_device() + self.insert_device() self.do_mount() after = '\n'.join(self._gen_listing()) self.do_umount() diff --git a/test/cmdtest_py_d/ct_xmrwallet.py b/test/cmdtest_py_d/ct_xmrwallet.py index 89e88bb9..939119ce 100755 --- a/test/cmdtest_py_d/ct_xmrwallet.py +++ b/test/cmdtest_py_d/ct_xmrwallet.py @@ -74,6 +74,7 @@ class CmdTestXMRWallet(CmdTestBase): color = True socks_port = 49237 # Bob’s daemon is stopped via process kill, not RPC, so put Bob last in list: + # user sid autosign shift kal_range add_coind_args user_data = ( ('miner', '98831F3A', False, 130, '1-2', []), ('alice', 'FE3C6545', False, 150, '1-4', []), @@ -84,12 +85,13 @@ class CmdTestXMRWallet(CmdTestBase): cmd_group = ( ('daemon_version', 'checking daemon version'), - ('gen_kafiles', 'generating key-address files'), + ('gen_kafiles_miner_alice', 'generating key-address files for Miner and Alice'), ('create_wallets_miner', 'creating Monero wallets (Miner)'), ('set_label_miner', 'setting an address label (Miner, primary account)'), ('mine_initial_coins', 'mining initial coins'), ('create_wallets_alice', 'creating Monero wallets (Alice)'), ('fund_alice', 'sending funds'), + ('check_bal_alice', 'mining, checking balance'), ('sync_wallets_all', 'syncing all wallets'), ('new_account_alice', 'creating a new account (Alice)'), @@ -337,9 +339,12 @@ class CmdTestXMRWallet(CmdTestBase): rpc_port = self.users['miner'].md.rpc_port return self.spawn( 'mmgen-tool', ['--coin=xmr', f'--rpc-port={rpc_port}', 'daemon_version'] ) - def gen_kafiles(self): + def gen_kafiles_miner_alice(self): + return self.gen_kafiles(['miner', 'alice']) + + def gen_kafiles(self, users): for user,data in self.users.items(): - if data.autosign or not data.kal_range: + if not user in users: continue run(['mkdir','-p',data.udir]) run(f'rm -f {data.kafile}',shell=True) @@ -356,6 +361,7 @@ class CmdTestXMRWallet(CmdTestBase): def create_wallets_miner(self): return self.create_wallets('miner') + def create_wallets_alice(self): return self.create_wallets('alice') @@ -433,19 +439,18 @@ class CmdTestXMRWallet(CmdTestBase): # NB: a large balance is required to avoid ‘insufficient outputs’ error return await self.mine_chk('miner',1,0,lambda x: x.ub > 2000,'unlocked balance > 2000') - async def fund_alice(self,wallet=1,check_bal=True): + async def fund_alice(self, wallet=1, amt=1234567891234): self.spawn('', msg_only=True, extra_desc='(transferring funds from Miner wallet)') await self.transfer( 'miner', - 1234567891234, + amt, read_from_file(self.users['alice'].addrfile_fs.format(wallet)), ) - if not check_bal: - return 'ok' - ok() - bal = '1.234567891234' + return 'ok' + + async def check_bal_alice(self, wallet=1, bal='1.234567891234'): return await self.mine_chk( - 'alice',wallet,0, + 'alice', wallet, 0, lambda x: str(x.ub) == bal,f'unlocked balance == {bal}', random_txs = self.dfl_random_txs ) @@ -482,6 +487,15 @@ class CmdTestXMRWallet(CmdTestBase): def list_wallets_all(self): return self.sync_wallets('alice', op='list', add_opts=['-Ee', '--full-address']) + def sync_wallets_alice(self): + return self.sync_wallets('alice') + + def sync_wallets_bob(self): + return self.sync_wallets('bob') + + def sync_wallets_miner(self): + return self.sync_wallets('miner') + def sync_wallets(self,user,op='sync',wallets=None,add_opts=[],bal_chk_func=None): data = self.users[user] if data.autosign: @@ -669,6 +683,7 @@ class CmdTestXMRWallet(CmdTestBase): async def open_wallet_user(self,user,wnum): data = self.users[user] if data.autosign: + self.insert_device_online() self.do_mount_online() silence() kal = (ViewKeyAddrList if data.autosign else KeyAddrList)( @@ -680,6 +695,7 @@ class CmdTestXMRWallet(CmdTestBase): end_silence() if data.autosign: self.do_umount_online() + self.remove_device_online() self.users[user].wd.start(silent=not (cfg.exact_output or cfg.verbose)) return data.wd_rpc.call( 'open_wallet', diff --git a/test/include/common.py b/test/include/common.py index 7a9dc23c..a4d98ca8 100755 --- a/test/include/common.py +++ b/test/include/common.py @@ -332,9 +332,9 @@ def get_ethkey(): else: die(1,f'ethkey executable not found (tried {cmdnames})') -def do_run(cmd): +def do_run(cmd, check=True): from subprocess import run,PIPE,DEVNULL - return run(cmd, stdout=PIPE, stderr=DEVNULL, check=True) + return run(cmd, stdout=PIPE, stderr=DEVNULL, check=check) class VirtBlockDevice: diff --git a/test/unit_tests_d/ut_dep.py b/test/unit_tests_d/ut_dep.py index 23962968..c8b3ec6b 100755 --- a/test/unit_tests_d/ut_dep.py +++ b/test/unit_tests_d/ut_dep.py @@ -51,12 +51,13 @@ class unit_tests: session.trust_env = False session.proxies.update({'https':'socks5h://127.243.172.8:20677'}) try: - session.get('https://127.188.29.17') + session.get('https://127.188.29.17', timeout=1) except Exception as e: - if type(e).__name__ == 'ConnectionError': + if type(e).__name__ in ('ConnectionError', 'ConnectTimeout'): return True else: - print(e) + ymsg('{}: {}'.format(type(e).__name__, e)) + msg('Is the ‘pysocks’ package installed?') return False def secp256k1(self,name,ut):