Skip to content

Commit aae71d7

Browse files
nashifAnas Nashif
authored andcommitted
sanitycheck: parse test cases from source files
This parses the tests that run within a test project/application from the source code and gives us a view of what was run, skipped and what was blocked due to early termination of the test. Signed-off-by: Anas Nashif <[email protected]>
1 parent 20495e8 commit aae71d7

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

scripts/sanitycheck

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ line break instead of white spaces.
158158
Most everyday users will run with no arguments.
159159
"""
160160

161+
import contextlib
162+
import mmap
161163
import argparse
162164
import os
163165
import sys
@@ -1362,6 +1364,8 @@ class TestCase:
13621364
from the testcase.yaml file
13631365
"""
13641366
self.code_location = os.path.join(testcase_root, workdir)
1367+
self.id = name
1368+
self.cases = []
13651369
self.type = tc_dict["type"]
13661370
self.tags = tc_dict["tags"]
13671371
self.extra_args = tc_dict["extra_args"]
@@ -1389,10 +1393,77 @@ class TestCase:
13891393
testcase_root).replace(os.path.realpath(ZEPHYR_BASE) + "/", ''),
13901394
workdir, name))
13911395

1396+
13921397
self.name = os.path.join(self.path)
13931398
self.defconfig = {}
13941399
self.yamlfile = yamlfile
13951400

1401+
def scan_file(self, inf_name):
1402+
include_regex = re.compile(
1403+
br"#include\s*<ztest\.h>",
1404+
re.MULTILINE)
1405+
suite_regex = re.compile(
1406+
br"^\s*ztest_test_suite\(\s*(?P<suite_name>[a-zA-Z0-9_]+)[\s,]*$",
1407+
re.MULTILINE)
1408+
stc_regex = re.compile(
1409+
br"^\s*ztest_(user_)?unit_test\((test_)?(?P<stc_name>[a-zA-Z0-9_]+)\)[\s,;\)]*$",
1410+
re.MULTILINE)
1411+
suite_run_regex = re.compile(
1412+
br"^\s*ztest_run_test_suite\((?P<suite_name>[a-zA-Z0-9_]+)\)",
1413+
re.MULTILINE)
1414+
achtung_regex = re.compile(
1415+
br"(#ifdef|#endif)",
1416+
re.MULTILINE)
1417+
warnings = None
1418+
1419+
with open(inf_name) as inf:
1420+
with contextlib.closing(mmap.mmap(inf.fileno(), 0, mmap.MAP_PRIVATE,
1421+
mmap.PROT_READ, 0)) as main_c:
1422+
#if not include_regex.search(main_c):
1423+
# return None, None #"skipped, not using ztest.h"
1424+
1425+
suite_regex_match = suite_regex.search(main_c)
1426+
if not suite_regex_match:
1427+
# can't find ztest_test_suite, maybe a client, because
1428+
# it includes ztest.h
1429+
return None, None
1430+
1431+
suite_run_match = suite_run_regex.search(main_c)
1432+
if not suite_run_match:
1433+
raise ValueError("can't find ztest_run_test_suite")
1434+
1435+
achtung_matches = re.findall(
1436+
achtung_regex,
1437+
main_c[suite_regex_match.end():suite_run_match.start()])
1438+
if achtung_matches:
1439+
warnings = "found invalid %s in ztest_test_suite()" \
1440+
% ", ".join(set(achtung_matches))
1441+
matches = re.findall(
1442+
stc_regex,
1443+
main_c[suite_regex_match.end():suite_run_match.start()])
1444+
return matches, warnings
1445+
1446+
def scan_path(self, path):
1447+
subcases = []
1448+
for filename in glob.glob(os.path.join(path, "src", "*.c")):
1449+
try:
1450+
_subcases, warnings = self.scan_file(filename)
1451+
if warnings:
1452+
warning("%s: %s", filename, warnings)
1453+
if _subcases:
1454+
subcases += _subcases
1455+
except ValueError as e:
1456+
error("%s: can't find: %s", filename, e)
1457+
return subcases
1458+
1459+
1460+
def parse_subcases(self):
1461+
results = self.scan_path(self.code_location)
1462+
for sub in results:
1463+
name = "{}.{}".format(self.id, sub[2].decode())
1464+
self.cases.append(name)
1465+
1466+
13961467
def __str__(self):
13971468
return self.name
13981469

@@ -1505,6 +1576,7 @@ class TestSuite:
15051576
tc_dict = parsed_data.get_test(name, testcase_valid_keys)
15061577
tc = TestCase(testcase_root, workdir, name, tc_dict,
15071578
yaml_path)
1579+
tc.parse_subcases()
15081580

15091581
self.testcases[tc.name] = tc
15101582

0 commit comments

Comments
 (0)