Skip to content

Commit 3315f2d

Browse files
committed
options: add new --run-pattern
Add the --run-pattern|-S option to filter tests based on regexp. For example, the following command will filter all tests which contain "sendfile" or "madvise" in their name (including arguments) inside the syscalls testing suite: kirk -S "sendfile|madvise" -r syscalls Reviewed-by: Petr Vorel <pvorel@suse.cz> Acked-by: Cyril Hrubis <chrubis@suse.cz> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
1 parent 01f107e commit 3315f2d

File tree

3 files changed

+74
-5
lines changed

3 files changed

+74
-5
lines changed

libkirk/main.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,14 @@ def _start_session(
296296
# start event loop
297297
exit_code = RC_OK
298298

299+
# read tests regex filter
300+
run_pattern = args.run_pattern
301+
if run_pattern:
302+
try:
303+
re.compile(run_pattern)
304+
except re.error:
305+
parser.error(f"'{run_pattern}' is not a valid regular expression")
306+
299307
async def session_run() -> None:
300308
"""
301309
Run session then stop events handler.
@@ -304,6 +312,7 @@ async def session_run() -> None:
304312
await session.run(
305313
command=args.run_command,
306314
suites=args.run_suite,
315+
pattern=run_pattern,
307316
report_path=args.json_report,
308317
restore=restore_dir,
309318
)
@@ -414,6 +423,10 @@ def run(cmd_args: list = None) -> None:
414423
"-r",
415424
nargs="*",
416425
help="List of suites to run")
426+
parser.add_argument(
427+
"--run-pattern",
428+
"-S",
429+
help="Run all tests matching the regex pattern")
417430
parser.add_argument(
418431
"--run-command",
419432
"-c",
@@ -465,6 +478,9 @@ def run(cmd_args: list = None) -> None:
465478
if args.json_report and os.path.exists(args.json_report):
466479
parser.error(f"JSON report file already exists: {args.json_report}")
467480

481+
if args.run_pattern and not args.run_suite:
482+
parser.error("--run-pattern must be used with --run-suite")
483+
468484
if not args.run_suite and not args.run_command:
469485
parser.error("--run-suite/--run-command are required")
470486

libkirk/session.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
.. moduleauthor:: Andrea Cervesato <andrea.cervesato@suse.com>
77
"""
88
import os
9+
import re
910
import logging
1011
import asyncio
1112
import libkirk
@@ -186,16 +187,16 @@ async def _stop_sut(self) -> None:
186187
await libkirk.events.fire("sut_stop", self._sut.name)
187188
await self._sut.stop(iobuffer=RedirectSUTStdout(self._sut, False))
188189

189-
async def _read_suites(self, suites: list, restore: str) -> list:
190+
async def _get_suites_objects(self, names: list) -> list:
190191
"""
191-
Read suites and return a list of Suite objects.
192+
Return suites objects by giving their names.
192193
"""
193194
coros = []
194-
for suite in suites:
195+
for suite in names:
195196
coros.append(self._framework.find_suite(self._sut, suite))
196197

197198
if not coros:
198-
raise KirkException(f"Can't find suites: {suites}")
199+
raise KirkException(f"Can't find suites: {names}")
199200

200201
suites_obj = await asyncio.gather(*coros, return_exceptions=True)
201202
for suite in suites_obj:
@@ -205,6 +206,31 @@ async def _read_suites(self, suites: list, restore: str) -> list:
205206
if not suite:
206207
raise KirkException("Can't find suite objects")
207208

209+
return suites_obj
210+
211+
async def _read_suites(
212+
self,
213+
suites: list,
214+
pattern: str,
215+
restore: str) -> list:
216+
"""
217+
Read suites and return a list of Suite objects.
218+
"""
219+
suites_obj = await self._get_suites_objects(suites)
220+
221+
if pattern:
222+
matcher = re.compile(pattern)
223+
224+
for suite_obj in suites_obj:
225+
toremove = []
226+
227+
for test in suite_obj.tests:
228+
if not matcher.search(test.name):
229+
toremove.append(test)
230+
231+
for item in toremove:
232+
suite_obj.tests.remove(item)
233+
208234
restored = self._read_restored_session(restore)
209235
if restored:
210236
await libkirk.events.fire("session_restore", restore)
@@ -224,6 +250,13 @@ async def _read_suites(self, suites: list, restore: str) -> list:
224250

225251
toremove.clear()
226252

253+
num_tests = 0
254+
for suite_obj in suites_obj:
255+
num_tests += len(suite_obj.tests)
256+
257+
if num_tests == 0:
258+
raise KirkException("No tests selected")
259+
227260
return suites_obj
228261

229262
async def _exec_command(self, command: str) -> None:
@@ -286,10 +319,13 @@ async def stop(self) -> None:
286319
await libkirk.events.fire("session_stopped")
287320
self._stop = False
288321

322+
# consider changing the arguments handling if new ones must be added
323+
# pylint: disable=too-many-positional-arguments
289324
async def run(
290325
self,
291326
command: str = None,
292327
suites: list = None,
328+
pattern: str = None,
293329
report_path: str = None,
294330
restore: str = None) -> None:
295331
"""
@@ -298,6 +334,8 @@ async def run(
298334
:type command: str
299335
:param suites: list of suites to execute
300336
:type suites: list
337+
:param pattern: string pattern to match tests
338+
:types pattern: str
301339
:param report_path: JSON report path
302340
:type report_path: str
303341
:param restore: temporary directory generated by a previous session
@@ -318,7 +356,8 @@ async def run(
318356
await self._exec_command(command)
319357

320358
if suites:
321-
suites_obj = await self._read_suites(suites, restore)
359+
suites_obj = await self._read_suites(
360+
suites, pattern, restore)
322361
await self._scheduler.schedule(suites_obj)
323362
except KirkException as err:
324363
if not self._stop:

libkirk/tests/test_session.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ async def test_run(self, session):
4444
"""
4545
await session.run(suites=["suite01", "suite02"])
4646

47+
async def test_run_pattern(self, tmpdir, session):
48+
"""
49+
Test run method when executing tests filtered out with a pattern.
50+
"""
51+
report = str(tmpdir / "report.json")
52+
await session.run(
53+
suites=["suite01", "suite02"],
54+
pattern="test01|test02",
55+
report_path=report)
56+
57+
with open(report, "r", encoding="utf-8") as report_file:
58+
report_data = json.loads(report_file.read())
59+
assert len(report_data["results"]) == 4
60+
4761
async def test_run_report(self, tmpdir, session):
4862
"""
4963
Test run method when executing suites, generating a report.

0 commit comments

Comments
 (0)