def _check_sloppy_fork(self, name, value): if self._pid == os.getpid(): return yatest_logger.error("Skip tracing to avoid data corruption, name = %s, value = %s", name, value) try: # Lock wreckage tracefile to avoid race if multiple tests use fork sloppily if filelock: lock = filelock.FileLock(self._wreckage_filename + '.lock') lock.acquire() with open(self._wreckage_filename, 'a') as afile: self._file = afile parts = [ "It looks like you have leaked process - it could corrupt internal test machinery files.", "Usually it happens when you casually use fork() without os._exit(),", "which results in two pytest processes running at the same time.", "Pid of the original pytest's process is {}, however current process has {} pid.".format(self._pid, os.getpid()), ] if self._current_test[1]: parts.append("Most likely the problem is in '{}' test.".format(self._current_test)) else: parts.append("Most likely new process was created before any test was launched (during the import stage?).") if value.get('comment'): comment = value.get('comment', '').strip() # multiline comment newline_required = '\n' if '\n' in comment else '' parts.append("Debug info: name = '{}' comment:{}{}".format(name, newline_required, comment)) else: val_str = json.dumps(value, ensure_ascii=False).encode('utf-8') parts.append("Debug info: name = '{}' value = '{}'".format(name, base64.b64encode(val_str))) msg = "[[bad]]{}".format('\n'.join(parts)) class_name, subtest_name = self._current_test if subtest_name: data = { 'class': class_name, 'subtest': subtest_name, 'status': 'fail', 'comment': msg, } # overwrite original status self._dump_trace('subtest-finished', data) else: self._dump_trace('suite_event', {"errors": [('fail', msg)]}) except Exception as e: yatest_logger.exception(e) finally: os._exit(38)
def _check_intricate_respawn(self): pid_file = self._filename + '.pid' try: # python2 doesn't support open(f, 'x') afile = os.fdopen( os.open(pid_file, os.O_WRONLY | os.O_EXCL | os.O_CREAT), 'w') afile.write(str(self._pid)) afile.close() return except OSError as e: if e.errno != errno.EEXIST: raise # Looks like the test binary was respawned if from_ya_test(): try: with open(pid_file) as afile: prev_pid = afile.read() except Exception as e: prev_pid = '(failed to obtain previous pid: {})'.format(e) parts = [ "Aborting test run: test machinery found that the test binary {} has already been run before." .format(sys.executable), "Looks like test has incorrect respawn/relaunch logic within test binary.", "Test should not try to restart itself - this is a poorly designed test case that leads to errors and could corrupt internal test machinery files.", "Debug info: previous pid:{} current:{}".format( prev_pid, self._pid), ] msg = '\n'.join(parts) yatest_logger.error(msg) if filelock: lock = filelock.FileLock(self._wreckage_filename + '.lock') lock.acquire() with open(self._wreckage_filename, 'a') as afile: self._file = afile self._dump_trace('suite_event', {"errors": [('fail', '[[bad]]' + msg)]}) raise Exception(msg) else: # Test binary is launched without `ya make -t`'s testing machinery - don't rely on clean environment pass