cmdtest.py: suppress traceback with expected non-zero exit val

This commit is contained in:
The MMGen Project 2024-03-08 14:13:23 +00:00
commit cf2e308713
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
16 changed files with 90 additions and 91 deletions

View file

@ -1 +1 @@
14.1.dev18
14.1.dev19

View file

@ -69,8 +69,8 @@ def exec_wrapper_write_traceback(e,exit_val):
if 'SystemExit' in exc_line:
tb_lines.pop()
if os.getenv('EXEC_WRAPPER_EXIT_OK'):
sys.stdout.write(c.red(exc_line))
if os.getenv('EXEC_WRAPPER_EXIT_VAL') == str(exit_val):
sys.stdout.write(c.yellow(exc_line) + '\n')
else:
sys.stdout.write('{}\n{}\n'.format(
c.yellow('\n'.join(tb_lines)),

View file

@ -616,8 +616,11 @@ class CmdTestRunner:
direct_exec = False,
no_passthru_opts = False,
spawn_env_override = None,
exit_val = None,
env = {}):
self.exit_val = exit_val
desc = self.tg.test_name if cfg.names else self.gm.dpy_data[self.tg.test_name][1]
if extra_desc:
desc += ' ' + extra_desc
@ -684,6 +687,7 @@ class CmdTestRunner:
spawn_env.update({
'MMGEN_HOLD_PROTECT_DISABLE': '' if send_delay else '1',
'MMGEN_TEST_SUITE_POPEN_SPAWN': '' if pexpect_spawn else '1',
'EXEC_WRAPPER_EXIT_VAL': '' if exit_val is None else str(exit_val),
})
spawn_env.update(env)
@ -963,7 +967,7 @@ class CmdTestRunner:
def process_retval(self,cmd,ret):
if type(ret).__name__ == 'MMGenPexpect':
ret.ok()
ret.ok(exit_val=self.exit_val)
self.cmd_total += 1
elif ret == 'ok':
ok()

View file

@ -89,11 +89,11 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtestBDBWallet)
'mmgen-txcreate',
opts
+ ['--alice', '--autosign']
+ [f'{self.burn_addr},1.23456', f'{sid}:{chg_addr}'])
+ [f'{self.burn_addr},1.23456', f'{sid}:{chg_addr}'],
exit_val = exit_val or None)
if exit_val:
t.read()
self.remove_device_online()
t.req_exit_val = exit_val
return t
t = self.txcreate_ui_common(
t,
@ -121,15 +121,14 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtestBDBWallet)
self.insert_device_online()
t = self.spawn(
'mmgen-txsend',
['--quiet', '--abort'])
['--quiet', '--abort'],
exit_val = 2 if err else 1 if user_exit else None)
if err:
t.expect('No unsent transactions')
t.req_exit_val = 2
else:
t.expect('(y/N): ', 'n' if user_exit else 'y')
if user_exit:
t.expect('Exiting at user request')
t.req_exit_val = 1
else:
for pat in del_expect:
t.expect(pat, regex=True)
@ -191,11 +190,10 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtestBDBWallet)
self.insert_device_online()
t = self.spawn(
'mmgen-txsend',
['--alice', '--autosign', '--status', '--verbose'])
['--alice', '--autosign', '--status', '--verbose'],
exit_val = exit_val)
t.expect(expect)
self.remove_device_online()
if exit_val:
t.req_exit_val = exit_val
return t
def alice_txstatus1(self):
@ -209,7 +207,7 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtestBDBWallet)
return self._alice_txstatus('in mempool')
def alice_txstatus4(self):
return self._alice_txstatus('1 confirmation')
return self._alice_txstatus('1 confirmation', 0)
def _alice_txsend(self, comment=None, no_wait=False):
if not no_wait:
@ -226,10 +224,9 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtestBDBWallet)
def alice_txsend_bad_no_unsent(self):
self.insert_device_online()
t = self.spawn('mmgen-txsend', ['--quiet', '--autosign'])
t = self.spawn('mmgen-txsend', ['--quiet', '--autosign'], exit_val=2)
t.expect('No unsent transactions')
t.read()
t.req_exit_val = 2
self.remove_device_online()
return t
@ -239,11 +236,11 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtestBDBWallet)
self.insert_device_online()
t = self.spawn(
'mmgen-txbump',
['--alice', '--autosign'])
['--alice', '--autosign'],
exit_val = 1 if bad_tx_desc else None)
if bad_tx_desc:
t.expect('Only sent transactions')
t.expect(bad_tx_desc)
t.req_exit_val = 1
else:
t.expect(f'to deduct the fee from .* change output\): ', '\n', regex=True)
t.expect(r'(Y/n): ', 'y') # output OK?

View file

@ -636,14 +636,17 @@ class CmdTestAutosign(CmdTestAutosignBase):
tx_desc = Signable.transaction.desc
t = self.spawn(
'mmgen-autosign',
self.opts + args)
self.opts + args,
exit_val = 1
if 'wait' in args
or self.bad_tx_count
or (have_msg and self.bad_msg_count) else None)
t.expect(
f'{self.tx_count} {tx_desc}{suf(self.tx_count)} signed' if self.tx_count else
f'No unsigned {tx_desc}s')
if self.bad_tx_count:
t.expect(f'{self.bad_tx_count} {tx_desc}{suf(self.bad_tx_count)} failed to sign')
t.req_exit_val = 1
if have_msg:
t.expect(
@ -655,13 +658,11 @@ class CmdTestAutosign(CmdTestAutosignBase):
t.expect(
f'{self.bad_msg_count} message file{suf(self.bad_msg_count)}{{0,1}} failed to sign',
regex = True)
t.req_exit_val = 1
if 'wait' in args:
t.expect('Waiting')
imsg(purple('\nKilling wait loop!'))
t.kill(2)
t.req_exit_val = 1
else:
t.read()
@ -805,7 +806,8 @@ class CmdTestAutosignLive(CmdTestAutosignBTC):
t = self.spawn(
'mmgen-autosign',
self.opts + (led_opts or []) + ['--quiet', '--no-summary', 'wait'],
no_msg = True)
no_msg = True,
exit_val = 1)
if not cfg.exact_output:
omsg('')
@ -818,7 +820,6 @@ class CmdTestAutosignLive(CmdTestAutosignBTC):
imsg(purple('\nKilling wait loop!'))
t.kill(2) # 2 = SIGINT
t.req_exit_val = 1
if self.simulate_led and led_opts:
t.expect('Stopping LED')

View file

@ -44,13 +44,14 @@ class CmdTestCfgFile(CmdTestBase):
CmdTestBase.__init__(self,trunner,cfgs,spawn)
self.spawn_env['MMGEN_TEST_SUITE_CFGTEST'] = '1'
def spawn_test(self,args=[],extra_desc='',pexpect_spawn=None):
def spawn_test(self,args=[],extra_desc='',pexpect_spawn=None, exit_val=None):
return self.spawn(
'test/misc/cfg.py',
[f'--data-dir={self.path("data_dir")}'] + args,
cmd_dir = '.',
extra_desc = extra_desc,
pexpect_spawn = pexpect_spawn)
pexpect_spawn = pexpect_spawn,
exit_val = exit_val)
def path(self,id_str):
return {
@ -111,7 +112,7 @@ class CmdTestCfgFile(CmdTestBase):
chk = cfg_file_sample.cls_make_metadata(d)
write_to_file(self.path('sample'),'\n'.join(d+chk) + '\n')
t = self.spawn_test(args=args,pexpect_spawn=pexpect_spawn)
t = self.spawn_test(args=args, pexpect_spawn=pexpect_spawn, exit_val=1 if old_set else None)
t.expect('options have changed')
for s in ('have been added','monero_','have been removed','zcash_','foo','bar'):
@ -136,7 +137,6 @@ class CmdTestCfgFile(CmdTestBase):
if old_set:
t.expect('unrecognized option')
t.req_exit_val = 1
if args == ['parse_test']:
t.expect('parsed chunks: 29')
@ -159,10 +159,10 @@ class CmdTestCfgFile(CmdTestBase):
old_set = True,
pexpect_spawn = not sys.platform == 'win32')
def _autoset_opts(self,args=[],text='rpc_backend aiohttp\n'):
def _autoset_opts(self, args=[], text='rpc_backend aiohttp\n', exit_val=None):
write_to_file( self.path('usr'), text )
imsg(yellow(f'Wrote cfg file:\n {text}'))
return self.spawn_test(args=args)
return self.spawn_test(args=args, exit_val=exit_val)
def autoset_opts(self):
return self._autoset_opts(args=['autoset_opts'])
@ -171,9 +171,7 @@ class CmdTestCfgFile(CmdTestBase):
return self._autoset_opts(args=['--rpc-backend=curl','autoset_opts_cmdline'])
def _autoset_opts_bad(self,kwargs):
t = self._autoset_opts(**kwargs)
t.req_exit_val = 1
return t
return self._autoset_opts(exit_val=1, **kwargs)
def autoset_opts_bad(self):
return self._autoset_opts_bad({'text':'rpc_backend foo\n'})

View file

@ -601,10 +601,11 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared):
ext = '21-23]{}.regtest.addrs',
expect = '9/9',
add_args = [],
bad_input = False):
bad_input = False,
exit_val = None):
ext = ext.format('' if cfg.debug_utf8 else '')
fn = self.get_file_with_ext(ext,no_dot=True,delete=False)
t = self.spawn('mmgen-addrimport', self.eth_args[1:-1] + add_args + [fn])
t = self.spawn('mmgen-addrimport', self.eth_args[1:-1] + add_args + [fn], exit_val=exit_val)
if bad_input:
return t
t.expect('Importing')
@ -750,11 +751,11 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared):
txfile = self.get_file_with_ext(ext,no_dot=True)
t = self.spawn(
'mmgen-txsend',
self.eth_args + add_args + ['--status', txfile])
self.eth_args + add_args + ['--status', txfile],
exit_val = exit_val)
t.expect(expect_str)
if expect_str2:
t.expect(expect_str2)
t.req_exit_val = exit_val
return t
def tx_status1(self):
@ -1119,18 +1120,18 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared):
t = self.addrimport(
ext = '[11-13]{}.regtest.addrs',
add_args = ['--token=abc'],
bad_input = True)
bad_input = True,
exit_val = 2)
t.expect('could not be resolved')
t.req_exit_val = 2
return t
def token_addrimport_badaddr2(self):
t = self.addrimport(
ext = '[11-13]{}.regtest.addrs',
add_args = ['--token='+'00deadbeef'*4],
bad_input = True)
bad_input = True,
exit_val = 2)
t.expect('could not be resolved')
t.req_exit_val = 2
return t
def token_addrimport(self,addr_file,addr_range,expect,extra_args=[]):

View file

@ -781,7 +781,8 @@ class CmdTestMain(CmdTestBase,CmdTestShared):
'mmgen-addrgen',
(['-S'] if stdout else []) +
self.segwit_arg +
['-i' + in_fmt, '-d', self.tmpdir, wf, self.addr_idx_list])
['-i' + in_fmt, '-d', self.tmpdir, wf, self.addr_idx_list],
exit_val = None if stdout else 1)
t.license()
t.expect_getend(f'Valid {wcls.desc} for Seed ID ')
vmsg('Comparing generated checksum with checksum from previous address file')
@ -790,7 +791,6 @@ class CmdTestMain(CmdTestBase,CmdTestShared):
t.expect_getend(r'Checksum for address data .*?: ',regex=True) )
if not stdout:
t.no_overwrite()
t.req_exit_val = 1
return t
def addrgen_hex(self,wf,_,in_fmt='mmhex'):
@ -806,7 +806,8 @@ class CmdTestMain(CmdTestBase,CmdTestShared):
+ self.segwit_arg
+ ['-i'+in_fmt, '-d', self.tmpdir]
+ ([wf] if wf else [])
+ [self.addr_idx_list])
+ [self.addr_idx_list],
exit_val = 1)
t.license()
t.expect_getend('Incog Wallet ID: ')
wcls = get_wallet_cls(fmt_code=in_fmt)
@ -816,7 +817,6 @@ class CmdTestMain(CmdTestBase,CmdTestShared):
chk = t.expect_getend(r'Checksum for address data .*?: ',regex=True)
verify_checksum_or_exit(self._get_addrfile_checksum(),chk)
t.no_overwrite()
t.req_exit_val = 1
return t
def addrgen_incog_hex(self,wf,_):
@ -973,7 +973,8 @@ class CmdTestMain(CmdTestBase,CmdTestShared):
non_mm_file = joinpath(self.tmpdir,non_mmgen_fn)
t = self.spawn(
'mmgen-txsign',
add_args + ['-d', self.tmpdir, '-k', non_mm_file, txf, wf])
add_args + ['-d', self.tmpdir, '-k', non_mm_file, txf, wf],
exit_val = 2 if bad_vsize else None)
t.license()
t.view_tx('n')
wcls = get_wallet_cls(ext=get_extension(wf))
@ -981,12 +982,9 @@ class CmdTestMain(CmdTestBase,CmdTestShared):
if bad_vsize:
t.expect('Estimated transaction vsize')
t.expect('1 transaction could not be signed')
exit_val = 2
else:
t.do_comment(False)
t.expect('Save signed transaction? (Y/n): ','y')
exit_val = 0
t.req_exit_val = exit_val
return t
def walletgen6(self,del_dw_run='dummy'):

View file

@ -168,9 +168,8 @@ class CmdTestHelp(CmdTestBase):
)
def usage(self):
t = self.spawn('mmgen-walletgen', ['foo'])
t = self.spawn('mmgen-walletgen', ['foo'], exit_val=1)
t.expect('USAGE: mmgen-walletgen')
t.req_exit_val = 1
return t
def version(self):

View file

@ -29,8 +29,8 @@ class CmdTestOpts(CmdTestBase):
('opt_bad_autoset', (41,"invalid autoset value", [])),
)
def spawn_prog(self,args):
return self.spawn('test/misc/opts.py',args,cmd_dir='.')
def spawn_prog(self, args, exit_val=None):
return self.spawn('test/misc/opts.py', args, cmd_dir='.', exit_val=exit_val)
def check_vals(self,args,vals):
t = self.spawn_prog(args)
@ -39,9 +39,8 @@ class CmdTestOpts(CmdTestBase):
return t
def do_run(self,args,expect,exit_val,regex=False):
t = self.spawn_prog(args)
t = self.spawn_prog(args, exit_val=exit_val or None)
t.expect(expect,regex=regex)
t.req_exit_val = exit_val
return t
def opt_helpscreen(self):

View file

@ -711,13 +711,11 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
return self.fund_wallet('alice',('L','S')[self.proto.cap('segwit')],rtFundAmt)
def user_twview(self, user, chk=None, expect=None, cmdline=['twview'], sort='age', exit_val=None):
t = self.spawn('mmgen-tool',[f'--{user}'] + cmdline + ['sort='+sort])
t = self.spawn('mmgen-tool',[f'--{user}'] + cmdline + ['sort='+sort], exit_val=exit_val)
if chk:
t.expect(r'{}\b.*\D{}\b'.format(*chk),regex=True)
if expect:
t.expect(expect)
if exit_val:
t.req_exit_val = exit_val
return t
def bob_twview_noaddrs(self):
@ -949,10 +947,12 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
tx_file,
exp1 = '',
exp2 = '',
extra_args = []):
extra_args = [],
exit_val = None):
t = self.spawn(
'mmgen-txsend',
['-d', self.tmpdir, '--'+user, '--status'] + extra_args + [tx_file])
['-d', self.tmpdir, '--'+user, '--status'] + extra_args + [tx_file],
exit_val = exit_val)
if exp1:
t.expect(exp1,regex=True)
if exp2:
@ -977,7 +977,8 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
return_after_send = False,
menu = ['M'],
skip_passphrase = False,
used_chg_addr_resp = None):
used_chg_addr_resp = None,
exit_val = None):
t = self.spawn(
'mmgen-txdo',
@ -985,7 +986,8 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
+ (['--fee='+fee] if fee else [])
+ extra_args
+ ([],[wf])[bool(wf)]
+ outputs_cl)
+ outputs_cl,
exit_val = exit_val)
self.txcreate_ui_common(
t,
@ -1132,12 +1134,12 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
self.write_to_tmpfile('rbf_txid',mp[0]+'\n')
return 'ok'
def bob_rbf_status(self, fee, exp1, exp2=''):
def bob_rbf_status(self, fee, exp1, exp2='', exit_val=None):
if not self.proto.cap('rbf'):
return 'skip'
ext = ',{}]{x}.regtest.sigtx'.format(fee[:-1],x='' if cfg.debug_utf8 else '')
txfile = self.get_file_with_ext(ext,delete=False,no_dot=True)
return self.user_txsend_status('bob', txfile, exp1, exp2)
return self.user_txsend_status('bob', txfile, exp1, exp2, exit_val=exit_val)
def bob_rbf_status1(self):
if not self.proto.cap('rbf'):
@ -1163,7 +1165,8 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
return self.bob_rbf_status(
rtFee[1],
'Transaction has been replaced',
f'{new_txid} in mempool')
f'{new_txid} in mempool',
exit_val = 0)
def bob_rbf_status3(self):
if not self.proto.cap('rbf'):
@ -1514,8 +1517,8 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
extra_args = [f'--locktime={locktime}'],
return_early = return_early,
add_comment = False,
return_after_send = True)
t.req_exit_val = exit_val
return_after_send = True,
exit_val = exit_val)
if expect:
t.expect(expect)
return t
@ -1556,9 +1559,9 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
return 'skip'
t = self.spawn(
'mmgen-tool',
['--alice','add_label',addr,'(none)'])
['--alice','add_label',addr,'(none)'],
exit_val = exit_val)
t.expect(reply,regex=True)
t.req_exit_val = exit_val
return t
def alice_add_comment_badaddr1(self):
@ -1809,19 +1812,21 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
addr = None,
ext = 'sigmsg.json',
cmd = 'verify',
msgfile = None):
msgfile = None,
exit_val = None):
return self.spawn(
'mmgen-msg', [
'--bob',
f'--outdir={self.tmpdir}',
cmd,
msgfile or get_file_with_ext(self.tmpdir,ext),
] + ([addr] if addr else []) )
]
+ ([addr] if addr else []),
exit_val = exit_val)
def bob_msgverify_raw(self):
t = self.bob_msgverify(ext='rawmsg.json')
t = self.bob_msgverify(ext='rawmsg.json', exit_val=1)
t.expect('No signatures')
t.req_exit_val = 1
return t
def bob_msgverify_single(self):
@ -1947,8 +1952,8 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
def _usr_auto_chg_bad(self,user,al_id,expect):
t = self.spawn(
'mmgen-txcreate',
['-d', self.tr.trash_dir, '-B', f'--{user}', self.burn_addr+', 0.01', al_id])
t.req_exit_val = 2
['-d', self.tr.trash_dir, '-B', f'--{user}', self.burn_addr+', 0.01', al_id],
exit_val = 2)
t.expect(expect)
return t

View file

@ -132,7 +132,7 @@ class CmdTestSeedSplit(CmdTestBase):
in_exts,
add_args = [],
sid = None,
bad_invocation = False,
exit_val = None,
master = None,
id_str = None):
td = self.get_tmp_subdir(tdir)
@ -145,8 +145,9 @@ class CmdTestSeedSplit(CmdTestBase):
+ ([f'--id-str={id_str}'] if id_str else [])
+ ['-d',td,'-o',ofmt]
+ (['--label','Joined Wallet Label','-r0'] if ofmt == 'w' else [])
+ shares)
if bad_invocation:
+ shares,
exit_val = exit_val)
if exit_val:
return t
icls = ( dfl_wcls if 'mmdat' in in_exts
else get_wallet_cls('incog') if 'mmincog' in in_exts
@ -241,8 +242,7 @@ class CmdTestSeedSplit(CmdTestBase):
['-H',self.get_hincog_arg(self.tdir2,'-master7')],master=7,id_str='φυβαρ')
def ss_bad_invocation(self,cmd,args,exit_val,errmsg):
t = self.spawn(cmd,args)
t.req_exit_val = exit_val
t = self.spawn(cmd, args, exit_val=exit_val)
t.expect(errmsg)
return t
@ -250,7 +250,7 @@ class CmdTestSeedSplit(CmdTestBase):
t = self.ss_join('3way_dfl','mmhex',
['mmwords','mmincox','bip39'],
id_str = 'foo',
bad_invocation = True)
exit_val = 1)
t.expect('option meaningless')
return t

View file

@ -195,13 +195,14 @@ class CmdTestShared:
view = 'n',
dfl_wallet = False):
opts = extra_opts + ['-d',self.tmpdir,txfile] + ([wf] if wf else [])
wcls = get_wallet_cls(ext = 'mmdat' if dfl_wallet else get_extension(wf))
t = self.spawn(
'mmgen-txsign',
opts,
extra_desc)
extra_desc,
exit_val = None if save or (wcls.enc and wcls.type != 'brain') else 1)
t.license()
t.view_tx(view)
wcls = get_wallet_cls( ext = 'mmdat' if dfl_wallet else get_extension(wf) )
if wcls.enc and wcls.type != 'brain':
t.passphrase(wcls.desc,self.wpasswd)
if save:
@ -210,7 +211,6 @@ class CmdTestShared:
t.do_comment(False,has_label=has_label)
t.expect('Save signed transaction? (Y/n): ','n')
t.expect('not saved')
t.req_exit_val = 1
return t
def ref_brain_chk(self,bw_file=ref_bw_file):

View file

@ -95,9 +95,9 @@ class CmdTestTool(CmdTestMain,CmdTestBase):
t = self.spawn(
'mmgen-tool',
['twview'],
env = { 'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir,'bad-comment-unspent.json') })
env = { 'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir,'bad-comment-unspent.json') },
exit_val = 2)
t.expect('cannot be converted to TwComment')
t.req_exit_val = 2
return t
def _decrypt_keystore(self,cmd,fn,pw,chk):

View file

@ -258,14 +258,12 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
def _abort_tx(self,expect,send=None,exit_val=None):
self.insert_device_online()
t = self.spawn('mmgen-xmrwallet', ['--autosign', 'abort'])
t = self.spawn('mmgen-xmrwallet', ['--autosign', 'abort'], exit_val=exit_val)
t.expect(expect)
if send:
t.send(send)
t.read() # required!
self.remove_device_online()
if exit_val:
t.req_exit_val = exit_val
return t
def abort_tx1(self):

View file

@ -51,7 +51,6 @@ class MMGenPexpect:
self.pexpect_spawn = pexpect_spawn
self.send_delay = send_delay
self.req_exit_val = 0
self.skip_ok = False
self.sent_value = None
self.spawn_env = spawn_env
@ -91,12 +90,12 @@ class MMGenPexpect:
if add_comment:
self.expect('Comment: ',add_comment+'\n')
def ok(self):
def ok(self, exit_val=None):
if not self.pexpect_spawn:
self.p.sendeof()
self.p.read()
ret = self.p.wait()
if ret != self.req_exit_val and not cfg.coverage:
if ret != (exit_val or 0) and not cfg.coverage:
die( 'TestSuiteSpawnedScriptException', f'Spawned script exited with value {ret}' )
if cfg.profile:
return