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_serial
, tool
, cleanup_test_files
=False):
32 device: Tests will run on the device of this ID.
33 tool: Name of the Valgrind tool.
34 cleanup_test_files: Whether or not to cleanup test files on device.
36 self
.device_serial
= device_serial
37 self
.device
= device_utils
.DeviceUtils(device_serial
)
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
48 self
._cleanup
_test
_files
= cleanup_test_files
50 def _PushTestServerPortInfoToDevice(self
):
51 """Pushes the latest port information to device."""
52 self
.device
.WriteFile(
53 self
.device
.GetExternalStoragePath() + '/' +
54 NET_TEST_SERVER_PORT_INFO_FILE
,
55 '%d:%d' % (self
.test_server_spawner_port
, self
.test_server_port
))
57 def RunTest(self
, test
):
58 """Runs a test. Needs to be overridden.
65 (base_test_result.TestRunResults, tests to rerun or None)
67 raise NotImplementedError
69 def InstallTestPackage(self
):
70 """Installs the test package once before all tests are run."""
74 """Run once before all tests are run."""
75 self
.InstallTestPackage()
78 """Run once after all tests are run."""
79 self
.ShutdownHelperToolsForTestSuite()
80 if self
._cleanup
_test
_files
:
81 self
.device
.old_interface
.RemovePushedFiles()
83 def LaunchTestHttpServer(self
, document_root
, port
=None,
84 extra_config_contents
=None):
85 """Launches an HTTP server to serve HTTP tests.
88 document_root: Document root of the HTTP server.
89 port: port on which we want to the http server bind.
90 extra_config_contents: Extra config contents for the HTTP server.
92 self
._http
_server
= lighttpd_server
.LighttpdServer(
93 document_root
, port
=port
, extra_config_contents
=extra_config_contents
)
94 if self
._http
_server
.StartupHttpServer():
95 logging
.info('http server started: http://localhost:%s',
96 self
._http
_server
.port
)
98 logging
.critical('Failed to start http server')
99 self
._ForwardPortsForHttpServer
()
100 return (self
._forwarder
_device
_port
, self
._http
_server
.port
)
102 def _ForwardPorts(self
, port_pairs
):
103 """Forwards a port."""
104 Forwarder
.Map(port_pairs
, self
.device
, self
.tool
)
106 def _UnmapPorts(self
, port_pairs
):
107 """Unmap previously forwarded ports."""
108 for (device_port
, _
) in port_pairs
:
109 Forwarder
.UnmapDevicePort(device_port
, self
.device
)
111 # Deprecated: Use ForwardPorts instead.
112 def StartForwarder(self
, port_pairs
):
113 """Starts TCP traffic forwarding for the given |port_pairs|.
116 host_port_pairs: A list of (device_port, local_port) tuples to forward.
118 self
._ForwardPorts
(port_pairs
)
120 def _ForwardPortsForHttpServer(self
):
121 """Starts a forwarder for the HTTP server.
123 The forwarder forwards HTTP requests and responses between host and device.
125 self
._ForwardPorts
([(self
._forwarder
_device
_port
, self
._http
_server
.port
)])
127 def _RestartHttpServerForwarderIfNecessary(self
):
128 """Restarts the forwarder if it's not open."""
129 # Checks to see if the http server port is being used. If not forwards the
131 # TODO(dtrainor): This is not always reliable because sometimes the port
132 # will be left open even after the forwarder has been killed.
133 if not ports
.IsDevicePortUsed(self
.device
, self
._forwarder
_device
_port
):
134 self
._ForwardPortsForHttpServer
()
136 def ShutdownHelperToolsForTestSuite(self
):
137 """Shuts down the server and the forwarder."""
138 if self
._http
_server
:
139 self
._UnmapPorts
([(self
._forwarder
_device
_port
, self
._http
_server
.port
)])
140 self
._http
_server
.ShutdownHttpServer()