| OLD | NEW | 
|    1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |    1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|    2 # Use of this source code is governed by a BSD-style license that can be |    2 # Use of this source code is governed by a BSD-style license that can be | 
|    3 # found in the LICENSE file. |    3 # found in the LICENSE file. | 
|    4  |    4  | 
|    5 """Helper functions common to native test runners.""" |    5 """Helper functions common to native, java and python test runners.""" | 
|    6  |    6  | 
 |    7 import contextlib | 
 |    8 import fcntl | 
 |    9 import httplib | 
|    7 import logging |   10 import logging | 
|    8 import optparse |   11 import optparse | 
|    9 import os |   12 import os | 
 |   13 import re | 
 |   14 import socket | 
|   10 import subprocess |   15 import subprocess | 
|   11 import sys |   16 import sys | 
 |   17 import traceback | 
|   12  |   18  | 
|   13 # TODO(michaelbai): Move constant definitions like below to a common file. |   19 import cmd_helper | 
|   14 FORWARDER_PATH = '/data/local/tmp/forwarder' |  | 
|   15  |  | 
|   16 CHROME_DIR = os.path.abspath(os.path.join(sys.path[0], '..', '..')) |  | 
|   17  |  | 
|   18  |  | 
|   19 def IsRunningAsBuildbot(): |  | 
|   20   """Returns True if we are currently running on buildbot; False otherwise.""" |  | 
|   21   return bool(os.getenv('BUILDBOT_BUILDERNAME')) |  | 
|   22  |  | 
|   23  |  | 
|   24 def ReportBuildbotLink(label, url): |  | 
|   25   """Adds a link with name |label| linking to |url| to current buildbot step. |  | 
|   26  |  | 
|   27   Args: |  | 
|   28     label: A string with the name of the label. |  | 
|   29     url: A string of the URL. |  | 
|   30   """ |  | 
|   31   if IsRunningAsBuildbot(): |  | 
|   32     print '@@@STEP_LINK@%s@%s@@@' % (label, url) |  | 
|   33  |  | 
|   34  |  | 
|   35 def ReportBuildbotMsg(msg): |  | 
|   36   """Appends |msg| to the current buildbot step text. |  | 
|   37  |  | 
|   38   Args: |  | 
|   39     msg: String to be appended. |  | 
|   40   """ |  | 
|   41   if IsRunningAsBuildbot(): |  | 
|   42     print '@@@STEP_TEXT@%s@@@' % msg |  | 
|   43  |  | 
|   44 def ReportBuildbotError(): |  | 
|   45   """Marks the current step as failed.""" |  | 
|   46   if IsRunningAsBuildbot(): |  | 
|   47     print '@@@STEP_FAILURE@@@' |  | 
|   48  |   20  | 
|   49  |   21  | 
|   50 def GetExpectations(file_name): |   22 def GetExpectations(file_name): | 
|   51   """Returns a list of test names in the |file_name| test expectations file.""" |   23   """Returns a list of test names in the |file_name| test expectations file.""" | 
|   52   if not file_name or not os.path.exists(file_name): |   24   if not file_name or not os.path.exists(file_name): | 
|   53     return [] |   25     return [] | 
|   54   return [x for x in [x.strip() for x in file(file_name).readlines()] |   26   return [x for x in [x.strip() for x in file(file_name).readlines()] | 
|   55           if x and x[0] != '#'] |   27           if x and x[0] != '#'] | 
|   56  |   28  | 
|   57  |   29  | 
|   58 def SetLogLevel(verbose_count): |   30 def SetLogLevel(verbose_count): | 
|   59   """Sets log level as |verbose_count|.""" |   31   """Sets log level as |verbose_count|.""" | 
|   60   log_level = logging.WARNING  # Default. |   32   log_level = logging.WARNING  # Default. | 
|   61   if verbose_count == 1: |   33   if verbose_count == 1: | 
|   62     log_level = logging.INFO |   34     log_level = logging.INFO | 
|   63   elif verbose_count >= 2: |   35   elif verbose_count >= 2: | 
|   64     log_level = logging.DEBUG |   36     log_level = logging.DEBUG | 
|   65   logging.getLogger().setLevel(log_level) |   37   logging.getLogger().setLevel(log_level) | 
|   66  |  | 
|   67  |  | 
|   68 def CreateTestRunnerOptionParser(usage=None, default_timeout=60): |  | 
|   69   """Returns a new OptionParser with arguments applicable to all tests.""" |  | 
|   70   option_parser = optparse.OptionParser(usage=usage) |  | 
|   71   option_parser.add_option('-t', dest='timeout', |  | 
|   72                            help='Timeout to wait for each test', |  | 
|   73                            type='int', |  | 
|   74                            default=default_timeout) |  | 
|   75   option_parser.add_option('-c', dest='cleanup_test_files', |  | 
|   76                            help='Cleanup test files on the device after run', |  | 
|   77                            action='store_true', |  | 
|   78                            default=False) |  | 
|   79   option_parser.add_option('-v', |  | 
|   80                            '--verbose', |  | 
|   81                            dest='verbose_count', |  | 
|   82                            default=0, |  | 
|   83                            action='count', |  | 
|   84                            help='Verbose level (multiple times for more)') |  | 
|   85   option_parser.add_option('--tool', |  | 
|   86                            dest='tool', |  | 
|   87                            help='Run the test under a tool ' |  | 
|   88                            '(use --tool help to list them)') |  | 
|   89   return option_parser |  | 
|   90  |  | 
|   91  |  | 
|   92 def ForwardDevicePorts(adb, ports, host_name='127.0.0.1'): |  | 
|   93   """Forwards a TCP port on the device back to the host. |  | 
|   94  |  | 
|   95   Works like adb forward, but in reverse. |  | 
|   96  |  | 
|   97   Args: |  | 
|   98     adb: Instance of AndroidCommands for talking to the device. |  | 
|   99     ports: A list of tuples (device_port, host_port) to forward. |  | 
|  100     host_name: Optional. Address to forward to, must be addressable from the |  | 
|  101                host machine. Usually this is omitted and loopback is used. |  | 
|  102  |  | 
|  103   Returns: |  | 
|  104     subprocess instance connected to the forwarder process on the device. |  | 
|  105   """ |  | 
|  106   adb.PushIfNeeded( |  | 
|  107       os.path.join(CHROME_DIR, 'out', 'Release', 'forwarder'), FORWARDER_PATH) |  | 
|  108   forward_string = ['%d:%d:%s' % |  | 
|  109                     (device, host, host_name) for device, host in ports] |  | 
|  110   logging.info("Forwarding ports: %s" % (forward_string)) |  | 
|  111  |  | 
|  112   return subprocess.Popen( |  | 
|  113       ['adb', '-s', adb._adb.GetSerialNumber(), |  | 
|  114        'shell', '%s -D %s' % (FORWARDER_PATH, ' '.join(forward_string))]) |  | 
|  115  |  | 
|  116  |  | 
|  117 def IsDevicePortUsed(adb, device_port): |  | 
|  118   """Checks whether the specified device port is used or not. |  | 
|  119  |  | 
|  120   Args: |  | 
|  121     adb: Instance of AndroidCommands for talking to the device. |  | 
|  122     device_port: Port on device we want to check. |  | 
|  123  |  | 
|  124   Returns: |  | 
|  125     True if the port on device is already used, otherwise returns False. |  | 
|  126   """ |  | 
|  127   base_url = '127.0.0.1:%d' % device_port |  | 
|  128   netstat_results = adb.RunShellCommand('netstat') |  | 
|  129   for single_connect in netstat_results: |  | 
|  130     # Column 3 is the local address which we want to check with. |  | 
|  131     if single_connect.split()[3] == base_url: |  | 
|  132       return True |  | 
|  133   return False |  | 
| OLD | NEW |