blob: f21f1be3f2d97597b94c50464a83fbee745b4ced [file] [log] [blame]
# Copyright 2014 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.
from __future__ import absolute_import
import json
import time
from six.moves import range # pylint: disable=redefined-builtin
from devil.android import forwarder
from devil.android import ports
from pylib.base import test_server
from pylib.constants import host_paths
with host_paths.SysPath(host_paths.BUILD_COMMON_PATH):
import chrome_test_server_spawner
# The tests should not need more than one test server instance.
MAX_TEST_SERVER_INSTANCES = 1
def _WaitUntil(predicate, max_attempts=5):
"""Blocks until the provided predicate (function) is true.
Returns:
Whether the provided predicate was satisfied once (before the timeout).
"""
sleep_time_sec = 0.025
for _ in range(1, max_attempts):
if predicate():
return True
time.sleep(sleep_time_sec)
sleep_time_sec = min(1, sleep_time_sec * 2) # Don't wait more than 1 sec.
return False
class PortForwarderAndroid(chrome_test_server_spawner.PortForwarder):
def __init__(self, device, tool):
self.device = device
self.tool = tool
def Map(self, port_pairs):
forwarder.Forwarder.Map(port_pairs, self.device, self.tool)
def GetDevicePortForHostPort(self, host_port):
return forwarder.Forwarder.DevicePortForHostPort(host_port)
def WaitHostPortAvailable(self, port):
return _WaitUntil(lambda: ports.IsHostPortAvailable(port))
def WaitPortNotAvailable(self, port):
return _WaitUntil(lambda: not ports.IsHostPortAvailable(port))
def WaitDevicePortReady(self, port):
return _WaitUntil(lambda: ports.IsDevicePortUsed(self.device, port))
def Unmap(self, device_port):
forwarder.Forwarder.UnmapDevicePort(device_port, self.device)
class LocalTestServerSpawner(test_server.TestServer):
def __init__(self, port, device, tool):
super(LocalTestServerSpawner, self).__init__()
self._device = device
self._spawning_server = chrome_test_server_spawner.SpawningServer(
port, PortForwarderAndroid(device, tool), MAX_TEST_SERVER_INSTANCES)
self._tool = tool
@property
def server_address(self):
return self._spawning_server.server.server_address
@property
def port(self):
return self.server_address[1]
#override
def SetUp(self):
# See net/test/spawned_test_server/remote_test_server.h for description of
# the fields in the config file.
test_server_config = json.dumps({
'spawner_url_base': 'http://localhost:%d' % self.port
})
self._device.WriteFile(
'%s/net-test-server-config' % self._device.GetExternalStoragePath(),
test_server_config)
forwarder.Forwarder.Map(
[(self.port, self.port)], self._device, self._tool)
self._spawning_server.Start()
#override
def Reset(self):
self._spawning_server.CleanupState()
#override
def TearDown(self):
self.Reset()
self._spawning_server.Stop()
forwarder.Forwarder.UnmapDevicePort(self.port, self._device)