Improved test/test.py dependency system; added test for passchg
This commit is contained in:
parent
5ac42135c4
commit
7602425b4a
1 changed files with 118 additions and 80 deletions
198
test/test.py
198
test/test.py
|
|
@ -16,6 +16,8 @@ cmd_data = OrderedDict([
|
|||
# test description depends
|
||||
['walletgen', (1,'wallet generation', [[[],1]])],
|
||||
['walletchk', (1,'wallet check', [[["mmdat"],1]])],
|
||||
['passchg', (5,'password, label and hash preset change',[[["mmdat"],1]])],
|
||||
['walletchk_newpass',(5,'wallet check with new pw, label and hash preset',[[["mmdat"],5]])],
|
||||
['addrgen', (1,'address generation', [[["mmdat"],1]])],
|
||||
['addrimport', (1,'address import', [[["addrs"],1]])],
|
||||
['txcreate', (1,'transaction creation', [[["addrs"],1]])],
|
||||
|
|
@ -51,12 +53,12 @@ cmd_data = OrderedDict([
|
|||
['walletgen4',(4,'wallet generation (4) (brainwallet)', [])],
|
||||
['addrgen4', (4,'address generation (4)', [[["mmdat"],4]])],
|
||||
['txcreate4', (4,'tx creation with inputs and outputs from four seed sources, plus non-MMGen inputs and outputs', [[["addrs"],1],[["addrs"],2],[["addrs"],3],[["addrs"],4]])],
|
||||
['txsign4', (4,'tx signing with inputs and outputs from incog file, mnemonic file, wallet and brainwallet, plus non-MMGen inputs and outputs', [[["mmincog"],1],[["mmwords"],2],[["mmdat"],3],[["mmbrain","raw",non_mmgen_fn],4]])],
|
||||
['txsign4', (4,'tx signing with inputs and outputs from incog file, mnemonic file, wallet and brainwallet, plus non-MMGen inputs and outputs', [[["mmincog"],1],[["mmwords"],2],[["mmdat"],3],[["mmbrain","raw"],4]])],
|
||||
])
|
||||
|
||||
utils = {
|
||||
'check_deps': 'check dependencies for specified command, deleting out-of-date files',
|
||||
'clean': 'clean specified tmp dir(s) (1,2,3,4; no arg = all tmpdirs)',
|
||||
'check_deps': 'check dependencies for specified command',
|
||||
'clean': 'clean specified tmp dir(s) 1, 2, 3 or 4 (no arg = all dirs)',
|
||||
}
|
||||
|
||||
addrs_per_wallet = 8
|
||||
|
|
@ -112,19 +114,29 @@ cfgs = {
|
|||
'addrs': "addrgen4",
|
||||
'raw': "txcreate4",
|
||||
'sig': "txsign4",
|
||||
non_mmgen_fn: "txcreate4"
|
||||
},
|
||||
'bw_filename': "brainwallet.mmbrain",
|
||||
'bw_params': "256,1",
|
||||
},
|
||||
'5': {
|
||||
'tmpdir': "test/tmp5",
|
||||
'wpasswd': "My changed password",
|
||||
'dep_generators': {
|
||||
'mmdat': "passchg",
|
||||
},
|
||||
},
|
||||
}
|
||||
cfg = cfgs['1']
|
||||
|
||||
from binascii import hexlify
|
||||
def getrand(n): return int(hexlify(os.urandom(n)),16)
|
||||
def msgrepr(d): sys.stderr.write(repr(d)+"\n")
|
||||
def msgrepr_exit(d):
|
||||
sys.stderr.write(repr(d)+"\n")
|
||||
|
||||
def msgrepr(*args):
|
||||
for d in args:
|
||||
sys.stdout.write(repr(d)+"\n")
|
||||
|
||||
def msgrepr_exit(*args):
|
||||
for d in args:
|
||||
sys.stdout.write(repr(d)+"\n")
|
||||
sys.exit()
|
||||
|
||||
# total of two outputs must be < 10 BTC
|
||||
|
|
@ -135,6 +147,7 @@ for k in cfgs.keys():
|
|||
|
||||
meta_cmds = OrderedDict([
|
||||
['gen', (1,("walletgen","walletchk","addrgen"))],
|
||||
['pass', (5,("passchg","walletchk_newpass"))],
|
||||
['tx', (1,("txcreate","txsign","txsend"))],
|
||||
['export', (1,[k for k in cmd_data if k[:7] == "export_" and cmd_data[k][0] == 1])],
|
||||
['gen_sp', (1,[k for k in cmd_data if k[:8] == "addrgen_" and cmd_data[k][0] == 1])],
|
||||
|
|
@ -278,19 +291,18 @@ def cleandir(d):
|
|||
for f in files:
|
||||
os.unlink(os.path.join(d,f))
|
||||
|
||||
def get_file_with_ext(ext,mydir,delete=False):
|
||||
flist = [os.path.join(mydir,f)
|
||||
for f in os.listdir(mydir) if f.split(".")[-1] == ext]
|
||||
if not flist:
|
||||
flist = [os.path.join(mydir,f)
|
||||
for f in os.listdir(mydir) if ".".join(f.split(".")[-2:]) == ext]
|
||||
if not flist:
|
||||
return False
|
||||
def get_file_with_ext(ext,mydir,delete=True):
|
||||
|
||||
if len(flist) > 1 or delete:
|
||||
if not quiet:
|
||||
msg("Multiple *.%s files in '%s' - deleting" % (ext,mydir))
|
||||
for f in flist: os.unlink(f)
|
||||
flist = [os.path.join(mydir,f) for f in os.listdir(mydir)
|
||||
if f == ext or f[-(len(ext)+1):] == "."+ext]
|
||||
|
||||
if not flist: return False
|
||||
|
||||
if len(flist) > 1:
|
||||
if delete:
|
||||
if not quiet:
|
||||
msg("Multiple *.%s files in '%s' - deleting" % (ext,mydir))
|
||||
for f in flist: os.unlink(f)
|
||||
return False
|
||||
else:
|
||||
return flist[0]
|
||||
|
|
@ -323,6 +335,7 @@ class MMGenExpect(object):
|
|||
)
|
||||
else:
|
||||
msg_r("Testing %s " % (desc+":"))
|
||||
# msgrepr(mmgen_cmd,cmd_args); msg("")
|
||||
if env: self.p = pexpect.spawn(mmgen_cmd,cmd_args,env=env)
|
||||
else: self.p = pexpect.spawn(mmgen_cmd,cmd_args)
|
||||
if exact_output: self.p.logfile = sys.stdout
|
||||
|
|
@ -348,8 +361,9 @@ class MMGenExpect(object):
|
|||
my_expect(self.p,("Enter passphrase for new %s: " % what), passphrase+"\n")
|
||||
my_expect(self.p,"Repeat passphrase: ", passphrase+"\n")
|
||||
|
||||
def passphrase(self,what,passphrase):
|
||||
my_expect(self.p,("Enter passphrase for %s.*?: " % what),
|
||||
def passphrase(self,what,passphrase,pwtype=""):
|
||||
if pwtype: pwtype += " "
|
||||
my_expect(self.p,("Enter %spassphrase for %s.*?: " % (pwtype,what)),
|
||||
passphrase+"\n",regex=True)
|
||||
|
||||
def hash_preset(self,what,preset=''):
|
||||
|
|
@ -486,53 +500,73 @@ def do_between():
|
|||
|
||||
def do_cmd(ts,cmd):
|
||||
|
||||
al = []
|
||||
for exts,idx in cmd_data[cmd][2]:
|
||||
global cfg
|
||||
cfg = cfgs[str(idx)]
|
||||
for ext in exts:
|
||||
while True:
|
||||
infile = get_file_with_ext(ext,cfg['tmpdir'])
|
||||
if infile:
|
||||
al.append(infile); break
|
||||
else:
|
||||
dg = cfg['dep_generators'][ext]
|
||||
if not quiet: msg("Need *.%s from '%s'" % (ext,dg))
|
||||
do_cmd(ts,dg)
|
||||
do_between()
|
||||
d = [(str(num),ext) for exts,num in cmd_data[cmd][2] for ext in exts]
|
||||
al = [get_file_with_ext(ext,cfgs[num]['tmpdir']) for num,ext in d]
|
||||
|
||||
global cfg
|
||||
cfg = cfgs[str(cmd_data[cmd][0])]
|
||||
|
||||
MMGenTestSuite.__dict__[cmd](*([ts,cmd] + al))
|
||||
|
||||
|
||||
hincog_bytes = 1024*1024
|
||||
hincog_offset = 98765
|
||||
hincog_seedlen = 256
|
||||
|
||||
rebuild_list = OrderedDict()
|
||||
|
||||
def check_if_needs_rebuild(num,ext):
|
||||
ret = False
|
||||
def get_num_ext_for_cmd(cmd):
|
||||
num = str(cmd_data[cmd][0])
|
||||
dgl = cfgs[num]['dep_generators']
|
||||
# msgrepr(num,cmd,dgl)
|
||||
if cmd in dgl.values():
|
||||
ext = [k for k in dgl if dgl[k] == cmd][0]
|
||||
return (num,ext)
|
||||
else:
|
||||
return ('','')
|
||||
|
||||
fn = get_file_with_ext(ext,cfgs[num]['tmpdir'])
|
||||
if not fn: ret = True
|
||||
def check_needs_rerun(cmd,build=False,root=True,force_delete=False):
|
||||
|
||||
cmd = cfgs[num]['dep_generators'][ext]
|
||||
deps = [(str(n),e) for exts,n in cmd_data[cmd][2] for e in exts]
|
||||
rerun = True if root else False
|
||||
|
||||
num,ext = get_num_ext_for_cmd(cmd) # does cmd produce a needed dependency?
|
||||
if num and (force_delete or not root):
|
||||
fn = get_file_with_ext(ext,cfgs[num]['tmpdir'],delete=build)
|
||||
if not fn: rerun = True
|
||||
if fn and force_delete:
|
||||
os.unlink(fn); fn = ""
|
||||
else: fn = ""
|
||||
|
||||
fdeps = [(str(n),e) for exts,n in cmd_data[cmd][2] for e in exts]
|
||||
cdeps = [cfgs[str(n)]['dep_generators'][e] for n,e in fdeps]
|
||||
|
||||
if fn:
|
||||
my_age = os.stat(fn).st_mtime
|
||||
for num,ext in deps:
|
||||
f = get_file_with_ext(ext,cfgs[num]['tmpdir'])
|
||||
if f and os.stat(f).st_mtime > my_age: ret = True
|
||||
for num,ext in fdeps:
|
||||
f = get_file_with_ext(ext,cfgs[num]['tmpdir'],delete=build)
|
||||
if f and os.stat(f).st_mtime > my_age: rerun = True
|
||||
|
||||
for num,ext in deps:
|
||||
if check_if_needs_rebuild(num,ext): ret = True
|
||||
for cdep in cdeps:
|
||||
if check_needs_rerun(cdep,build=build,root=False): rerun = True
|
||||
|
||||
if ret and fn:
|
||||
if not quiet: msg("File '%s' out of date - deleting" % fn)
|
||||
os.unlink(fn)
|
||||
if build:
|
||||
if rerun:
|
||||
if fn and not root:
|
||||
os.unlink(fn)
|
||||
do_cmd(ts,cmd)
|
||||
if not root: do_between()
|
||||
else:
|
||||
# If prog produces multiple files:
|
||||
if cmd not in rebuild_list or rerun == True:
|
||||
rebuild_list[cmd] = (rerun,fn)
|
||||
|
||||
rebuild_list[cmd] = ret
|
||||
return ret
|
||||
return rerun
|
||||
|
||||
def mk_tmpdir(cfg):
|
||||
try: os.mkdir(cfg['tmpdir'],0755)
|
||||
except OSError as e:
|
||||
if e.errno != 17: raise
|
||||
else: msg("Created directory '%s'" % cfg['tmpdir'])
|
||||
|
||||
|
||||
class MMGenTestSuite(object):
|
||||
|
|
@ -551,19 +585,17 @@ class MMGenTestSuite(object):
|
|||
msg("'%s': unrecognized command" % cmd)
|
||||
sys.exit(1)
|
||||
|
||||
d = [(str(num),ext) for exts,num in cmd_data[cmd][2] for ext in exts]
|
||||
|
||||
if not quiet:
|
||||
w = "Checking" if d else "No"
|
||||
msg("%s dependencies for '%s'" % (w,cmd))
|
||||
msg("Checking dependencies for '%s'" % (cmd))
|
||||
|
||||
for num,ext in d:
|
||||
check_if_needs_rebuild(num,ext)
|
||||
check_needs_rerun(cmd,build=False)
|
||||
|
||||
if debug:
|
||||
for cmd in rebuild_list:
|
||||
msg("cmd: %-15s rebuild: %s" %
|
||||
(cmd, cyan("Yes") if rebuild_list[cmd] else "No"))
|
||||
w = max(len(i) for i in rebuild_list) + 1
|
||||
for cmd in rebuild_list:
|
||||
c = rebuild_list[cmd]
|
||||
m = "Rebuild" if (c[0] and c[1]) else "Build" if c[0] else "OK"
|
||||
msg("cmd {:<{w}} {}".format(cmd+":", m, w=w))
|
||||
# msgrepr(cmd,c)
|
||||
|
||||
|
||||
def clean(self,name,dirs=[]):
|
||||
|
|
@ -576,11 +608,7 @@ class MMGenTestSuite(object):
|
|||
sys.exit(1)
|
||||
|
||||
def walletgen(self,name,brain=False):
|
||||
try: os.mkdir(cfg['tmpdir'],0755)
|
||||
except OSError as e:
|
||||
if e.errno != 17: raise
|
||||
else: msg("Created directory '%s'" % cfg['tmpdir'])
|
||||
# cleandir(cfg['tmpdir'])
|
||||
mk_tmpdir(cfg)
|
||||
|
||||
args = ["-d",cfg['tmpdir'],"-p1","-r10"]
|
||||
if brain:
|
||||
|
|
@ -606,6 +634,25 @@ class MMGenTestSuite(object):
|
|||
t.written_to_file("Wallet")
|
||||
t.ok()
|
||||
|
||||
def passchg(self,name,walletfile):
|
||||
mk_tmpdir(cfg)
|
||||
|
||||
t = MMGenExpect(name,"mmgen-passchg",
|
||||
["-d",cfg['tmpdir'],"-p","2","-L","New Label","-r","16",walletfile])
|
||||
t.passphrase("MMGen wallet",cfgs['1']['wpasswd'],pwtype="old")
|
||||
t.expect_getend("Label changed: ")
|
||||
t.expect_getend("Hash preset has changed ")
|
||||
t.passphrase("MMGen wallet",cfg['wpasswd'],pwtype="new")
|
||||
t.expect("Repeat passphrase: ",cfg['wpasswd']+"\n")
|
||||
t.usr_rand(16)
|
||||
t.expect_getend("Key ID changed: ")
|
||||
t.written_to_file("Wallet")
|
||||
t.ok()
|
||||
|
||||
def walletchk_newpass(self,name,walletfile):
|
||||
t = self.walletchk_beg(name,[walletfile])
|
||||
t.ok()
|
||||
|
||||
def walletchk_beg(self,name,args):
|
||||
t = MMGenExpect(name,"mmgen-walletchk", args)
|
||||
t.expect("Getting MMGen wallet data from file '%s'" % args[-1])
|
||||
|
|
@ -838,8 +885,6 @@ class MMGenTestSuite(object):
|
|||
t.ok()
|
||||
|
||||
def walletgen2(self,name):
|
||||
global cfg
|
||||
cfg = cfgs['2']
|
||||
self.walletgen(name)
|
||||
|
||||
def addrgen2(self,name,walletfile):
|
||||
|
|
@ -865,8 +910,6 @@ class MMGenTestSuite(object):
|
|||
self.export_mnemonic(name,walletfile)
|
||||
|
||||
def walletgen3(self,name):
|
||||
global cfg
|
||||
cfg = cfgs['3']
|
||||
self.walletgen(name)
|
||||
|
||||
def addrgen3(self,name,walletfile):
|
||||
|
|
@ -890,8 +933,6 @@ class MMGenTestSuite(object):
|
|||
t.ok()
|
||||
|
||||
def walletgen4(self,name):
|
||||
global cfg
|
||||
cfg = cfgs['4']
|
||||
self.walletgen(name,brain=True)
|
||||
|
||||
def addrgen4(self,name,walletfile):
|
||||
|
|
@ -900,7 +941,8 @@ class MMGenTestSuite(object):
|
|||
def txcreate4(self,name,f1,f2,f3,f4):
|
||||
self.txcreate_common(name,sources=['1','2','3','4'],non_mmgen_input='4')
|
||||
|
||||
def txsign4(self,name,f1,f2,f3,f4,f5,non_mm_fn):
|
||||
def txsign4(self,name,f1,f2,f3,f4,f5):
|
||||
non_mm_fn = os.path.join(cfg['tmpdir'],non_mmgen_fn)
|
||||
t = MMGenExpect(name,"mmgen-txsign",
|
||||
["-d",cfg['tmpdir'],"-b",cfg['bw_params'],"-k",non_mm_fn,f1,f2,f3,f4,f5])
|
||||
t.license()
|
||||
|
|
@ -933,22 +975,18 @@ try:
|
|||
if cmd_args:
|
||||
arg1 = cmd_args[0]
|
||||
if arg1 in utils:
|
||||
if arg1 == "check_deps": debug = True
|
||||
MMGenTestSuite.__dict__[arg1](ts,arg1,cmd_args[1:])
|
||||
sys.exit()
|
||||
elif arg1 in meta_cmds:
|
||||
if len(cmd_args) == 1:
|
||||
ts.clean("clean",str(meta_cmds[arg1][0]))
|
||||
for cmd in meta_cmds[arg1][1]:
|
||||
do_cmd(ts,cmd)
|
||||
if cmd is not cmd_data.keys()[-1]: do_between()
|
||||
check_needs_rerun(cmd,build=True,force_delete=True)
|
||||
else:
|
||||
msg("Only one meta command may be specified")
|
||||
sys.exit(1)
|
||||
elif arg1 in cmd_data:
|
||||
if len(cmd_args) == 1:
|
||||
ts.check_deps("check_deps",[arg1])
|
||||
do_cmd(ts,arg1)
|
||||
check_needs_rerun(arg1,build=True)
|
||||
else:
|
||||
msg("Only one command may be specified")
|
||||
sys.exit(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue