summaryrefslogtreecommitdiffstats
path: root/testing/mozbase/mozrunner/tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testing/mozbase/mozrunner/tests/conftest.py81
-rw-r--r--testing/mozbase/mozrunner/tests/manifest.ini12
-rw-r--r--testing/mozbase/mozrunner/tests/test_crash.py36
-rw-r--r--testing/mozbase/mozrunner/tests/test_interactive.py40
-rw-r--r--testing/mozbase/mozrunner/tests/test_start.py61
-rw-r--r--testing/mozbase/mozrunner/tests/test_states.py22
-rw-r--r--testing/mozbase/mozrunner/tests/test_stop.py41
-rw-r--r--testing/mozbase/mozrunner/tests/test_threads.py57
-rw-r--r--testing/mozbase/mozrunner/tests/test_wait.py32
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()