Create a WPR supported infra to run WPR Record/Replay test.

R=harringtond@chromium.org, hypan@google.com, jbudorick@chromium.org

Bug: 1060399
Change-Id: I7bca6af9dbea13605f08f7afe1c06f4e525c9116
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2108536
Reviewed-by: John Budorick <jbudorick@chromium.org>
Reviewed-by: Theresa  <twellington@chromium.org>
Reviewed-by: Haiyang Pan <hypan@google.com>
Reviewed-by: Dan H <harringtond@chromium.org>
Commit-Queue: Arthur Wang <wuwang@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#769389}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 7b47b383a5d19ad9466c4ef7403b1d79a91bdd38
This commit is contained in:
Arthur Wang 2020-05-15 19:54:28 +00:00 коммит произвёл Commit Bot
Родитель e6e3afd234
Коммит a133697a3f
8 изменённых файлов: 589 добавлений и 28 удалений

Просмотреть файл

@ -86,6 +86,7 @@ def CommonChecks(input_api, output_api):
J('pylib', 'symbols', 'apk_native_libs_unittest.py'),
J('pylib', 'symbols', 'elf_symbolizer_unittest.py'),
J('pylib', 'symbols', 'symbol_utils_unittest.py'),
J('pylib', 'utils', 'chrome_proxy_utils_test.py'),
J('pylib', 'utils', 'decorators_test.py'),
J('pylib', 'utils', 'device_dependencies_test.py'),
J('pylib', 'utils', 'dexdump_test.py'),

Просмотреть файл

@ -521,6 +521,8 @@ class InstrumentationTestInstance(test_instance.TestInstance):
self._skia_gold_properties = None
self._initializeSkiaGoldAttributes(args)
self._wpr_enable_record = args.wpr_enable_record
self._external_shard_index = args.test_launcher_shard_index
self._total_external_shards = args.test_launcher_total_shards
@ -865,6 +867,14 @@ class InstrumentationTestInstance(test_instance.TestInstance):
def wait_for_java_debugger(self):
return self._wait_for_java_debugger
@property
def wpr_record_mode(self):
return self._wpr_enable_record
@property
def wpr_replay_mode(self):
return not self._wpr_enable_record
#override
def TestType(self):
return 'instrumentation'

Просмотреть файл

@ -36,17 +36,16 @@ from pylib.instrumentation import instrumentation_test_instance
from pylib.local.device import local_device_environment
from pylib.local.device import local_device_test_run
from pylib.output import remote_output_manager
from pylib.utils import chrome_proxy_utils
from pylib.utils import gold_utils
from pylib.utils import instrumentation_tracing
from pylib.utils import shared_preference_utils
from py_trace_event import trace_event
from py_trace_event import trace_time
from py_utils import contextlib_ext
from py_utils import tempfile_ext
import tombstones
with host_paths.SysPath(
os.path.join(host_paths.DIR_SOURCE_ROOT, 'third_party'), 0):
import jinja2 # pylint: disable=import-error
@ -88,6 +87,8 @@ _EXTRA_PACKAGE_UNDER_TEST = ('org.chromium.chrome.test.pagecontroller.rules.'
FEATURE_ANNOTATION = 'Feature'
RENDER_TEST_FEATURE_ANNOTATION = 'RenderTest'
WPR_ARCHIVE_FILE_PATH_ANNOTATION = 'WPRArchiveConfigFilePath'
WPR_RECORD_REPLAY_TEST_FEATURE_ANNOTATION = 'WPRRecordReplayTest'
# This needs to be kept in sync with formatting in |RenderUtils.imageName|
RE_RENDER_IMAGE_NAME = re.compile(
@ -141,11 +142,13 @@ class LocalDeviceInstrumentationTestRun(
def __init__(self, env, test_instance):
super(LocalDeviceInstrumentationTestRun, self).__init__(
env, test_instance)
self._chrome_proxy = None
self._context_managers = collections.defaultdict(list)
self._flag_changers = {}
self._render_tests_device_output_dir = None
self._shared_prefs_to_restore = []
self._skia_gold_work_dir = None
self._skia_gold_session_manager = None
self._skia_gold_work_dir = None
#override
def TestPackage(self):
@ -556,14 +559,35 @@ class LocalDeviceInstrumentationTestRun(
timeout = None
logging.info('preparing to run %s: %s', test_display_name, test)
render_tests_device_output_dir = None
if _IsRenderTest(test):
# TODO(mikecase): Add DeviceTempDirectory class and use that instead.
render_tests_device_output_dir = posixpath.join(
device.GetExternalStoragePath(),
'render_test_output_dir')
self._render_tests_device_output_dir = posixpath.join(
device.GetExternalStoragePath(), 'render_test_output_dir')
flags_to_add.append('--render-test-output-dir=%s' %
render_tests_device_output_dir)
self._render_tests_device_output_dir)
if _IsWPRRecordReplayTest(test):
wpr_archive_config_relative_path = _GetWPRArchiveConfig(test)
if not wpr_archive_config_relative_path:
raise RuntimeError('Could not find the WPR archive config file path '
'from annotation.')
wpr_archive_config_path = os.path.join(host_paths.DIR_SOURCE_ROOT,
wpr_archive_config_relative_path)
if self._test_instance.wpr_replay_mode:
# In replay mode, gets archive file from wpr_archive_config_path
archive_path = chrome_proxy_utils.GetWPRArchiveFromConfig(
self._GetUniqueTestName(test), [wpr_archive_config_path])
else:
# In record mode, uses test unique name as file name.
# The file will be marked as untracked file and need to be
# 'git add' later by the user.
archive_path = os.path.join(os.path.dirname(wpr_archive_config_path),
self._GetUniqueTestName(test) + '.wprgo')
self._chrome_proxy = chrome_proxy_utils.ChromeProxySession()
self._chrome_proxy.wpr_record_mode = self._test_instance.wpr_record_mode
self._chrome_proxy.Start(device, archive_path)
flags_to_add.extend(self._chrome_proxy.GetFlags())
if flags_to_add:
self._CreateFlagChangerIfNeeded(device)
@ -620,11 +644,12 @@ class LocalDeviceInstrumentationTestRun(
# check to see if any failure images were generated even if the test
# does not fail.
try:
self._ProcessRenderTestResults(
device, render_tests_device_output_dir, results)
self._ProcessRenderTestResults(device, results)
finally:
device.RemovePath(render_tests_device_output_dir,
recursive=True, force=True)
device.RemovePath(self._render_tests_device_output_dir,
recursive=True,
force=True)
self._render_tests_device_output_dir = None
def pull_ui_screen_captures():
screenshots = []
@ -653,13 +678,23 @@ class LocalDeviceInstrumentationTestRun(
json_data['image_link'] = image_archive.Link()
return json_data
def stop_chrome_proxy():
# Removes the port forwarding
if self._chrome_proxy:
self._chrome_proxy.Stop(device)
if self._chrome_proxy.wpr_replay_mode:
# Remove the wpr archive file if it previously ran in replay mode
os.remove(self._chrome_proxy.wpr_archive_path)
self._chrome_proxy = None
# While constructing the TestResult objects, we can parallelize several
# steps that involve ADB. These steps should NOT depend on any info in
# the results! Things such as whether the test CRASHED have not yet been
# determined.
post_test_steps = [
restore_flags, restore_timeout_scale, handle_coverage_data,
handle_render_test_data, pull_ui_screen_captures
restore_flags, restore_timeout_scale, stop_chrome_proxy,
handle_coverage_data, handle_render_test_data, pull_ui_screen_captures
]
if self._env.concurrent_adb:
reraiser_thread.RunAsync(post_test_steps)
@ -920,16 +955,15 @@ class LocalDeviceInstrumentationTestRun(
screenshot_device_file.close()
_SetLinkOnResults(results, link_name, screenshot_host_file.Link())
def _ProcessRenderTestResults(
self, device, render_tests_device_output_dir, results):
self._ProcessSkiaGoldRenderTestResults(
device, render_tests_device_output_dir, results)
self._ProcessLocalRenderTestResults(device, render_tests_device_output_dir,
results)
def _ProcessRenderTestResults(self, device, results):
if not self._render_tests_device_output_dir:
return
self._ProcessSkiaGoldRenderTestResults(device, results)
self._ProcessLocalRenderTestResults(device, results)
def _ProcessSkiaGoldRenderTestResults(
self, device, render_tests_device_output_dir, results):
gold_dir = posixpath.join(render_tests_device_output_dir, _DEVICE_GOLD_DIR)
def _ProcessSkiaGoldRenderTestResults(self, device, results):
gold_dir = posixpath.join(self._render_tests_device_output_dir,
_DEVICE_GOLD_DIR)
if not device.FileExists(gold_dir):
return
@ -1053,18 +1087,17 @@ class LocalDeviceInstrumentationTestRun(
'Given unhandled SkiaGoldSession StatusCode %s with error %s',
status, error)
def _ProcessLocalRenderTestResults(self, device,
render_tests_device_output_dir, results):
def _ProcessLocalRenderTestResults(self, device, results):
failure_images_device_dir = posixpath.join(
render_tests_device_output_dir, 'failures')
self._render_tests_device_output_dir, 'failures')
if not device.FileExists(failure_images_device_dir):
return
diff_images_device_dir = posixpath.join(
render_tests_device_output_dir, 'diffs')
self._render_tests_device_output_dir, 'diffs')
golden_images_device_dir = posixpath.join(
render_tests_device_output_dir, 'goldens')
self._render_tests_device_output_dir, 'goldens')
for failure_filename in device.ListDirectory(failure_images_device_dir):
@ -1145,6 +1178,22 @@ class LocalDeviceInstrumentationTestRun(
return timeout
def _IsWPRRecordReplayTest(test):
"""Determines whether a test or a list of tests is a WPR RecordReplay Test."""
if not isinstance(test, list):
test = [test]
return any([
WPR_RECORD_REPLAY_TEST_FEATURE_ANNOTATION in t['annotations'].get(
FEATURE_ANNOTATION, {}).get('value', ()) for t in test
])
def _GetWPRArchiveConfig(test):
"""Retrieves the config from the WPRArchiveConfigFilePath annotation."""
return test['annotations'].get(WPR_ARCHIVE_FILE_PATH_ANNOTATION,
{}).get('value', ())
def _IsRenderTest(test):
"""Determines if a test or list of tests has a RenderTest amongst them."""
if not isinstance(test, list):

Просмотреть файл

@ -61,6 +61,88 @@ class LocalDeviceInstrumentationTestRunTest(unittest.TestCase):
'SadTest.testNotRun', base_test_result.ResultType.NOTRUN)
self.assertTrue(self._obj._ShouldRetry(test, result))
def testIsWPRRecordReplayTest_matchedWithKey(self):
test = {
'annotations': {
'Feature': {
'value': ['WPRRecordReplayTest', 'dummy']
}
},
'class': 'WPRDummyTest',
'method': 'testRun',
'is_junit4': True,
}
self.assertTrue(
local_device_instrumentation_test_run._IsWPRRecordReplayTest(test))
def testIsWPRRecordReplayTest_noMatchedKey(self):
test = {
'annotations': {
'Feature': {
'value': ['abc', 'dummy']
}
},
'class': 'WPRDummyTest',
'method': 'testRun',
'is_junit4': True,
}
self.assertFalse(
local_device_instrumentation_test_run._IsWPRRecordReplayTest(test))
def testGetWPRArchiveConfig_matchedWithKey(self):
test = {
'annotations': {
'WPRArchiveConfigFilePath': {
'value': 'abc'
}
},
'class': 'WPRDummyTest',
'method': 'testRun',
'is_junit4': True,
}
self.assertEqual(
local_device_instrumentation_test_run._GetWPRArchiveConfig(test), 'abc')
def testGetWPRArchiveConfig_noMatchedWithKey(self):
test = {
'annotations': {
'Feature': {
'value': 'abc'
}
},
'class': 'WPRDummyTest',
'method': 'testRun',
'is_junit4': True,
}
self.assertFalse(
local_device_instrumentation_test_run._GetWPRArchiveConfig(test))
def testIsRenderTest_matchedWithKey(self):
test = {
'annotations': {
'Feature': {
'value': ['RenderTest', 'dummy']
}
},
'class': 'DummyTest',
'method': 'testRun',
'is_junit4': True,
}
self.assertTrue(local_device_instrumentation_test_run._IsRenderTest(test))
def testIsRenderTest_noMatchedKey(self):
test = {
'annotations': {
'Feature': {
'value': ['abc', 'dummy']
}
},
'class': 'DummyTest',
'method': 'testRun',
'is_junit4': True,
}
self.assertFalse(local_device_instrumentation_test_run._IsRenderTest(test))
if __name__ == '__main__':
unittest.main(verbosity=2)

Просмотреть файл

@ -0,0 +1,169 @@
# Copyright 2020 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.
"""Utilities for setting up and tear down WPR and TsProxy service."""
import py_utils
from py_utils import binary_manager
from py_utils import ts_proxy_server
from py_utils import webpagereplay_go_server
from devil.android import forwarder
PROXY_HOST_IP = '127.0.0.1'
# From Catapult/WebPageReplay document.
IGNORE_CERT_ERROR_SPKI_LIST = 'PhrPvGIaAMmd29hj8BCZOq096yj7uMpRNHpn5PDxI6I='
PROXY_SERVER = 'socks5://localhost'
DEFAULT_DEVICE_PORT = 1080
DEFAULT_ROUND_TRIP_LATENCY_MS = 100
DEFAULT_DOWNLOAD_BANDWIDTH_KBPS = 72000
DEFAULT_UPLOAD_BANDWIDTH_KBPS = 72000
def GetWPRArchiveFromConfig(test_name, config):
"""Downloads the wpr archive from given config and test name."""
return binary_manager.BinaryManager(config).FetchPath(
test_name, py_utils.GetHostOsName(), py_utils.GetHostArchName())
class WPRServer(object):
"""Utils to set up a webpagereplay_go_server instance."""
def __init__(self):
self._archive_path = None
self._host_http_port = 0
self._host_https_port = 0
self._record_mode = False
self._server = None
def StartServer(self, wpr_archive_path):
"""Starts a webpagereplay_go_server instance."""
if wpr_archive_path == self._archive_path and self._server:
# Reuse existing webpagereplay_go_server instance.
return
if self._server:
self.StopServer()
replay_options = []
if self._record_mode:
replay_options.append('--record')
ports = {}
if not self._server:
self._server = webpagereplay_go_server.ReplayServer(
wpr_archive_path,
PROXY_HOST_IP,
http_port=self._host_http_port,
https_port=self._host_https_port,
replay_options=replay_options)
self._archive_path = wpr_archive_path
ports = self._server.StartServer()
self._host_http_port = ports['http']
self._host_https_port = ports['https']
def StopServer(self):
"""Stops the webpagereplay_go_server instance and resets archive."""
self._server.StopServer()
self._server = None
self._host_http_port = 0
self._host_https_port = 0
@property
def record_mode(self):
return self._record_mode
@record_mode.setter
def record_mode(self, value):
self._record_mode = value
@property
def http_port(self):
return self._host_http_port
@property
def https_port(self):
return self._host_https_port
@property
def archive_path(self):
return self._archive_path
class ChromeProxySession(object):
"""Utils to help set up a Chrome Proxy."""
def __init__(self, device_proxy_port=DEFAULT_DEVICE_PORT):
self._device_proxy_port = device_proxy_port
self._ts_proxy_server = ts_proxy_server.TsProxyServer(PROXY_HOST_IP)
self._wpr_server = WPRServer()
@property
def wpr_record_mode(self):
"""Returns whether this proxy session was running in record mode."""
return self._wpr_server.record_mode
@wpr_record_mode.setter
def wpr_record_mode(self, value):
self._wpr_server.record_mode = value
@property
def wpr_replay_mode(self):
"""Returns whether this proxy session was running in replay mode."""
return not self._wpr_server.record_mode
@property
def wpr_archive_path(self):
"""Returns the wpr archive file path used in this proxy session."""
return self._wpr_server.archive_path
@property
def device_proxy_port(self):
return self._device_proxy_port
def GetFlags(self):
"""Gets the chrome command line flags to be needed by ChromeProxySession."""
extra_flags = []
extra_flags.append('--ignore-certificate-errors-spki-list=%s' %
IGNORE_CERT_ERROR_SPKI_LIST)
extra_flags.append('--proxy-server=%s:%s' %
(PROXY_SERVER, self._device_proxy_port))
return extra_flags
def Start(self, device, wpr_archive_path):
"""Start the wpr_server as well as the ts_proxy server and setups env.
Args:
device: A DeviceUtils instance.
wpr_archive_path: A abs path to the wpr archive file.
"""
self._wpr_server.StartServer(wpr_archive_path)
self._ts_proxy_server.StartServer()
# Maps device port to host port
forwarder.Forwarder.Map(
[(self._device_proxy_port, self._ts_proxy_server.port)], device)
# Maps tsProxy port to wpr http/https ports
self._ts_proxy_server.UpdateOutboundPorts(
http_port=self._wpr_server.http_port,
https_port=self._wpr_server.https_port)
self._ts_proxy_server.UpdateTrafficSettings(
round_trip_latency_ms=DEFAULT_ROUND_TRIP_LATENCY_MS,
download_bandwidth_kbps=DEFAULT_DOWNLOAD_BANDWIDTH_KBPS,
upload_bandwidth_kbps=DEFAULT_UPLOAD_BANDWIDTH_KBPS)
def Stop(self, device):
"""Stops the wpr_server, and ts_proxy server and tears down env.
Note that Stop does not reset wpr_record_mode, wpr_replay_mode,
wpr_archive_path property.
Args:
device: A DeviceUtils instance.
"""
self._wpr_server.StopServer()
self._ts_proxy_server.StopServer()
forwarder.Forwarder.UnmapDevicePort(self._device_proxy_port, device)

Просмотреть файл

@ -0,0 +1,237 @@
#!/usr/bin/env vpython
# Copyright 2020 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.
"""Tests for chrome_proxy_utils."""
#pylint: disable=protected-access
import os
import unittest
from pylib.constants import host_paths
from pylib.utils import chrome_proxy_utils
from devil.android import forwarder
from devil.android import device_utils
from devil.android.sdk import adb_wrapper
from py_utils import ts_proxy_server
from py_utils import webpagereplay_go_server
with host_paths.SysPath(host_paths.PYMOCK_PATH):
import mock # pylint: disable=import-error
def _DeviceUtilsMock(test_serial, is_ready=True):
"""Returns a DeviceUtils instance based on given serial."""
adb = mock.Mock(spec=adb_wrapper.AdbWrapper)
adb.__str__ = mock.Mock(return_value=test_serial)
adb.GetDeviceSerial.return_value = test_serial
adb.is_ready = is_ready
return device_utils.DeviceUtils(adb)
class ChromeProxySessionTest(unittest.TestCase):
"""Unittest for ChromeProxySession."""
#pylint: disable=no-self-use
@mock.patch.object(forwarder.Forwarder, 'Map')
@mock.patch.object(chrome_proxy_utils.WPRServer, 'StartServer')
@mock.patch.object(ts_proxy_server.TsProxyServer, 'StartServer')
@mock.patch.object(ts_proxy_server.TsProxyServer, 'UpdateOutboundPorts')
@mock.patch.object(ts_proxy_server.TsProxyServer, 'UpdateTrafficSettings')
@mock.patch('py_utils.ts_proxy_server.TsProxyServer.port',
new_callable=mock.PropertyMock)
def test_Start(self, port_mock, traffic_setting_mock, outboundport_mock,
start_server_mock, wpr_mock, forwarder_mock):
chrome_proxy = chrome_proxy_utils.ChromeProxySession(4)
chrome_proxy._wpr_server._host_http_port = 1
chrome_proxy._wpr_server._host_https_port = 2
port_mock.return_value = 3
device = _DeviceUtilsMock('01234')
chrome_proxy.Start(device, 'abc')
forwarder_mock.assert_called_once_with([(4, 3)], device)
wpr_mock.assert_called_once_with('abc')
start_server_mock.assert_called_once()
outboundport_mock.assert_called_once_with(http_port=1, https_port=2)
traffic_setting_mock.assert_called_once_with(download_bandwidth_kbps=72000,
round_trip_latency_ms=100,
upload_bandwidth_kbps=72000)
port_mock.assert_called_once()
@mock.patch.object(forwarder.Forwarder, 'UnmapDevicePort')
@mock.patch.object(chrome_proxy_utils.WPRServer, 'StopServer')
@mock.patch.object(ts_proxy_server.TsProxyServer, 'StopServer')
def test_Stop(self, ts_proxy_mock, wpr_mock, forwarder_mock):
chrome_proxy = chrome_proxy_utils.ChromeProxySession(4)
device = _DeviceUtilsMock('01234')
chrome_proxy.wpr_record_mode = True
chrome_proxy._wpr_server._archive_path = 'abc'
chrome_proxy.Stop(device)
forwarder_mock.assert_called_once_with(4, device)
wpr_mock.assert_called_once_with()
ts_proxy_mock.assert_called_once_with()
#pylint: enable=no-self-use
@mock.patch.object(forwarder.Forwarder, 'UnmapDevicePort')
@mock.patch.object(webpagereplay_go_server.ReplayServer, 'StopServer')
@mock.patch.object(ts_proxy_server.TsProxyServer, 'StopServer')
def test_Stop_WithProperties(self, ts_proxy_mock, wpr_mock, forwarder_mock):
chrome_proxy = chrome_proxy_utils.ChromeProxySession(4)
chrome_proxy._wpr_server._server = webpagereplay_go_server.ReplayServer(
os.path.abspath(__file__), chrome_proxy_utils.PROXY_HOST_IP, 0, 0, [])
chrome_proxy._wpr_server._archive_path = os.path.abspath(__file__)
device = _DeviceUtilsMock('01234')
chrome_proxy.wpr_record_mode = True
chrome_proxy.Stop(device)
forwarder_mock.assert_called_once_with(4, device)
wpr_mock.assert_called_once_with()
ts_proxy_mock.assert_called_once_with()
self.assertFalse(chrome_proxy.wpr_replay_mode)
self.assertEquals(chrome_proxy.wpr_archive_path, os.path.abspath(__file__))
def test_SetWPRRecordMode(self):
chrome_proxy = chrome_proxy_utils.ChromeProxySession(4)
chrome_proxy.wpr_record_mode = True
self.assertTrue(chrome_proxy._wpr_server.record_mode)
self.assertTrue(chrome_proxy.wpr_record_mode)
self.assertFalse(chrome_proxy.wpr_replay_mode)
chrome_proxy.wpr_record_mode = False
self.assertFalse(chrome_proxy._wpr_server.record_mode)
self.assertFalse(chrome_proxy.wpr_record_mode)
self.assertTrue(chrome_proxy.wpr_replay_mode)
def test_SetWPRArchivePath(self):
chrome_proxy = chrome_proxy_utils.ChromeProxySession(4)
chrome_proxy._wpr_server._archive_path = 'abc'
self.assertEquals(chrome_proxy.wpr_archive_path, 'abc')
def test_UseDefaultDeviceProxyPort(self):
chrome_proxy = chrome_proxy_utils.ChromeProxySession()
expected_flags = [
'--ignore-certificate-errors-spki-list='
'PhrPvGIaAMmd29hj8BCZOq096yj7uMpRNHpn5PDxI6I=',
'--proxy-server=socks5://localhost:1080'
]
self.assertEquals(chrome_proxy.device_proxy_port, 1080)
self.assertListEqual(chrome_proxy.GetFlags(), expected_flags)
def test_UseNewDeviceProxyPort(self):
chrome_proxy = chrome_proxy_utils.ChromeProxySession(1)
expected_flags = [
'--ignore-certificate-errors-spki-list='
'PhrPvGIaAMmd29hj8BCZOq096yj7uMpRNHpn5PDxI6I=',
'--proxy-server=socks5://localhost:1'
]
self.assertEquals(chrome_proxy.device_proxy_port, 1)
self.assertListEqual(chrome_proxy.GetFlags(), expected_flags)
class WPRServerTest(unittest.TestCase):
@mock.patch('py_utils.webpagereplay_go_server.ReplayServer')
def test_StartSever_fresh_replaymode(self, wpr_mock):
wpr_server = chrome_proxy_utils.WPRServer()
wpr_archive_file = os.path.abspath(__file__)
wpr_server.StartServer(wpr_archive_file)
wpr_mock.assert_called_once_with(wpr_archive_file,
'127.0.0.1',
http_port=0,
https_port=0,
replay_options=[])
self.assertEqual(wpr_server._archive_path, wpr_archive_file)
self.assertTrue(wpr_server._server)
@mock.patch('py_utils.webpagereplay_go_server.ReplayServer')
def test_StartSever_fresh_recordmode(self, wpr_mock):
wpr_server = chrome_proxy_utils.WPRServer()
wpr_server.record_mode = True
wpr_server.StartServer(os.path.abspath(__file__))
wpr_archive_file = os.path.abspath(__file__)
wpr_mock.assert_called_once_with(wpr_archive_file,
'127.0.0.1',
http_port=0,
https_port=0,
replay_options=['--record'])
self.assertEqual(wpr_server._archive_path, os.path.abspath(__file__))
self.assertTrue(wpr_server._server)
#pylint: disable=no-self-use
@mock.patch.object(webpagereplay_go_server.ReplayServer, 'StartServer')
def test_StartSever_recordmode(self, start_server_mock):
wpr_server = chrome_proxy_utils.WPRServer()
start_server_mock.return_value = {'http': 1, 'https': 2}
wpr_server.StartServer(os.path.abspath(__file__))
start_server_mock.assert_called_once()
self.assertEqual(wpr_server._host_http_port, 1)
self.assertEqual(wpr_server._host_https_port, 2)
self.assertEqual(wpr_server._archive_path, os.path.abspath(__file__))
self.assertTrue(wpr_server._server)
@mock.patch.object(webpagereplay_go_server.ReplayServer, 'StartServer')
def test_StartSever_reuseServer(self, start_server_mock):
wpr_server = chrome_proxy_utils.WPRServer()
wpr_server._server = webpagereplay_go_server.ReplayServer(
os.path.abspath(__file__),
chrome_proxy_utils.PROXY_HOST_IP,
http_port=0,
https_port=0,
replay_options=[])
wpr_server._archive_path = os.path.abspath(__file__)
wpr_server.StartServer(os.path.abspath(__file__))
start_server_mock.assert_not_called()
@mock.patch.object(webpagereplay_go_server.ReplayServer, 'StartServer')
@mock.patch.object(webpagereplay_go_server.ReplayServer, 'StopServer')
def test_StartSever_notReuseServer(self, stop_server_mock, start_server_mock):
wpr_server = chrome_proxy_utils.WPRServer()
wpr_server._server = webpagereplay_go_server.ReplayServer(
os.path.abspath(__file__),
chrome_proxy_utils.PROXY_HOST_IP,
http_port=0,
https_port=0,
replay_options=[])
wpr_server._archive_path = ''
wpr_server.StartServer(os.path.abspath(__file__))
start_server_mock.assert_called_once()
stop_server_mock.assert_called_once()
#pylint: enable=no-self-use
@mock.patch.object(webpagereplay_go_server.ReplayServer, 'StopServer')
def test_StopServer(self, stop_server_mock):
wpr_server = chrome_proxy_utils.WPRServer()
wpr_server._server = webpagereplay_go_server.ReplayServer(
os.path.abspath(__file__),
chrome_proxy_utils.PROXY_HOST_IP,
http_port=0,
https_port=0,
replay_options=[])
wpr_server.StopServer()
stop_server_mock.assert_called_once()
self.assertFalse(wpr_server._server)
self.assertFalse(wpr_server._archive_path)
self.assertFalse(wpr_server.http_port)
self.assertFalse(wpr_server.https_port)
def test_SetWPRRecordMode(self):
wpr_server = chrome_proxy_utils.WPRServer()
wpr_server.record_mode = True
self.assertTrue(wpr_server.record_mode)
wpr_server.record_mode = False
self.assertFalse(wpr_server.record_mode)
if __name__ == '__main__':
unittest.main(verbosity=2)

Просмотреть файл

@ -539,6 +539,13 @@ def AddInstrumentationTestOptions(parser):
help='Wait for java debugger to attach before running any application '
'code. Also disables test timeouts and sets retries=0.')
# WPR record mode.
parser.add_argument('--wpr-enable-record',
action='store_true',
default=False,
help='If true, WPR server runs in record mode.'
'otherwise, runs in replay mode.')
# These arguments are suppressed from the help text because they should
# only ever be specified by an intermediate script.
parser.add_argument(

Просмотреть файл

@ -13,12 +13,17 @@
../../third_party/catapult/common/py_trace_event/third_party/protobuf/encoder.py
../../third_party/catapult/common/py_trace_event/third_party/protobuf/wire_format.py
../../third_party/catapult/common/py_utils/py_utils/__init__.py
../../third_party/catapult/common/py_utils/py_utils/atexit_with_log.py
../../third_party/catapult/common/py_utils/py_utils/binary_manager.py
../../third_party/catapult/common/py_utils/py_utils/cloud_storage.py
../../third_party/catapult/common/py_utils/py_utils/cloud_storage_global_lock.py
../../third_party/catapult/common/py_utils/py_utils/contextlib_ext.py
../../third_party/catapult/common/py_utils/py_utils/lock.py
../../third_party/catapult/common/py_utils/py_utils/modules_util.py
../../third_party/catapult/common/py_utils/py_utils/retry_util.py
../../third_party/catapult/common/py_utils/py_utils/tempfile_ext.py
../../third_party/catapult/common/py_utils/py_utils/ts_proxy_server.py
../../third_party/catapult/common/py_utils/py_utils/webpagereplay_go_server.py
../../third_party/catapult/dependency_manager/dependency_manager/__init__.py
../../third_party/catapult/dependency_manager/dependency_manager/archive_info.py
../../third_party/catapult/dependency_manager/dependency_manager/base_config.py
@ -196,6 +201,7 @@ pylib/symbols/__init__.py
pylib/symbols/deobfuscator.py
pylib/symbols/stack_symbolizer.py
pylib/utils/__init__.py
pylib/utils/chrome_proxy_utils.py
pylib/utils/decorators.py
pylib/utils/device_dependencies.py
pylib/utils/dexdump.py