def wait_subprocess(process, stream=None, echo=False, postprocess_hook=None): """Waits for subprocess to finish and returns (final status, stdout). This will also consume the remaining output to return it. Returns: Process exit code, stdout remaining in process prior to this invocation. Any previously read output from the process will not be included. """ text_lines = [] if process.stdout is not None: # stdout isnt going to another stream; collect it from the pipe. for raw_line in iter(process.stdout.readline, ''): if not raw_line: break decoded_line = raw_line.decode(encoding='utf-8') text_lines.append(decoded_line) if stream: stream.write(raw_line) stream.flush() process.wait() if stream is None: # Close stdout pipe if we didnt give a stream. # Otherwise caller owns the stream. process.stdout.close() if hasattr(process, 'start_date'): end_date = datetime.datetime.now() delta_time_str = timedelta_string(end_date - process.start_date) else: delta_time_str = 'UNKNOWN' returncode = process.returncode stdout = ''.join(text_lines) if stream: stream.write('\n\n----\n{time} Spawned process completed' ' with returncode {returncode} in {delta_time}.\n'.format( time=log_timestring(now=end_date), returncode=returncode, delta_time=delta_time_str)) stream.flush() if echo: logging.info('%s returned %d with output:\n%s', process.pid, returncode, stdout) logging.debug('Finished %s with returncode=%d in %s', process.pid, returncode, delta_time_str) if postprocess_hook: postprocess_hook(returncode, stdout) return returncode, stdout.strip()
def test_deltatime_string(self): timedelta = datetime.timedelta tests = [(timedelta(1, 60 * 60 * 4 + 60 * 5 + 2, 123456), 'days=1 + 04:05:02'), (timedelta(1, 60 * 5 + 2, 123456), 'days=1 + 00:05:02'), (timedelta(1, 2, 123456), 'days=1 + 00:00:02'), (timedelta(0, 60 * 60 * 4 + 60 * 5 + 2, 123456), '04:05:02'), (timedelta(0, 60 * 5 + 2, 123456), '05:02'), (timedelta(0, 2, 123456), '2.123 secs')] for test in tests: self.assertEquals(test[1], timedelta_string(test[0]))
def test_deltatime_string(self): timedelta = datetime.timedelta tests = [ (timedelta(1, 60 * 60 * 4 + 60 * 5 + 2, 123456), 'days=1 + 04:05:02'), (timedelta(1, 60 * 5 + 2, 123456), 'days=1 + 00:05:02'), (timedelta(1, 2, 123456), 'days=1 + 00:00:02'), (timedelta(0, 60 * 60 * 4 + 60 * 5 + 2, 123456), '04:05:02'), (timedelta(0, 60 * 5 + 2, 123456), '05:02'), (timedelta(0, 2, 123456), '2.123 secs') ] for test in tests: self.assertEqual(test[1], timedelta_string(test[0]))
def wait_subprocess(process, stream=None, echo=False, postprocess_hook=None): """Waits for subprocess to finish and returns (final status, stdout). This will also consume the remaining output to return it. Returns: Process exit code, stdout remaining in process prior to this invocation. Any previously read output from the process will not be included. """ text_lines = [] if process.stdout is not None: # stdout isnt going to another stream; collect it from the pipe. for raw_line in iter(process.stdout.readline, ""): if not raw_line: break decoded_line = raw_line.decode(encoding="utf-8") text_lines.append(decoded_line) if stream: stream.write(decoded_line) stream.flush() if process.stderr is not None: log_level = logging.INFO if echo else logging.DEBUG # stderr isn't going to another file handle; log it for raw_line in iter(process.stderr.readline, ""): decoded_line = raw_line.decode(encoding="utf-8").rstrip("\n") logging.log( log_level, "PID %s wrote to stderr: %s", process.pid, decoded_line ) process.wait() if stream is None and process.stdout is not None: # Close stdout pipe if we didnt give a stream. # Otherwise caller owns the stream. process.stdout.close() if hasattr(process, "start_date"): end_date = datetime.datetime.now() delta_time_str = timedelta_string(end_date - process.start_date) else: delta_time_str = "UNKNOWN" returncode = process.returncode stdout = "".join(text_lines) if stream: stream.write( "\n\n----\n{time} Spawned process completed" " with returncode {returncode} in {delta_time}.\n".format( time=log_timestring(now=end_date), returncode=returncode, delta_time=delta_time_str, ) ) stream.flush() if echo: logging.info("%s returned %d with output:\n%s", process.pid, returncode, stdout) logging.debug( "Finished %s with returncode=%d in %s", process.pid, returncode, delta_time_str ) if postprocess_hook: postprocess_hook(returncode, stdout) return returncode, stdout.strip()