from getopt import getopt
from tempfile import mkstemp
from subprocess import Popen, PIPE
-from difflib import Differ
+from difflib import unified_diff
from hashlib import md5
from shutil import copy
-l List test(s)
-s Show test(s)
-r Run test(s)
- -f Fix failed test(s)
+ -f Fix failed test(s) / create initial output for new test(s)
-c Report decoder code coverage
-R <directory> Save test reports to <directory>
<test> Protocol decoder name ("i2c") and optionally test name ("i2c/rtc")""")
'name': f.pop(0),
'channels': [],
'options': [],
+ 'initial_pins': [],
}
while len(f):
if len(f) == 1:
pd_spec['channels'].append([opt, val])
elif a == 'option':
pd_spec['options'].append([opt, val])
+ elif a == 'initial_pin':
+ try:
+ val = int(val)
+ except:
+ raise E_syntax
+ pd_spec['initial_pins'].append([opt, val])
else:
raise E_syntax
tclist[-1]['pdlist'].append(pd_spec)
raise E_syntax
tclist[-1]['stack'] = f
elif key == 'input':
- if len(f) != 1:
+ if len(f) < 1:
raise E_syntax
- tclist[-1]['input'] = f[0]
+ input_spec = {
+ 'name': f.pop(0),
+ 'format': None,
+ 'options': [],
+ }
+ while len(f):
+ if len(f) < 2:
+ # Always needs <key> <value>
+ raise E_syntax
+ a, b = f[:2]
+ f = f[2:]
+ if a == 'format':
+ input_spec['format'] = b
+ elif a == 'option':
+ input_spec['options'].append(b)
+ else:
+ raise E_syntax
+ tclist[-1]['input'] = input_spec
elif key == 'output':
op_spec = {
'pd': f.pop(0),
def diff_text(f1, f2):
t1 = open(f1).readlines()
t2 = open(f2).readlines()
- diff = []
- d = Differ()
- for line in d.compare(t1, t2):
- if line[:2] in ('- ', '+ '):
- diff.append(line.strip())
-
+ diff = list(unified_diff(t1, t2))
+ diff = diff[2:] # Strip two from/to filename lines with "+++"/"---".
+ diff = [d.strip() for d in diff if d[0] in ('+', '-')]
return diff
args.extend(['-p', "%s=%d" % (label, channel)])
for option, value in spd['options']:
args.extend(['-o', "%s=%s" % (option, value)])
- args.extend(['-i', os.path.join(dumps_dir, tc['input'])])
+ for label, initial_pin in spd['initial_pins']:
+ args.extend(['-N', "%s=%d" % (label, initial_pin)])
+ # Setup input spec for this test (optional format spec).
+ in_spec = tc['input']
+ infile = os.path.join(dumps_dir, in_spec['name'])
+ args.extend(['-i', infile])
+ if in_spec['format']:
+ args.extend(['-I', in_spec['format']])
+ for opt in in_spec['options']:
+ args.extend(['-I', opt])
+ # Setup output spec for this test.
for op in tc['output']:
name = "%s/%s/%s" % (pd, tc['name'], op['type'])
opargs = ['-O', "%s:%s" % (op['pd'], op['type'])]
return results, errors
+def get_run_tests_error_diff_counts(results):
+ """Get error and diff counters from run_tests() results."""
+ errs = 0
+ diffs = 0
+ for result in results:
+ if 'error' in result:
+ errs += 1
+ if 'diff' in result:
+ diffs += 1
+ return errs, diffs
+
def gen_report(result):
out = []
for label, channel in pd['channels']:
print(" Channel %s=%d" % (label, channel))
for option, value in pd['options']:
- print(" Option %s=%d" % (option, value))
+ print(" Option %s=%s" % (option, value))
+ for label, initial_pin in pd['initial_pins']:
+ print(" Initial pin %s=%d" % (label, initial_pin))
if 'stack' in tc:
print(" Stack: %s" % ' '.join(tc['stack']))
print(" Input: %s" % tc['input'])
try:
if args:
testlist = get_tests(args)
- elif opt_all:
+ elif opt_all or opt_list:
testlist = get_tests(os.listdir(tests_dir))
else:
usage("Specify either -a or tests.")
ERR("Could not find sigrok-dumps repository at %s" % dumps_dir)
sys.exit(1)
results, errors = run_tests(testlist, fix=opt_fix)
- ret = errors
+ ret = 0
+ errs, diffs = get_run_tests_error_diff_counts(results)
+ if errs:
+ ret = 1
+ elif diffs:
+ ret = 2
elif opt_show:
show_tests(testlist)
elif opt_list:
raise
sys.exit(ret)
-