Chromium Code Reviews| 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..b828d90268236673979027a943fe910c76b12a09 |
| --- /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. |
| + |
|
Nirnimesh
2011/10/21 08:16:15
nit: only one blank line needed here.
michaelbai
2011/10/21 21:08:41
Done.
|
| + |
| +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. |
| + |
| + Args: |
|
Nirnimesh
2011/10/21 08:16:15
this should go in __init__
michaelbai
2011/10/21 21:08:41
Done.
|
| + device: Tests will run on the device of this ID. |
| + """ |
| + |
| + def __init__(self, device): |
| + self.device = device |
|
Nirnimesh
2011/10/21 08:16:15
I don't see self.device being used anywhere else.
michaelbai
2011/10/21 21:08:41
It is used in subclass like single_tests_runner
|
| + self.adb = android_commands.AndroidCommands(device=device) |
|
Nirnimesh
2011/10/21 08:16:15
all member vars should have _ prefix
self._adb
Sa
|
| + # 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): |
|
Nirnimesh
2011/10/21 08:16:15
remove commented out code
|
| + # 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)]) |