From 13ab25764f80f6bb9fb4f457a323b58a1920b597 Mon Sep 17 00:00:00 2001 From: MMGen Date: Mon, 20 May 2019 15:44:30 +0000 Subject: [PATCH] [msys2]: test suite fixes and additions --- mmgen/addr.py | 4 +--- mmgen/keccak.py | 0 mmgen/regtest.py | 11 +++++++--- mmgen/seed.py | 2 +- mmgen/tool.py | 6 +++++- test/common.py | 2 +- test/test-release.sh | 35 ++++++++++++++++++++------------ test/test_py_d/ts_ethdev.py | 4 +++- test/test_py_d/ts_ref_altcoin.py | 4 ---- test/tooltest.py | 4 ++-- test/tooltest2.py | 21 ++++++++++++------- 11 files changed, 57 insertions(+), 36 deletions(-) mode change 100644 => 100755 mmgen/keccak.py diff --git a/mmgen/addr.py b/mmgen/addr.py index 56e36b87..96f55af7 100755 --- a/mmgen/addr.py +++ b/mmgen/addr.py @@ -119,8 +119,6 @@ class AddrGeneratorZcashZ(AddrGenerator): def to_addr(self,pubhex): # pubhex is really privhex key = bytes.fromhex(pubhex) assert len(key) == 32,'{}: incorrect privkey length'.format(len(key)) - if g.platform == 'win': - ydie(1,'Zcash z-addresses not supported on Windows platform') from nacl.bindings import crypto_scalarmult_base p2 = crypto_scalarmult_base(self.zhash256(key,1)) from mmgen.protocol import _b58chk_encode @@ -225,7 +223,7 @@ class KeyGenerator(MMGenObject): if not opt.key_generator or opt.key_generator == 2 or generator == 2: return super(cls,cls).__new__(KeyGeneratorSecp256k1) else: - msg('Using (slow) native Python ECDSA library for address generation') + qmsg('Using (slow) native Python ECDSA library for address generation') return super(cls,cls).__new__(KeyGeneratorPython) elif pubkey_type in ('zcash_z','monero'): me = super(cls,cls).__new__(KeyGeneratorDummy) diff --git a/mmgen/keccak.py b/mmgen/keccak.py old mode 100644 new mode 100755 diff --git a/mmgen/regtest.py b/mmgen/regtest.py index c668b116..8051acef 100755 --- a/mmgen/regtest.py +++ b/mmgen/regtest.py @@ -236,11 +236,16 @@ def setup(): def get_current_user_win(quiet=False): if test_daemon() == 'stopped': return None logfile = os.path.join(daemon_dir,'debug.log') - p = start_cmd('grep','Wallet completed loading in',logfile,quiet=True) - last_line = p.stdout.readlines()[-1].decode() + for ss in ('Wallet completed loading in','Using wallet wallet'): + o = start_cmd('grep',ss,logfile,quiet=True).stdout.readlines() + if o: + last_line = o[-1].decode() + break + else: + rdie(2,"Unable to find user info in 'debug.log'") import re - m = re.search(r'\[wallet.dat.([a-z]+)\]',last_line) + m = re.search(r'\bwallet\.dat\.([a-z]+)',last_line) if not m: return None diff --git a/mmgen/seed.py b/mmgen/seed.py index ab317ae6..a9b1c66a 100755 --- a/mmgen/seed.py +++ b/mmgen/seed.py @@ -555,7 +555,7 @@ class Mnemonic (SeedSourceUnenc): ch = get_char_raw('',num_chars=1).decode() if ch in '\b\x7f': if s: s = s[:-1] - elif ch in '\n ': + elif ch in '\n\r ': if s: break elif ch not in ascii_lowercase: pad += 1 diff --git a/mmgen/tool.py b/mmgen/tool.py index 9ce1dd7d..c105499f 100755 --- a/mmgen/tool.py +++ b/mmgen/tool.py @@ -25,6 +25,8 @@ from mmgen.common import * from mmgen.crypto import * from mmgen.addr import * +NL = ('\n','\r\n')[g.platform=='win'] + def _create_call_sig(cmd,parsed=False): m = getattr(MMGenToolCmd,cmd) @@ -159,7 +161,9 @@ def _process_args(cmd,cmd_args): die(1,"'Binary input data must be supplied via STDIN") if have_stdin_input and arg_type == 'str' and type(arg) == bytes: - arg = arg.decode().rstrip('\n') + arg = arg.decode() + if arg[-len(NL):] == NL: # rstrip one newline + arg = arg[:-len(NL)] if arg_type == 'bool': if arg.lower() in ('true','yes','1','on'): arg = True diff --git a/test/common.py b/test/common.py index c92bb45f..ab464d68 100755 --- a/test/common.py +++ b/test/common.py @@ -56,7 +56,7 @@ def cleandir(d,do_msg=False): try: os.unlink(os.path.join(d_enc,f)) except: - rmtree(os.path.join(d_enc,f)) + rmtree(os.path.join(d_enc,f),ignore_errors=True) def mk_tmpdir(d): try: os.mkdir(d,0o755) diff --git a/test/test-release.sh b/test/test-release.sh index 04a00d40..d6376c29 100755 --- a/test/test-release.sh +++ b/test/test-release.sh @@ -1,6 +1,14 @@ #!/bin/bash # Tested on Linux, MSys2 +REFDIR='test/ref' +if uname -a | grep -q MSYS; then + SUDO='' MSYS2=1; +else + SUDO='sudo' MSYS2='' +fi +RED="\e[31;1m" GREEN="\e[32;1m" YELLOW="\e[33;1m" RESET="\e[0m" + trap 'echo -e "${GREEN}Exiting at user request$RESET"; exit' INT umask 0022 @@ -25,7 +33,7 @@ dfl_tests='obj unit hash alts monero eth autosign btc btc_tn btc_rt bch bch_rt l add_tests='autosign_minimal autosign_live' PROGNAME=$(basename $0) -while getopts hbCfiIlOpRtvV OPT +while getopts hbCfFiIlOpRtvV OPT do case "$OPT" in h) printf " %-16s Test MMGen release\n" "${PROGNAME}:" @@ -34,6 +42,7 @@ do echo " '-b' Buffer keypresses for all invocations of 'test/test.py'" echo " '-C' Run tests in coverage mode" echo " '-f' Speed up the tests by using fewer rounds" + echo " '-F' Reduce rounds even further" echo " '-i' Create and install Python package, then run tests. A branch" echo " must be supplied as the first argument" echo " '-I' Install the package only; don't run tests" @@ -79,7 +88,8 @@ do gentest_py="$python $gentest_py" mmgen_tool="$python $mmgen_tool" mmgen_keygen="$python $mmgen_keygen" ;& - f) rounds=10 rounds_min=3 rounds_mid=25 rounds_max=50 monero_addrs='3,23' unit_tests_py+=" --fast" ;; + f) FAST=1 rounds=10 rounds_min=3 rounds_mid=25 rounds_max=50 monero_addrs='3,23' unit_tests_py+=" --fast" ;; + F) FAST=1 rounds=2 rounds_min=1 rounds_mid=3 rounds_max=5 monero_addrs='3,23' unit_tests_py+=" --fast" ;; i) INSTALL=1 ;; I) INSTALL_ONLY=1 ;; l) echo -e "Default tests:\n $dfl_tests" @@ -99,14 +109,11 @@ do esac done +[ "$MSYS2" -a ! "$FAST" ] && tooltest2_py+=' --fork' [ "$EXACT_OUTPUT" -o "$VERBOSE" ] || objtest_py+=" -S" shift $((OPTIND-1)) -REFDIR='test/ref' -if uname -a | grep -qi mingw; then SUDO='' MINGW=1; else SUDO='sudo' MINGW=''; fi -[ "$MINGW" ] || RED="\e[31;1m" GREEN="\e[32;1m" YELLOW="\e[33;1m" RESET="\e[0m" - [ "$INSTALL" ] && { BRANCH=$1; shift BRANCHES=$(git branch) @@ -138,10 +145,10 @@ install() { cd .test-release ./setup.py sdist mkdir pydist && cd pydist - if [ "$MINGW" ]; then unzip ../dist/mmgen-*.zip; else tar zxvf ../dist/mmgen-*gz; fi + if [ "$MSYS2" ]; then unzip ../dist/mmgen-*.zip; else tar zxvf ../dist/mmgen-*gz; fi cd mmgen-* eval "$SUDO ./setup.py clean --all" - [ "$MINGW" ] && ./setup.py build --compiler=mingw32 + [ "$MSYS2" ] && ./setup.py build --compiler=mingw32 eval "$SUDO ./setup.py install --force" ) set +x @@ -200,6 +207,8 @@ t_hash=" " f_hash='Hash function tests complete' +[ "$MSYS2" ] && t_hash_skip='2' # gmp issues + i_alts='Gen-only altcoin' s_alts='The following tests will test generation operations for all supported altcoins' t_alts=" @@ -223,6 +232,7 @@ t_alts=" $gentest_py --coin=xmr 2 $rounds $gentest_py --coin=xmr --use-internal-keccak-module 2 $rounds_min $gentest_py --coin=zec 2 $rounds + $gentest_py --coin=zec --type=zcash_z 2 $rounds_mid " # disabled, pycoin generates old-style LTC Segwit addrs: @@ -233,9 +243,8 @@ t_alts=" # $gentest_py --coin=eth 2:ext $rounds # $gentest_py --all 2:pyethereum $rounds -[ "$MINGW" ] || { +[ "$MSYS2" ] || { # no pycoin, zcash-mini t_alts="$t_alts - $gentest_py --coin=zec --type=zcash_z 2 $rounds_mid $gentest_py --coin=zec --type=zcash_z 2:ext $rounds_mid $gentest_py --all 2:zcash_mini $rounds_mid $gentest_py --all 2:pycoin $rounds @@ -252,7 +261,7 @@ f_alts='Gen-only altcoin tests completed' [ "$NO_TMPFILE_REMOVAL" ] || rm -rf /tmp/mmgen-test-release* -if [ "$MINGW" ]; then +if [ "$MSYS2" ]; then TMPDIR='/tmp/mmgen-test-release' else TMPDIR='/tmp/mmgen-test-release-'$(cat /dev/urandom | base32 - | head -n1 | cut -b 1-16) @@ -272,7 +281,7 @@ t_monero=" " f_monero='Monero tests completed' -[ "$MINGW" ] || { +[ "$MSYS2" ] || { # password file descriptor issues, cannot use popen_spawn() t_monero="$t_monero $mmgen_tool -q --accept-defaults --outdir $TMPDIR keyaddrlist2monerowallets $TMPDIR/*-XMR*.akeys addrs=23 $mmgen_tool -q --accept-defaults --outdir $TMPDIR keyaddrlist2monerowallets $TMPDIR/*-XMR*.akeys addrs=103-200 @@ -408,7 +417,7 @@ t_tool=" $tooltest_py --coin=zec cryptocoin $tooltest_py --coin=zec --type=zcash_z cryptocoin " -[ "$MINGW" ] && t_tool_skip='10' +[ "$MSYS2" ] && t_tool_skip='10' f_tool='tooltest tests completed' diff --git a/test/test_py_d/ts_ethdev.py b/test/test_py_d/ts_ethdev.py index 318c80b1..ce54184c 100755 --- a/test/test_py_d/ts_ethdev.py +++ b/test/test_py_d/ts_ethdev.py @@ -779,7 +779,9 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): def stop(self): self.spawn('',msg_only=True) - if subprocess.call(['which','parity'],stdout=subprocess.PIPE) == 0: + if g.platform == 'win': + my_raw_input('Please stop parity and Press ENTER to continue: ') + elif subprocess.call(['which','parity'],stdout=subprocess.PIPE) == 0: pid = self.read_from_tmpfile(parity_pid_fn) if opt.no_daemon_stop: msg_r('(leaving daemon running by user request)') diff --git a/test/test_py_d/ts_ref_altcoin.py b/test/test_py_d/ts_ref_altcoin.py index 337b2be4..2f0a3af1 100755 --- a/test/test_py_d/ts_ref_altcoin.py +++ b/test/test_py_d/ts_ref_altcoin.py @@ -176,7 +176,6 @@ class TestSuiteRefAltcoin(TestSuiteRef,TestSuiteBase): return self.ref_addrfile_chk(ftype='addr',coin='ZEC',subdir='zcash',pfx='-ZEC-C') def ref_addrfile_chk_zec_z(self): - if self.skip_for_win(): return 'skip' return self.ref_addrfile_chk(ftype='addr',coin='ZEC',subdir='zcash',pfx='-ZEC-Z',mmtype='z') def ref_addrfile_chk_xmr(self): @@ -196,10 +195,7 @@ class TestSuiteRefAltcoin(TestSuiteRef,TestSuiteBase): return self.ref_addrfile_chk(ftype='keyaddr',coin='ZEC',subdir='zcash',pfx='-ZEC-C') def ref_keyaddrfile_chk_zec_z(self): - if self.skip_for_win(): return 'skip' return self.ref_addrfile_chk(ftype='keyaddr',coin='ZEC',subdir='zcash',pfx='-ZEC-Z',mmtype='z') def ref_keyaddrfile_chk_xmr(self): return self.ref_addrfile_chk(ftype='keyaddr',coin='XMR',subdir='monero',pfx='-XMR-M') - - diff --git a/test/tooltest.py b/test/tooltest.py index cb6878a2..e9463994 100755 --- a/test/tooltest.py +++ b/test/tooltest.py @@ -135,9 +135,9 @@ if not opt.system: spawn_cmd = [mmgen_cmd] if opt.coverage: d,f = init_coverage() - spawn_cmd = ['python','-m','trace','--count','--coverdir='+d,'--file='+f] + spawn_cmd + spawn_cmd = ['python3','-m','trace','--count','--coverdir='+d,'--file='+f] + spawn_cmd elif g.platform == 'win': - spawn_cmd = ['python'] + spawn_cmd + spawn_cmd = ['python3'] + spawn_cmd add_spawn_args = ['--data-dir='+cfg['tmpdir']] + ['--{}{}'.format( k.replace('_','-'),'='+getattr(opt,k) if getattr(opt,k) != True else '') diff --git a/test/tooltest2.py b/test/tooltest2.py index 0d4c1b8a..da696e7c 100755 --- a/test/tooltest2.py +++ b/test/tooltest2.py @@ -38,6 +38,8 @@ from test.common import * from mmgen.obj import is_wif,is_coin_addr from mmgen.seed import is_mnemonic +NL = ('\n','\r\n')[g.platform=='win'] + def is_str(s): return type(s) == str def md5_hash(s): @@ -47,6 +49,7 @@ def md5_hash(s): def md5_hash_strip(s): import re s = re.sub('\x1b\[[;0-9]+?m','',s) # strip ANSI color sequences + s = s.replace(NL,'\n') # fix DOS newlines return md5_hash(s.strip()) opts_data = { @@ -76,12 +79,13 @@ If no command is given, the whole suite of tests is run. } } + sample_text_hexdump = ( - '000000: 5468 6520 5469 6d65 7320 3033 2f4a 616e\n' + - '000010: 2f32 3030 3920 4368 616e 6365 6c6c 6f72\n' + - '000020: 206f 6e20 6272 696e 6b20 6f66 2073 6563\n' + - '000030: 6f6e 6420 6261 696c 6f75 7420 666f 7220\n' + - '000040: 6261 6e6b 73' ) + '000000: 5468 6520 5469 6d65 7320 3033 2f4a 616e{n}' + + '000010: 2f32 3030 3920 4368 616e 6365 6c6c 6f72{n}' + + '000020: 206f 6e20 6272 696e 6b20 6f66 2073 6563{n}' + + '000030: 6f6e 6420 6261 696c 6f75 7420 666f 7220{n}' + + '000040: 6261 6e6b 73').format(n=NL) kafile_opts = ['-p1','-Ptest/ref/keyaddrfile_password'] kafile_code = ( @@ -616,7 +620,7 @@ def run_test(gid,cmd_name): if cmd_err: vmsg(cmd_err.strip().decode()) if p.wait() != 0: import re - m = re.match(b"tool command returned '(None|False)'\n",cmd_err) + m = re.match(b"tool command returned '(None|False)'"+NL.encode(),cmd_err) if m: return { b'None': None, b'False': False }[m.group(1)] else: @@ -662,6 +666,9 @@ def run_test(gid,cmd_name): if opt.fork: cmd_out = fork_cmd(cmd_name,args,out,opts,exec_code) else: + if stdin_input and g.platform == 'win': + msg('Skipping for MSWin - no os.fork()') + continue cmd_out = run_func(cmd_name,args,out,opts,exec_code) vmsg('Output: {}\n'.format(cmd_out if issubclass(type(out),str) else repr(cmd_out))) @@ -688,7 +695,7 @@ def run_test(gid,cmd_name): assert func_out == out[1],( "{}({}) == {} failed!\nOutput: {}".format(out[0].__name__,cmd_out,out[1],func_out)) elif type(out) in (list,tuple): - for co,o in zip(cmd_out.split('\n') if opt.fork else cmd_out,out): + for co,o in zip(cmd_out.split(NL) if opt.fork else cmd_out,out): check_output(co,o) else: check_output(cmd_out,out)