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
3 # found in the LICENSE file.
5 """Base class for running tests on a single device."""
7 # TODO(jbudorick) Deprecate and remove this class and all subclasses after
8 # any relevant parts have been ported to the new environment + test instance
13 from pylib
import ports
14 from pylib
.device
import device_utils
15 from pylib
.forwarder
import Forwarder
16 from pylib
.valgrind_tools
import CreateTool
17 # TODO(frankf): Move this to pylib/utils
18 import lighttpd_server
21 # A file on device to store ports of net test server. The format of the file is
22 # test-spawner-server-port:test-server-port
23 NET_TEST_SERVER_PORT_INFO_FILE
= 'net-test-server-ports'
26 class BaseTestRunner(object):
27 """Base class for running tests on a single device."""
29 def __init__(self
, device
, tool
):
32 device: An instance of DeviceUtils that the tests will run on.
33 tool: Name of the Valgrind tool.
35 assert isinstance(device
, device_utils
.DeviceUtils
)
37 self
.device_serial
= self
.device
.adb
.GetDeviceSerial()
38 self
.tool
= CreateTool(tool
, self
.device
)
39 self
._http
_server
= None
40 self
._forwarder
_device
_port
= 8000
41 self
.forwarder_base_url
= ('http://localhost:%d' %
42 self
._forwarder
_device
_port
)
43 # We will allocate port for test server spawner when calling method
44 # LaunchChromeTestServerSpawner and allocate port for test server when
45 # starting it in TestServerThread.
46 self
.test_server_spawner_port
= 0
47 self
.test_server_port
= 0
49 def _PushTestServerPortInfoToDevice(self
):
50 """Pushes the latest port information to device."""
51 self
.device
.WriteFile(
52 self
.device
.GetExternalStoragePath() + '/' +
53 NET_TEST_SERVER_PORT_INFO_FILE
,
54 '%d:%d' % (self
.test_server_spawner_port
, self
.test_server_port
))
56 def RunTest(self
, test
):
57 """Runs a test. Needs to be overridden.
64 (base_test_result.TestRunResults, tests to rerun or None)
66 raise NotImplementedError
68 def InstallTestPackage(self
):
69 """Installs the test package once before all tests are run."""
73 """Run once before all tests are run."""
74 self
.InstallTestPackage()
77 """Run once after all tests are run."""
78 self
.ShutdownHelperToolsForTestSuite()
80 def LaunchTestHttpServer(self
, document_root
, port
=None,
81 extra_config_contents
=None):
82 """Launches an HTTP server to serve HTTP tests.
85 document_root: Document root of the HTTP server.
86 port: port on which we want to the http server bind.
87 extra_config_contents: Extra config contents for the HTTP server.
89 self
._http
_server
= lighttpd_server
.LighttpdServer(
90 document_root
, port
=port
, extra_config_contents
=extra_config_contents
)
91 if self
._http
_server
.StartupHttpServer():
92 logging
.info('http server started: http://localhost:%s',
93 self
._http
_server
.port
)
95 logging
.critical('Failed to start http server')
96 self
._ForwardPortsForHttpServer
()
97 return (self
._forwarder
_device
_port
, self
._http
_server
.port
)
99 def _ForwardPorts(self
, port_pairs
):
100 """Forwards a port."""
101 Forwarder
.Map(port_pairs
, self
.device
, self
.tool
)
103 def _UnmapPorts(self
, port_pairs
):
104 """Unmap previously forwarded ports."""
105 for (device_port
, _
) in port_pairs
:
106 Forwarder
.UnmapDevicePort(device_port
, self
.device
)
108 # Deprecated: Use ForwardPorts instead.
109 def StartForwarder(self
, port_pairs
):
110 """Starts TCP traffic forwarding for the given |port_pairs|.
113 host_port_pairs: A list of (device_port, local_port) tuples to forward.
115 self
._ForwardPorts
(port_pairs
)
117 def _ForwardPortsForHttpServer(self
):
118 """Starts a forwarder for the HTTP server.
120 The forwarder forwards HTTP requests and responses between host and device.
122 self
._ForwardPorts
([(self
._forwarder
_device
_port
, self
._http
_server
.port
)])
124 def _RestartHttpServerForwarderIfNecessary(self
):
125 """Restarts the forwarder if it's not open."""
126 # Checks to see if the http server port is being used. If not forwards the
128 # TODO(dtrainor): This is not always reliable because sometimes the port
129 # will be left open even after the forwarder has been killed.
130 if not ports
.IsDevicePortUsed(self
.device
, self
._forwarder
_device
_port
):
131 self
._ForwardPortsForHttpServer
()
133 def ShutdownHelperToolsForTestSuite(self
):
134 """Shuts down the server and the forwarder."""
135 if self
._http
_server
:
136 self
._UnmapPorts
([(self
._forwarder
_device
_port
, self
._http
_server
.port
)])
137 self
._http
_server
.ShutdownHttpServer()