コード例 #1
0
 def LaunchChromeTestServerSpawner(self):
     """Launches test server spawner."""
     server_ready = False
     error_msgs = []
     # Try 3 times to launch test spawner server.
     for i in xrange(0, 3):
         # Do not allocate port for test server here. We will allocate
         # different port for individual test in TestServerThread.
         self.test_server_spawner_port = ports.AllocateTestServerPort()
         self._spawning_server = SpawningServer(
             self.test_server_spawner_port, self.adb, self.tool,
             self.build_type)
         self._spawning_server.Start()
         server_ready, error_msg = ports.IsHttpServerConnectable(
             '127.0.0.1',
             self.test_server_spawner_port,
             path='/ping',
             expected_read='ready')
         if server_ready:
             break
         else:
             error_msgs.append(error_msg)
         self._spawning_server.Stop()
         # Wait for 2 seconds then restart.
         time.sleep(2)
     if not server_ready:
         logging.error(';'.join(error_msgs))
         raise Exception('Can not start the test spawner server.')
     self._PushTestServerPortInfoToDevice()
     self._spawner_forwarder = Forwarder(
         self.adb,
         [(self.test_server_spawner_port, self.test_server_spawner_port)],
         self.tool, '127.0.0.1', self.build_type)
コード例 #2
0
 def LaunchChromeTestServerSpawner(self):
     """Launches test server spawner."""
     self._spawning_server = SpawningServer(TEST_SERVER_SPAWNER_PORT,
                                            TEST_SERVER_PORT)
     self._spawning_server.Start()
     # TODO(yfriedman): Ideally we'll only try to start up a port forwarder if
     # there isn't one already running but for now we just get an error message
     # and the existing forwarder still works.
     self._spawner_forwarder = run_tests_helper.ForwardDevicePorts(
         self.adb, [(TEST_SERVER_SPAWNER_PORT, TEST_SERVER_SPAWNER_PORT),
                    (TEST_SERVER_PORT, TEST_SERVER_PORT)])
コード例 #3
0
class BaseTestRunner(object):
    """Base class for running tests on a single device."""
    def __init__(self, device):
        """
      Args:
        device: Tests will run on the device of this ID.
    """
        self.device = device
        self.adb = android_commands.AndroidCommands(device=device)
        # Synchronize date/time between host and device. Otherwise same file on
        # host and device may have different timestamp which may cause
        # AndroidCommands.PushIfNeeded failed, or a test which may compare timestamp
        # got from http head and local time could be failed.
        self.adb.SynchronizeDateTime()
        self._http_server = None
        self._forwarder = None
        self._spawning_server = None
        self._spawner_forwarder = None
        self._forwarder_device_port = 8000
        self.forwarder_base_url = ('http://localhost:%d' %
                                   self._forwarder_device_port)
        self.flags = FlagChanger(self.adb)

    def RunTests(self):
        # TODO(bulach): this should actually do SetUp / RunTestsInternal / TearDown.
        # Refactor the various subclasses to expose a RunTestsInternal without
        # any params.
        raise NotImplementedError

    def SetUp(self):
        """Called before tests run."""
        pass

    def TearDown(self):
        """Called when tests finish running."""
        self.ShutdownHelperToolsForTestSuite()

    def CopyTestData(self, test_data_paths, dest_dir):
        """Copies |test_data_paths| list of files/directories to |dest_dir|.

    Args:
      test_data_paths: A list of files or directories relative to |dest_dir|
          which should be copied to the device. The paths must exist in
          |CHROME_DIR|.
      dest_dir: Absolute path to copy to on the device.
    """
        for p in test_data_paths:
            self.adb.PushIfNeeded(os.path.join(run_tests_helper.CHROME_DIR, p),
                                  os.path.join(dest_dir, p))

    def LaunchTestHttpServer(self, document_root, extra_config_contents=None):
        """Launches an HTTP server to serve HTTP tests.

    Args:
      document_root: Document root of the HTTP server.
      extra_config_contents: Extra config contents for the HTTP server.
    """
        self._http_server = lighttpd_server.LighttpdServer(
            document_root, extra_config_contents=extra_config_contents)
        if self._http_server.StartupHttpServer():
            logging.info('http server started: http://localhost:%s',
                         self._http_server.port)
        else:
            logging.critical('Failed to start http server')
        # Root access needed to make the forwarder executable work.
        self.adb.EnableAdbRoot()
        self.StartForwarderForHttpServer()

    def StartForwarderForHttpServer(self):
        """Starts a forwarder for the HTTP server.

    The forwarder forwards HTTP requests and responses between host and device.
    """
        # Sometimes the forwarder device port may be already used. We have to kill
        # all forwarder processes to ensure that the forwarder can be started since
        # currently we can not associate the specified port to related pid.
        # TODO(yfriedman/wangxianzhu): This doesn't work as most of the time the
        # port is in use but the forwarder is already dead. Killing all forwarders
        # is overly destructive and breaks other tests which make use of forwarders.
        # if IsDevicePortUsed(self.adb, self._forwarder_device_port):
        #   self.adb.KillAll('forwarder')
        self._forwarder = run_tests_helper.ForwardDevicePorts(
            self.adb, [(self._forwarder_device_port, self._http_server.port)])

    def RestartHttpServerForwarderIfNecessary(self):
        """Restarts the forwarder if it's not open."""
        # Checks to see if the http server port is being used.  If not forwards the
        # request.
        # TODO(dtrainor): This is not always reliable because sometimes the port
        # will be left open even after the forwarder has been killed.
        if not run_tests_helper.IsDevicePortUsed(self.adb,
                                                 self._forwarder_device_port):
            self.StartForwarderForHttpServer()

    def ShutdownHelperToolsForTestSuite(self):
        """Shuts down the server and the forwarder."""
        # Forwarders should be killed before the actual servers they're forwarding
        # to as they are clients potentially with open connections and to allow for
        # proper hand-shake/shutdown.
        if self._forwarder or self._spawner_forwarder:
            # Kill all forwarders on the device and then kill the process on the host
            # (if it exists)
            self.adb.KillAll('forwarder')
            if self._forwarder:
                self._forwarder.kill()
            if self._spawner_forwarder:
                self._spawner_forwarder.kill()
        if self._http_server:
            self._http_server.ShutdownHttpServer()
        if self._spawning_server:
            self._spawning_server.Stop()
        self.flags.Restore()

    def LaunchChromeTestServerSpawner(self):
        """Launches test server spawner."""
        self._spawning_server = SpawningServer(TEST_SERVER_SPAWNER_PORT,
                                               TEST_SERVER_PORT)
        self._spawning_server.Start()
        # TODO(yfriedman): Ideally we'll only try to start up a port forwarder if
        # there isn't one already running but for now we just get an error message
        # and the existing forwarder still works.
        self._spawner_forwarder = run_tests_helper.ForwardDevicePorts(
            self.adb, [(TEST_SERVER_SPAWNER_PORT, TEST_SERVER_SPAWNER_PORT),
                       (TEST_SERVER_PORT, TEST_SERVER_PORT)])
コード例 #4
0
class BaseTestRunner(object):
    """Base class for running tests on a single device.

  A subclass should implement RunTests() with no parameter, so that calling
  the Run() method will set up tests, run them and tear them down.
  """
    def __init__(self, device, tool, shard_index, build_type):
        """
      Args:
        device: Tests will run on the device of this ID.
        shard_index: Index number of the shard on which the test suite will run.
        build_type: 'Release' or 'Debug'.
    """
        self.device = device
        self.adb = android_commands.AndroidCommands(device=device)
        self.tool = CreateTool(tool, self.adb)
        self._http_server = None
        self._forwarder = None
        self._forwarder_device_port = 8000
        self.forwarder_base_url = ('http://localhost:%d' %
                                   self._forwarder_device_port)
        self.flags = FlagChanger(self.adb)
        self.shard_index = shard_index
        self.flags.AddFlags(['--disable-fre'])
        self._spawning_server = None
        self._spawner_forwarder = None
        # We will allocate port for test server spawner when calling method
        # LaunchChromeTestServerSpawner and allocate port for test server when
        # starting it in TestServerThread.
        self.test_server_spawner_port = 0
        self.test_server_port = 0
        self.build_type = build_type

    def _PushTestServerPortInfoToDevice(self):
        """Pushes the latest port information to device."""
        self.adb.SetFileContents(
            self.adb.GetExternalStorage() + '/' +
            NET_TEST_SERVER_PORT_INFO_FILE,
            '%d:%d' % (self.test_server_spawner_port, self.test_server_port))

    def Run(self):
        """Calls subclass functions to set up tests, run them and tear them down.

    Returns:
      Test results returned from RunTests().
    """
        if not self.HasTests():
            return True
        self.SetUp()
        try:
            return self.RunTests()
        finally:
            self.TearDown()

    def SetUp(self):
        """Called before tests run."""
        pass

    def HasTests(self):
        """Whether the test suite has tests to run."""
        return True

    def RunTests(self):
        """Runs the tests. Need to be overridden."""
        raise NotImplementedError

    def TearDown(self):
        """Called when tests finish running."""
        self.ShutdownHelperToolsForTestSuite()

    def CopyTestData(self, test_data_paths, dest_dir):
        """Copies |test_data_paths| list of files/directories to |dest_dir|.

    Args:
      test_data_paths: A list of files or directories relative to |dest_dir|
          which should be copied to the device. The paths must exist in
          |CHROME_DIR|.
      dest_dir: Absolute path to copy to on the device.
    """
        for p in test_data_paths:
            self.adb.PushIfNeeded(os.path.join(constants.CHROME_DIR, p),
                                  os.path.join(dest_dir, p))

    def LaunchTestHttpServer(self,
                             document_root,
                             port=None,
                             extra_config_contents=None):
        """Launches an HTTP server to serve HTTP tests.

    Args:
      document_root: Document root of the HTTP server.
      port: port on which we want to the http server bind.
      extra_config_contents: Extra config contents for the HTTP server.
    """
        self._http_server = lighttpd_server.LighttpdServer(
            document_root,
            port=port,
            extra_config_contents=extra_config_contents)
        if self._http_server.StartupHttpServer():
            logging.info('http server started: http://localhost:%s',
                         self._http_server.port)
        else:
            logging.critical('Failed to start http server')
        self.StartForwarderForHttpServer()

    def StartForwarder(self, port_pairs):
        """Starts TCP traffic forwarding for the given |port_pairs|.

    Args:
      host_port_pairs: A list of (device_port, local_port) tuples to forward.
    """
        # Sometimes the forwarder device port may be already used. We have to kill
        # all forwarder processes to ensure that the forwarder can be started since
        # currently we can not associate the specified port to related pid.
        self.adb.KillAll('forwarder')
        if self._forwarder:
            self._forwarder.Close()
        self._forwarder = Forwarder(self.adb, port_pairs, self.tool,
                                    '127.0.0.1', self.build_type)

    def StartForwarderForHttpServer(self):
        """Starts a forwarder for the HTTP server.

    The forwarder forwards HTTP requests and responses between host and device.
    """
        self.StartForwarder([(self._forwarder_device_port,
                              self._http_server.port)])

    def RestartHttpServerForwarderIfNecessary(self):
        """Restarts the forwarder if it's not open."""
        # Checks to see if the http server port is being used.  If not forwards the
        # request.
        # TODO(dtrainor): This is not always reliable because sometimes the port
        # will be left open even after the forwarder has been killed.
        if not ports.IsDevicePortUsed(self.adb, self._forwarder_device_port):
            self.StartForwarderForHttpServer()

    def ShutdownHelperToolsForTestSuite(self):
        """Shuts down the server and the forwarder."""
        # Forwarders should be killed before the actual servers they're forwarding
        # to as they are clients potentially with open connections and to allow for
        # proper hand-shake/shutdown.
        if self._forwarder or self._spawner_forwarder:
            # Kill all forwarders on the device and then kill the process on the host
            # (if it exists)
            self.adb.KillAll('forwarder')
            if self._forwarder:
                self._forwarder.Close()
            if self._spawner_forwarder:
                self._spawner_forwarder.Close()
        if self._http_server:
            self._http_server.ShutdownHttpServer()
        if self._spawning_server:
            self._spawning_server.Stop()
        self.flags.Restore()

    def LaunchChromeTestServerSpawner(self):
        """Launches test server spawner."""
        server_ready = False
        error_msgs = []
        # Try 3 times to launch test spawner server.
        for i in xrange(0, 3):
            # Do not allocate port for test server here. We will allocate
            # different port for individual test in TestServerThread.
            self.test_server_spawner_port = ports.AllocateTestServerPort()
            self._spawning_server = SpawningServer(
                self.test_server_spawner_port, self.adb, self.tool,
                self.build_type)
            self._spawning_server.Start()
            server_ready, error_msg = ports.IsHttpServerConnectable(
                '127.0.0.1',
                self.test_server_spawner_port,
                path='/ping',
                expected_read='ready')
            if server_ready:
                break
            else:
                error_msgs.append(error_msg)
            self._spawning_server.Stop()
            # Wait for 2 seconds then restart.
            time.sleep(2)
        if not server_ready:
            logging.error(';'.join(error_msgs))
            raise Exception('Can not start the test spawner server.')
        self._PushTestServerPortInfoToDevice()
        self._spawner_forwarder = Forwarder(
            self.adb,
            [(self.test_server_spawner_port, self.test_server_spawner_port)],
            self.tool, '127.0.0.1', self.build_type)