diff --git a/examples/rules/rules.yaml b/examples/rules/rules.yaml index 468c363..869f7d7 100644 --- a/examples/rules/rules.yaml +++ b/examples/rules/rules.yaml @@ -6,15 +6,14 @@ target_date: "start_date - 7|days" - rule: "Dependent Rule 1" - rule: "Dependent Rule 2" - jira_issues: - - id: main + - jira_issue_id: main template: "examples/jira/main.yaml" subtasks: - id: add_beta_repos template: "examples/jira/add_beta_repos.yaml" - id: notify_team template: "examples/jira/notify_team.yaml" - - id: secondary + - jira_issue_id: secondary template: "examples/jira/secondary.yaml" - version: 1 @@ -22,11 +21,9 @@ prerequisites: - schedule_task: "TASK" target_date: "start_date - 3|weeks" - jira_issues: [] - version: 1 name: "Dependent Rule 2" prerequisites: - schedule_task: "TASK" target_date: "start_date - 2|weeks" - jira_issues: [] diff --git a/src/retasc/models/jira_issue.py b/src/retasc/models/jira_issue.py deleted file mode 100644 index 90e5b27..0000000 --- a/src/retasc/models/jira_issue.py +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later -from pydantic import BaseModel, Field - - -class JiraIssueTemplate(BaseModel): - """Jira issue template with optional sub-tasks.""" - - id: str = Field(description="Unique identifier for the issue.") - template: str = Field(description="The template file for the jira issue.") - subtasks: list["JiraIssueTemplate"] = Field( - default=[], description="The subtasks for the jira issue." - ) - - @property - def label(self): - return f"retasc-id-{self.id}" diff --git a/src/retasc/models/parse_rules.py b/src/retasc/models/parse_rules.py index 61b7ecf..ab0e2ec 100644 --- a/src/retasc/models/parse_rules.py +++ b/src/retasc/models/parse_rules.py @@ -2,7 +2,6 @@ import logging import os from collections import defaultdict -from collections.abc import Iterator from dataclasses import dataclass, field from glob import iglob from itertools import chain @@ -11,14 +10,11 @@ from pydantic import ValidationError from retasc.models.rule import Rule +from retasc.utils import to_comma_separated logger = logging.getLogger(__name__) -def to_comma_separated(items: list) -> str: - return ", ".join(sorted(repr(str(x)) for x in items)) - - class RuleParsingError(RuntimeError): pass @@ -40,17 +36,6 @@ def parse_yaml_objects(rule_file: str) -> list[dict]: return [data] -def template_filenames(rule: Rule) -> Iterator[str]: - for issue in rule.jira_issues: - yield issue.template - yield from (x.template for x in issue.subtasks) - - -def template_paths(rule: Rule, templates_path: str) -> Iterator[str]: - for file in template_filenames(rule): - yield f"{templates_path}/{file}" - - @dataclass class ParseState: """Keeps state for parsing and validation.""" @@ -98,20 +83,6 @@ def validate_existing_dependent_rules(self) -> None: if errors: self._add_invalid_rule_error(rule, "\n ".join(errors)) - def validate_existing_jira_templates(self, templates_path: str) -> None: - for rule in self.rules.values(): - missing_files = [ - file - for file in template_paths(rule, templates_path) - if not os.path.isfile(file) - ] - if missing_files: - file_list = to_comma_separated(missing_files) - self._add_invalid_rule_error( - rule, - f"Jira issue template files not found: {file_list}", - ) - def _add_invalid_rule_error(self, rule: Rule, error: str) -> None: filename = self.rule_files[rule.name][0] self.errors.append( @@ -119,7 +90,7 @@ def _add_invalid_rule_error(self, rule: Rule, error: str) -> None: ) -def parse_rules(path: str, templates_path: str = ".") -> dict[str, Rule]: +def parse_rules(path: str) -> dict[str, Rule]: """ Parses rules in path recursively to dict with rule name as key and the rule as value. @@ -131,7 +102,6 @@ def parse_rules(path: str, templates_path: str = ".") -> dict[str, Rule]: state.validate_unique_rule_names() state.validate_existing_dependent_rules() - state.validate_existing_jira_templates(templates_path) if state.errors: error_list = "\n".join(state.errors) diff --git a/src/retasc/models/prerequisites/__init__.py b/src/retasc/models/prerequisites/__init__.py index 207c2f0..3a2e6c8 100644 --- a/src/retasc/models/prerequisites/__init__.py +++ b/src/retasc/models/prerequisites/__init__.py @@ -1,6 +1,12 @@ # SPDX-License-Identifier: GPL-3.0-or-later from .condition import PrerequisiteCondition +from .jira_issue import PrerequisiteJiraIssue from .rule import PrerequisiteRule from .schedule import PrerequisiteSchedule -type Prerequisite = PrerequisiteCondition | PrerequisiteSchedule | PrerequisiteRule +type Prerequisite = ( + PrerequisiteCondition + | PrerequisiteSchedule + | PrerequisiteRule + | PrerequisiteJiraIssue +) diff --git a/src/retasc/models/prerequisites/base.py b/src/retasc/models/prerequisites/base.py index bfca05e..b5e54f7 100644 --- a/src/retasc/models/prerequisites/base.py +++ b/src/retasc/models/prerequisites/base.py @@ -18,7 +18,7 @@ def validation_errors(self, rules) -> list[str]: """Return validation errors if any.""" return [] - def state(self, context) -> ReleaseRuleState: + def update_state(self, context) -> ReleaseRuleState: """Update template variables if needed and returns current state.""" raise NotImplementedError() diff --git a/src/retasc/models/prerequisites/condition.py b/src/retasc/models/prerequisites/condition.py index c729531..f3c02aa 100644 --- a/src/retasc/models/prerequisites/condition.py +++ b/src/retasc/models/prerequisites/condition.py @@ -19,7 +19,7 @@ class PrerequisiteCondition(PrerequisiteBase): """).strip() ) - def state(self, context) -> ReleaseRuleState: + def update_state(self, context) -> ReleaseRuleState: is_completed = context.template.evaluate(self.condition) context.report.set("result", is_completed) return ReleaseRuleState.Completed if is_completed else ReleaseRuleState.Pending diff --git a/src/retasc/models/prerequisites/jira_issue.py b/src/retasc/models/prerequisites/jira_issue.py new file mode 100644 index 0000000..20b61d5 --- /dev/null +++ b/src/retasc/models/prerequisites/jira_issue.py @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +import os +from collections.abc import Iterator +from itertools import takewhile + +from pydantic import BaseModel, Field + +from retasc.models.release_rule_state import ReleaseRuleState +from retasc.utils import to_comma_separated + +from .base import PrerequisiteBase + + +class JiraIssueTemplate(BaseModel): + id: str = Field(description="Unique identifier for the issue.") + template: str = Field(description="Path to the Jira issue template YAML file") + + +class PrerequisiteJiraIssue(PrerequisiteBase): + """Prerequisite Rule.""" + + jira_issue_id: str = Field(description="Unique identifier for the issue.") + template: str = Field(description="Path to the Jira issue template YAML file") + subtasks: list[JiraIssueTemplate] = Field(default_factory=list) + + def validation_errors(self, rules) -> list[str]: + errors = [] + + missing_files = { + file for file in template_paths(self) if not os.path.isfile(file) + } + if missing_files: + file_list = to_comma_separated(missing_files) + errors.append(f"Jira issue template files not found: {file_list}") + + own_issue_ids = set(jira_issue_ids(self)) + preceding_issue_ids = { + issue_id + for prereq in takewhile( + lambda x: x is not self, jira_issue_prerequisites(rules) + ) + for issue_id in jira_issue_ids(prereq) + } + duplicate_issue_ids = own_issue_ids.intersection(preceding_issue_ids) + if duplicate_issue_ids: + id_list = to_comma_separated(duplicate_issue_ids) + errors.append(f"Jira issue ID(s) already used elsewhere: {id_list}") + + return errors + + def update_state(self, context) -> ReleaseRuleState: + """Return Completed only if all rules were closed.""" + label = f"retasc-id-{self.jira_issue_id}" + if label in context.closed_issue_labels: + return ReleaseRuleState.Completed + # TODO: Create new or update existing issue from the template if + # context.prerequisites_state is ReleaseRuleState.InProgress + return ReleaseRuleState.InProgress + + def section_name(self) -> str: + return f"jira: {self.jira_issue_id!r}" + + +def templates_root() -> str: + return os.getenv("RETASC_JIRA_TEMPLATES_ROOT", ".") + + +def template_filenames(prereq: PrerequisiteJiraIssue) -> Iterator[str]: + yield prereq.template + for x in prereq.subtasks: + yield x.template + + +def template_paths(prereq: PrerequisiteJiraIssue) -> Iterator[str]: + root = templates_root() + for file in template_filenames(prereq): + yield f"{root}/{file}" + + +def jira_issue_ids(prereq: PrerequisiteJiraIssue) -> Iterator[str]: + yield prereq.jira_issue_id + for x in prereq.subtasks: + yield x.id + + +def jira_issue_prerequisites(rules): + for rule in rules: + for prereq in rule.prerequisites: + if isinstance(prereq, PrerequisiteJiraIssue): + yield prereq + # Ignore this from coverage since rules is always non-empty and the + # iteration always stops at a specific prerequisite. + return # pragma: no cover diff --git a/src/retasc/models/prerequisites/rule.py b/src/retasc/models/prerequisites/rule.py index 1e5468b..dfa6e34 100644 --- a/src/retasc/models/prerequisites/rule.py +++ b/src/retasc/models/prerequisites/rule.py @@ -16,10 +16,10 @@ def validation_errors(self, rules) -> list[str]: return [f"Dependent rule does not exist: {self.rule!r}"] return [] - def state(self, context) -> ReleaseRuleState: + def update_state(self, context) -> ReleaseRuleState: """Return Completed only if all rules were closed.""" rule = context.template.render(self.rule) - return context.rules[rule].state(context=context) + return context.rules[rule].update_state(context=context) def section_name(self) -> str: return f"rule: {self.rule!r}" diff --git a/src/retasc/models/prerequisites/schedule.py b/src/retasc/models/prerequisites/schedule.py index 21467a1..71acdc0 100644 --- a/src/retasc/models/prerequisites/schedule.py +++ b/src/retasc/models/prerequisites/schedule.py @@ -52,7 +52,7 @@ def _params(self, context) -> dict: ) return local_params - def state(self, context) -> ReleaseRuleState: + def update_state(self, context) -> ReleaseRuleState: """ Fetch schedule and given task, update templating parameters and return Completed. diff --git a/src/retasc/models/rule.py b/src/retasc/models/rule.py index c10d6f7..b250f7b 100644 --- a/src/retasc/models/rule.py +++ b/src/retasc/models/rule.py @@ -4,7 +4,6 @@ from pydantic import BaseModel, Field -from retasc.models.jira_issue import JiraIssueTemplate from retasc.models.prerequisites import Prerequisite from retasc.models.release_rule_state import ReleaseRuleState @@ -24,9 +23,6 @@ class Config: prerequisites: list[Prerequisite] = Field( description="The prerequisites for the rule." ) - jira_issues: list[JiraIssueTemplate] = Field( - description="The jira issues to create and manager for the rule." - ) products: list[str] = Field( description="Affected Product Pages product short names", default_factory=lambda: ["rhel"], @@ -40,26 +36,15 @@ def __hash__(self): return hash(self.name) @cache - def state(self, context) -> ReleaseRuleState: + def update_state(self, context) -> ReleaseRuleState: """ Return Completed only if all issues were closed, otherwise returns Pending if any prerequisites are Pending, and InProgress in other cases. """ - pending_issues = [ - template.label - for template in self.jira_issues - if template.label not in context.closed_issue_labels - ] - if not pending_issues: - return ReleaseRuleState.Completed - - context.report.set("pending_issues", pending_issues) - - result = ReleaseRuleState.InProgress for prereq in self.prerequisites: with context.report.section(prereq.section_name()): - state = prereq.state(context) + state = prereq.update_state(context) context.report.set("state", state.name) - result = min(result, state) - return result + context.prerequisites_state = min(context.prerequisites_state, state) + return context.prerequisites_state diff --git a/src/retasc/run.py b/src/retasc/run.py index 396ea70..eccbb82 100644 --- a/src/retasc/run.py +++ b/src/retasc/run.py @@ -7,6 +7,7 @@ from retasc.jira_client import JiraClient from retasc.models.parse_rules import parse_rules +from retasc.models.release_rule_state import ReleaseRuleState from retasc.models.rule import Rule from retasc.product_pages_api import ProductPagesApi from retasc.report import Report @@ -39,11 +40,11 @@ def parse_version(release: str) -> tuple[int, int]: return int(x["major"]), int(x["minor"]) -def update_jira_issues(rule: Rule, context: RuntimeContext): +def update_state(rule: Rule, context: RuntimeContext): with context.report.section(rule.name): - state = rule.state(context) + context.prerequisites_state = ReleaseRuleState.Completed + state = rule.update_state(context) context.report.set("state", state.name) - # TODO: Update or create Jira issues according to the state. def iterate_rules(context: RuntimeContext) -> Iterator[tuple[str, str, list[Rule]]]: @@ -88,7 +89,7 @@ def run(*, dry_run: bool) -> Report: "minor": minor, **rule.params, } - update_jira_issues(rule, context) + update_state(rule, context) if dry_run: logger.warning("To apply changes, run without --dry-run flag") diff --git a/src/retasc/runtime_context.py b/src/retasc/runtime_context.py index c01d86f..5e9d7dc 100644 --- a/src/retasc/runtime_context.py +++ b/src/retasc/runtime_context.py @@ -6,6 +6,7 @@ from requests import Session from retasc.jira_client import JiraClient +from retasc.models.release_rule_state import ReleaseRuleState from retasc.models.rule import Rule from retasc.product_pages_api import ProductPagesApi from retasc.report import Report @@ -22,6 +23,7 @@ class RuntimeContext: template: TemplateManager session: Session report: Report + prerequisites_state: ReleaseRuleState = ReleaseRuleState.Pending release: str = "" diff --git a/src/retasc/utils.py b/src/retasc/utils.py new file mode 100644 index 0000000..0d2f0cc --- /dev/null +++ b/src/retasc/utils.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +def to_comma_separated(items: list) -> str: + return ", ".join(sorted(repr(str(x)) for x in items)) diff --git a/tests/conftest.py b/tests/conftest.py index 1fd4550..fb569ee 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,7 +17,6 @@ def rule_dict(): {"schedule_task": "GA for rhel {{ major }}.{{ minor }}"}, {"condition": "today >= start_date + 5|days"}, ], - "jira_issues": [], } @@ -53,8 +52,9 @@ def mock_env(monkeypatch): @fixture(autouse=True) def mock_jira(): - with patch("retasc.run.JiraClient", autospec=True) as mock: - mock(ANY, token=ANY, session=ANY).search_issues.return_value = [] + with patch("retasc.run.JiraClient", autospec=True) as mock_cls: + mock = mock_cls(ANY, token=ANY, session=ANY) + mock.search_issues.return_value = [] yield mock diff --git a/tests/factory.py b/tests/factory.py index 3b1172d..c5df05a 100644 --- a/tests/factory.py +++ b/tests/factory.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later from textwrap import dedent -from retasc.models.jira_issue import JiraIssueTemplate +from retasc.models.prerequisites.jira_issue import PrerequisiteJiraIssue from retasc.models.rule import Rule @@ -13,9 +13,7 @@ def __init__(self, tmpdir, rules_dict): self.tmpdir = tmpdir self.rules_dict = rules_dict - def new_rule( - self, *, name=None, version=1, prerequisites=[], jira_issues=[], **kwargs - ): + def new_rule(self, *, name=None, version=1, prerequisites=[], **kwargs): if name is None: self.last_rule_id += 1 name = f"test_rule_{self.last_rule_id}" @@ -24,13 +22,12 @@ def new_rule( version=version, name=name, prerequisites=prerequisites, - jira_issues=jira_issues, **kwargs, ) self.rules_dict[name] = rule return rule - def new_jira_template(self, template, *, subtasks=[]): + def new_jira_issue_prerequisite(self, template, *, subtasks=[]): self.last_jira_template_id += 1 id = f"test_jira_template_{self.last_jira_template_id}" @@ -38,4 +35,6 @@ def new_jira_template(self, template, *, subtasks=[]): with open(tmp, "w") as f: f.write(dedent(template)) - return JiraIssueTemplate(id=id, template=template, subtasks=subtasks) + return PrerequisiteJiraIssue( + jira_issue_id=id, template=template, subtasks=subtasks + ) diff --git a/tests/test_main.py b/tests/test_main.py index 2343980..eecc855 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -56,7 +56,6 @@ def test_run(arg, capsys): rhel rhel-10.0 Example Rule - pending_issues: ['retasc-id-main', 'retasc-id-secondary'] condition: 'major >= 10' result: True state: Completed @@ -64,13 +63,29 @@ def test_run(arg, capsys): target_date: 1989-12-25 state: Completed rule: 'Dependent Rule 1' + schedule: 'TASK' + target_date: 1989-12-13 + state: Completed state: Completed rule: 'Dependent Rule 2' + schedule: 'TASK' + target_date: 1989-12-20 + state: Completed state: Completed + jira: 'main' + state: InProgress + jira: 'secondary' + state: InProgress state: InProgress Dependent Rule 1 + schedule: 'TASK' + target_date: 1989-12-13 + state: Completed state: Completed Dependent Rule 2 + schedule: 'TASK' + target_date: 1989-12-20 + state: Completed state: Completed """) in stdout diff --git a/tests/test_parse_rules.py b/tests/test_parse_rules.py index 375cb8d..b7b0cba 100644 --- a/tests/test_parse_rules.py +++ b/tests/test_parse_rules.py @@ -2,7 +2,7 @@ import re import yaml -from pytest import mark, raises +from pytest import fixture, mark, raises from retasc.models.parse_rules import RuleParsingError, parse_rules @@ -20,17 +20,15 @@ {"condition": "today >= start_date + 5|days"}, {"rule": "Dependent Rule 1"}, {"rule": "Dependent Rule 2"}, - ], - "jira_issues": [ { - "id": "main", + "jira_issue_id": "main", "template": "main.yaml", "subtasks": [ {"id": "main1", "template": "subtask1.yaml"}, {"id": "main2", "template": "subtask2.yaml"}, ], }, - {"id": "secondary", "template": "secondary.yaml"}, + {"jira_issue_id": "secondary", "template": "secondary.yaml"}, ], } DEPENDENT_RULES_DATA = [ @@ -41,7 +39,6 @@ {"schedule_task": "TASK"}, {"condition": "today >= start_date - 2|weeks"}, ], - "jira_issues": [], }, { "version": 1, @@ -50,11 +47,16 @@ {"schedule_task": "TASK"}, {"condition": "today >= start_date - 1|weeks"}, ], - "jira_issues": [], }, ] +@fixture +def templates_root(tmp_path, monkeypatch): + monkeypatch.setenv("RETASC_JIRA_TEMPLATES_ROOT", str(tmp_path)) + yield tmp_path + + def create_jira_templates(path): for template in JIRA_TEMPLATES: file = path / template @@ -76,12 +78,12 @@ def test_parse_rule_valid_simple(rule_path): parse_rules(str(rule_path / "other_rules.yml")) -def test_parse_rule_valid(tmp_path, rule_path): +def test_parse_rule_valid(templates_root, rule_path): file = rule_path / "rule.yaml" file.write_text(yaml.dump(RULE_DATA)) create_dependent_rules(rule_path) - create_jira_templates(tmp_path) - parse_rules(str(rule_path), templates_path=tmp_path) + create_jira_templates(templates_root) + parse_rules(str(rule_path)) def test_parse_rule_invalid(invalid_rule_file): @@ -89,20 +91,20 @@ def test_parse_rule_invalid(invalid_rule_file): parse_rules(invalid_rule_file) -def test_parse_rule_missing_dependent_rules(tmp_path, rule_path): +def test_parse_rule_missing_dependent_rules(templates_root, rule_path): file = rule_path / "rule.yaml" file.write_text(yaml.dump(RULE_DATA)) - create_jira_templates(tmp_path) + create_jira_templates(templates_root) expected_error = re.escape( f"Invalid rule 'Example Rule' (file {str(file)!r}):" "\n Dependent rule does not exist: 'Dependent Rule 1'" "\n Dependent rule does not exist: 'Dependent Rule 2'" ) with raises(RuleParsingError, match=expected_error): - parse_rules(str(rule_path), templates_path=tmp_path) + parse_rules(str(rule_path)) -def test_parse_rule_missing_jira_templates(rule_path, tmp_path): +def test_parse_rule_missing_jira_templates(rule_path, templates_root): file = rule_path / "rule.yaml" file.write_text(yaml.dump(RULE_DATA, sort_keys=False)) create_dependent_rules(rule_path) @@ -112,10 +114,39 @@ def test_parse_rule_missing_jira_templates(rule_path, tmp_path): "\n Jira issue template files not found: " ) + "[^\n]*" - + re.escape(repr(str(tmp_path / "main.yaml"))) + + re.escape(repr(str(templates_root / "main.yaml"))) + ) + with raises(RuleParsingError, match=expected_error): + parse_rules(str(rule_path)) + + +def test_parse_rule_duplicate_jira_ids(rule_path, templates_root): + file = rule_path / "rule.yaml" + rule2 = { + "version": 1, + "name": "Example Rule 2", + "prerequisites": [ + { + "jira_issue_id": "main", + "template": "main.yaml", + "subtasks": [ + {"id": "main1", "template": "subtask1.yaml"}, + ], + }, + {"jira_issue_id": "secondary", "template": "secondary.yaml"}, + ], + } + rules_data = [RULE_DATA, rule2] + file.write_text(yaml.dump(rules_data)) + create_dependent_rules(rule_path) + create_jira_templates(templates_root) + expected_error = re.escape( + f"Invalid rule 'Example Rule 2' (file {str(file)!r}):" + "\n Jira issue ID(s) already used elsewhere: 'main', 'main1'" + "\n Jira issue ID(s) already used elsewhere: 'secondary'" ) with raises(RuleParsingError, match=expected_error): - parse_rules(str(rule_path), templates_path=tmp_path) + parse_rules(str(rule_path)) def test_parse_rule_duplicate_name(rule_path, rule_dict): diff --git a/tests/test_run.py b/tests/test_run.py index 88c6f8d..819f1a4 100644 --- a/tests/test_run.py +++ b/tests/test_run.py @@ -41,15 +41,15 @@ def test_run_rule_simple(factory): assert report.data == {"rhel": {"rhel-10.0": {"rule1": {"state": "Completed"}}}} -def test_run_rule_simple_in_progress(factory): - template = factory.new_jira_template(DUMMY_ISSUE) - rule = factory.new_rule(jira_issues=[template]) +def test_run_rule_jira_issue_in_progress(factory): + jira_issue_prereq = factory.new_jira_issue_prerequisite(DUMMY_ISSUE) + rule = factory.new_rule(prerequisites=[jira_issue_prereq]) report = run(dry_run=True) assert report.data == { "rhel": { "rhel-10.0": { rule.name: { - "pending_issues": ["retasc-id-test_jira_template_1"], + "jira: 'test_jira_template_1'": {"state": "InProgress"}, "state": "InProgress", } } @@ -57,6 +57,30 @@ def test_run_rule_simple_in_progress(factory): } +def test_run_rule_jira_issue_completed(factory, mock_jira): + jira_issue_prereq = factory.new_jira_issue_prerequisite(DUMMY_ISSUE) + rule = factory.new_rule(prerequisites=[jira_issue_prereq]) + mock_jira.search_issues.return_value = [ + { + "fields": { + "labels": ["retasc-id-test_jira_template_1"], + "resolution": "Closed", + } + } + ] + report = run(dry_run=True) + assert report.data == { + "rhel": { + "rhel-10.0": { + rule.name: { + "jira: 'test_jira_template_1'": {"state": "Completed"}, + "state": "Completed", + } + } + } + } + + @mark.parametrize( ("condition_expr", "result"), ( @@ -67,9 +91,9 @@ def test_run_rule_simple_in_progress(factory): ), ) def test_run_rule_condition_disabled(condition_expr, result, factory): - template = factory.new_jira_template(DUMMY_ISSUE) + jira_issue_prereq = factory.new_jira_issue_prerequisite(DUMMY_ISSUE) condition = PrerequisiteCondition(condition=condition_expr) - rule = factory.new_rule(prerequisites=[condition], jira_issues=[template]) + rule = factory.new_rule(prerequisites=[condition, jira_issue_prereq]) report = run(dry_run=True) assert report.data == { @@ -80,7 +104,7 @@ def test_run_rule_condition_disabled(condition_expr, result, factory): "result": result, "state": "Completed" if result else "Pending", }, - "pending_issues": ["retasc-id-test_jira_template_1"], + "jira: 'test_jira_template_1'": {"state": "InProgress"}, "state": "InProgress" if result else "Pending", } } @@ -108,14 +132,10 @@ def test_run_rule_schedule_target_date(target_date, result, mock_pp, factory): end_date=datetime.now(UTC).date(), ), } - template = factory.new_jira_template(DUMMY_ISSUE) schedule = PrerequisiteSchedule(schedule_task="TASK", target_date=target_date) - rule = factory.new_rule( - prerequisites=[schedule], - jira_issues=[template], - ) + rule = factory.new_rule(prerequisites=[schedule]) - state = "InProgress" if result else "Pending" + state = "Completed" if result else "Pending" report = run(dry_run=True) assert report.data["rhel"]["rhel-10.0"][rule.name]["state"] == state @@ -139,14 +159,10 @@ def test_run_rule_schedule_params(condition_expr, result, mock_pp, factory): end_date=date(1990, 1, 3), ), } - template = factory.new_jira_template(DUMMY_ISSUE) schedule = PrerequisiteSchedule(schedule_task="TASK") condition = PrerequisiteCondition(condition=condition_expr) - rule = factory.new_rule( - prerequisites=[schedule, condition], - jira_issues=[template], - ) + rule = factory.new_rule(prerequisites=[schedule, condition]) - state = "InProgress" if result else "Pending" + state = "Completed" if result else "Pending" report = run(dry_run=True) assert report.data["rhel"]["rhel-10.0"][rule.name]["state"] == state diff --git a/tests/test_validate_rules.py b/tests/test_validate_rules.py index 8e11dde..062a304 100644 --- a/tests/test_validate_rules.py +++ b/tests/test_validate_rules.py @@ -12,7 +12,7 @@ def test_prerequisite_base(): base = PrerequisiteBase() assert base.validation_errors([]) == [] with raises(NotImplementedError): - base.state(Mock()) + base.update_state(Mock()) with raises(NotImplementedError): base.section_name()