-
Notifications
You must be signed in to change notification settings - Fork 13
/
conftest.py
129 lines (106 loc) · 4.4 KB
/
conftest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import importlib
import _pytest.unittest
import pytest
# Must be called before importing irctest.cases.
pytest.register_assert_rewrite("irctest.cases")
from irctest.basecontrollers import ( # noqa: E402
BaseClientController,
BaseServerController,
)
from irctest.cases import ( # noqa: E402
BaseClientTestCase,
BaseServerTestCase,
_IrcTestCase,
)
def pytest_addoption(parser):
"""Called by pytest, registers CLI options passed to the pytest command."""
parser.addoption(
"--controller", help="Which module to use to run the tested software."
)
parser.addoption(
"--services-controller", help="Which module to use to run a services package."
)
parser.addoption(
"--openssl-bin", type=str, default="openssl", help="The openssl binary to use"
)
def pytest_configure(config):
"""Called by pytest, after it parsed the command-line."""
module_name = config.getoption("controller")
services_module_name = config.getoption("services_controller")
if module_name is None:
print("Missing --controller option, errors may occur.")
_IrcTestCase.controllerClass = None
_IrcTestCase.show_io = True # TODO
return
try:
module = importlib.import_module(module_name)
except ImportError:
pytest.exit("Cannot import module {}".format(module_name), 1)
controller_class = module.get_irctest_controller_class()
if issubclass(controller_class, BaseClientController):
from irctest import client_tests as module
if services_module_name is not None:
pytest.exit("You may not use --services-controller for client tests.")
elif issubclass(controller_class, BaseServerController):
from irctest import server_tests as module
else:
pytest.exit(
r"{}.Controller should be a subclass of "
r"irctest.basecontroller.Base{{Client,Server}}Controller".format(
module_name
),
1,
)
if services_module_name is not None:
try:
services_module = importlib.import_module(services_module_name)
except ImportError:
pytest.exit("Cannot import module {}".format(services_module_name), 1)
controller_class.services_controller_class = (
services_module.get_irctest_controller_class()
)
_IrcTestCase.controllerClass = controller_class
_IrcTestCase.controllerClass.openssl_bin = config.getoption("openssl_bin")
_IrcTestCase.show_io = True # TODO
def pytest_collection_modifyitems(session, config, items):
"""Called by pytest after finishing the test collection,
and before actually running the tests.
This function filters out client tests if running with a server controller,
and vice versa.
"""
# First, check if we should run server tests or client tests
server_tests = client_tests = False
if _IrcTestCase.controllerClass is None:
pass
elif issubclass(_IrcTestCase.controllerClass, BaseServerController):
server_tests = True
elif issubclass(_IrcTestCase.controllerClass, BaseClientController):
client_tests = True
else:
assert False, (
f"{_IrcTestCase.controllerClass} inherits neither "
f"BaseClientController or BaseServerController"
)
filtered_items = []
# Iterate over each of the test functions (they are pytest "Nodes")
for item in items:
assert isinstance(item, _pytest.python.Function)
# unittest-style test functions have the node of UnitTest class as parent
if tuple(map(int, _pytest.__version__.split("."))) >= (7,):
assert isinstance(item.parent, _pytest.python.Class)
else:
assert isinstance(item.parent, _pytest.python.Instance)
# and that node references the UnitTest class
assert issubclass(item.parent.cls, _IrcTestCase)
# and in this project, TestCase classes all inherit either from
# BaseClientController or BaseServerController.
if issubclass(item.parent.cls, BaseServerTestCase):
if server_tests:
filtered_items.append(item)
elif issubclass(item.parent.cls, BaseClientTestCase):
if client_tests:
filtered_items.append(item)
else:
filtered_items.append(item)
# Finally, rewrite in-place the list of tests pytest will run
items[:] = filtered_items