Skip to content

Commit 3504a66

Browse files
committed
Add select-testcases.py
Split main functionality off of scs-compliance-check.py -- use together with 'iaas/openstack_test.py -c cloud -' for a very similar effect for far reduced lines of code. What remains to be done: produce report yaml (either with a separate script again, or equip openstack_test.py), and then evaluate the report with respect to the spec yaml. Signed-off-by: Matthias Büchse <matthias.buechse@alasca.cloud>
1 parent 7051713 commit 3504a66

1 file changed

Lines changed: 116 additions & 0 deletions

File tree

Tests/select-testcases.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import re
5+
import sys
6+
import getopt
7+
import datetime
8+
import logging
9+
import yaml
10+
11+
from scs_cert_lib import load_spec, annotate_validity
12+
13+
14+
logger = logging.getLogger(__name__)
15+
16+
17+
def usage(file=sys.stdout):
18+
"""Output usage information"""
19+
print("""Usage: select-testcases.py [options] SPEC_YAML
20+
21+
Arguments:
22+
SPEC_YAML: yaml file specifying the certificate scope
23+
24+
Options:
25+
-d/--date YYYY-MM-DD: Check standards valid on specified date instead of today
26+
-V/--version VERS: Force version VERS of the standard (instead of deriving from date)
27+
-S/--sections SECTION_LIST: comma-separated list of sections to test (default: all sections)
28+
-t/--tests REGEX: regular expression to select individual testcases based on their ids
29+
""", file=file)
30+
31+
32+
class Config:
33+
def __init__(self):
34+
self.arg0 = None
35+
self.checkdate = datetime.date.today()
36+
self.version = None
37+
self.sections = None
38+
self.tests = None
39+
40+
def apply_argv(self, argv):
41+
"""Parse options. May exit the program."""
42+
try:
43+
opts, args = getopt.gnu_getopt(argv, "hd:V:S:t:", (
44+
"help", "date=", "version=", "sections=", "tests=",
45+
))
46+
except getopt.GetoptError:
47+
usage(file=sys.stderr)
48+
raise
49+
for opt in opts:
50+
if opt[0] == "-h" or opt[0] == "--help":
51+
usage()
52+
sys.exit(0)
53+
elif opt[0] == "-d" or opt[0] == "--date":
54+
self.checkdate = datetime.date.fromisoformat(opt[1])
55+
elif opt[0] == "-V" or opt[0] == "--version":
56+
self.version = opt[1]
57+
elif opt[0] == "-S" or opt[0] == "--sections":
58+
self.sections = [x.strip() for x in opt[1].split(",")]
59+
elif opt[0] == "-t" or opt[0] == "--tests":
60+
self.tests = re.compile(opt[1])
61+
else:
62+
logger.error(f"Unknown argument {opt[0]}")
63+
if len(args) != 1:
64+
usage(file=sys.stderr)
65+
raise RuntimeError("need precisely one argument")
66+
self.arg0 = args[0]
67+
68+
69+
def select_valid(versions: list) -> list:
70+
return [version for version in versions if version['_explicit_validity']]
71+
72+
73+
def main(argv):
74+
"""Entry point for the checker"""
75+
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
76+
config = Config()
77+
config.apply_argv(argv)
78+
with open(config.arg0, "r", encoding="UTF-8") as specfile:
79+
spec = load_spec(yaml.load(specfile, Loader=yaml.SafeLoader))
80+
annotate_validity(spec['timeline'], spec['versions'], config.checkdate)
81+
if config.version is None:
82+
versions = select_valid(spec['versions'].values())
83+
else:
84+
versions = [spec['versions'].get(config.version)]
85+
if versions[0] is None:
86+
raise RuntimeError(f"Requested version '{config.version}' not found")
87+
if not versions:
88+
raise RuntimeError(f"No valid version found for {config.checkdate}")
89+
title = spec['name']
90+
if config.sections:
91+
title += f" [sections: {', '.join(config.sections)}]"
92+
if config.tests:
93+
title += f" [tests: '{config.tests.pattern}']"
94+
# collect all testcases we need
95+
testcase_lookup = spec['testcases']
96+
all_testcase_ids = set()
97+
for version in versions:
98+
for tc_id in version['testcase_ids']:
99+
if config.sections and testcase_lookup.get(tc_id, {}).get('section') not in config.sections:
100+
continue
101+
if config.tests and not config.tests.match(tc_id):
102+
continue
103+
all_testcase_ids.add(tc_id)
104+
logger.info(f"{title}: {len(all_testcase_ids)} testcases")
105+
if all_testcase_ids:
106+
print('\n'.join(sorted(all_testcase_ids)))
107+
108+
109+
if __name__ == "__main__":
110+
try:
111+
sys.exit(main(sys.argv[1:]))
112+
except SystemExit:
113+
raise
114+
except BaseException as exc:
115+
logger.critical(f"{str(exc) or repr(exc)}")
116+
raise

0 commit comments

Comments
 (0)