Skip to content

Commit

Permalink
sq: correct 'continue' behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszachy committed Jun 4, 2024
1 parent b600ac6 commit 3975832
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 55 deletions.
108 changes: 53 additions & 55 deletions fmf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import re
import subprocess
from io import open
from itertools import chain
from pprint import pformat as pretty
from typing import Any, Dict, Optional, Protocol

Expand Down Expand Up @@ -394,8 +393,6 @@ class describing the environment context. By default, the key
except KeyError:
rules = []

additional_rules = copy.deepcopy(additional_rules)

# Accept same type as rules from data
if additional_rules is None:
additional_rules = []
Expand All @@ -404,59 +401,60 @@ class describing the environment context. By default, the key

context.case_sensitive = case_sensitive

# Check and apply each rule
for rule in chain(rules, additional_rules):

# Rule must be a dictionary
if not isinstance(rule, dict):
raise utils.FormatError("Adjust rule should be a dictionary.")

# Missing 'when' means always enabled rule
try:
condition = rule['when']
except KeyError:
condition = True

# The optional 'continue' key should be a bool
continue_ = rule.get('continue', True)
if not isinstance(continue_, bool):
raise utils.FormatError(
"The 'continue' value should be bool, "
"got '{}'.".format(continue_))

# Apply remaining rule attributes if context matches
try:
if context.matches(condition):
if decision_callback:
decision_callback(self, rule, True)

# Remove special keys (when, because...) from the rule
apply_rule = {
key: value
for key, value in rule.items()
if key not in ADJUST_CONTROL_KEYS
}
self._merge_special(self.data, apply_rule)

# First matching rule wins, skip the rest of this set unless continue
if not continue_:
break
else:
# 'continue' has to affect only its rule_set
for rule_set in rules, additional_rules:
# Check and apply each rule
for rule in rule_set:
# Rule must be a dictionary
if not isinstance(rule, dict):
raise utils.FormatError("Adjust rule should be a dictionary.")

# Missing 'when' means always enabled rule
try:
condition = rule['when']
except KeyError:
condition = True

# The optional 'continue' key should be a bool
continue_ = rule.get('continue', True)
if not isinstance(continue_, bool):
raise utils.FormatError(
"The 'continue' value should be bool, "
"got '{}'.".format(continue_))

# Apply remaining rule attributes if context matches
try:
if context.matches(condition):
if decision_callback:
decision_callback(self, rule, True)

# Remove special keys (when, because...) from the rule
apply_rule = {
key: value
for key, value in rule.items()
if key not in ADJUST_CONTROL_KEYS
}
self._merge_special(self.data, apply_rule)

# First matching rule wins, skip the rest of this set unless continue
if not continue_:
break
else:
if decision_callback:
decision_callback(self, rule, False)
# Handle undecided rules as requested
except fmf.context.CannotDecide:
if decision_callback:
decision_callback(self, rule, False)
# Handle undecided rules as requested
except fmf.context.CannotDecide:
if decision_callback:
decision_callback(self, rule, None)

if undecided == 'skip':
continue
elif undecided == 'raise':
raise
else:
raise utils.GeneralError(
"Invalid value for the 'undecided' parameter. Should "
"be 'skip' or 'raise', got '{}'.".format(undecided))
decision_callback(self, rule, None)

if undecided == 'skip':
continue
elif undecided == 'raise':
raise
else:
raise utils.GeneralError(
"Invalid value for the 'undecided' parameter. Should "
"be 'skip' or 'raise', got '{}'.".format(undecided))

# Adjust all child nodes as well
for child in self.children.values():
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/test_adjust.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,19 @@ def test_adjusted_additional(self, mini, centos):
mini.adjust(centos, additional_rules={'enabled': True})
assert mini.get('enabled') is True

def test_adjusted_additional_after_continue(self, full, centos):
""" Additional rule is evaluated even if 'node' rule has continue:false """
full.adjust(centos,
additional_rules=[{'tag': 'foo'},
{'require': 'bar',
'continue': False,
'when': 'distro == centos'},
{'recommend': 'baz'}])
assert full.get('enabled') is False
assert full.get('tag') == 'foo'
assert full.get('require') == 'bar'
assert full.get('recommend', []) == []

def test_keep_original_adjust_rules(self, mini, centos):
original_adjust = copy.deepcopy(mini.get('adjust'))
mini.adjust(centos)
Expand Down

0 comments on commit 3975832

Please sign in to comment.