Index: build/android/base_test_runner.py |
diff --git a/build/android/base_test_runner.py b/build/android/base_test_runner.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b136d8d650602397a4a2c3639f4c2bd64952e055 |
--- /dev/null |
+++ b/build/android/base_test_runner.py |
@@ -0,0 +1,147 @@ |
+#!/usr/bin/python |
+# Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+import logging |
+import os |
+ |
+import android_commands |
+from chrome_test_server_spawner import SpawningServer |
+from flag_changer import FlagChanger |
+import lighttpd_server |
+import run_tests_helper |
+ |
+FORWARDER_PATH = '/data/local/tmp/forwarder' |
+# These ports must match up with the constants in net/test/test_server.cc |
+TEST_SERVER_SPAWNER_PORT = 8001 |
+TEST_SERVER_PORT = 8002 |
+TEST_SYNC_SERVER_PORT = 8003 |
+ |
+ |
+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)]) |