diff --git a/python/mozperftest/mozperftest/mach_commands.py b/python/mozperftest/mozperftest/mach_commands.py index 6a84f5986f09..d008ea21fd70 100644 --- a/python/mozperftest/mozperftest/mach_commands.py +++ b/python/mozperftest/mozperftest/mach_commands.py @@ -309,10 +309,12 @@ class PerftestTests(MachCommandBase): "run", pytest.__file__, options, + "--duration", + "10", tests, ] assert self._run_python_script( - "coverage", *args, label="running tests", verbose=verbose + "coverage", *args, label="running tests", verbose=verbose, display=verbose ) if run_coverage_check and not self._run_python_script( "coverage", "report", display=True diff --git a/python/mozperftest/mozperftest/system/profile.py b/python/mozperftest/mozperftest/system/profile.py index 748d6fd7c3fe..f087f7cb9b4e 100644 --- a/python/mozperftest/mozperftest/system/profile.py +++ b/python/mozperftest/mozperftest/system/profile.py @@ -88,7 +88,7 @@ class Profile(Layer): if self.get_arg("directory") is not None: # no need to create one or load a conditioned one - return + return metadata # fresh profile profile = create_profile(app="firefox") diff --git a/python/mozperftest/mozperftest/system/proxy.py b/python/mozperftest/mozperftest/system/proxy.py index 03c51f20a38d..caa738f9db41 100644 --- a/python/mozperftest/mozperftest/system/proxy.py +++ b/python/mozperftest/mozperftest/system/proxy.py @@ -25,10 +25,10 @@ class OutputHandler(object): self.port_event = threading.Event() def __call__(self, line): - if not line.strip(): + line = line.strip() + if not line: return line = line.decode("utf-8", errors="replace") - try: data = json.loads(line) except ValueError: @@ -40,7 +40,7 @@ class OutputHandler(object): # our subprocess. m = re.match(r"Proxy running on port (\d+)", data.get("message", "")) if m: - self.port = m.group(1) + self.port = int(m.group(1)) self.port_event.set() LOG.log_raw(data) else: @@ -50,7 +50,10 @@ class OutputHandler(object): self.port_event.set() def process_output(self, line): - LOG.process_output(self.proc.pid, line) + if self.proc is None: + LOG.process_output(line) + else: + LOG.process_output(self.proc.pid, line) def wait_for_port(self): self.port_event.wait() @@ -100,9 +103,10 @@ class ProxyRunner(Layer): replay_file = target self.info("Setting up the proxy") - # replace with artifacts command = [ - "mozproxy", + self.mach_cmd.virtualenv_manager.python_path, + "-m", + "mozproxy.driver", "--local", "--binary=" + self.mach_cmd.get_binary_path(), "--topsrcdir=" + self.mach_cmd.topsrcdir, diff --git a/python/mozperftest/mozperftest/tests/support.py b/python/mozperftest/mozperftest/tests/support.py index e4b2f2b1b868..8bde48dd4dca 100644 --- a/python/mozperftest/mozperftest/tests/support.py +++ b/python/mozperftest/mozperftest/tests/support.py @@ -4,6 +4,7 @@ import contextlib import shutil import os from pathlib import Path +import sys from mozperftest.metadata import Metadata from mozperftest.environment import MachEnvironment @@ -52,6 +53,8 @@ def get_running_env(**kwargs): mach_cmd._mach_context = MagicMock() mach_cmd._mach_context.state_dir = tempfile.mkdtemp() mach_cmd.run_process.return_value = 0 + mach_cmd.virtualenv_manager = MagicMock() + mach_cmd.virtualenv_manager.python_path = sys.executable mach_args = { "flavor": "desktop-browser", diff --git a/python/mozperftest/mozperftest/tests/test_proxy.py b/python/mozperftest/mozperftest/tests/test_proxy.py index fc4551a4fa70..2cabed5cb732 100644 --- a/python/mozperftest/mozperftest/tests/test_proxy.py +++ b/python/mozperftest/mozperftest/tests/test_proxy.py @@ -4,72 +4,101 @@ import os import pytest import shutil import tempfile -import time +import json from unittest import mock -from mozbuild.base import MozbuildObject from mozperftest.tests.support import get_running_env from mozperftest.environment import SYSTEM -from mozperftest.utils import install_package, silence +from mozperftest.utils import silence +from mozperftest.system.proxy import OutputHandler + here = os.path.abspath(os.path.dirname(__file__)) example_dump = os.path.join(here, "..", "system", "example.zip") -@pytest.fixture(scope="module") -def install_mozproxy(): - build = MozbuildObject.from_environment(cwd=here) - build.virtualenv_manager.activate() +class FakeOutputHandler: + def finished(self): + pass - mozbase = os.path.join(build.topsrcdir, "testing", "mozbase") - mozproxy_deps = ["mozinfo", "mozlog", "mozproxy"] - for i in mozproxy_deps: - install_package(build.virtualenv_manager, os.path.join(mozbase, i)) - return build + def wait_for_port(self): + return 1234 + + +class ProcHandler: + def __init__(self, *args, **kw): + self.args = args + self.kw = kw + self.pid = 1234 + + def wait(self, *args): + return + + run = wait + + @property + def proc(self): + return self + + +@pytest.fixture(scope="module") +def running_env(): + return get_running_env(proxy=True) def mock_download_file(url, dest): shutil.copyfile(example_dump, dest) -def test_replay(install_mozproxy): - mach_cmd, metadata, env = get_running_env(proxy=True) +@mock.patch("mozperftest.system.proxy.OutputHandler", new=FakeOutputHandler) +@mock.patch("mozperftest.system.proxy.ProcessHandler", new=ProcHandler) +@mock.patch("os.kill") +def test_replay(killer, running_env): + mach_cmd, metadata, env = running_env system = env.layers[SYSTEM] env.set_arg("proxy-replay", example_dump) - # XXX this will run for real, we need to mock HTTP calls with system as proxy, silence(): proxy(metadata) - # Give mitmproxy a bit of time to start up so we can verify that it's - # actually running before we tear things down. - time.sleep(5) @mock.patch("mozperftest.system.proxy.download_file", mock_download_file) -def test_replay_url(install_mozproxy): - mach_cmd, metadata, env = get_running_env(proxy=True) +@mock.patch("mozperftest.system.proxy.ProcessHandler", new=ProcHandler) +@mock.patch("mozperftest.system.proxy.OutputHandler", new=FakeOutputHandler) +@mock.patch("os.kill") +def test_replay_url(killer, running_env): + mach_cmd, metadata, env = running_env system = env.layers[SYSTEM] env.set_arg("proxy-replay", "http://example.dump") - # XXX this will run for real, we need to mock HTTP calls with system as proxy, silence(): proxy(metadata) - # Give mitmproxy a bit of time to start up so we can verify that it's - # actually running before we tear things down. - time.sleep(5) -def test_record(install_mozproxy): - mach_cmd, metadata, env = get_running_env(proxy=True) +@mock.patch("mozperftest.system.proxy.download_file", mock_download_file) +@mock.patch("mozperftest.system.proxy.ProcessHandler", new=ProcHandler) +@mock.patch("mozperftest.system.proxy.OutputHandler", new=FakeOutputHandler) +@mock.patch("os.kill") +def test_record(killer, running_env): + mach_cmd, metadata, env = running_env system = env.layers[SYSTEM] with tempfile.TemporaryDirectory() as tmpdir: recording = os.path.join(tmpdir, "recording.dump") env.set_arg("proxy-record", recording) - # XXX this will run for real, we need to mock HTTP calls with system as proxy, silence(): proxy(metadata) - assert os.path.exists(recording) + + +@mock.patch("mozperftest.system.proxy.LOG") +def test_output_handler(logged): + hdlr = OutputHandler() + hdlr(b"simple line") + hdlr(json.dumps({"not": "expected data"}).encode()) + + # this catches the port + hdlr(json.dumps({"action": "", "message": "Proxy running on port 1234"}).encode()) + assert hdlr.wait_for_port() == 1234 if __name__ == "__main__": diff --git a/testing/mozbase/mozproxy/mozproxy/driver.py b/testing/mozbase/mozproxy/mozproxy/driver.py index 41c78615ac96..4a96ad69eb8a 100644 --- a/testing/mozbase/mozproxy/mozproxy/driver.py +++ b/testing/mozbase/mozproxy/mozproxy/driver.py @@ -83,3 +83,7 @@ def main(): except Exception as e: LOG.error(str(e), exc_info=True) return EXIT_EXCEPTION + + +if __name__ == "__main__": + main()