def _WatchTestOutput(self, p):
        """Watches the test output.
    Args:
      p: the process generating output as created by pexpect.spawn.
    """
        ok_tests = []
        failed_tests = []
        crashed_tests = []
        timed_out_tests = []

        # Test case statuses.
        re_run = re.compile('\[ RUN      \] ?(.*)\r\n')
        re_fail = re.compile('\[  FAILED  \] ?(.*)\r\n')
        re_ok = re.compile('\[       OK \] ?(.*?) .*\r\n')

        # Test run statuses.
        re_passed = re.compile('\[  PASSED  \] ?(.*)\r\n')
        re_runner_fail = re.compile('\[ RUNNER_FAILED \] ?(.*)\r\n')
        # Signal handlers are installed before starting tests
        # to output the CRASHED marker when a crash happens.
        re_crash = re.compile('\[ CRASHED      \](.*)\r\n')

        try:
            while True:
                full_test_name = None

                found = p.expect([re_run, re_passed, re_runner_fail],
                                 timeout=self.timeout)
                if found == 1:  # re_passed
                    break
                elif found == 2:  # re_runner_fail
                    break
                else:  # re_run
                    full_test_name = p.match.group(1).replace('\r', '')
                    found = p.expect([re_ok, re_fail, re_crash],
                                     timeout=self.timeout)
                    if found == 0:  # re_ok
                        if full_test_name == p.match.group(1).replace(
                                '\r', ''):
                            ok_tests += [
                                BaseTestResult(full_test_name, p.before)
                            ]
                    elif found == 2:  # re_crash
                        crashed_tests += [
                            BaseTestResult(full_test_name, p.before)
                        ]
                        break
                    else:  # re_fail
                        failed_tests += [
                            BaseTestResult(full_test_name, p.before)
                        ]
        except pexpect.EOF:
            logging.error('Test terminated - EOF')
            # We're here because either the device went offline, or the test harness
            # crashed without outputting the CRASHED marker (crbug.com/175538).
            if not self.adb.IsOnline():
                raise errors.DeviceUnresponsiveError(
                    'Device %s went offline.' % self.device)
            elif full_test_name:
                crashed_tests += [BaseTestResult(full_test_name, p.before)]
        except pexpect.TIMEOUT:
            logging.error('Test terminated after %d second timeout.',
                          self.timeout)
            if full_test_name:
                timed_out_tests += [BaseTestResult(full_test_name, p.before)]
        finally:
            p.close()

        ret_code = self._GetGTestReturnCode()
        if ret_code:
            logging.critical(
                'gtest exit code: %d\npexpect.before: %s\npexpect.after: %s',
                ret_code, p.before, p.after)

        # Create TestResults and return
        return TestResults.FromRun(ok=ok_tests,
                                   failed=failed_tests,
                                   crashed=crashed_tests,
                                   timed_out=timed_out_tests)