Skip to content

Commit 4955f25

Browse files
committed
options: add new --run-pattern
Add the --run-pattern|-S option to filter tests based on regexp. A common usage example is as follows: kirk --run-pattern "sendfile|madvise" Signed-off-by: Andrea Cervesato <[email protected]>
1 parent 9be824f commit 4955f25

File tree

3 files changed

+76
-6
lines changed

3 files changed

+76
-6
lines changed

libkirk/main.py

Lines changed: 15 additions & 2 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,8 +478,8 @@ 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

468-
if not args.run_suite and not args.run_command:
469-
parser.error("--run-suite/--run-command are required")
481+
if not args.run_suite and not args.run_command and not args.run_pattern:
482+
parser.error("At least one of the run commands is required")
470483

471484
if args.skip_file and not os.path.isfile(args.skip_file):
472485
parser.error(f"'{args.skip_file}' skip file doesn't exist")

libkirk/session.py

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
.. moduleauthor:: Andrea Cervesato <[email protected]>
77
"""
88
import os
9+
import re
910
import logging
1011
import asyncio
1112
import libkirk
@@ -14,6 +15,7 @@
1415
from libkirk import KirkException
1516
from libkirk.sut import SUT
1617
from libkirk.sut import IOBuffer
18+
from libkirk.data import Suite
1719
from libkirk.results import TestResults
1820
from libkirk.export import JSONExporter
1921
from libkirk.scheduler import SuiteScheduler
@@ -186,16 +188,16 @@ async def _stop_sut(self) -> None:
186188
await libkirk.events.fire("sut_stop", self._sut.name)
187189
await self._sut.stop(iobuffer=RedirectSUTStdout(self._sut, False))
188190

189-
async def _read_suites(self, suites: list, restore: str) -> list:
191+
async def _get_suites_objects(self, names: list) -> list:
190192
"""
191-
Read suites and return a list of Suite objects.
193+
Return suites objects by giving their names.
192194
"""
193195
coros = []
194-
for suite in suites:
196+
for suite in names:
195197
coros.append(self._framework.find_suite(self._sut, suite))
196198

197199
if not coros:
198-
raise KirkException(f"Can't find suites: {suites}")
200+
raise KirkException(f"Can't find suites: {names}")
199201

200202
suites_obj = await asyncio.gather(*coros, return_exceptions=True)
201203
for suite in suites_obj:
@@ -205,6 +207,39 @@ async def _read_suites(self, suites: list, restore: str) -> list:
205207
if not suite:
206208
raise KirkException("Can't find suite objects")
207209

210+
return suites_obj
211+
212+
async def _filter_tests(self, pattern: str) -> list:
213+
"""
214+
Read all tests from all the testing suites which are matching the regex.
215+
"""
216+
if not pattern:
217+
raise ValueError("pattern regex is empty")
218+
219+
suites = await self._framework.get_suites(self._sut)
220+
if not suites:
221+
return []
222+
223+
suites_obj = await self._get_suites_objects(suites)
224+
225+
tests = []
226+
matcher = re.compile(pattern)
227+
228+
for suite in suites_obj:
229+
for test in suite.tests:
230+
if matcher.search(test.name):
231+
tests.append(test)
232+
233+
suite = Suite('ltp_filtered_tests', tests)
234+
235+
return [suite]
236+
237+
async def _read_suites(self, suites: list, restore: str) -> list:
238+
"""
239+
Read suites and return a list of Suite objects.
240+
"""
241+
suites_obj = await self._get_suites_objects(suites)
242+
208243
restored = self._read_restored_session(restore)
209244
if restored:
210245
await libkirk.events.fire("session_restore", restore)
@@ -286,10 +321,13 @@ async def stop(self) -> None:
286321
await libkirk.events.fire("session_stopped")
287322
self._stop = False
288323

324+
# consider changing the arguments handling if new ones must be added
325+
# pylint: disable=too-many-positional-arguments
289326
async def run(
290327
self,
291328
command: str = None,
292329
suites: list = None,
330+
pattern: str = None,
293331
report_path: str = None,
294332
restore: str = None) -> None:
295333
"""
@@ -298,6 +336,8 @@ async def run(
298336
:type command: str
299337
:param suites: list of suites to execute
300338
:type suites: list
339+
:param pattern: string pattern to match tests
340+
:types pattern: str
301341
:param report_path: JSON report path
302342
:type report_path: str
303343
:param restore: temporary directory generated by a previous session
@@ -317,6 +357,10 @@ async def run(
317357
if command:
318358
await self._exec_command(command)
319359

360+
if pattern:
361+
suites_obj = await self._filter_tests(pattern)
362+
await self._scheduler.schedule(suites_obj)
363+
320364
if suites:
321365
suites_obj = await self._read_suites(suites, restore)
322366
await self._scheduler.schedule(suites_obj)

libkirk/tests/test_session.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ 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+
pattern="test01|test02",
54+
report_path=report)
55+
56+
with open(report, "r", encoding="utf-8") as report_file:
57+
report_data = json.loads(report_file.read())
58+
assert len(report_data["results"]) == 8
59+
4760
async def test_run_report(self, tmpdir, session):
4861
"""
4962
Test run method when executing suites, generating a report.

0 commit comments

Comments
 (0)