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()
Example #2
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.assertEquals(test[1], timedelta_string(test[0]))
Example #3
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()