Skip to content

Commit 862ec5f

Browse files
committed
Fix validity check to avoid breaking consumer requirements
1 parent cb37328 commit 862ec5f

3 files changed

Lines changed: 56 additions & 6 deletions

File tree

src/extensions/score_metamodel/checks/check_options.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,19 @@ def check_validity_consistency(
291291
if need["type"] not in ("stkh_req", "feat_req"):
292292
return
293293

294-
valid_from = need.get("valid_from", None)
295-
valid_until = need.get("valid_until", None)
294+
valid_from_values = _get_normalized(need, "valid_from")
295+
valid_until_values = _get_normalized(need, "valid_until")
296296

297-
if not valid_from or not valid_until:
297+
if valid_until_values and not valid_from_values:
298+
log.warning_for_need(need, "is missing required attribute: `valid_from`.")
298299
return
299300

301+
if not valid_from_values or not valid_until_values:
302+
return
303+
304+
valid_from = valid_from_values[0]
305+
valid_until = valid_until_values[0]
306+
300307
valid_from_version = parse_milestone(valid_from)
301308
valid_until_version = parse_milestone(valid_until)
302309
if valid_from_version >= valid_until_version:

src/extensions/score_metamodel/metamodel.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,16 +263,14 @@ needs_types:
263263
rationale: ^.+$
264264
# req-Id: tool_req__docs_common_attr_security
265265
security: ^(YES|NO)$
266-
# req-Id: tool_req__docs_req_attr_validity_correctness
267-
valid_from: ^v(0|[1-9]\d*)\.(0|[1-9]\d*)(\.(0|[1-9]\d*))?$
268266
optional_options:
269267
# req-Id: tool_req__docs_req_attr_reqcov
270268
reqcovered: ^(YES|NO)$
271269
# req-Id: tool_req__docs_req_attr_testcov
272270
testcovered: ^(YES|NO)$
273271
hash: ^.*$
274272
# req-Id: tool_req__docs_req_attr_validity_correctness
275-
# valid_from: ^v(0|[1-9]\d*)\.(0|[1-9]\d*)(\.(0|[1-9]\d*))?$
273+
valid_from: ^v(0|[1-9]\d*)\.(0|[1-9]\d*)(\.(0|[1-9]\d*))?$
276274
valid_until: ^v(0|[1-9]\d*)\.(0|[1-9]\d*)(\.(0|[1-9]\d*))?$
277275
tags:
278276
- requirement

src/extensions/score_metamodel/tests/test_check_options.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from score_metamodel.checks.check_options import (
2121
check_extra_options,
2222
check_options,
23+
check_validity_consistency,
2324
parse_milestone,
2425
)
2526
from score_metamodel.tests import fake_check_logger, need
@@ -128,3 +129,47 @@ def test_milestone_parsing():
128129
assert parse_milestone("v0.5") == (0, 5, 0)
129130
assert parse_milestone("v1.0") == (1, 0, 0)
130131
assert parse_milestone("v1.0.1") == (1, 0, 1)
132+
133+
134+
def test_validity_consistency_requires_valid_from_if_valid_until_present():
135+
logger = fake_check_logger()
136+
app = Mock(spec=Sphinx)
137+
need_1 = need(
138+
id="stkh_req__001",
139+
type="stkh_req",
140+
valid_until="v1.0",
141+
)
142+
143+
check_validity_consistency(app, need_1, cast(CheckLogger, logger))
144+
145+
logger.assert_warning("is missing required attribute: `valid_from`.")
146+
147+
148+
def test_validity_consistency_allows_missing_validity_pair():
149+
logger = fake_check_logger()
150+
app = Mock(spec=Sphinx)
151+
need_1 = need(
152+
id="stkh_req__001",
153+
type="stkh_req",
154+
)
155+
156+
check_validity_consistency(app, need_1, cast(CheckLogger, logger))
157+
158+
logger.assert_no_warnings()
159+
160+
161+
def test_validity_consistency_warns_on_invalid_range():
162+
logger = fake_check_logger()
163+
app = Mock(spec=Sphinx)
164+
need_1 = need(
165+
id="feat_req__001",
166+
type="feat_req",
167+
valid_from="v2.0",
168+
valid_until="v1.0",
169+
)
170+
171+
check_validity_consistency(app, need_1, cast(CheckLogger, logger))
172+
173+
logger.assert_warning(
174+
"inconsistent validity: valid_from (v2.0) >= valid_until (v1.0)."
175+
)

0 commit comments

Comments
 (0)