Skip to content

Commit a353b63

Browse files
committed
PoC of profiles support
1 parent 1971d30 commit a353b63

File tree

8 files changed

+128
-0
lines changed

8 files changed

+128
-0
lines changed

fmf/base.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import fmf.context
1616
import fmf.utils as utils
1717
from fmf.utils import dict_to_yaml, log
18+
from fmf.profile import Profile
1819

1920
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2021
# Constants
@@ -794,3 +795,7 @@ def __getitem__(self, key):
794795
return self.children[key[1:]]
795796
else:
796797
return self.data[key]
798+
799+
def apply_profile(self, profile: Profile) -> None:
800+
profile.apply_rule(self)
801+

fmf/profile.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from copy import deepcopy
2+
from fmf.context import Context
3+
#from fmf.base import Tree
4+
5+
class ProfileError(Exception):
6+
pass
7+
8+
9+
class ProfileWithoutWhereStatement(ProfileError):
10+
pass
11+
12+
13+
class Profile:
14+
15+
def __init__(self, rule: dict, name = None):
16+
self._raw_rule = rule
17+
self.name = name
18+
if "where" not in self._raw_rule.keys():
19+
raise ProfileWithoutWhereStatement
20+
self.where = self._raw_rule.pop("where")
21+
self.rules = deepcopy(self._raw_rule)
22+
23+
def _check_if_fmf_node_match(self, node):
24+
context = Context(**node.data)
25+
return context.matches(self.where)
26+
27+
def _apply_rule(self, node):
28+
29+
if not self._check_if_fmf_node_match(node):
30+
return
31+
for rule in self.rules:
32+
if isinstance(rule, str) and rule.endswith("?"):
33+
rule_clear = rule[:-1]
34+
data = {rule_clear : self.rules[rule]}
35+
if rule_clear in node.data:
36+
# do not override if defined
37+
continue
38+
else:
39+
data = {rule: self.rules[rule]}
40+
node._merge_special(node.data, data)
41+
42+
def apply_rule(self, node):
43+
for item in node.climb():
44+
self._apply_rule(item)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
plan1_definition:
2+
where: execute is defined cc and discover is defined
3+
# append to prepare phase
4+
prepare+:
5+
name: some name
6+
how: shell
7+
script: systemctl start httpd
8+
# create reporting if not defined
9+
report?:
10+
how: html
11+
open: true
12+
13+
# override provision by own definition
14+
provision:
15+
how: virtual
16+
image: fedora-37
17+
18+
19+
test1_definition:
20+
where: summary is defined and test is defined
21+
new_attribute: hello world
22+
test+: appended
23+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1

tests/unit/data/profile/tree/main.fmf

Whitespace-only changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/base:
2+
summary: test plans
3+
execute:
4+
how: tmt
5+
provision:
6+
how: minute
7+
/plan0:
8+
discover:
9+
how: fmf
10+
/plan1:
11+
discover:
12+
how: shell
13+
report:
14+
how: polarion
15+
prepare:
16+
name: some name
17+
how: shell
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test: test1.sh
2+
summary: hello

tests/unit/test_profile.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from unittest import TestCase
2+
from pathlib import Path
3+
4+
import yaml
5+
6+
from fmf import Tree
7+
from fmf.profile import Profile
8+
9+
PROFILE_PATH = Path(__file__).parent / "data" / "profile"
10+
PROFILE = PROFILE_PATH / "profile_file.yaml"
11+
12+
class ProfileLoad(TestCase):
13+
def setUp(self) -> None:
14+
with PROFILE.open("r") as profile_file:
15+
self.profile_data = yaml.safe_load(profile_file)
16+
17+
def test_load(self):
18+
profiles = []
19+
for k, v in self.profile_data.items():
20+
profiles.append(Profile(v, name=k))
21+
22+
23+
class ProfileApply(TestCase):
24+
def setUp(self) -> None:
25+
with PROFILE.open("r") as profile_file:
26+
self.profile_data = yaml.safe_load(profile_file)
27+
self.profiles = []
28+
for k, v in self.profile_data.items():
29+
self.profiles.append(Profile(v, name=k))
30+
self.fmf_tree = Tree(PROFILE_PATH / "tree")
31+
32+
def test_apply_to_test(self):
33+
for profile in self.profiles:
34+
self.fmf_tree.apply_profile(profile)
35+
for item in self.fmf_tree.climb():
36+
print(item.data)

0 commit comments

Comments
 (0)