Changeset View
Changeset View
Standalone View
Standalone View
test/functional/test_runner.py
Show All 30 Lines | |||||
GREEN = ("", "") | GREEN = ("", "") | ||||
if os.name == 'posix': | if os.name == 'posix': | ||||
# primitive formatting on supported | # primitive formatting on supported | ||||
# terminal via ANSI escape sequences: | # terminal via ANSI escape sequences: | ||||
BOLD = ('\033[0m', '\033[1m') | BOLD = ('\033[0m', '\033[1m') | ||||
RED = ("\033[0m", "\033[31m") | RED = ("\033[0m", "\033[31m") | ||||
GREEN = ("\033[0m", "\033[32m") | GREEN = ("\033[0m", "\033[32m") | ||||
TEST_EXIT_PASSED = 0 | |||||
TEST_EXIT_SKIPPED = 77 | |||||
BASE_SCRIPTS = [ | BASE_SCRIPTS = [ | ||||
# Longest test should go first, to favor running tests in parallel | # Longest test should go first, to favor running tests in parallel | ||||
'wallet-hd.py', | 'wallet-hd.py', | ||||
'walletbackup.py', | 'walletbackup.py', | ||||
# vv Tests less than 5m vv | # vv Tests less than 5m vv | ||||
'p2p-fullblocktest.py', | 'p2p-fullblocktest.py', | ||||
'fundrawtransaction.py', | 'fundrawtransaction.py', | ||||
'p2p-compactblocks.py', | 'p2p-compactblocks.py', | ||||
▲ Show 20 Lines • Show All 207 Lines • ▼ Show 20 Lines | def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=False, args=[]): | ||||
time0 = time.time() | time0 = time.time() | ||||
job_queue = TestHandler(jobs, tests_dir, test_list, flags) | job_queue = TestHandler(jobs, tests_dir, test_list, flags) | ||||
max_len_name = len(max(test_list, key=len)) | max_len_name = len(max(test_list, key=len)) | ||||
results = BOLD[1] + "%s | %s | %s\n\n" % ( | results = BOLD[1] + "%s | %s | %s\n\n" % ( | ||||
"TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] | "TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] | ||||
for _ in range(len(test_list)): | for _ in range(len(test_list)): | ||||
(name, stdout, stderr, passed, duration) = job_queue.get_next() | (name, stdout, stderr, status, duration) = job_queue.get_next() | ||||
all_passed = all_passed and passed | all_passed = all_passed and status != "Failed" | ||||
time_sum += duration | time_sum += duration | ||||
print('\n' + BOLD[1] + name + BOLD[0] + ":") | print('\n' + BOLD[1] + name + BOLD[0] + ":") | ||||
print('' if passed else stdout + '\n', end='') | print('' if status == "Passed" else stdout + '\n', end='') | ||||
print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') | print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') | ||||
print("Pass: {bold}{result}{unbold}, Duration: {duration}s\n".format( | print("Pass: {bold}{result}{unbold}, Duration: {duration}s\n".format( | ||||
bold=BOLD[1], result=passed, unbold=BOLD[0], duration=duration)) | bold=BOLD[1], result=status, unbold=BOLD[0], duration=duration)) | ||||
result = "{name} | {passed} | {duration}s\n".format(name=name.ljust( | result = "{name} | {passed} | {duration}s\n".format(name=name.ljust( | ||||
max_len_name), passed=str(passed).ljust(6), duration=duration) | max_len_name), passed=str(status).ljust(6), duration=duration) | ||||
if passed: | if status == "Passed": | ||||
results += GREEN[1] + result + GREEN[0] | results += GREEN[1] + result + GREEN[0] | ||||
else: | else: | ||||
results += RED[1] + result + RED[0] | results += RED[1] + result + RED[0] | ||||
results += BOLD[1] + "\n{name} | {passed} | {duration}s (accumulated)".format( | results += BOLD[1] + "\n{name} | {passed} | {duration}s (accumulated)".format( | ||||
name="ALL".ljust(max_len_name), passed=str(all_passed).ljust(6), duration=time_sum) + BOLD[0] | name="ALL".ljust(max_len_name), passed=str(all_passed).ljust(6), duration=time_sum) + BOLD[0] | ||||
print(results) | print(results) | ||||
print("\nRuntime: {} s".format(int(time.time() - time0))) | print("\nRuntime: {} s".format(int(time.time() - time0))) | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | def get_next(self): | ||||
# In travis, timeout individual tests after 20 minutes (to stop tests hanging and not | # In travis, timeout individual tests after 20 minutes (to stop tests hanging and not | ||||
# providing useful output. | # providing useful output. | ||||
proc.send_signal(signal.SIGINT) | proc.send_signal(signal.SIGINT) | ||||
if proc.poll() is not None: | if proc.poll() is not None: | ||||
log_out.seek(0), log_err.seek(0) | log_out.seek(0), log_err.seek(0) | ||||
[stdout, stderr] = [l.read().decode('utf-8') | [stdout, stderr] = [l.read().decode('utf-8') | ||||
for l in (log_out, log_err)] | for l in (log_out, log_err)] | ||||
log_out.close(), log_err.close() | log_out.close(), log_err.close() | ||||
passed = stderr == "" and proc.returncode == 0 | if proc.returncode == TEST_EXIT_PASSED and stderr == "": | ||||
status = "Passed" | |||||
elif proc.returncode == TEST_EXIT_SKIPPED: | |||||
status = "Skipped" | |||||
else: | |||||
status = "Failed" | |||||
self.num_running -= 1 | self.num_running -= 1 | ||||
self.jobs.remove(j) | self.jobs.remove(j) | ||||
return name, stdout, stderr, passed, int( | return name, stdout, stderr, status, int( | ||||
time.time() - time0) | time.time() - time0) | ||||
print('.', end='', flush=True) | print('.', end='', flush=True) | ||||
class RPCCoverage(object): | class RPCCoverage(object): | ||||
""" | """ | ||||
Coverage reporting utilities for test_runner. | Coverage reporting utilities for test_runner. | ||||
▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines |