Skip to content

Commit 0e3a043

Browse files
committed
feat(cli/generator): Add method to generate report type to pusher actors mapping
1 parent 80d7f8f commit 0e3a043

File tree

4 files changed

+78
-3
lines changed

4 files changed

+78
-3
lines changed

src/powerapi/cli/generator.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,14 @@ class Generator:
9595
def __init__(self, component_group_name):
9696
self.component_group_name = component_group_name
9797

98-
def generate(self, main_config: dict) -> dict[str, type[Actor]]:
98+
def generate(self, main_config: dict) -> dict[str, Actor]:
9999
"""
100100
Generate an actor class and actor start message from config dict
101101
"""
102102
if self.component_group_name not in main_config:
103103
raise PowerAPIException('Configuration error : no ' + self.component_group_name + ' specified')
104104

105105
actors = {}
106-
107106
for component_name, component_config in main_config[self.component_group_name].items():
108107
try:
109108
actors[component_name] = self._gen_actor(component_config, main_config, component_name)
@@ -112,7 +111,7 @@ def generate(self, main_config: dict) -> dict[str, type[Actor]]:
112111

113112
return actors
114113

115-
def _gen_actor(self, component_config: dict, main_config: dict, component_name: str) -> type[Actor]:
114+
def _gen_actor(self, component_config: dict, main_config: dict, component_name: str) -> Actor:
116115
raise NotImplementedError()
117116

118117

@@ -346,6 +345,25 @@ def _actor_factory(self, actor_name: str, main_config: dict, component_config: d
346345
level_logger = logging.DEBUG if main_config[GENERAL_CONF_VERBOSE_KEY] else logging.WARNING
347346
return PusherActor(actor_name, database, logger_level=level_logger)
348347

348+
def generate_report_type_to_actor_mapping(self, main_config: dict, actors: dict[str, Actor]) -> dict[type[Report], list[PusherActor]]:
349+
"""
350+
Generate the report type to actors mapping dict.
351+
:param main_config: Main configuration
352+
:param actors: Dictionary of actors (result of the `generate` method)
353+
:return: Dictionary mapping the report type to actors that should process it
354+
"""
355+
if self.component_group_name not in main_config:
356+
raise PowerAPIException(f'Configuration error: Component "{self.component_group_name}" is not defined')
357+
358+
report_type_to_actor = {}
359+
for component_name, component_config in main_config[self.component_group_name].items():
360+
try:
361+
report_type_to_actor.setdefault(component_config[COMPONENT_MODEL_KEY], []).append(actors[component_name])
362+
except KeyError as exn:
363+
raise PowerAPIException(f'Undefined parameter for "{component_name}" {self.component_group_name}') from exn
364+
365+
return report_type_to_actor
366+
349367

350368
class ProcessorGenerator(Generator):
351369
"""

tests/unit/cli/conftest.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ def several_inputs_outputs_stream_config():
6767
return load_configuration_from_json_file(file_name='several_inputs_outputs_stream_mode_enabled_configuration.json')
6868

6969

70+
@pytest.fixture
71+
def single_input_multiple_outputs_with_different_report_type():
72+
"""
73+
Configuration with several inputs and outputs and stream mode enabled
74+
"""
75+
return load_configuration_from_json_file('single_input_multiple_outputs_with_different_report_type_configuration.json')
76+
77+
7078
@pytest.fixture
7179
def several_inputs_outputs_stream_mongo_without_some_arguments_config(several_inputs_outputs_stream_config):
7280
"""

tests/unit/cli/test_generator.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from powerapi.processor.pre.k8s import K8sPreProcessorActor
3838
from powerapi.puller import PullerActor
3939
from powerapi.pusher import PusherActor
40+
from powerapi.report import PowerReport, FormulaReport
4041

4142

4243
####################
@@ -277,6 +278,20 @@ def test_generate_pusher_raise_exception_when_missing_arguments_in_opentsdb_outp
277278
generator.generate(several_inputs_outputs_stream_opentsdb_without_some_arguments_config)
278279

279280

281+
def test_generate_pusher_report_type_to_actor_mapping(single_input_multiple_outputs_with_different_report_type):
282+
"""
283+
Test generating a report type to actor mapping from a configuration having multiple outputs for different report types.
284+
"""
285+
config = single_input_multiple_outputs_with_different_report_type
286+
generator = PusherGenerator()
287+
actors = generator.generate(config)
288+
report_type_to_actor_mapping = generator.generate_report_type_to_actor_mapping(config, actors)
289+
290+
assert set(report_type_to_actor_mapping.keys()) == {PowerReport, FormulaReport}
291+
assert report_type_to_actor_mapping[PowerReport] == [actors['powerrep1'], actors['powerrep2']]
292+
assert report_type_to_actor_mapping[FormulaReport] == [actors['formularep']]
293+
294+
280295
################################
281296
# PreProcessorActorGenerator Test #
282297
################################
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"verbose": true,
3+
"stream": true,
4+
"input": {
5+
"hwpcsensor": {
6+
"model": "HWPCReport",
7+
"type": "mongodb",
8+
"uri": "mongodb://example",
9+
"db": "inputdb",
10+
"collection": "hwpcsensor"
11+
}
12+
},
13+
"output": {
14+
"powerrep1": {
15+
"type": "mongodb",
16+
"model": "PowerReport",
17+
"uri": "mongodb://example",
18+
"db": "outputdb",
19+
"collection": "powerrep"
20+
},
21+
"powerrep2": {
22+
"type": "csv",
23+
"model": "PowerReport",
24+
"directory": "/tmp/powerapi-csv-export-test"
25+
},
26+
"formularep": {
27+
"type": "mongodb",
28+
"model": "FormulaReport",
29+
"uri": "mongodb://example",
30+
"db": "outputdb",
31+
"collection": "formularep"
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)