diff --git a/test/crossrunner/report.py b/test/crossrunner/report.py
index be7271c..cc5f26f 100644
--- a/test/crossrunner/report.py
+++ b/test/crossrunner/report.py
@@ -39,396 +39,396 @@
 
 
 def generate_known_failures(testdir, overwrite, save, out):
-  def collect_failures(results):
-    success_index = 5
-    for r in results:
-      if not r[success_index]:
-        yield TestEntry.get_name(*r)
-  try:
-    with logfile_open(path_join(testdir, RESULT_JSON), 'r') as fp:
-      results = json.load(fp)
-  except IOError:
-    sys.stderr.write('Unable to load last result. Did you run tests ?\n')
-    return False
-  fails = collect_failures(results['results'])
-  if not overwrite:
-    known = load_known_failures(testdir)
-    known.extend(fails)
-    fails = known
-  fails_json = json.dumps(sorted(set(fails)), indent=2, separators=(',', ': '))
-  if save:
-    with logfile_open(os.path.join(testdir, FAIL_JSON % platform.system()), 'w+') as fp:
-      fp.write(fails_json)
-    sys.stdout.write('Successfully updated known failures.\n')
-  if out:
-    sys.stdout.write(fails_json)
-    sys.stdout.write('\n')
-  return True
+    def collect_failures(results):
+        success_index = 5
+        for r in results:
+            if not r[success_index]:
+                yield TestEntry.get_name(*r)
+    try:
+        with logfile_open(path_join(testdir, RESULT_JSON), 'r') as fp:
+            results = json.load(fp)
+    except IOError:
+        sys.stderr.write('Unable to load last result. Did you run tests ?\n')
+        return False
+    fails = collect_failures(results['results'])
+    if not overwrite:
+        known = load_known_failures(testdir)
+        known.extend(fails)
+        fails = known
+    fails_json = json.dumps(sorted(set(fails)), indent=2, separators=(',', ': '))
+    if save:
+        with logfile_open(os.path.join(testdir, FAIL_JSON % platform.system()), 'w+') as fp:
+            fp.write(fails_json)
+        sys.stdout.write('Successfully updated known failures.\n')
+    if out:
+        sys.stdout.write(fails_json)
+        sys.stdout.write('\n')
+    return True
 
 
 def load_known_failures(testdir):
-  try:
-    with logfile_open(path_join(testdir, FAIL_JSON % platform.system()), 'r') as fp:
-      return json.load(fp)
-  except IOError:
-    return []
+    try:
+        with logfile_open(path_join(testdir, FAIL_JSON % platform.system()), 'r') as fp:
+            return json.load(fp)
+    except IOError:
+        return []
 
 
 class TestReporter(object):
-  # Unfortunately, standard library doesn't handle timezone well
-  # DATETIME_FORMAT = '%a %b %d %H:%M:%S %Z %Y'
-  DATETIME_FORMAT = '%a %b %d %H:%M:%S %Y'
+    # Unfortunately, standard library doesn't handle timezone well
+    # DATETIME_FORMAT = '%a %b %d %H:%M:%S %Z %Y'
+    DATETIME_FORMAT = '%a %b %d %H:%M:%S %Y'
 
-  def __init__(self):
-    self._log = multiprocessing.get_logger()
-    self._lock = multiprocessing.Lock()
+    def __init__(self):
+        self._log = multiprocessing.get_logger()
+        self._lock = multiprocessing.Lock()
 
-  @classmethod
-  def test_logfile(cls, test_name, prog_kind, dir=None):
-    relpath = path_join('log', '%s_%s.log' % (test_name, prog_kind))
-    return relpath if not dir else os.path.realpath(path_join(dir, relpath))
+    @classmethod
+    def test_logfile(cls, test_name, prog_kind, dir=None):
+        relpath = path_join('log', '%s_%s.log' % (test_name, prog_kind))
+        return relpath if not dir else os.path.realpath(path_join(dir, relpath))
 
-  def _start(self):
-    self._start_time = time.time()
+    def _start(self):
+        self._start_time = time.time()
 
-  @property
-  def _elapsed(self):
-    return time.time() - self._start_time
+    @property
+    def _elapsed(self):
+        return time.time() - self._start_time
 
-  @classmethod
-  def _format_date(cls):
-    return '%s' % datetime.datetime.now().strftime(cls.DATETIME_FORMAT)
+    @classmethod
+    def _format_date(cls):
+        return '%s' % datetime.datetime.now().strftime(cls.DATETIME_FORMAT)
 
-  def _print_date(self):
-    print(self._format_date(), file=self.out)
+    def _print_date(self):
+        print(self._format_date(), file=self.out)
 
-  def _print_bar(self, out=None):
-    print(
-      '==========================================================================',
-      file=(out or self.out))
+    def _print_bar(self, out=None):
+        print(
+            '==========================================================================',
+            file=(out or self.out))
 
-  def _print_exec_time(self):
-    print('Test execution took {:.1f} seconds.'.format(self._elapsed), file=self.out)
+    def _print_exec_time(self):
+        print('Test execution took {:.1f} seconds.'.format(self._elapsed), file=self.out)
 
 
 class ExecReporter(TestReporter):
-  def __init__(self, testdir, test, prog):
-    super(ExecReporter, self).__init__()
-    self._test = test
-    self._prog = prog
-    self.logpath = self.test_logfile(test.name, prog.kind, testdir)
-    self.out = None
-
-  def begin(self):
-    self._start()
-    self._open()
-    if self.out and not self.out.closed:
-      self._print_header()
-    else:
-      self._log.debug('Output stream is not available.')
-
-  def end(self, returncode):
-    self._lock.acquire()
-    try:
-      if self.out and not self.out.closed:
-        self._print_footer(returncode)
-        self._close()
+    def __init__(self, testdir, test, prog):
+        super(ExecReporter, self).__init__()
+        self._test = test
+        self._prog = prog
+        self.logpath = self.test_logfile(test.name, prog.kind, testdir)
         self.out = None
-      else:
-        self._log.debug('Output stream is not available.')
-    finally:
-      self._lock.release()
 
-  def killed(self):
-    print(file=self.out)
-    print('Server process is successfully killed.', file=self.out)
-    self.end(None)
+    def begin(self):
+        self._start()
+        self._open()
+        if self.out and not self.out.closed:
+            self._print_header()
+        else:
+            self._log.debug('Output stream is not available.')
 
-  def died(self):
-    print(file=self.out)
-    print('*** Server process has died unexpectedly ***', file=self.out)
-    self.end(None)
+    def end(self, returncode):
+        self._lock.acquire()
+        try:
+            if self.out and not self.out.closed:
+                self._print_footer(returncode)
+                self._close()
+                self.out = None
+            else:
+                self._log.debug('Output stream is not available.')
+        finally:
+            self._lock.release()
 
-  _init_failure_exprs = {
-    'server': list(map(re.compile, [
-      '[Aa]ddress already in use',
-      'Could not bind',
-      'EADDRINUSE',
-    ])),
-    'client': list(map(re.compile, [
-      '[Cc]onnection refused',
-      'Could not connect to localhost',
-      'ECONNREFUSED',
-      'No such file or directory',  # domain socket
-    ])),
-  }
+    def killed(self):
+        print(file=self.out)
+        print('Server process is successfully killed.', file=self.out)
+        self.end(None)
 
-  def maybe_false_positive(self):
-    """Searches through log file for socket bind error.
-    Returns True if suspicious expression is found, otherwise False"""
-    try:
-      if self.out and not self.out.closed:
+    def died(self):
+        print(file=self.out)
+        print('*** Server process has died unexpectedly ***', file=self.out)
+        self.end(None)
+
+    _init_failure_exprs = {
+        'server': list(map(re.compile, [
+            '[Aa]ddress already in use',
+            'Could not bind',
+            'EADDRINUSE',
+        ])),
+        'client': list(map(re.compile, [
+            '[Cc]onnection refused',
+            'Could not connect to localhost',
+            'ECONNREFUSED',
+            'No such file or directory',  # domain socket
+        ])),
+    }
+
+    def maybe_false_positive(self):
+        """Searches through log file for socket bind error.
+        Returns True if suspicious expression is found, otherwise False"""
+        try:
+            if self.out and not self.out.closed:
+                self.out.flush()
+            exprs = self._init_failure_exprs[self._prog.kind]
+
+            def match(line):
+                for expr in exprs:
+                    if expr.search(line):
+                        return True
+
+            with logfile_open(self.logpath, 'r') as fp:
+                if any(map(match, fp)):
+                    return True
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except Exception as ex:
+            self._log.warn('[%s]: Error while detecting false positive: %s' % (self._test.name, str(ex)))
+            self._log.info(traceback.print_exc())
+        return False
+
+    def _open(self):
+        self.out = logfile_open(self.logpath, 'w+')
+
+    def _close(self):
+        self.out.close()
+
+    def _print_header(self):
+        self._print_date()
+        print('Executing: %s' % str_join(' ', self._prog.command), file=self.out)
+        print('Directory: %s' % self._prog.workdir, file=self.out)
+        print('config:delay: %s' % self._test.delay, file=self.out)
+        print('config:timeout: %s' % self._test.timeout, file=self.out)
+        self._print_bar()
         self.out.flush()
-      exprs = self._init_failure_exprs[self._prog.kind]
 
-      def match(line):
-        for expr in exprs:
-          if expr.search(line):
-            return True
-
-      with logfile_open(self.logpath, 'r') as fp:
-        if any(map(match, fp)):
-          return True
-    except (KeyboardInterrupt, SystemExit):
-      raise
-    except Exception as ex:
-      self._log.warn('[%s]: Error while detecting false positive: %s' % (self._test.name, str(ex)))
-      self._log.info(traceback.print_exc())
-    return False
-
-  def _open(self):
-    self.out = logfile_open(self.logpath, 'w+')
-
-  def _close(self):
-    self.out.close()
-
-  def _print_header(self):
-    self._print_date()
-    print('Executing: %s' % str_join(' ', self._prog.command), file=self.out)
-    print('Directory: %s' % self._prog.workdir, file=self.out)
-    print('config:delay: %s' % self._test.delay, file=self.out)
-    print('config:timeout: %s' % self._test.timeout, file=self.out)
-    self._print_bar()
-    self.out.flush()
-
-  def _print_footer(self, returncode=None):
-    self._print_bar()
-    if returncode is not None:
-      print('Return code: %d' % returncode, file=self.out)
-    else:
-      print('Process is killed.', file=self.out)
-    self._print_exec_time()
-    self._print_date()
+    def _print_footer(self, returncode=None):
+        self._print_bar()
+        if returncode is not None:
+            print('Return code: %d' % returncode, file=self.out)
+        else:
+            print('Process is killed.', file=self.out)
+        self._print_exec_time()
+        self._print_date()
 
 
 class SummaryReporter(TestReporter):
-  def __init__(self, basedir, testdir_relative, concurrent=True):
-    super(SummaryReporter, self).__init__()
-    self._basedir = basedir
-    self._testdir_rel = testdir_relative
-    self.logdir = path_join(self.testdir, LOG_DIR)
-    self.out_path = path_join(self.testdir, RESULT_JSON)
-    self.concurrent = concurrent
-    self.out = sys.stdout
-    self._platform = platform.system()
-    self._revision = self._get_revision()
-    self._tests = []
-    if not os.path.exists(self.logdir):
-      os.mkdir(self.logdir)
-    self._known_failures = load_known_failures(self.testdir)
-    self._unexpected_success = []
-    self._flaky_success = []
-    self._unexpected_failure = []
-    self._expected_failure = []
-    self._print_header()
+    def __init__(self, basedir, testdir_relative, concurrent=True):
+        super(SummaryReporter, self).__init__()
+        self._basedir = basedir
+        self._testdir_rel = testdir_relative
+        self.logdir = path_join(self.testdir, LOG_DIR)
+        self.out_path = path_join(self.testdir, RESULT_JSON)
+        self.concurrent = concurrent
+        self.out = sys.stdout
+        self._platform = platform.system()
+        self._revision = self._get_revision()
+        self._tests = []
+        if not os.path.exists(self.logdir):
+            os.mkdir(self.logdir)
+        self._known_failures = load_known_failures(self.testdir)
+        self._unexpected_success = []
+        self._flaky_success = []
+        self._unexpected_failure = []
+        self._expected_failure = []
+        self._print_header()
 
-  @property
-  def testdir(self):
-    return path_join(self._basedir, self._testdir_rel)
+    @property
+    def testdir(self):
+        return path_join(self._basedir, self._testdir_rel)
 
-  def _result_string(self, test):
-    if test.success:
-      if test.retry_count == 0:
-        return 'success'
-      elif test.retry_count == 1:
-        return 'flaky(1 retry)'
-      else:
-        return 'flaky(%d retries)' % test.retry_count
-    elif test.expired:
-      return 'failure(timeout)'
-    else:
-      return 'failure(%d)' % test.returncode
-
-  def _get_revision(self):
-    p = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'],
-                         cwd=self.testdir, stdout=subprocess.PIPE)
-    out, _ = p.communicate()
-    return out.strip()
-
-  def _format_test(self, test, with_result=True):
-    name = '%s-%s' % (test.server.name, test.client.name)
-    trans = '%s-%s' % (test.transport, test.socket)
-    if not with_result:
-      return '{:24s}{:13s}{:25s}'.format(name[:23], test.protocol[:12], trans[:24])
-    else:
-      return '{:24s}{:13s}{:25s}{:s}\n'.format(name[:23], test.protocol[:12], trans[:24], self._result_string(test))
-
-  def _print_test_header(self):
-    self._print_bar()
-    print(
-      '{:24s}{:13s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'),
-      file=self.out)
-
-  def _print_header(self):
-    self._start()
-    print('Apache Thrift - Integration Test Suite', file=self.out)
-    self._print_date()
-    self._print_test_header()
-
-  def _print_unexpected_failure(self):
-    if len(self._unexpected_failure) > 0:
-      self.out.writelines([
-        '*** Following %d failures were unexpected ***:\n' % len(self._unexpected_failure),
-        'If it is introduced by you, please fix it before submitting the code.\n',
-        # 'If not, please report at https://issues.apache.org/jira/browse/THRIFT\n',
-      ])
-      self._print_test_header()
-      for i in self._unexpected_failure:
-        self.out.write(self._format_test(self._tests[i]))
-      self._print_bar()
-    else:
-      print('No unexpected failures.', file=self.out)
-
-  def _print_flaky_success(self):
-    if len(self._flaky_success) > 0:
-      print(
-          'Following %d tests were expected to cleanly succeed but needed retry:' % len(self._flaky_success),
-          file=self.out)
-      self._print_test_header()
-      for i in self._flaky_success:
-        self.out.write(self._format_test(self._tests[i]))
-      self._print_bar()
-
-  def _print_unexpected_success(self):
-    if len(self._unexpected_success) > 0:
-      print(
-        'Following %d tests were known to fail but succeeded (maybe flaky):' % len(self._unexpected_success),
-        file=self.out)
-      self._print_test_header()
-      for i in self._unexpected_success:
-        self.out.write(self._format_test(self._tests[i]))
-      self._print_bar()
-
-  def _http_server_command(self, port):
-    if sys.version_info[0] < 3:
-      return 'python -m SimpleHTTPServer %d' % port
-    else:
-      return 'python -m http.server %d' % port
-
-  def _print_footer(self):
-    fail_count = len(self._expected_failure) + len(self._unexpected_failure)
-    self._print_bar()
-    self._print_unexpected_success()
-    self._print_flaky_success()
-    self._print_unexpected_failure()
-    self._write_html_data()
-    self._assemble_log('unexpected failures', self._unexpected_failure)
-    self._assemble_log('known failures', self._expected_failure)
-    self.out.writelines([
-      'You can browse results at:\n',
-      '\tfile://%s/%s\n' % (self.testdir, RESULT_HTML),
-      '# If you use Chrome, run:\n',
-      '# \tcd %s\n#\t%s\n' % (self._basedir, self._http_server_command(8001)),
-      '# then browse:\n',
-      '# \thttp://localhost:%d/%s/\n' % (8001, self._testdir_rel),
-      'Full log for each test is here:\n',
-      '\ttest/log/client_server_protocol_transport_client.log\n',
-      '\ttest/log/client_server_protocol_transport_server.log\n',
-      '%d failed of %d tests in total.\n' % (fail_count, len(self._tests)),
-    ])
-    self._print_exec_time()
-    self._print_date()
-
-  def _render_result(self, test):
-    return [
-      test.server.name,
-      test.client.name,
-      test.protocol,
-      test.transport,
-      test.socket,
-      test.success,
-      test.as_expected,
-      test.returncode,
-      {
-        'server': self.test_logfile(test.name, test.server.kind),
-        'client': self.test_logfile(test.name, test.client.kind),
-      },
-    ]
-
-  def _write_html_data(self):
-    """Writes JSON data to be read by result html"""
-    results = [self._render_result(r) for r in self._tests]
-    with logfile_open(self.out_path, 'w+') as fp:
-      fp.write(json.dumps({
-        'date': self._format_date(),
-        'revision': str(self._revision),
-        'platform': self._platform,
-        'duration': '{:.1f}'.format(self._elapsed),
-        'results': results,
-      }, indent=2))
-
-  def _assemble_log(self, title, indexes):
-    if len(indexes) > 0:
-      def add_prog_log(fp, test, prog_kind):
-        print('*************************** %s message ***************************' % prog_kind,
-              file=fp)
-        path = self.test_logfile(test.name, prog_kind, self.testdir)
-        if os.path.exists(path):
-          with logfile_open(path, 'r') as prog_fp:
-            print(prog_fp.read(), file=fp)
-      filename = title.replace(' ', '_') + '.log'
-      with logfile_open(os.path.join(self.logdir, filename), 'w+') as fp:
-        for test in map(self._tests.__getitem__, indexes):
-          fp.write('TEST: [%s]\n' % test.name)
-          add_prog_log(fp, test, test.server.kind)
-          add_prog_log(fp, test, test.client.kind)
-          fp.write('**********************************************************************\n\n')
-      print('%s are logged to %s/%s/%s' % (title.capitalize(), self._testdir_rel, LOG_DIR, filename))
-
-  def end(self):
-    self._print_footer()
-    return len(self._unexpected_failure) == 0
-
-  def add_test(self, test_dict):
-    test = TestEntry(self.testdir, **test_dict)
-    self._lock.acquire()
-    try:
-      if not self.concurrent:
-        self.out.write(self._format_test(test, False))
-        self.out.flush()
-      self._tests.append(test)
-      return len(self._tests) - 1
-    finally:
-      self._lock.release()
-
-  def add_result(self, index, returncode, expired, retry_count):
-    self._lock.acquire()
-    try:
-      failed = returncode is None or returncode != 0
-      flaky = not failed and retry_count != 0
-      test = self._tests[index]
-      known = test.name in self._known_failures
-      if failed:
-        if known:
-          self._log.debug('%s failed as expected' % test.name)
-          self._expected_failure.append(index)
+    def _result_string(self, test):
+        if test.success:
+            if test.retry_count == 0:
+                return 'success'
+            elif test.retry_count == 1:
+                return 'flaky(1 retry)'
+            else:
+                return 'flaky(%d retries)' % test.retry_count
+        elif test.expired:
+            return 'failure(timeout)'
         else:
-          self._log.info('unexpected failure: %s' % test.name)
-          self._unexpected_failure.append(index)
-      elif flaky and not known:
-        self._log.info('unexpected flaky success: %s' % test.name)
-        self._flaky_success.append(index)
-      elif not flaky and known:
-        self._log.info('unexpected success: %s' % test.name)
-        self._unexpected_success.append(index)
-      test.success = not failed
-      test.returncode = returncode
-      test.retry_count = retry_count
-      test.expired = expired
-      test.as_expected = known == failed
-      if not self.concurrent:
-        self.out.write(self._result_string(test) + '\n')
-      else:
-        self.out.write(self._format_test(test))
-    finally:
-      self._lock.release()
+            return 'failure(%d)' % test.returncode
+
+    def _get_revision(self):
+        p = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'],
+                             cwd=self.testdir, stdout=subprocess.PIPE)
+        out, _ = p.communicate()
+        return out.strip()
+
+    def _format_test(self, test, with_result=True):
+        name = '%s-%s' % (test.server.name, test.client.name)
+        trans = '%s-%s' % (test.transport, test.socket)
+        if not with_result:
+            return '{:24s}{:13s}{:25s}'.format(name[:23], test.protocol[:12], trans[:24])
+        else:
+            return '{:24s}{:13s}{:25s}{:s}\n'.format(name[:23], test.protocol[:12], trans[:24], self._result_string(test))
+
+    def _print_test_header(self):
+        self._print_bar()
+        print(
+            '{:24s}{:13s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'),
+            file=self.out)
+
+    def _print_header(self):
+        self._start()
+        print('Apache Thrift - Integration Test Suite', file=self.out)
+        self._print_date()
+        self._print_test_header()
+
+    def _print_unexpected_failure(self):
+        if len(self._unexpected_failure) > 0:
+            self.out.writelines([
+                '*** Following %d failures were unexpected ***:\n' % len(self._unexpected_failure),
+                'If it is introduced by you, please fix it before submitting the code.\n',
+                # 'If not, please report at https://issues.apache.org/jira/browse/THRIFT\n',
+            ])
+            self._print_test_header()
+            for i in self._unexpected_failure:
+                self.out.write(self._format_test(self._tests[i]))
+            self._print_bar()
+        else:
+            print('No unexpected failures.', file=self.out)
+
+    def _print_flaky_success(self):
+        if len(self._flaky_success) > 0:
+            print(
+                'Following %d tests were expected to cleanly succeed but needed retry:' % len(self._flaky_success),
+                file=self.out)
+            self._print_test_header()
+            for i in self._flaky_success:
+                self.out.write(self._format_test(self._tests[i]))
+            self._print_bar()
+
+    def _print_unexpected_success(self):
+        if len(self._unexpected_success) > 0:
+            print(
+                'Following %d tests were known to fail but succeeded (maybe flaky):' % len(self._unexpected_success),
+                file=self.out)
+            self._print_test_header()
+            for i in self._unexpected_success:
+                self.out.write(self._format_test(self._tests[i]))
+            self._print_bar()
+
+    def _http_server_command(self, port):
+        if sys.version_info[0] < 3:
+            return 'python -m SimpleHTTPServer %d' % port
+        else:
+            return 'python -m http.server %d' % port
+
+    def _print_footer(self):
+        fail_count = len(self._expected_failure) + len(self._unexpected_failure)
+        self._print_bar()
+        self._print_unexpected_success()
+        self._print_flaky_success()
+        self._print_unexpected_failure()
+        self._write_html_data()
+        self._assemble_log('unexpected failures', self._unexpected_failure)
+        self._assemble_log('known failures', self._expected_failure)
+        self.out.writelines([
+            'You can browse results at:\n',
+            '\tfile://%s/%s\n' % (self.testdir, RESULT_HTML),
+            '# If you use Chrome, run:\n',
+            '# \tcd %s\n#\t%s\n' % (self._basedir, self._http_server_command(8001)),
+            '# then browse:\n',
+            '# \thttp://localhost:%d/%s/\n' % (8001, self._testdir_rel),
+            'Full log for each test is here:\n',
+            '\ttest/log/client_server_protocol_transport_client.log\n',
+            '\ttest/log/client_server_protocol_transport_server.log\n',
+            '%d failed of %d tests in total.\n' % (fail_count, len(self._tests)),
+        ])
+        self._print_exec_time()
+        self._print_date()
+
+    def _render_result(self, test):
+        return [
+            test.server.name,
+            test.client.name,
+            test.protocol,
+            test.transport,
+            test.socket,
+            test.success,
+            test.as_expected,
+            test.returncode,
+            {
+                'server': self.test_logfile(test.name, test.server.kind),
+                'client': self.test_logfile(test.name, test.client.kind),
+            },
+        ]
+
+    def _write_html_data(self):
+        """Writes JSON data to be read by result html"""
+        results = [self._render_result(r) for r in self._tests]
+        with logfile_open(self.out_path, 'w+') as fp:
+            fp.write(json.dumps({
+                'date': self._format_date(),
+                'revision': str(self._revision),
+                'platform': self._platform,
+                'duration': '{:.1f}'.format(self._elapsed),
+                'results': results,
+            }, indent=2))
+
+    def _assemble_log(self, title, indexes):
+        if len(indexes) > 0:
+            def add_prog_log(fp, test, prog_kind):
+                print('*************************** %s message ***************************' % prog_kind,
+                      file=fp)
+                path = self.test_logfile(test.name, prog_kind, self.testdir)
+                if os.path.exists(path):
+                    with logfile_open(path, 'r') as prog_fp:
+                        print(prog_fp.read(), file=fp)
+            filename = title.replace(' ', '_') + '.log'
+            with logfile_open(os.path.join(self.logdir, filename), 'w+') as fp:
+                for test in map(self._tests.__getitem__, indexes):
+                    fp.write('TEST: [%s]\n' % test.name)
+                    add_prog_log(fp, test, test.server.kind)
+                    add_prog_log(fp, test, test.client.kind)
+                    fp.write('**********************************************************************\n\n')
+            print('%s are logged to %s/%s/%s' % (title.capitalize(), self._testdir_rel, LOG_DIR, filename))
+
+    def end(self):
+        self._print_footer()
+        return len(self._unexpected_failure) == 0
+
+    def add_test(self, test_dict):
+        test = TestEntry(self.testdir, **test_dict)
+        self._lock.acquire()
+        try:
+            if not self.concurrent:
+                self.out.write(self._format_test(test, False))
+                self.out.flush()
+            self._tests.append(test)
+            return len(self._tests) - 1
+        finally:
+            self._lock.release()
+
+    def add_result(self, index, returncode, expired, retry_count):
+        self._lock.acquire()
+        try:
+            failed = returncode is None or returncode != 0
+            flaky = not failed and retry_count != 0
+            test = self._tests[index]
+            known = test.name in self._known_failures
+            if failed:
+                if known:
+                    self._log.debug('%s failed as expected' % test.name)
+                    self._expected_failure.append(index)
+                else:
+                    self._log.info('unexpected failure: %s' % test.name)
+                    self._unexpected_failure.append(index)
+            elif flaky and not known:
+                self._log.info('unexpected flaky success: %s' % test.name)
+                self._flaky_success.append(index)
+            elif not flaky and known:
+                self._log.info('unexpected success: %s' % test.name)
+                self._unexpected_success.append(index)
+            test.success = not failed
+            test.returncode = returncode
+            test.retry_count = retry_count
+            test.expired = expired
+            test.as_expected = known == failed
+            if not self.concurrent:
+                self.out.write(self._result_string(test) + '\n')
+            else:
+                self.out.write(self._format_test(test))
+        finally:
+            self._lock.release()
