def _wait_for_process(self, proc_dict, step_num): # handle counters, status msgs, and other stuff on stderr proc = proc_dict['proc'] stderr_lines = self._process_stderr_from_script(proc.stderr, step_num=step_num) tb_lines = _find_python_traceback(stderr_lines) # proc.stdout isn't always defined if proc.stdout: proc.stdout.close() proc.stderr.close() returncode = proc.wait() if returncode != 0: # show counters before raising exception counters = self._counters[step_num] if counters: log.info(_format_counters(counters)) # try to throw a useful exception if tb_lines: for line in tb_lines: log.error(line.rstrip('\r\n')) reason = str(CalledProcessError(returncode, proc_dict['args'])) raise StepFailedException(reason=reason, step_num=step_num, num_steps=len(self._get_steps()))
def _wait_for_process(self, proc_dict, step_num): # handle counters, status msgs, and other stuff on stderr proc = proc_dict['proc'] stderr_lines = self._process_stderr_from_script( proc.stderr, step_num=step_num) tb_lines = _find_python_traceback(stderr_lines) # proc.stdout isn't always defined if proc.stdout: proc.stdout.close() proc.stderr.close() returncode = proc.wait() if returncode != 0: # show counters before raising exception counters = self._counters[step_num] if counters: log.info(_format_counters(counters)) # try to throw a useful exception if tb_lines: for line in tb_lines: log.error(line.rstrip('\r\n')) reason = str( CalledProcessError(returncode, proc_dict['args'])) raise StepFailedException( reason=reason, step_num=step_num, num_steps=len(self._get_steps()))
def test_find_python_traceback(self): def run(*args): return Popen(args, stdout=PIPE, stderr=PIPE).communicate() # sanity-check normal operations ok_stdout, ok_stderr = run('python', '-c', "print(sorted('321'))") self.assertEqual(ok_stdout.rstrip(), b"['1', '2', '3']") self.assertEqual(_find_python_traceback(BytesIO(ok_stderr)), None) # Oops, can't sort a number. stdout, stderr = run('python', '-c', "print(sorted(321))") # We expect something like this: # # Traceback (most recent call last): # File "<string>", line 1, in <module> # TypeError: 'int' object is not iterable self.assertEqual(stdout, b'') # save the traceback for the next step tb = _find_python_traceback(BytesIO(stderr)) self.assertNotEqual(tb, None) assert isinstance(tb, list) # The first line ("Traceback...") is not skipped self.assertIn("Traceback (most recent call last):", tb[0]) self.assertIn("TypeError: 'int' object is not iterable", tb[-1]) # PyPy doesn't support -v if hasattr(sys, 'pypy_version_info'): return # make sure we can find the same traceback in noise verbose_stdout, verbose_stderr = run('python', '-v', '-c', "print(sorted(321))") self.assertEqual(verbose_stdout, b'') self.assertNotEqual(verbose_stderr, stderr) verbose_tb = _find_python_traceback(BytesIO(verbose_stderr)) self.assertEqual(verbose_tb, tb)
def test_find_python_traceback(self): def run(*args): return Popen(args, stdout=PIPE, stderr=PIPE).communicate() # sanity-check normal operations ok_stdout, ok_stderr = run('python', '-c', "print(sorted('321'))") self.assertEqual(ok_stdout.rstrip(), b"['1', '2', '3']") self.assertEqual(_find_python_traceback(BytesIO(ok_stderr)), None) # Oops, can't sort a number. stdout, stderr = run('python', '-c', "print(sorted(321))") # We expect something like this: # # Traceback (most recent call last): # File "<string>", line 1, in <module> # TypeError: 'int' object is not iterable self.assertEqual(stdout, b'') # save the traceback for the next step tb = _find_python_traceback(BytesIO(stderr)) self.assertNotEqual(tb, None) assert isinstance(tb, list) # The first line ("Traceback...") is not skipped self.assertIn("Traceback (most recent call last):", tb[0]) self.assertIn("TypeError: 'int' object is not iterable", tb[-1]) # PyPy doesn't support -v if hasattr(sys, 'pypy_version_info'): return # make sure we can find the same traceback in noise verbose_stdout, verbose_stderr = run( 'python', '-v', '-c', "print(sorted(321))") self.assertEqual(verbose_stdout, b'') self.assertNotEqual(verbose_stderr, stderr) verbose_tb = _find_python_traceback(BytesIO(verbose_stderr)) self.assertEqual(verbose_tb, tb)
def test_find_python_traceback_with_more_stderr_2(self): total_traceback = self.EXAMPLE_STDERR_TRACEBACK_2 + b'junk\n' tb = _find_python_traceback(BytesIO(total_traceback)) self.assertEqual(''.join(tb), self.EXAMPLE_STDERR_TRACEBACK_2.decode('ascii'))
def test_find_multiple_python_tracebacks(self): total_traceback = self.EXAMPLE_TRACEBACK + b'junk\n' tb = _find_python_traceback(BytesIO(total_traceback)) self.assertEqual(''.join(tb), self.EXAMPLE_TRACEBACK.decode('ascii'))