Skip to content
This repository was archived by the owner on Jan 26, 2025. It is now read-only.

Commit 63f9293

Browse files
authored
Merge pull request #6 from insight-platform/fix-labels-parsing
Updating labels parsing and validation
2 parents 180567c + fc24612 commit 63f9293

File tree

5 files changed

+105
-13
lines changed

5 files changed

+105
-13
lines changed

src/pipeline_watchdog/config/config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
from typing import List, Optional
55

66

7+
def validate_container_labels(labels: List[List[str]]):
8+
if not labels:
9+
raise ValueError(f'Container labels cannot be empty.')
10+
11+
712
class Action(Enum):
813
STOP = 'stop'
914
RESTART = 'restart'
@@ -28,6 +33,9 @@ class QueueConfig:
2833
container_labels: List[List[str]]
2934
"""List of labels to filter the containers to which the action is applied."""
3035

36+
def __post_init__(self):
37+
validate_container_labels(self.container_labels)
38+
3139

3240
@dataclass
3341
class FlowConfig:
@@ -48,6 +56,9 @@ class FlowConfig:
4856
container_labels: List[List[str]]
4957
"""List of labels to filter the containers to which the action is applied."""
5058

59+
def __post_init__(self):
60+
validate_container_labels(self.container_labels)
61+
5162

5263
@dataclass
5364
class WatchConfig:

src/pipeline_watchdog/config/parser.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ def __init__(self, config_path: str):
1212

1313
@staticmethod
1414
def __parse_labels(labels_list: list) -> list:
15-
labels = []
16-
for label_dict in labels_list:
17-
if isinstance(label_dict.labels, ListConfig):
18-
labels.append(label_dict.labels)
19-
else:
20-
labels.append([label_dict.labels])
21-
return labels
15+
container_labels = []
16+
for label_dict in OmegaConf.to_object(labels_list):
17+
labels = label_dict.get('labels')
18+
if labels is not None:
19+
if isinstance(labels, list):
20+
container_labels.append(labels)
21+
else:
22+
container_labels.append([labels])
23+
return container_labels
2224

2325
@staticmethod
2426
def __parse_queue_config(queue_config: dict):

tests/config/test_parser.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22

33
import pytest
4+
from omegaconf import ListConfig
45

56
from src.pipeline_watchdog.config import WatchConfig
67
from src.pipeline_watchdog.config.parser import ConfigParser
@@ -14,6 +15,27 @@ def test_parse(config_file_path, watch_config):
1415
assert len(config.watch_configs) == 2
1516
assert config.watch_configs[0] == watch_config
1617

18+
# check that OmegaConf types are properly converted
19+
assert not any(
20+
isinstance(labels, ListConfig)
21+
for container_labels in [
22+
config.watch_configs[0].queue.container_labels,
23+
config.watch_configs[0].egress.container_labels,
24+
config.watch_configs[0].ingress.container_labels,
25+
]
26+
for labels in container_labels
27+
)
28+
assert all(
29+
isinstance(label, str)
30+
for container_labels in [
31+
config.watch_configs[0].queue.container_labels,
32+
config.watch_configs[0].egress.container_labels,
33+
config.watch_configs[0].ingress.container_labels,
34+
]
35+
for labels in container_labels
36+
for label in labels
37+
)
38+
1739
# check optional fields
1840
assert config.watch_configs[1] == WatchConfig(
1941
buffer='buffer2:8002', queue=None, egress=None, ingress=None
@@ -34,3 +56,11 @@ def test_parse_invalid(invalid_config_file_path):
3456
match='Field ".*" must be specified in the watch config.',
3557
):
3658
ConfigParser(invalid_config_file_path).parse()
59+
60+
61+
def test_parse_empty_labels(invalid_config_with_empty_labels):
62+
with pytest.raises(
63+
ValueError,
64+
match='Container labels cannot be empty.',
65+
):
66+
ConfigParser(invalid_config_with_empty_labels).parse()

tests/conftest.py

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,7 @@ def config_file_path():
8888
)
8989
)
9090
def empty_config_file_path(request, tmpdir):
91-
config_file = tmpdir.join('empty_config.txt')
92-
config_file.write(request.param)
93-
94-
return str(config_file)
91+
return create_tmp_config_file(tmpdir, request.param)
9592

9693

9794
@pytest.fixture(
@@ -103,9 +100,61 @@ def empty_config_file_path(request, tmpdir):
103100
)
104101
)
105102
def invalid_config_file_path(request, tmpdir):
103+
return create_tmp_config_file(tmpdir, request.param)
104+
105+
106+
@pytest.fixture(
107+
params=(
108+
{
109+
'watch': [
110+
{
111+
'buffer': 'buffer1:8000',
112+
'queue': {
113+
'action': 'restart',
114+
'length': 18,
115+
'cooldown': '60s',
116+
'polling_interval': '10s',
117+
'container': [],
118+
},
119+
}
120+
]
121+
},
122+
{
123+
'watch': [
124+
{
125+
'buffer': 'buffer1:8000',
126+
'egress': {
127+
'action': 'restart',
128+
'idle': '100s',
129+
'cooldown': '60s',
130+
'container': [],
131+
},
132+
}
133+
]
134+
},
135+
{
136+
'watch': [
137+
{
138+
'buffer': 'buffer1:8000',
139+
'ingress': {
140+
'action': 'restart',
141+
'idle': '100s',
142+
'cooldown': '60s',
143+
'container': [],
144+
},
145+
}
146+
]
147+
},
148+
)
149+
)
150+
def invalid_config_with_empty_labels(request, tmpdir):
151+
return create_tmp_config_file(tmpdir, request.param)
152+
153+
154+
def create_tmp_config_file(tmpdir, config):
106155
config_file = tmpdir.join('empty_config.txt')
107156

108-
yaml_str = yaml.dump(request.param)
157+
yaml_str = yaml.dump(config)
109158
config_file.write(yaml_str)
110159

111160
return str(config_file)

tests/test_config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ watch:
1515
polling_interval: ${oc.env:POLLING_INTERVAL}
1616
container:
1717
- labels: egress-label=egress-value
18-
- labels: some-label
18+
- labels: [some-label]
1919
ingress:
2020
action: restart
2121
cooldown: 30s

0 commit comments

Comments
 (0)