summaryrefslogtreecommitdiff
path: root/tests/unit/utils
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/utils')
-rw-r--r--tests/unit/utils/test_qtutils.py6
-rw-r--r--tests/unit/utils/test_version.py91
-rw-r--r--tests/unit/utils/usertypes/test_timer.py63
3 files changed, 145 insertions, 15 deletions
diff --git a/tests/unit/utils/test_qtutils.py b/tests/unit/utils/test_qtutils.py
index c7af3162c..0a3afa416 100644
--- a/tests/unit/utils/test_qtutils.py
+++ b/tests/unit/utils/test_qtutils.py
@@ -758,8 +758,10 @@ class TestPyQIODevice:
# pylint: enable=no-member,useless-suppression
else:
pytest.skip("Needs os.SEEK_HOLE or os.SEEK_DATA available.")
+
pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly)
with pytest.raises(io.UnsupportedOperation):
+ # pylint: disable=possibly-used-before-assignment
pyqiodev.seek(0, whence)
@pytest.mark.flaky
@@ -1116,13 +1118,13 @@ class TestQObjRepr:
assert qtutils.qobj_repr(obj) == expected
def test_class_name(self):
- obj = QTimer()
+ obj = QTimer() # misc: ignore
hidden = sip.cast(obj, QObject)
expected = f"<{self._py_repr(hidden)}, className='QTimer'>"
assert qtutils.qobj_repr(hidden) == expected
def test_both(self):
- obj = QTimer()
+ obj = QTimer() # misc: ignore
obj.setObjectName("Pomodoro")
hidden = sip.cast(obj, QObject)
expected = f"<{self._py_repr(hidden)}, objectName='Pomodoro', className='QTimer'>"
diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py
index 38134b40e..5d2863100 100644
--- a/tests/unit/utils/test_version.py
+++ b/tests/unit/utils/test_version.py
@@ -899,21 +899,45 @@ class TestWebEngineVersions:
webengine=utils.VersionNumber(5, 15, 2),
chromium=None,
source='UA'),
- "QtWebEngine 5.15.2",
+ (
+ "QtWebEngine 5.15.2\n"
+ " (source: UA)"
+ ),
),
(
version.WebEngineVersions(
webengine=utils.VersionNumber(5, 15, 2),
chromium='87.0.4280.144',
source='UA'),
- "QtWebEngine 5.15.2, based on Chromium 87.0.4280.144",
+ (
+ "QtWebEngine 5.15.2\n"
+ " based on Chromium 87.0.4280.144\n"
+ " (source: UA)"
+ ),
),
(
version.WebEngineVersions(
webengine=utils.VersionNumber(5, 15, 2),
chromium='87.0.4280.144',
source='faked'),
- "QtWebEngine 5.15.2, based on Chromium 87.0.4280.144 (from faked)",
+ (
+ "QtWebEngine 5.15.2\n"
+ " based on Chromium 87.0.4280.144\n"
+ " (source: faked)"
+ ),
+ ),
+ (
+ version.WebEngineVersions(
+ webengine=utils.VersionNumber(5, 15, 2),
+ chromium='87.0.4280.144',
+ chromium_security='9000.1',
+ source='faked'),
+ (
+ "QtWebEngine 5.15.2\n"
+ " based on Chromium 87.0.4280.144\n"
+ " with security patches up to 9000.1 (plus any distribution patches)\n"
+ " (source: faked)"
+ ),
),
])
def test_str(self, version, expected):
@@ -950,6 +974,7 @@ class TestWebEngineVersions:
expected = version.WebEngineVersions(
webengine=utils.VersionNumber(5, 15, 2),
chromium='83.0.4103.122',
+ chromium_security='86.0.4240.183',
source='UA',
)
assert version.WebEngineVersions.from_ua(ua) == expected
@@ -959,21 +984,27 @@ class TestWebEngineVersions:
expected = version.WebEngineVersions(
webengine=utils.VersionNumber(5, 15, 2),
chromium='83.0.4103.122',
+ chromium_security='86.0.4240.183',
source='ELF',
)
assert version.WebEngineVersions.from_elf(elf_version) == expected
- @pytest.mark.parametrize('pyqt_version, chromium_version', [
- ('5.15.2', '83.0.4103.122'),
- ('5.15.3', '87.0.4280.144'),
- ('5.15.4', '87.0.4280.144'),
- ('5.15.5', '87.0.4280.144'),
- ('6.2.0', '90.0.4430.228'),
- ('6.3.0', '94.0.4606.126'),
+ @pytest.mark.parametrize('pyqt_version, chromium_version, security_version', [
+ ('5.15.2', '83.0.4103.122', '86.0.4240.183'),
+ ('5.15.3', '87.0.4280.144', '88.0.4324.150'),
+ ('5.15.4', '87.0.4280.144', None),
+ ('5.15.5', '87.0.4280.144', None),
+ ('5.15.6', '87.0.4280.144', None),
+ ('5.15.7', '87.0.4280.144', '94.0.4606.61'),
+ ('6.2.0', '90.0.4430.228', '93.0.4577.63'),
+ ('6.2.99', '90.0.4430.228', None),
+ ('6.3.0', '94.0.4606.126', '99.0.4844.84'),
+ ('6.99.0', None, None),
])
- def test_from_pyqt(self, freezer, pyqt_version, chromium_version):
- if freezer and pyqt_version in ['5.15.3', '5.15.4', '5.15.5']:
+ def test_from_pyqt(self, freezer, pyqt_version, chromium_version, security_version):
+ if freezer and utils.VersionNumber(5, 15, 3) <= utils.VersionNumber.parse(pyqt_version) < utils.VersionNumber(6):
chromium_version = '83.0.4103.122'
+ security_version = '86.0.4240.183'
expected_pyqt_version = '5.15.2'
else:
expected_pyqt_version = pyqt_version
@@ -981,6 +1012,7 @@ class TestWebEngineVersions:
expected = version.WebEngineVersions(
webengine=utils.VersionNumber.parse(expected_pyqt_version),
chromium=chromium_version,
+ chromium_security=security_version,
source='PyQt',
)
assert version.WebEngineVersions.from_pyqt(pyqt_version) == expected
@@ -1024,6 +1056,39 @@ class TestWebEngineVersions:
assert inferred == real
+ def test_real_chromium_security_version(self, qapp):
+ """Check the API for reading the chromium security patch version."""
+ try:
+ from qutebrowser.qt.webenginecore import (
+ qWebEngineChromiumVersion,
+ qWebEngineChromiumSecurityPatchVersion,
+ )
+ except ImportError:
+ pytest.skip("Requires QtWebEngine 6.3+")
+
+ base = utils.VersionNumber.parse(qWebEngineChromiumVersion())
+ security = utils.VersionNumber.parse(qWebEngineChromiumSecurityPatchVersion())
+ assert security >= base
+
+ def test_chromium_security_version_dict(self, qapp):
+ """Check if we infer the QtWebEngine security version properly.
+
+ Note this test mostly tests that our overview in version.py (also
+ intended for human readers) is accurate. The code we call here is never
+ going to be called in real-life situations, as the API is available.
+ """
+ try:
+ from qutebrowser.qt.webenginecore import (
+ qWebEngineVersion,
+ qWebEngineChromiumSecurityPatchVersion,
+ )
+ except ImportError:
+ pytest.skip("Requires QtWebEngine 6.3+")
+
+ inferred = version.WebEngineVersions.from_webengine(
+ qWebEngineVersion(), source="API")
+ assert inferred.chromium_security == qWebEngineChromiumSecurityPatchVersion()
+
class FakeQSslSocket:
@@ -1294,7 +1359,7 @@ def test_version_info(params, stubs, monkeypatch, config_stub):
else:
monkeypatch.delattr(version, 'qtutils.qWebKitVersion', raising=False)
patches['objects.backend'] = usertypes.Backend.QtWebEngine
- substitutions['backend'] = 'QtWebEngine 1.2.3 (from faked)'
+ substitutions['backend'] = 'QtWebEngine 1.2.3\n (source: faked)'
if params.known_distribution:
patches['distribution'] = lambda: version.DistributionInfo(
diff --git a/tests/unit/utils/usertypes/test_timer.py b/tests/unit/utils/usertypes/test_timer.py
index c02f160b6..6aabc8c04 100644
--- a/tests/unit/utils/usertypes/test_timer.py
+++ b/tests/unit/utils/usertypes/test_timer.py
@@ -4,6 +4,9 @@
"""Tests for Timer."""
+import logging
+import fnmatch
+
import pytest
from qutebrowser.qt.core import QObject
@@ -65,3 +68,63 @@ def test_timeout_set_interval(qtbot):
with qtbot.wait_signal(t.timeout, timeout=3000):
t.setInterval(200)
t.start()
+
+
+@pytest.mark.parametrize(
+ "elapsed_ms, expected",
+ [
+ (0, False),
+ (1, False),
+ (600, True),
+ (999, True),
+ (1000, True),
+ ],
+)
+def test_early_timeout_check(qtbot, mocker, elapsed_ms, expected):
+ time_mock = mocker.patch("time.monotonic", autospec=True)
+
+ t = usertypes.Timer()
+ t.setInterval(1000) # anything long enough to not actually fire
+ time_mock.return_value = 0 # assigned to _start_time in start()
+ t.start()
+ time_mock.return_value = elapsed_ms / 1000 # used for `elapsed`
+
+ assert t.check_timeout_validity() is expected
+
+ t.stop()
+
+
+def test_early_timeout_handler(qtbot, mocker, caplog):
+ time_mock = mocker.patch("time.monotonic", autospec=True)
+
+ t = usertypes.Timer(name="t")
+ t.setInterval(3)
+ t.setSingleShot(True)
+ time_mock.return_value = 0
+ with caplog.at_level(logging.WARNING):
+ with qtbot.wait_signal(t.timeout, timeout=10):
+ t.start()
+ time_mock.return_value = 1 / 1000
+
+ assert len(caplog.messages) == 1
+ assert fnmatch.fnmatch(
+ caplog.messages[-1],
+ "Timer t (id *) triggered too early: interval 3 but only 0.001s passed",
+ )
+
+
+def test_early_manual_fire(qtbot, mocker, caplog):
+ """Same as above but start() never gets called."""
+ time_mock = mocker.patch("time.monotonic", autospec=True)
+
+ t = usertypes.Timer(name="t")
+ t.setInterval(3)
+ t.setSingleShot(True)
+ time_mock.return_value = 0
+ with caplog.at_level(logging.WARNING):
+ with qtbot.wait_signal(t.timeout, timeout=10):
+ t.timeout.emit()
+ time_mock.return_value = 1 / 1000
+
+ assert len(caplog.messages) == 0
+ assert t.check_timeout_validity()