From 056de3bc5c7413707c578db548aa3029e2535f42 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sat, 29 Oct 2022 20:10:23 +0000 Subject: [PATCH] minor cleanups; test.py add `--demo` option Testing/demo: $ test/test.py --demo regtest --- mmgen/ui.py | 2 +- test/include/pexpect.py | 40 +++++++++++++++++++------------------- test/test.py | 15 ++++++++++++-- test/test_py_d/ts_input.py | 32 +++++++++++++++--------------- 4 files changed, 50 insertions(+), 39 deletions(-) diff --git a/mmgen/ui.py b/mmgen/ui.py index c39ac303..f795a89b 100755 --- a/mmgen/ui.py +++ b/mmgen/ui.py @@ -74,7 +74,7 @@ def line_input(prompt,echo=True,insert_txt='',hold_protect=True): else: from getpass import getpass if g.platform == 'win': - # MSWin hack - getpass('foo') doesn't flush stderr + # MSYS2/MSWin hack - getpass('foo') doesn't flush stderr - TODO: has this been fixed? msg_r(prompt.strip()) # getpass('') adds a space sys.stderr.flush() reply = getpass('') diff --git a/test/include/pexpect.py b/test/include/pexpect.py index 24b6081c..af82044f 100755 --- a/test/include/pexpect.py +++ b/test/include/pexpect.py @@ -33,9 +33,8 @@ except ImportError as e: die(2,red(f'Pexpect module is missing. Cannnot run test suite ({e!r})')) def debug_pexpect_msg(p): - if opt.debug_pexpect: - msg('\n{}{}{}'.format( red('BEFORE ['), p.before, red(']') )) - msg('{}{}{}'.format( red('MATCH ['), p.after, red(']') )) + msg('\n{}{}{}'.format( red('BEFORE ['), p.before, red(']') )) + msg('{}{}{}'.format( red('MATCH ['), p.after, red(']') )) NL = '\n' @@ -154,10 +153,12 @@ class MMGenPexpect: def expect_getend(self,s,regex=False): ret = self.expect(s,regex=regex,nonl=True) - debug_pexpect_msg(self.p) + if opt.debug_pexpect: + debug_pexpect_msg(self.p) # readline() of partial lines doesn't work with PopenSpawn, so do this instead: self.expect(NL,nonl=True,silent=True) - debug_pexpect_msg(self.p) + if opt.debug_pexpect: + debug_pexpect_msg(self.p) end = self.p.before.rstrip() if not g.debug: vmsg(f' ==> {cyan(end)}') @@ -186,14 +187,11 @@ class MMGenPexpect: if not silent: if opt.verbose: msg_r('EXPECT ' + yellow(str(s))) - elif not opt.exact_output: msg_r('+') + elif not opt.exact_output: + msg_r('+') try: - if s == '': - ret = 0 - else: - f = (self.p.expect_exact,self.p.expect)[bool(regex)] - ret = f(s) + ret = (self.p.expect_exact,self.p.expect)[bool(regex)](s) if s else 0 except pexpect.TIMEOUT: if opt.debug_pexpect: raise @@ -202,7 +200,8 @@ class MMGenPexpect: m3 = f'sent value: [{self.sent_value}]' if self.sent_value != None else '' die(2,m1+m2+m3) - debug_pexpect_msg(self.p) + if opt.debug_pexpect: + debug_pexpect_msg(self.p) if opt.verbose and type(s) != str: msg_r(f' ==> {ret} ') @@ -210,20 +209,21 @@ class MMGenPexpect: if ret == -1: die(4,f'Error. Expect returned {ret}') else: - if t == '': - if not nonl and not silent: vmsg('') - else: + if t: self.send(t,delay,s) + else: + if not nonl and not silent: + vmsg('') return ret def send(self,t,delay=None,s=False): - self.sent_value = None delay = delay or (0,0.3)[bool(opt.buf_keypress)] - if delay: time.sleep(delay) + if delay: + time.sleep(delay) ret = self.p.send(t) # returns num bytes written - if ret: - self.sent_value = t - if delay: time.sleep(delay) + self.sent_value = t if ret else None + if opt.demo and delay: + time.sleep(delay) if opt.verbose: ls = '' if opt.debug or not s else ' ' es = '' if s else ' ' diff --git a/test/test.py b/test/test.py index 3532afa5..c2e50e18 100755 --- a/test/test.py +++ b/test/test.py @@ -96,7 +96,12 @@ g.quiet = False # if 'quiet' was set in config file, disable here os.environ['MMGEN_QUIET'] = '0' # for this script and spawned scripts opts_data = { - 'sets': [('list_current_cmd_groups',True,'list_cmd_groups',True)], + 'sets': [ + ('list_current_cmd_groups',True,'list_cmd_groups',True), + ('demo',True,'exact_output',True), + ('demo',True,'buf_keypress',True), + ('demo',True,'pexpect_spawn',True), + ], 'text': { 'desc': 'Test suite for the MMGen suite', 'usage':'[options] [command [..command]] | [command_group[.command_subgroup][:command]]', @@ -111,6 +116,8 @@ opts_data = { -c, --print-cmdline Print the command line of each spawned command -C, --coverage Produce code coverage info using trace module -x, --debug-pexpect Produce debugging output for pexpect calls +--, --demo Add extra delay after each send to make input visible. + Implies --exact-output --pexpect-spawn --buf-keypress -D, --no-daemon-stop Don't stop auto-started daemons after running tests -E, --direct-exec Bypass pexpect and execute a command directly (for debugging only) @@ -615,7 +622,11 @@ class TestSuiteRunner(object): env.update({ 'EXEC_WRAPPER_TRACEBACK':'' }) # Python 3.9: OR the dicts from test.include.pexpect import MMGenPexpect - return MMGenPexpect( args, no_output=no_output, env=env, pexpect_spawn=pexpect_spawn ) + return MMGenPexpect( + args = args, + no_output = no_output, + env = env, + pexpect_spawn = pexpect_spawn ) def end_msg(self): t = int(time.time() - self.start_time) diff --git a/test/test_py_d/ts_input.py b/test/test_py_d/ts_input.py index 55d8fe4e..fc9825b5 100755 --- a/test/test_py_d/ts_input.py +++ b/test/test_py_d/ts_input.py @@ -190,29 +190,29 @@ class TestSuiteInput(TestSuiteBase): return t - def password_entry(self,prompt,cmd_args): - t = self.spawn('test/misc/password_entry.py',cmd_args,cmd_dir='.') + def _password_entry(self,prompt,opts=[],term=False): + t = self.spawn( 'test/misc/password_entry.py', opts, cmd_dir='.', pexpect_spawn=term ) + imsg('Terminal: {}'.format(term)) pw = 'abc-α' t.expect(prompt,pw+'\n') ret = t.expect_getend('Entered: ') assert ret == pw, f'Password mismatch! {ret} != {pw}' return t - def password_entry_noecho(self): - if self.skip_for_win(): - m = "getpass() doesn't work with pexpect.popen_spawn!\n" - m += 'Perform the following test by hand with non-ASCII password abc-α:\n' - m += ' test/misc/password_entry.py' - return ('skip_warn',m) - return self.password_entry('Enter passphrase: ',[]) + # TODO: has this been fixed? + winskip_msg = """ + getpass() doesn't work with pexpect.popen_spawn on MSYS2! + Perform the following test by hand with non-ASCII password abc-α + or another password in your native alphabet: - def password_entry_echo(self): - if self.skip_for_win(): - m = "getpass() doesn't work with pexpect.popen_spawn!\n" - m += 'Perform the following test by hand with non-ASCII password abc-α:\n' - m += ' test/misc/password_entry.py --echo-passphrase' - return ('skip_warn',m) - return self.password_entry('Enter passphrase (echoed): ',['--echo-passphrase']) + test/misc/input_func.py{} passphrase + """ + + def password_entry_noecho(self,term=False): + return self._password_entry('Enter passphrase: ',term=term) + + def password_entry_echo(self,term=False): + return self._password_entry('Enter passphrase (echoed): ',['--echo-passphrase'],term=term) def _mn2hex(self,fmt,entry_mode='full',mn=None,pad_entry=False,enter_for_dfl=False): mn = mn or sample_mn[fmt]['mn'].split()