1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4import logging
5
6from telemetry.testing import run_tests
7
8
9def RunChromeOSTests(browser_type, tests_to_run):
10  """ Run ChromeOS tests.
11  Args:
12    |browser_type|: string specifies which browser type to use.
13    |tests_to_run|: a list of tuples (top_level_dir, unit_tests), whereas
14      |top_level_dir| specifies the top level directory for running tests, and
15      |unit_tests| is a list of string test names to run.
16  """
17  stream = _LoggingOutputStream()
18  error_string = ''
19
20  for (top_level_dir, unit_tests) in tests_to_run:
21    logging.info('Running unit tests in %s with browser_type "%s".' %
22                 (top_level_dir, browser_type))
23
24    ret = _RunOneSetOfTests(browser_type, top_level_dir, unit_tests, stream)
25    if ret:
26      error_string += 'The unit tests of %s failed.\n' % top_level_dir
27  return error_string
28
29
30def _RunOneSetOfTests(browser_type, top_level_dir, tests, stream):
31  args = ['--browser', browser_type,
32          '--top-level-dir', top_level_dir,
33          '--jobs', '1',
34          '--disable-logging-config'] + tests
35  return run_tests.RunTestsCommand.main(args, stream=stream)
36
37
38class _LoggingOutputStream(object):
39
40  def __init__(self):
41    self._buffer = []
42
43  def write(self, s):
44    """Buffer a string write. Log it when we encounter a newline."""
45    if '\n' in s:
46      segments = s.split('\n')
47      segments[0] = ''.join(self._buffer + [segments[0]])
48      log_level = logging.getLogger().getEffectiveLevel()
49      try:  # TODO(dtu): We need this because of crbug.com/394571
50        logging.getLogger().setLevel(logging.INFO)
51        for line in segments[:-1]:
52          logging.info(line)
53      finally:
54        logging.getLogger().setLevel(log_level)
55      self._buffer = [segments[-1]]
56    else:
57      self._buffer.append(s)
58
59  def flush(self):
60    pass
61