Skip to content

Commit

Permalink
Add initial pytest support
Browse files Browse the repository at this point in the history
Add a new dbusmock.pytest_fixtures module which exports an initial set
of fixtures. These mostly just wrap DbusTestCase into a fixture, plus
some convenience functions for starting a system or session bus. In the
future we may have more fixtures to spawn templates, etc.

Ensure that all of our unit tests run with pytest. As that is expensive,
only run it for TEST_CODE=1 in Fedora stable. On the others, only run
the basic TestAPI checks and the fixtures checks.

Thanks to @whot for the initial investigation and proposal!
  • Loading branch information
martinpitt committed Aug 20, 2023
1 parent 178b7c8 commit 38b329d
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 10 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,7 @@ the mock server as a program.

python-dbusmock is hosted on https://github.com/martinpitt/python-dbusmock

Run the unit tests with

python3 -m unittest
Run the unit tests with `python3 -m unittest` or `pytest`.

In CI, the unit tests run in containers. You can run them locally with e.g.

Expand Down
43 changes: 43 additions & 0 deletions dbusmock/pytest_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'''pytest fixtures for DBusMock'''

# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option) any
# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text
# of the license.

__author__ = 'Martin Pitt'
__copyright__ = '(c) 2023 Martin Pitt <martin@piware.de>'

from typing import Iterator

import pytest

import dbusmock.testcase


@pytest.fixture(name='dbusmock_testcase', scope='session')
def fixture_dbusmock_testcase() -> Iterator[dbusmock.testcase.DBusTestCase]:
'''Export the whole DBusTestCase as a fixture.'''

testcase = dbusmock.testcase.DBusTestCase()
testcase.setUp()
yield testcase
testcase.tearDown()
testcase.tearDownClass()


@pytest.fixture(scope='session')
def dbusmock_testcase_system(dbusmock_testcase) -> dbusmock.testcase.DBusTestCase:
'''Export the whole DBusTestCase as a fixture, with system bus started'''

dbusmock_testcase.start_system_bus()
return dbusmock_testcase


@pytest.fixture(scope='session')
def dbusmock_testcase_session(dbusmock_testcase) -> dbusmock.testcase.DBusTestCase:
'''Export the whole DBusTestCase as a fixture, with session bus started'''

dbusmock_testcase.start_session_bus()
return dbusmock_testcase
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest_plugins = "dbusmock.pytest_fixtures"
3 changes: 2 additions & 1 deletion tests/run-debian
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ eatmydata apt-get -y --purge dist-upgrade
# install build dependencies
eatmydata apt-get install --no-install-recommends -y git \
python3-all python3-setuptools python3-setuptools-scm python3-build python3-venv \
python3-dbus python3-gi gir1.2-glib-2.0 \
python3-dbus python3-pytest python3-gi gir1.2-glib-2.0 \
dbus libnotify-bin upower network-manager bluez ofono ofono-scripts

# systemd's tools otherwise fail on "not been booted with systemd"
Expand All @@ -27,6 +27,7 @@ export TEST_CODE="$TEST_CODE"
cp -r $(pwd) /tmp/source
cd /tmp/source
python3 -m unittest -v
python3 -m pytest -vv -k 'test_pytest or TestAPI'
# massively parallel test to check for races
for i in \$(seq 100); do
( PYTHONPATH=. python3 tests/test_api.py TestTemplates || touch /tmp/fail ) &
Expand Down
17 changes: 11 additions & 6 deletions tests/run-fedora
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set -eux
# install build dependencies
dnf -y install python3-setuptools python3 python3-gobject-base \
python3-dbus dbus-x11 util-linux \
python3-dbus python3-pytest dbus-x11 util-linux \
upower NetworkManager bluez libnotify polkit

if ! grep -q :el /etc/os-release; then
Expand All @@ -19,12 +19,17 @@ mkdir -p /run/systemd/system

# run build and test as user
useradd build
su -s /bin/sh - build << EOF
su -s /bin/sh - build << EOF || { [ -z "$DEBUG" ] || sleep infinity; exit 1; }
set -ex
cd /source
export TEST_CODE="$TEST_CODE"
python3 -m unittest -v || {
[ -z "$DEBUG" ] || sleep infinity
exit 1
}
python3 -m unittest -v
# run all tests with pytest only on TEST_CODE, as that is expensive
if [ -n "$TEST_CODE" ]; then
python3 -m pytest -v
else
python3 -m pytest -vv -k 'test_pytest or TestAPI'
fi
EOF
29 changes: 29 additions & 0 deletions tests/test_pytest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import subprocess

import dbusmock


def test_dbusmock_testcase_spawn_server(dbusmock_testcase_session):
test_iface = 'org.freedesktop.Test.Main'

p_mock = dbusmock_testcase_session.spawn_server(
'org.freedesktop.Test', '/', test_iface, stdout=subprocess.DEVNULL)

obj_test = dbusmock_testcase_session.get_dbus().get_object('org.freedesktop.Test', '/')

obj_test.AddMethod('', 'Upper', 's', 's', 'ret = args[0].upper()', interface_name=dbusmock.MOCK_IFACE)
assert obj_test.Upper('hello', interface=test_iface) == 'HELLO'

p_mock.terminate()
p_mock.wait()


def test_dbusmock_testcase_spawn_system_template(dbusmock_testcase_system):
p_mock, _obj = dbusmock_testcase_system.spawn_server_template('upower', stdout=subprocess.DEVNULL)

out = subprocess.check_output(['upower', '--dump'], universal_newlines=True)
assert 'version:' in out
assert '0.99' in out

p_mock.terminate()
p_mock.wait()

0 comments on commit 38b329d

Please sign in to comment.