| 98 | |
| 99 | |
| 100 | class TestRunner: |
| 101 | def __init__(self, ddnet, ddnet_server, ddnet_mastersrv, repo_dir, test_dir, show_full_output, valgrind_memcheck, keep_tmpdirs, timeout_multiplier): |
| 102 | self.ddnet = ddnet |
| 103 | self.ddnet_server = ddnet_server |
| 104 | self.ddnet_mastersrv = ddnet_mastersrv |
| 105 | self.repo_dir = repo_dir |
| 106 | self.data_dir = os.path.join(test_dir, "data") |
| 107 | self.test_dir = test_dir |
| 108 | self.extra_env_vars = {} |
| 109 | self.show_full_output = show_full_output |
| 110 | self.keep_tmpdirs = keep_tmpdirs |
| 111 | self.timeout_multiplier = timeout_multiplier |
| 112 | self.valgrind_memcheck = valgrind_memcheck |
| 113 | if self.valgrind_memcheck: |
| 114 | self.timeout_multiplier *= 20 |
| 115 | |
| 116 | def run_test(self, test): |
| 117 | tmp_dir = tempfile.mkdtemp(prefix=f"integration_{test.name}_", dir=self.test_dir) |
| 118 | tmp_dir_cleanup = not self.keep_tmpdirs |
| 119 | try: |
| 120 | env = TestEnvironment(self, test.name, tmp_dir, timeout=test.timeout) |
| 121 | try: |
| 122 | test(env) |
| 123 | except Exception as e: # noqa: BLE001 blind-except |
| 124 | env.kill_all() |
| 125 | error = "".join(traceback.format_exception(type(e), e, e.__traceback__)) |
| 126 | error = error + env.format_valgrind_memcheck_errors() |
| 127 | error = error + env.format_stdout_stderr() |
| 128 | tmp_dir_cleanup = False |
| 129 | else: |
| 130 | env.kill_all() |
| 131 | error = None |
| 132 | if self.valgrind_memcheck: |
| 133 | error = env.format_valgrind_memcheck_errors() |
| 134 | if error: |
| 135 | error = error + env.format_stdout_stderr() |
| 136 | tmp_dir_cleanup = False |
| 137 | else: |
| 138 | error = None |
| 139 | finally: |
| 140 | if tmp_dir_cleanup: |
| 141 | shutil.rmtree(tmp_dir) |
| 142 | tmp_dir = None |
| 143 | elif error: |
| 144 | with open(os.path.join(tmp_dir, "test_failure.log"), "w", encoding="utf-8") as test_failure_file: |
| 145 | test_failure_file.write(error) |
| 146 | return relpath(tmp_dir) if tmp_dir is not None else None, error |
| 147 | |
| 148 | def run_tests(self, tests): |
| 149 | tests = list(tests) |
| 150 | print("running {} test{}".format(len(tests), "s" if len(tests) != 1 else "")) |
| 151 | start = time() |
| 152 | failed = [] |
| 153 | num_passed = 0 |
| 154 | num_skipped = 0 |
| 155 | for test in tests: |
| 156 | if test.requires_mastersrv and self.ddnet_mastersrv is None: |
| 157 | print(f"{test.name} ... {YELLOW}skipped{RESET}") |