diff --git a/lib/test_suite.py b/lib/test_suite.py index 98906359..d1fcd509 100644 --- a/lib/test_suite.py +++ b/lib/test_suite.py @@ -4,18 +4,13 @@ import re import lib +from lib.app_server import AppServer from lib.colorer import color_stdout from lib.inspector import TarantoolInspector from lib.server import Server from lib.tarantool_server import TarantoolServer -from lib.app_server import AppServer from lib.unittest_server import UnittestServer -from lib.utils import non_empty_valgrind_logs -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO class ConfigurationError(RuntimeError): def __init__(self, name, value, expected): @@ -66,7 +61,6 @@ def get_multirun_params(self, test_path): result = self.multi_run.get('*', None) return result - def __init__(self, suite_path, args): """Initialize a test suite: check that it exists and contains a syntactically correct configuration file. Then create @@ -77,7 +71,7 @@ def __init__(self, suite_path, args): self.suite_path = suite_path self.ini["core"] = "tarantool" - if os.access(suite_path, os.F_OK) == False: + if not os.access(suite_path, os.F_OK): raise RuntimeError("Suite %s doesn't exist" % repr(suite_path)) # read the suite config @@ -92,12 +86,19 @@ def __init__(self, suite_path, args): self.ini['long_run'] = [] for i in ["script"]: - self.ini[i] = os.path.join(suite_path, self.ini[i]) if i in self.ini else None + self.ini[i] = os.path.join(suite_path, self.ini[i]) \ + if i in self.ini else None for i in ["disabled", "valgrind_disabled", "release_disabled"]: - self.ini[i] = dict.fromkeys(self.ini[i].split()) if i in self.ini else dict() + self.ini[i] = dict.fromkeys(self.ini[i].split()) \ + if i in self.ini else dict() for i in ["lua_libs"]: - self.ini[i] = map(lambda x: os.path.join(suite_path, x), - dict.fromkeys(self.ini[i].split()) if i in self.ini else dict()) + self.ini[i] = map( + lambda x: os.path.join(suite_path, x), + dict.fromkeys(self.ini[i].split()) + if i in self.ini else dict()) + + self.ini.update( + dict(show_reproduce_content=self.show_reproduce_content())) def find_tests(self): if self.ini['core'] == 'tarantool': @@ -144,8 +145,8 @@ def is_test_enabled(self, test, conf, server): ] for check in checks: check_enabled, disabled_tests = check - if check_enabled and (test_name in disabled_tests - or tconf in disabled_tests): + if check_enabled and (test_name in disabled_tests or + tconf in disabled_tests): return False return True @@ -177,20 +178,15 @@ def run_test(self, test, server, inspector): 'new', 'fail', or 'disabled'. """ test.inspector = inspector - color_stdout( - os.path.join( - self.ini['suite'], - os.path.basename(test.name) - ).ljust(48), - schema='t_name' - ) + test_name = os.path.basename(test.name) + color_stdout(os.path.join(self.ini['suite'], test_name).ljust(48), + schema='t_name') # for better diagnostics in case of a long-running test conf = '' if test.run_params: conf = test.conf_name color_stdout(conf.ljust(16), schema='test_var') - test_name = os.path.basename(test.name) if self.is_test_enabled(test, conf, server): short_status = test.run(server) @@ -205,12 +201,23 @@ def run_test(self, test, server, inspector): return short_status def is_parallel(self): - val = self.ini.get('is_parallel', 'False').lower() - if val == 'true': - val = True - elif val == 'false': - val = False - else: - raise ConfigurationError() - pass - return val + val = self.ini.get('is_parallel', 'false') + if isinstance(val, bool): + return val + # If value is not boolean it come from ini file, need to + # convert string 'True' or 'False' into boolean representation + if val.lower() not in ['true', 'false']: + raise ConfigurationError('is_parallel', val, "'True' or 'False'") + return val.lower() == 'true' + + def show_reproduce_content(self): + val = self.ini.get('show_reproduce_content', 'true') + if isinstance(val, bool): + return val + # If value is not boolean it come from ini file, need to + # convert string 'True' or 'False' into boolean representation + if val.lower() not in ['true', 'false']: + raise ConfigurationError('show_reproduce_content', + val, + "'True' or 'False'") + return val.lower() == 'true' diff --git a/lib/worker.py b/lib/worker.py index c6e8c58f..9e494204 100644 --- a/lib/worker.py +++ b/lib/worker.py @@ -78,6 +78,7 @@ def get_task_groups(): 'gen_worker': gen_worker, 'task_ids': task_ids, 'is_parallel': suite.is_parallel(), + 'show_reproduce_content': suite.show_reproduce_content() } return res @@ -131,12 +132,14 @@ class WorkerTaskResult(BaseWorkerMessage): worker. The short_status (string) field intended to give short note whether the task processed successfully or not, but with little more flexibility than binary True/False. The task_id (any hashable object) field hold ID of - the processed task. + the processed task. The show_reproduce_content configuration form suite.ini """ - def __init__(self, worker_id, worker_name, task_id, short_status): + def __init__(self, worker_id, worker_name, task_id, + short_status, show_reproduce_content): super(WorkerTaskResult, self).__init__(worker_id, worker_name) self.short_status = short_status self.task_id = task_id + self.show_reproduce_content = show_reproduce_content class WorkerOutput(BaseWorkerMessage): @@ -198,7 +201,8 @@ def current_task(self, task_id): task_name, task_param, task_result_filepath) def wrap_result(self, task_id, short_status): - return WorkerTaskResult(self.id, self.name, task_id, short_status) + return WorkerTaskResult(self.id, self.name, task_id, short_status, + self.suite.show_reproduce_content()) def sigterm_handler(self, signum, frame): self.sigterm_received = True diff --git a/listeners.py b/listeners.py index 5e95325e..d07c670b 100644 --- a/listeners.py +++ b/listeners.py @@ -40,7 +40,9 @@ def process_result(self, obj): self.stats[obj.short_status] += 1 if obj.short_status == 'fail': - self.failed_tasks.append((obj.task_id, obj.worker_name)) + self.failed_tasks.append((obj.task_id, + obj.worker_name, + obj.show_reproduce_content)) def print_statistics(self): """Returns are there failed tasks.""" @@ -53,15 +55,16 @@ def print_statistics(self): return False color_stdout('Failed tasks:\n', schema='test_var') - for task_id, worker_name in self.failed_tasks: + for task_id, worker_name, show_reproduce_content in self.failed_tasks: logfile = self.get_logfile(worker_name) - reproduce_file_path = get_reproduce_file(worker_name) color_stdout('- %s' % yaml.safe_dump(task_id), schema='test_var') color_stdout('# logfile: %s\n' % logfile) + reproduce_file_path = get_reproduce_file(worker_name) color_stdout('# reproduce file: %s\n' % reproduce_file_path) - color_stdout("---\n", schema='separator') - lib.utils.print_tail_n(reproduce_file_path) - color_stdout("...\n", schema='separator') + if show_reproduce_content: + color_stdout("---\n", schema='separator') + lib.utils.print_tail_n(reproduce_file_path) + color_stdout("...\n", schema='separator') return True diff --git a/test-run.py b/test-run.py index 38bc6eb2..3ee3beca 100755 --- a/test-run.py +++ b/test-run.py @@ -151,6 +151,7 @@ def main_loop_consistent(failed_test_ids): color_stdout('-' * 75, "\n", schema='separator') task_ids = task_group['task_ids'] + show_reproduce_content = task_group['show_reproduce_content'] if not task_ids: continue worker_id = 1 @@ -162,9 +163,10 @@ def main_loop_consistent(failed_test_ids): lib.worker.get_reproduce_file(worker.name) color_stdout('Reproduce file %s\n' % reproduce_file_path, schema='error') - color_stdout("---\n", schema='separator') - lib.utils.print_tail_n(reproduce_file_path) - color_stdout("...\n", schema='separator') + if show_reproduce_content: + color_stdout("---\n", schema='separator') + lib.utils.print_tail_n(reproduce_file_path) + color_stdout("...\n", schema='separator') failed_test_ids.append(task_id) if not lib.Options().args.is_force: worker.stop_server(cleanup=False)