diff options
Diffstat (limited to '')
-rw-r--r-- | testing/mozbase/mozrunner/tests/conftest.py | 81 | ||||
-rw-r--r-- | testing/mozbase/mozrunner/tests/manifest.ini | 12 | ||||
-rw-r--r-- | testing/mozbase/mozrunner/tests/test_crash.py | 36 | ||||
-rw-r--r-- | testing/mozbase/mozrunner/tests/test_interactive.py | 40 | ||||
-rw-r--r-- | testing/mozbase/mozrunner/tests/test_start.py | 61 | ||||
-rw-r--r-- | testing/mozbase/mozrunner/tests/test_states.py | 22 | ||||
-rw-r--r-- | testing/mozbase/mozrunner/tests/test_stop.py | 41 | ||||
-rw-r--r-- | testing/mozbase/mozrunner/tests/test_threads.py | 57 | ||||
-rw-r--r-- | testing/mozbase/mozrunner/tests/test_wait.py | 32 |
9 files changed, 382 insertions, 0 deletions
diff --git a/testing/mozbase/mozrunner/tests/conftest.py b/testing/mozbase/mozrunner/tests/conftest.py new file mode 100644 index 0000000000..991fc376fb --- /dev/null +++ b/testing/mozbase/mozrunner/tests/conftest.py @@ -0,0 +1,81 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import os +import threading +from time import sleep + +import mozrunner +import pytest +from moztest.selftest import fixtures + + +@pytest.fixture(scope="session") +def get_binary(): + if "BROWSER_PATH" in os.environ: + os.environ["GECKO_BINARY_PATH"] = os.environ["BROWSER_PATH"] + + def inner(app): + if app not in ("chrome", "chromium", "firefox"): + pytest.xfail(reason="{} support not implemented".format(app)) + + if app == "firefox": + binary = fixtures.binary() + elif app == "chrome": + binary = os.environ.get("CHROME_BINARY_PATH") + elif app == "chromium": + binary = os.environ.get("CHROMIUM_BINARY_PATH") + + if not binary: + pytest.skip("could not find a {} binary".format(app)) + return binary + + return inner + + +@pytest.fixture(params=["firefox", "chrome", "chromium"]) +def runner(request, get_binary): + app = request.param + binary = get_binary(app) + + cmdargs = ["--headless"] + if app in ["chrome", "chromium"]: + # prevents headless chromium from exiting after loading the page + cmdargs.append("--remote-debugging-port=9222") + # only needed on Windows, but no harm in specifying it everywhere + cmdargs.append("--disable-gpu") + runner = mozrunner.runners[app](binary, cmdargs=cmdargs) + runner.app = app + yield runner + runner.stop() + + +class RunnerThread(threading.Thread): + def __init__(self, runner, start=False, timeout=1): + threading.Thread.__init__(self) + self.runner = runner + self.timeout = timeout + self.do_start = start + + def run(self): + sleep(self.timeout) + if self.do_start: + self.runner.start() + else: + self.runner.stop() + + +@pytest.fixture +def create_thread(): + threads = [] + + def inner(*args, **kwargs): + thread = RunnerThread(*args, **kwargs) + threads.append(thread) + return thread + + yield inner + + for thread in threads: + thread.join() diff --git a/testing/mozbase/mozrunner/tests/manifest.ini b/testing/mozbase/mozrunner/tests/manifest.ini new file mode 100644 index 0000000000..7348004fdf --- /dev/null +++ b/testing/mozbase/mozrunner/tests/manifest.ini @@ -0,0 +1,12 @@ +[DEFAULT] +subsuite = mozbase +# We skip these tests in automated Windows builds because they trigger crashes +# in sh.exe; see bug 1489277. +skip-if = automation && os == 'win' +[test_crash.py] +[test_interactive.py] +[test_start.py] +[test_states.py] +[test_stop.py] +[test_threads.py] +[test_wait.py] diff --git a/testing/mozbase/mozrunner/tests/test_crash.py b/testing/mozbase/mozrunner/tests/test_crash.py new file mode 100644 index 0000000000..820851aa1c --- /dev/null +++ b/testing/mozbase/mozrunner/tests/test_crash.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +from unittest.mock import patch + +import mozunit +import pytest + + +@pytest.mark.parametrize("logger", [True, False]) +def test_crash_count_with_or_without_logger(runner, logger): + if runner.app == "chrome": + pytest.xfail("crash checking not implemented for ChromeRunner") + + if not logger: + runner.logger = None + fn = "check_for_crashes" + else: + fn = "log_crashes" + + with patch("mozcrash.{}".format(fn), return_value=2) as mock: + assert runner.crashed == 0 + assert runner.check_for_crashes() == 2 + assert runner.crashed == 2 + assert runner.check_for_crashes() == 2 + assert runner.crashed == 4 + + mock.return_value = 0 + assert runner.check_for_crashes() == 0 + assert runner.crashed == 4 + + +if __name__ == "__main__": + mozunit.main() diff --git a/testing/mozbase/mozrunner/tests/test_interactive.py b/testing/mozbase/mozrunner/tests/test_interactive.py new file mode 100644 index 0000000000..ab700d334c --- /dev/null +++ b/testing/mozbase/mozrunner/tests/test_interactive.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +from time import sleep + +import mozunit + + +def test_run_interactive(runner, create_thread): + """Bug 965183: Run process in interactive mode and call wait()""" + runner.start(interactive=True) + + thread = create_thread(runner, timeout=2) + thread.start() + + # This is a blocking call. So the process should be killed by the thread + runner.wait() + thread.join() + assert not runner.is_running() + + +def test_stop_interactive(runner): + """Bug 965183: Explicitely stop process in interactive mode""" + runner.start(interactive=True) + runner.stop() + + +def test_wait_after_process_finished(runner): + """Wait after the process has been stopped should not raise an error""" + runner.start(interactive=True) + sleep(1) + runner.process_handler.kill() + + returncode = runner.wait(1) + + assert returncode not in [None, 0] + assert runner.process_handler is not None + + +if __name__ == "__main__": + mozunit.main() diff --git a/testing/mozbase/mozrunner/tests/test_start.py b/testing/mozbase/mozrunner/tests/test_start.py new file mode 100644 index 0000000000..56e01ae84d --- /dev/null +++ b/testing/mozbase/mozrunner/tests/test_start.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +from time import sleep +from unittest.mock import patch + +import mozunit +from mozrunner import RunnerNotStartedError +from pytest import raises + + +def test_start_process(runner): + """Start the process and test properties""" + assert runner.process_handler is None + + runner.start() + + assert runner.is_running() + assert runner.process_handler is not None + + +def test_start_process_called_twice(runner): + """Start the process twice and test that first process is gone""" + runner.start() + # Bug 925480 + # Make a copy until mozprocess can kill a specific process + process_handler = runner.process_handler + + runner.start() + + try: + assert process_handler.wait(1) not in [None, 0] + finally: + process_handler.kill() + + +def test_start_with_timeout(runner): + """Start the process and set a timeout""" + runner.start(timeout=0.1) + sleep(1) + + assert not runner.is_running() + + +def test_start_with_outputTimeout(runner): + """Start the process and set a timeout""" + runner.start(outputTimeout=0.1) + sleep(1) + + assert not runner.is_running() + + +def test_fail_to_start(runner): + with patch("mozprocess.ProcessHandler.__init__") as ph_mock: + ph_mock.side_effect = Exception("Boom!") + with raises(RunnerNotStartedError): + runner.start(outputTimeout=0.1) + sleep(1) + + +if __name__ == "__main__": + mozunit.main() diff --git a/testing/mozbase/mozrunner/tests/test_states.py b/testing/mozbase/mozrunner/tests/test_states.py new file mode 100644 index 0000000000..b2eb3d119c --- /dev/null +++ b/testing/mozbase/mozrunner/tests/test_states.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +import mozunit +import pytest +from mozrunner import RunnerNotStartedError + + +def test_errors_before_start(runner): + """Bug 965714: Not started errors before start() is called""" + + with pytest.raises(RunnerNotStartedError): + runner.is_running() + + with pytest.raises(RunnerNotStartedError): + runner.returncode + + with pytest.raises(RunnerNotStartedError): + runner.wait() + + +if __name__ == "__main__": + mozunit.main() diff --git a/testing/mozbase/mozrunner/tests/test_stop.py b/testing/mozbase/mozrunner/tests/test_stop.py new file mode 100644 index 0000000000..a4f2b1fadd --- /dev/null +++ b/testing/mozbase/mozrunner/tests/test_stop.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import signal + +import mozunit + + +def test_stop_process(runner): + """Stop the process and test properties""" + runner.start() + returncode = runner.stop() + + assert not runner.is_running() + assert returncode not in [None, 0] + assert runner.returncode == returncode + assert runner.process_handler is not None + assert runner.wait(1) == returncode + + +def test_stop_before_start(runner): + """Stop the process before it gets started should not raise an error""" + runner.stop() + + +def test_stop_process_custom_signal(runner): + """Stop the process via a custom signal and test properties""" + runner.start() + returncode = runner.stop(signal.SIGTERM) + + assert not runner.is_running() + assert returncode not in [None, 0] + assert runner.returncode == returncode + assert runner.process_handler is not None + assert runner.wait(1) == returncode + + +if __name__ == "__main__": + mozunit.main() diff --git a/testing/mozbase/mozrunner/tests/test_threads.py b/testing/mozbase/mozrunner/tests/test_threads.py new file mode 100644 index 0000000000..fa77d92688 --- /dev/null +++ b/testing/mozbase/mozrunner/tests/test_threads.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import mozunit + + +def test_process_start_via_thread(runner, create_thread): + """Start the runner via a thread""" + thread = create_thread(runner, True, 2) + + thread.start() + thread.join() + + assert runner.is_running() + + +def test_process_stop_via_multiple_threads(runner, create_thread): + """Stop the runner via multiple threads""" + runner.start() + threads = [] + for i in range(5): + thread = create_thread(runner, False, 5) + threads.append(thread) + thread.start() + + # Wait until the process has been stopped by another thread + for thread in threads: + thread.join() + returncode = runner.wait(1) + + assert returncode not in [None, 0] + assert runner.returncode == returncode + assert runner.process_handler is not None + assert runner.wait(2) == returncode + + +def test_process_post_stop_via_thread(runner, create_thread): + """Stop the runner and try it again with a thread a bit later""" + runner.start() + thread = create_thread(runner, False, 5) + thread.start() + + # Wait a bit to start the application gets started + runner.wait(1) + returncode = runner.stop() + thread.join() + + assert returncode not in [None, 0] + assert runner.returncode == returncode + assert runner.process_handler is not None + assert runner.wait(2) == returncode + + +if __name__ == "__main__": + mozunit.main() diff --git a/testing/mozbase/mozrunner/tests/test_wait.py b/testing/mozbase/mozrunner/tests/test_wait.py new file mode 100644 index 0000000000..d7ba721b3d --- /dev/null +++ b/testing/mozbase/mozrunner/tests/test_wait.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import mozunit + + +def test_wait_while_running(runner): + """Wait for the process while it is running""" + runner.start() + returncode = runner.wait(1) + + assert runner.is_running() + assert returncode is None + assert runner.returncode == returncode + assert runner.process_handler is not None + + +def test_wait_after_process_finished(runner): + """Bug 965714: wait() after stop should not raise an error""" + runner.start() + runner.process_handler.kill() + + returncode = runner.wait(1) + + assert returncode not in [None, 0] + assert runner.process_handler is not None + + +if __name__ == "__main__": + mozunit.main() |