From 41376eb515aaf95a0fca7fae05e5369f5782a7a2 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sat, 5 Feb 2022 13:32:56 +0000 Subject: [PATCH] new MMGenSystemExit exception; remove rdie(), ydie() --- mmgen/base_proto/bitcoin/tx/status.py | 2 +- mmgen/devtools.py | 6 ++--- mmgen/exception.py | 13 ++++++++++ mmgen/fileutil.py | 2 +- mmgen/led.py | 2 +- mmgen/main.py | 34 +++++++++++++++++++-------- mmgen/main_addrimport.py | 2 +- mmgen/main_autosign.py | 2 +- mmgen/main_tool.py | 6 ++--- mmgen/main_txsign.py | 2 +- mmgen/protocol.py | 9 ++++--- mmgen/regtest.py | 2 +- mmgen/rpc.py | 6 ++--- mmgen/twaddrs.py | 6 +++-- mmgen/tx/new.py | 8 +++---- mmgen/util.py | 24 +++++++------------ scripts/create-token.py | 2 +- scripts/exec_wrapper.py | 12 ++++++---- test/gentest.py | 2 +- test/include/pexpect.py | 11 +++++---- test/objattrtest.py | 12 +++++----- test/scrambletest.py | 4 ++-- test/test.py | 8 +++---- test/test_py_d/ts_autosign.py | 6 ++--- test/test_py_d/ts_ethdev.py | 4 ++-- test/test_py_d/ts_misc.py | 2 +- test/test_py_d/ts_regtest.py | 6 ++--- test/test_py_d/ts_seedsplit.py | 10 ++++---- test/tooltest.py | 9 ++++--- test/tooltest2.py | 2 +- test/unit_tests.py | 6 ++--- test/unit_tests_d/ut_daemon.py | 4 ++-- test/unit_tests_d/ut_indexed_dict.py | 2 +- 33 files changed, 126 insertions(+), 102 deletions(-) diff --git a/mmgen/base_proto/bitcoin/tx/status.py b/mmgen/base_proto/bitcoin/tx/status.py index 35cbc72a..e956f384 100755 --- a/mmgen/base_proto/bitcoin/tx/status.py +++ b/mmgen/base_proto/bitcoin/tx/status.py @@ -82,7 +82,7 @@ class Status(TxBase.Status): elif await is_in_wallet(): die(0,f'Transaction has {r.confs} confirmation{suf(r.confs)}') elif await is_in_utxos(): - rdie(2,'ERROR: transaction is in the blockchain (but not in the tracking wallet)!') + die(4,'ERROR: transaction is in the blockchain (but not in the tracking wallet)!') elif await is_replaced(): msg('Transaction has been replaced') msg('Replacement transaction ' + ( diff --git a/mmgen/devtools.py b/mmgen/devtools.py index baaee1e5..25a35e08 100755 --- a/mmgen/devtools.py +++ b/mmgen/devtools.py @@ -135,7 +135,7 @@ if os.getenv('MMGEN_DEBUG') or os.getenv('MMGEN_TEST_SUITE') or os.getenv('MMGEN def immutable_attr_init_check(self): from .globalvars import g if g.test_suite: - from .util import rdie + from .util import die cls = type(self) for attrname in sorted({a for a in self.valid_attrs if a[0] != '_'}): for o in (cls,cls.__bases__[0]): # assume there's only one base class @@ -143,10 +143,10 @@ if os.getenv('MMGEN_DEBUG') or os.getenv('MMGEN_TEST_SUITE') or os.getenv('MMGEN attr = o.__dict__[attrname] break else: - rdie(3,f'unable to find descriptor {cls.__name__}.{attrname}') + die(4,f'unable to find descriptor {cls.__name__}.{attrname}') if type(attr).__name__ == 'ImmutableAttr': if attrname not in self.__dict__: - rdie(3, + die(4, f'attribute {attrname!r} of {cls.__name__} has not been initialized in constructor!') def print_diff(a,b,from_file='',to_file='',from_json=True): diff --git a/mmgen/exception.py b/mmgen/exception.py index e2b162f5..9d010ba3 100755 --- a/mmgen/exception.py +++ b/mmgen/exception.py @@ -20,6 +20,19 @@ mmgen.exception: Exception classes for the MMGen suite """ +class MMGenError(Exception): + + def __init__(self,errno,strerror,stdout): + self.mmcode = errno + self.stdout = stdout + super().__init__(strerror) + + def __repr__(self): + return f'{type(self).__name__}({self.mmcode}): {self}' + +class MMGenSystemExit(MMGenError): + pass + # 1: no hl, message only class UserNonConfirmation(Exception): mmcode = 1 class BadAgeFormat(Exception): mmcode = 1 diff --git a/mmgen/fileutil.py b/mmgen/fileutil.py index 1ac786c3..1bbde693 100755 --- a/mmgen/fileutil.py +++ b/mmgen/fileutil.py @@ -57,7 +57,7 @@ def check_binary(args): try: run(args,stdout=DEVNULL,stderr=DEVNULL,check=True) except: - rdie(2,f'{args[0]!r} binary missing, not in path, or not executable') + die(2,f'{args[0]!r} binary missing, not in path, or not executable') def shred_file(fn,verbose=False): check_binary(['shred','--version']) diff --git a/mmgen/led.py b/mmgen/led.py index 3545f1f4..94ee9dfa 100755 --- a/mmgen/led.py +++ b/mmgen/led.py @@ -89,7 +89,7 @@ class LEDControl: fp.write(f'{init_val}\n') return True except PermissionError: - ydie(1,'\n'+fmt(f""" + die(2,'\n'+fmt(f""" You do not have access to the {desc} file To allow access, run the following command: diff --git a/mmgen/main.py b/mmgen/main.py index fc4e97b3..a9addc9e 100755 --- a/mmgen/main.py +++ b/mmgen/main.py @@ -43,21 +43,35 @@ def launch(mod): except EOFError: sys.stderr.write('\nEnd of file\n') except Exception as e: + if os.getenv('MMGEN_EXEC_WRAPPER'): raise else: - try: m = '{}'.format(e.args[0]) - except: m = repr(e.args[0]) + try: + errmsg = '{}'.format(e.args[0]) + except: + errmsg = repr(e.args[0]) - from .util import die,ydie,rdie - d = [ (ydie,2,'\nMMGen Unhandled Exception ({n}): {m}'), - (die, 1,'{m}'), - (ydie,2,'{m}'), - (ydie,3,'\nMMGen Error ({n}): {m}'), - (rdie,4,'\nMMGen Fatal Error ({n}): {m}') - ][e.mmcode if hasattr(e,'mmcode') else 0] + from collections import namedtuple + from mmgen.color import nocolor,yellow,red + + _o = namedtuple('exit_data',['color','exit_val','fs']) + d = { + 1: _o(nocolor, 1, '{message}'), + 2: _o(yellow, 2, '{message}'), + 3: _o(yellow, 3, '\nMMGen Error ({name}): {message}'), + 4: _o(red, 4, '\nMMGen Fatal Error ({name}): {message}'), + 'x': _o(yellow, 5, '\nMMGen Unhandled Exception ({name}): {message}'), + }[getattr(e,'mmcode','x')] + + (sys.stdout if getattr(e,'stdout',None) else sys.stderr).write( + d.color(d.fs.format( + name = type(e).__name__, + message = errmsg )) + + '\n' ) + + sys.exit(d.exit_val) - d[0](d[1],d[2].format(n=type(e).__name__,m=m)) except SystemExit as e: if os.getenv('MMGEN_EXEC_WRAPPER') and e.code != 0: from mmgen.color import red diff --git a/mmgen/main_addrimport.py b/mmgen/main_addrimport.py index b0c9faa4..a52e4f3a 100755 --- a/mmgen/main_addrimport.py +++ b/mmgen/main_addrimport.py @@ -78,7 +78,7 @@ def parse_cmd_args(rpc,cmd_args): al = (AddrList,KeyAddrList)[bool(opt.keyaddr_file)](proto,infile) if al.al_id.mmtype in ('S','B'): if not rpc.info('segwit_is_active'): - rdie(2,'Segwit is not active on this chain. Cannot import Segwit addresses') + die(2,'Segwit is not active on this chain. Cannot import Segwit addresses') return al if len(cmd_args) == 1: diff --git a/mmgen/main_autosign.py b/mmgen/main_autosign.py index 1542c979..f2cbe9c5 100755 --- a/mmgen/main_autosign.py +++ b/mmgen/main_autosign.py @@ -164,7 +164,7 @@ async def check_daemons_running(): try: await rpc_init(proto) except SocketError as e: - ydie(1,f'{coin} daemon not running or not listening on port {proto.rpc_port}') + die(2,f'{coin} daemon not running or not listening on port {proto.rpc_port}') def get_wallet_files(): try: diff --git a/mmgen/main_tool.py b/mmgen/main_tool.py index 02b8cfa1..44cb0b16 100755 --- a/mmgen/main_tool.py +++ b/mmgen/main_tool.py @@ -281,7 +281,7 @@ def process_args(cmd,cmd_args,cls): return ( args, kwargs ) def process_result(ret,pager=False,print_result=False): - from .util import Msg,ydie,parse_bytespec + from .util import Msg,die,parse_bytespec """ Convert result to something suitable for output to screen and return it. If result is bytes and not convertible to utf8, output as binary using os.write(). @@ -294,7 +294,7 @@ def process_result(ret,pager=False,print_result=False): if ret == True: return True elif ret in (False,None): - ydie(1,f'tool command returned {ret!r}') + die(2,f'tool command returned {ret!r}') elif isinstance(ret,str): return triage_result(ret) elif isinstance(ret,int): @@ -312,7 +312,7 @@ def process_result(ret,pager=False,print_result=False): else: return ret else: - ydie(1,f'tool.py: can’t handle return value of type {type(ret).__name__!r}') + die(2,f'tool.py: can’t handle return value of type {type(ret).__name__!r}') def get_cmd_cls(cmd): for modname,cmdlist in mods.items(): diff --git a/mmgen/main_txsign.py b/mmgen/main_txsign.py index b8eaf4c4..9434a8c5 100755 --- a/mmgen/main_txsign.py +++ b/mmgen/main_txsign.py @@ -156,6 +156,6 @@ async def main(): bad_tx_count += 1 if bad_tx_count: - ydie(2,f'{bad_tx_count} transaction{suf(bad_tx_count)} could not be signed') + die(2,f'{bad_tx_count} transaction{suf(bad_tx_count)} could not be signed') run_session(main()) diff --git a/mmgen/protocol.py b/mmgen/protocol.py index 0d257baf..3d24a70a 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -69,7 +69,7 @@ class CoinProtocol(MMGenObject): if 'tx' not in self.mmcaps and g.is_txprog: from .util import die - die(1,f'Command {g.prog_name!r} not supported for coin {self.coin}') + die(2,f'Command {g.prog_name!r} not supported for coin {self.coin}') if hasattr(self,'chain_names'): self.chain_name = self.chain_names[0] # first chain name is default @@ -171,15 +171,14 @@ class CoinProtocol(MMGenObject): if 0 < int.from_bytes(sec,'big') < self.secp256k1_ge: return sec else: # chance of this is less than 1 in 2^127 - from .util import ydie + from .util import die,ymsg pk = int.from_bytes(sec,'big') if pk == 0: # chance of this is 1 in 2^256 - ydie(3,'Private key is zero!') + die(4,'Private key is zero!') elif pk == self.secp256k1_ge: # ditto - ydie(3,'Private key == secp256k1_ge!') + die(4,'Private key == secp256k1_ge!') else: if not g.test_suite: - from .util import ymsg ymsg(f'Warning: private key is greater than secp256k1 group order!:\n {hexpriv}') return (pk % self.secp256k1_ge).to_bytes(self.privkey_len,'big') diff --git a/mmgen/regtest.py b/mmgen/regtest.py index d4e9edd2..432dbf6a 100755 --- a/mmgen/regtest.py +++ b/mmgen/regtest.py @@ -102,7 +102,7 @@ class MMGenRegtest(MMGenObject): out = await self.rpc_call(*cmd_args,wallet='miner') if len(out) != blocks: - rdie(1,'Error generating blocks') + die(4,'Error generating blocks') gmsg(f'Mined {blocks} block{suf(blocks)}') diff --git a/mmgen/rpc.py b/mmgen/rpc.py index 0c04a071..6514930d 100755 --- a/mmgen/rpc.py +++ b/mmgen/rpc.py @@ -537,7 +537,7 @@ class BitcoinRPCClient(RPCClient,metaclass=AsyncInit): await self.icall('createwallet',wallet_name=wname) ymsg(f'Created {self.daemon.coind_name} wallet {wname!r}') elif len(wallets) > 1: # support only one loaded wallet for now - rdie(2,f'ERROR: more than one {self.daemon.coind_name} wallet loaded: {wallets}') + die(4,f'ERROR: more than one {self.daemon.coind_name} wallet loaded: {wallets}') wallet_checked.append(True) def get_daemon_cfg_fn(self): @@ -665,7 +665,7 @@ class EthereumRPCClient(RPCClient,metaclass=AsyncInit): import re vip = re.match(self.daemon.version_pat,vi,re.ASCII) if not vip: - ydie(1,fmt(f""" + die(2,fmt(f""" Aborting on daemon mismatch: Requested daemon: {self.daemon.id} Running daemon: {vi} @@ -821,7 +821,7 @@ def handle_unsupported_daemon_version(rpc,name,warn_only): daemon_warning('version',div=name,fmt_args=[rpc.daemon.coind_name]) else: name = rpc.daemon.coind_name - rdie(1,'\n'+fmt(f""" + die(2,'\n'+fmt(f""" The running {name} daemon has version {rpc.daemon_version_str}. This version of MMGen is tested only on {name} v{rpc.daemon.coind_version_str} and below. diff --git a/mmgen/twaddrs.py b/mmgen/twaddrs.py index ef8cd04d..7c3311af 100755 --- a/mmgen/twaddrs.py +++ b/mmgen/twaddrs.py @@ -43,7 +43,8 @@ class TwAddrList(MMGenDict,TwCommon,metaclass=AsyncInit): err = True msg(f'Duplicate MMGen ID ({mmid}) discovered in tracking wallet!\n') mmid_prev = mmid - if err: rdie(3,'Tracking wallet is corrupted!') + if err: + die(4,'Tracking wallet is corrupted!') def check_addr_array_lens(acct_pairs): err = False @@ -55,7 +56,8 @@ class TwAddrList(MMGenDict,TwCommon,metaclass=AsyncInit): msg(f'Label {label!r}: has no associated address!') else: msg(f'{addrs!r}: more than one {proto.coin} address in account!') - if err: rdie(3,'Tracking wallet is corrupted!') + if err: + die(4,'Tracking wallet is corrupted!') self.rpc = await rpc_init(proto) self.total = proto.coin_amt('0') diff --git a/mmgen/tx/new.py b/mmgen/tx/new.py index ffad4164..939970f9 100755 --- a/mmgen/tx/new.py +++ b/mmgen/tx/new.py @@ -17,7 +17,7 @@ from ..opts import opt from .base import Base from ..color import pink from ..obj import get_obj,HexStr -from ..util import msg,qmsg,fmt,suf,remove_dups,get_extension,keypress_confirm,do_license_msg,line_input +from ..util import msg,qmsg,fmt,die,suf,remove_dups,get_extension,keypress_confirm,do_license_msg,line_input from ..addr import is_mmgen_id,CoinAddr,is_coin_addr def mmaddr2coinaddr(mmaddr,ad_w,ad_f,proto): @@ -53,9 +53,9 @@ def mmaddr2coinaddr(mmaddr,ad_w,ad_f,proto): if not (opt.yes or keypress_confirm('Continue anyway?')): sys.exit(1) else: - ydie(2,wmsg('addr_not_found')) + die(2,wmsg('addr_not_found')) else: - ydie(2,wmsg('addr_not_found_no_addrfile')) + die(2,wmsg('addr_not_found_no_addrfile')) return CoinAddr(proto,coin_addr) @@ -208,7 +208,7 @@ class New(Base): 'ERROR: No change output specified' )) if self.has_segwit_outputs() and not self.rpc.info('segwit_is_active'): - rdie(2,f'{g.proj_name} Segwit address requested on the command line, ' + die(2,f'{g.proj_name} Segwit address requested on the command line, ' + 'but Segwit is not active on this chain') if not self.outputs: diff --git a/mmgen/util.py b/mmgen/util.py index f39cd5f1..9af2a404 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -120,11 +120,13 @@ def mdie(*args): mmsg(*args) sys.exit(0) -def die(ev=0,s=''): +def die(ev,s='',stdout=False): assert isinstance(ev,int) - if s: - msg(s) - sys.exit(ev) + from .exception import MMGenSystemExit,MMGenError + if ev <= 2: + raise MMGenSystemExit(ev,s,stdout) + else: + raise MMGenError(ev,s,stdout) def die_wait(delay,ev=0,s=''): assert isinstance(delay,int) @@ -142,16 +144,7 @@ def die_pause(ev=0,s=''): sys.exit(ev) def Die(ev=0,s=''): - assert isinstance(ev,int) - if s: - Msg(s) - sys.exit(ev) - -def rdie(ev=0,s=''): - die(ev,red(s)) - -def ydie(ev=0,s=''): - die(ev,yellow(s)) + die(ev=ev,s=s,stdout=True) def pp_fmt(d): import pprint @@ -206,8 +199,7 @@ def remove_dups(iterable,edesc='element',desc='list',quiet=False,hide=False): def exit_if_mswin(feature): if g.platform == 'win': - m = capfirst(feature) + ' not supported on the MSWin / MSYS2 platform' - ydie(1,m) + die(2, capfirst(feature) + ' not supported on the MSWin / MSYS2 platform' ) def get_keccak(): diff --git a/scripts/create-token.py b/scripts/create-token.py index 8e8b80c1..260494d6 100755 --- a/scripts/create-token.py +++ b/scripts/create-token.py @@ -243,7 +243,7 @@ def compile_code(code): if cp.returncode != 0: rmsg('Solidity compiler produced the following error:') msg(err) - rdie(2,f'Solidity compiler exited with error (return val: {cp.returncode})') + die(4,f'Solidity compiler exited with error (return val: {cp.returncode})') if err: ymsg('Solidity compiler produced the following warning:') msg(err) diff --git a/scripts/exec_wrapper.py b/scripts/exec_wrapper.py index d983a87a..acb97e33 100755 --- a/scripts/exec_wrapper.py +++ b/scripts/exec_wrapper.py @@ -32,7 +32,7 @@ def exec_wrapper_init(): # don't change: name is used to test if script is runni except: pass -def exec_wrapper_write_traceback(): +def exec_wrapper_write_traceback(e): import traceback,re lines = traceback.format_exception(*sys.exc_info()) # returns a list @@ -45,7 +45,11 @@ def exec_wrapper_write_traceback(): lines.pop() c = exec_wrapper_get_colors() - sys.stdout.write('{}{}'.format(c.yellow(''.join(lines)),c.red(exc))) + message = ( repr(e) if type(e).__name__ in ('MMGenError','MMGenSystemExit') else exc ) + sys.stdout.write('{}{}'.format( + c.yellow( ''.join(lines) ), + c.red(message) ) + + '\n' ) with open('my.err','w') as fp: fp.write(''.join(lines+[exc])) @@ -96,13 +100,13 @@ try: exec(fp.read()) except SystemExit as e: if e.code != 0 and not os.getenv('EXEC_WRAPPER_NO_TRACEBACK'): - exec_wrapper_write_traceback() + exec_wrapper_write_traceback(e) else: exec_wrapper_tracemalloc_log() exec_wrapper_end_msg() sys.exit(e.code) except Exception as e: - exec_wrapper_write_traceback() + exec_wrapper_write_traceback(e) retval = e.mmcode if hasattr(e,'mmcode') else e.code if hasattr(e,'code') else 1 sys.exit(retval) diff --git a/test/gentest.py b/test/gentest.py index c9ad7eb3..fd61ed29 100755 --- a/test/gentest.py +++ b/test/gentest.py @@ -318,7 +318,7 @@ def do_ab_test(proto,cfg,addr_type,gen1,kg2,ag,tool,cache_data): kg1 = KeyGenerator( proto, addr_type.pubkey_type, gen1 ) if type(kg1) == type(kg2): - rdie(1,'Key generators are the same!') + die(4,'Key generators are the same!') e = cinfo.get_entry(proto.coin,proto.network) qmsg(green("Comparing address generators '{A}' and '{B}' for {N} {c} ({n}), addrtype {a!r}".format( diff --git a/test/include/pexpect.py b/test/include/pexpect.py index 52a0904b..748e912b 100755 --- a/test/include/pexpect.py +++ b/test/include/pexpect.py @@ -23,7 +23,7 @@ test/pexpect.py: pexpect implementation for MMGen test suites import sys,os,time from mmgen.globalvars import g from mmgen.opts import opt -from mmgen.util import msg,msg_r,vmsg,vmsg_r,rmsg,red,yellow,green,cyan,die,rdie +from mmgen.util import msg,msg_r,vmsg,vmsg_r,rmsg,red,yellow,green,cyan,die from .common import * try: @@ -184,11 +184,12 @@ class MMGenPexpect(object): f = (self.p.expect_exact,self.p.expect)[bool(regex)] ret = f(s) except pexpect.TIMEOUT: - if opt.debug_pexpect: raise - m1 = red(f'\nERROR. Expect {s!r} timed out. Exiting\n') + if opt.debug_pexpect: + raise + m1 = f'\nERROR. Expect {s!r} timed out. Exiting\n' m2 = f'before: [{self.p.before}]\n' m3 = f'sent value: [{self.sent_value}]' if self.sent_value != None else '' - rdie(1,m1+m2+m3) + die(2,m1+m2+m3) debug_pexpect_msg(self.p) @@ -196,7 +197,7 @@ class MMGenPexpect(object): msg_r(f' ==> {ret} ') if ret == -1: - rdie(1,f'Error. Expect returned {ret}') + die(4,f'Error. Expect returned {ret}') else: if t == '': if not nonl and not silent: vmsg('') diff --git a/test/objattrtest.py b/test/objattrtest.py index 203efe5c..873193a1 100755 --- a/test/objattrtest.py +++ b/test/objattrtest.py @@ -69,7 +69,7 @@ def get_descriptor_obj(objclass,attrname): for o in (objclass,objclass.__bases__[0]): # assume there's only one base class if attrname in o.__dict__: return o.__dict__[attrname] - rdie(3,f'unable to find descriptor {objclass.__name__}.{attrname}') + die(4,f'unable to find descriptor {objclass.__name__}.{attrname}') def test_attr_perm(obj,attrname,perm_name,perm_value,dobj,attrval_type): @@ -93,15 +93,15 @@ def test_attr_perm(obj,attrname,perm_name,perm_value,dobj,attrval_type): elif perm_name == 'delete_ok': delattr(obj,attrname) except SampleObjError as e: - rdie(2,f'Test script error ({e})') + die(4,f'Test script error ({e})') except Exception as e: if perm_value == True: fs = '{!r}: unable to {} attribute {!r}, though {}ing is allowed ({})' - rdie(2,fs.format(type(obj).__name__,pname,attrname,pstem,e)) + die(4,fs.format(type(obj).__name__,pname,attrname,pstem,e)) else: if perm_value == False: fs = '{!r}: attribute {!r} is {n}able, though {n}ing is forbidden' - rdie(2,fs.format(type(obj).__name__,attrname,n=pstem)) + die(4,fs.format(type(obj).__name__,attrname,n=pstem)) def test_attr(data,obj,attrname,dobj,bits,attrval_type): if hasattr(obj,attrname): # TODO @@ -109,7 +109,7 @@ def test_attr(data,obj,attrname,dobj,bits,attrval_type): if attrval_type not in (td_attrval_type,type(None)): fs = '\nattribute {!r} of {!r} instance has incorrect type {!r} (should be {!r})' - rdie(2,fs.format(attrname,type(obj).__name__,attrval_type.__name__,td_attrval_type.__name__)) + die(4,fs.format(attrname,type(obj).__name__,attrval_type.__name__,td_attrval_type.__name__)) if hasattr(dobj,'__dict__'): d = dobj.__dict__ @@ -118,7 +118,7 @@ def test_attr(data,obj,attrname,dobj,bits,attrval_type): if k in d: if d[k] != bits[k]: fs = 'init value {iv}={a} for attr {n!r} does not match test data ({iv}={b})' - rdie(2,fs.format(iv=k,n=attrname,a=d[k],b=bits[k])) + die(4,fs.format(iv=k,n=attrname,a=d[k],b=bits[k])) if opt.verbose and d[k] == True: msg_r(f' {k}={d[k]!r}') diff --git a/test/scrambletest.py b/test/scrambletest.py index 2b81d233..9db7e56e 100755 --- a/test/scrambletest.py +++ b/test/scrambletest.py @@ -97,7 +97,7 @@ cmd_base = f'python3{cvr_opts} cmds/mmgen-{{}}gen -qS' def get_cmd_output(cmd): cp = run(cmd.split(),stdout=PIPE,stderr=PIPE) if cp.returncode != 0: - ydie(2,f'\nSpawned program exited with error code {cp.returncode}:\n{cp.stderr.decode()}') + die(2,f'\nSpawned program exited with error code {cp.returncode}:\n{cp.stderr.decode()}') return cp.stdout.decode().splitlines() def do_test(cmd,tdata,msg_str,addr_desc): @@ -115,7 +115,7 @@ def do_test(cmd,tdata,msg_str,addr_desc): s = k.replace('seed','seed[:8]').replace('addr',addr_desc) vmsg(f' {s:9}: {cmd_out[k]}') else: - rdie(1,f'\nError: sc_{k} value {cmd_out[k]} does not match reference value {ref_data[k]}') + die(4,f'\nError: sc_{k} value {cmd_out[k]} does not match reference value {ref_data[k]}') msg('OK') def do_coin_tests(): diff --git a/test/test.py b/test/test.py index 2d987884..099c28c4 100755 --- a/test/test.py +++ b/test/test.py @@ -40,7 +40,7 @@ def create_shm_dir(data_dir,trash_dir): try: run(['python3',os.path.join('cmds','mmgen-regtest'),'stop'],check=True) except: - rdie(1,f'Unable to remove {tdir!r}!') + die(4,f'Unable to remove {tdir!r}!') else: time.sleep(2) shutil.rmtree(tdir) @@ -977,7 +977,7 @@ class TestSuiteRunner(object): self.skipped_warnings.append( 'Test {!r} was skipped:\n {}'.format(cmd,'\n '.join(ret[1].split('\n')))) else: - rdie(1,f'{cmd!r} returned {ret}') + die(2,f'{cmd!r} returned {ret}') def check_deps(self,cmds): # TODO: broken if len(cmds) != 1: @@ -1057,9 +1057,9 @@ except KeyboardInterrupt: tr.warn_skipped() die(1,'\ntest.py exiting at user request') except TestSuiteException as e: - ydie(1,e.args[0]) + die(2,e.args[0]) except TestSuiteFatalException as e: - rdie(1,e.args[0]) + die(4,e.args[0]) except Exception: if 'exec_wrapper_init' in globals(): # test.py itself is running under exec_wrapper import traceback diff --git a/test/test_py_d/ts_autosign.py b/test/test_py_d/ts_autosign.py index 166a49a3..afd38580 100755 --- a/test/test_py_d/ts_autosign.py +++ b/test/test_py_d/ts_autosign.py @@ -244,18 +244,18 @@ class TestSuiteAutosign(TestSuiteBase): run(['mount',mountpoint],check=True) imsg(f'Mounted {mountpoint}') except: - ydie(1,f'Could not mount {mountpoint}! Exiting') + die(2,f'Could not mount {mountpoint}! Exiting') txdir = joinpath(mountpoint,'tx') if not os.path.isdir(txdir): - ydie(1,f'Directory {txdir} does not exist! Exiting') + die(2,f'Directory {txdir} does not exist! Exiting') def init_led(): try: cf = LEDControl(enabled=True,simulate=simulate) except Exception as e: msg(str(e)) - ydie(2,'LEDControl initialization failed') + die(2,'LEDControl initialization failed') for fn in (cf.board.status,cf.board.trigger): if fn: run(['sudo','chmod','0666',fn],check=True) diff --git a/test/test_py_d/ts_ethdev.py b/test/test_py_d/ts_ethdev.py index ee6a59ec..678617ef 100755 --- a/test/test_py_d/ts_ethdev.py +++ b/test/test_py_d/ts_ethdev.py @@ -59,7 +59,7 @@ def check_solc_ver(): try: cp = run(cmd.split(),check=False,stdout=PIPE) except Exception as e: - rdie(2,f'Unable to execute {cmd!r}: {e}') + die(4,f'Unable to execute {cmd!r}: {e}') res = cp.stdout.decode().strip() if cp.returncode == 0: omsg( @@ -750,7 +750,7 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): cp = run(cmd,stdout=DEVNULL,stderr=PIPE) if cp.returncode != 0: rmsg('solc failed with the following output:') - ydie(2,cp.stderr.decode()) + die(2,cp.stderr.decode()) imsg('ERC20 token {!r} compiled'.format( token_data['symbol'] )) return 'ok' diff --git a/test/test_py_d/ts_misc.py b/test/test_py_d/ts_misc.py index 23811a83..7219bfd9 100755 --- a/test/test_py_d/ts_misc.py +++ b/test/test_py_d/ts_misc.py @@ -59,7 +59,7 @@ class TestSuiteHelp(TestSuiteBase): def usage(self): t = self.spawn(f'mmgen-walletgen',['foo']) t.expect('USAGE: mmgen-walletgen') - t.expect('SystemExit: 1') + t.expect('MMGenSystemExit(1)') t.req_exit_val = 1 return t diff --git a/test/test_py_d/ts_regtest.py b/test/test_py_d/ts_regtest.py index 4d4520f2..2b0f3492 100755 --- a/test/test_py_d/ts_regtest.py +++ b/test/test_py_d/ts_regtest.py @@ -741,7 +741,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared): def get_mempool1(self): mp = self._get_mempool() if len(mp) != 1: - rdie(2,'Mempool has more or less than one TX!') + die(4,'Mempool has more or less than one TX!') self.write_to_tmpfile('rbf_txid',mp[0]+'\n') return 'ok' @@ -762,10 +762,10 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared): return 'skip' mp = self._get_mempool() if len(mp) != 1: - rdie(2,'Mempool has more or less than one TX!') + die(4,'Mempool has more or less than one TX!') chk = self.read_from_tmpfile('rbf_txid') if chk.strip() == mp[0]: - rdie(2,'TX in mempool has not changed! RBF bump failed') + die(4,'TX in mempool has not changed! RBF bump failed') self.write_to_tmpfile('rbf_txid2',mp[0]+'\n') return 'ok' diff --git a/test/test_py_d/ts_seedsplit.py b/test/test_py_d/ts_seedsplit.py index 4a9a9979..6f42b553 100755 --- a/test/test_py_d/ts_seedsplit.py +++ b/test/test_py_d/ts_seedsplit.py @@ -226,11 +226,11 @@ class TestSuiteSeedSplit(TestSuiteBase): def ss_bad_invocation1(self): return self.ss_bad_invocation( - 'mmgen-seedsplit',[],1,'SystemExit: 1') + 'mmgen-seedsplit',[],1,'MMGenSystemExit(1)') def ss_bad_invocation2(self): return self.ss_bad_invocation( - 'mmgen-seedsplit',['-M1','1:9'],1,'SystemExit: 1') + 'mmgen-seedsplit',['-M1','1:9'],1,'MMGenSystemExit(1)') def ss_bad_invocation3(self): return self.ss_bad_invocation( @@ -242,11 +242,11 @@ class TestSuiteSeedSplit(TestSuiteBase): def ss_bad_invocation5(self): return self.ss_bad_invocation( - 'mmgen-seedjoin',[],1,'SystemExit: 1') + 'mmgen-seedjoin',[],1,'MMGenSystemExit(1)') def ss_bad_invocation6(self): return self.ss_bad_invocation( - 'mmgen-seedjoin',[self.tmpdir+'/a'],1,'SystemExit: 1') + 'mmgen-seedjoin',[self.tmpdir+'/a'],1,'MMGenSystemExit(1)') def ss_bad_invocation7(self): return self.ss_bad_invocation( @@ -258,7 +258,7 @@ class TestSuiteSeedSplit(TestSuiteBase): def ss_bad_invocation9(self): return self.ss_bad_invocation( - 'mmgen-seedsplit',['x'],1,'SystemExit: 1') + 'mmgen-seedsplit',['x'],1,'MMGenSystemExit(1)') def ss_bad_invocation10(self): return self.ss_bad_invocation( diff --git a/test/tooltest.py b/test/tooltest.py index 85fe8422..a8e0adc2 100755 --- a/test/tooltest.py +++ b/test/tooltest.py @@ -238,7 +238,7 @@ class MMGenToolTestUtils(object): red('FAILED'), yellow('Command stderr output:'), err.decode() )) - rdie(1,f'Called process returned with an error (retcode {cp.returncode})') + die(2,f'Called process returned with an error (retcode {cp.returncode})') return (out,out.rstrip())[bool(strip)] def run_cmd_chk(self,name,f1,f2,kwargs='',extra_msg='',strip_hex=False,add_opts=[]): @@ -251,8 +251,7 @@ class MMGenToolTestUtils(object): return (a.lstrip('0') == b.lstrip('0')) if strip_hex else (a == b) if cmp_equal(ret,idata): ok() else: - fs = "Error: values don't match:\nIn: {!r}\nOut: {!r}" - rdie(3,fs.format(idata,ret)) + die(4, "Error: values don't match:\nIn: {!r}\nOut: {!r}".format(idata,ret)) return ret def run_cmd_nochk(self,name,f1,kwargs='',add_opts=[]): @@ -278,7 +277,7 @@ class MMGenToolTestUtils(object): else: if not hush: ok() else: - rdie(3,f'Error for command {name!r}') + die(4,f'Error for command {name!r}') def run_cmd_randinput(self,name,strip=True,add_opts=[]): s = getrand(128) @@ -298,7 +297,7 @@ def ok_or_die(val,chk_func,s,skip_ok=False): if ret: if not skip_ok: ok() else: - rdie(3,f'Returned value {val!r} is not a {s}') + die(4,f'Returned value {val!r} is not a {s}') class MMGenToolTestCmds(object): diff --git a/test/tooltest2.py b/test/tooltest2.py index f5db4cc1..b773fdb4 100755 --- a/test/tooltest2.py +++ b/test/tooltest2.py @@ -782,7 +782,7 @@ def fork_cmd(cmd_name,args,out,opts,stdin_input): if m: return { b'None': None, b'False': False }[m.group(1)] else: - ydie(1,f'Spawned program exited with error: {cp.stderr}') + die(2,f'Spawned program exited with error: {cp.stderr}') return cmd_out.strip() diff --git a/test/unit_tests.py b/test/unit_tests.py index 154c67d8..db123631 100755 --- a/test/unit_tests.py +++ b/test/unit_tests.py @@ -95,7 +95,7 @@ class UnitTestHelpers(object): assert exc == exc_chk, m_exc.format(exc,exc_chk) assert re.search(emsg_chk,emsg), m_err.format(emsg,emsg_chk) else: - rdie(3,m_noraise.format(desc,exc_chk)) + die(4,m_noraise.format(desc,exc_chk)) tests_seen = [] @@ -110,7 +110,7 @@ def run_test(test,subtest=None): if type(ret).__name__ == 'coroutine': ret = run_session(ret) if not ret: - rdie(1,f'Unit subtest {subtest!r} failed') + die(4,f'Unit subtest {subtest!r} failed') pass if test not in tests_seen: @@ -139,7 +139,7 @@ def run_test(test,subtest=None): run_subtest(subtest) else: if not mod.unit_test().run_test(test,UnitTestHelpers): - rdie(1,'Unit test {test!r} failed') + die(4,'Unit test {test!r} failed') try: for test in (cmd_args or all_tests): diff --git a/test/unit_tests_d/ut_daemon.py b/test/unit_tests_d/ut_daemon.py index 39135b19..9b65e4f5 100755 --- a/test/unit_tests_d/ut_daemon.py +++ b/test/unit_tests_d/ut_daemon.py @@ -77,9 +77,9 @@ def test_cmds(op): try: cp = run([d.exec_fn,'--help'],stdout=PIPE,stderr=PIPE) except: - ydie(1,f'Unable to execute {d.exec_fn}') + die(2,f'Unable to execute {d.exec_fn}') if cp.returncode: - ydie(1,f'Unable to execute {d.exec_fn}') + die(2,f'Unable to execute {d.exec_fn}') else: vmsg('{:16} {}'.format( d.exec_fn+':', diff --git a/test/unit_tests_d/ut_indexed_dict.py b/test/unit_tests_d/ut_indexed_dict.py index 15428f97..66248610 100755 --- a/test/unit_tests_d/ut_indexed_dict.py +++ b/test/unit_tests_d/ut_indexed_dict.py @@ -21,7 +21,7 @@ class unit_test(object): def bad4(): d.clear() def bad5(): d.update(d) - def odie(n): rdie(3,f'\nillegal action {bad_msg[n]!r} failed to raise exception') + def odie(n): die(4,f'\nillegal action {bad_msg[n]!r} failed to raise exception') def omsg(e): vmsg(' - ' + e.args[0]) msg_r('Testing class IndexedDict...')