|
27 | 27 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 | 28 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
|
30 | | -import copy |
| 30 | +from unittest.mock import Mock |
31 | 31 |
|
32 | 32 | import pytest |
33 | 33 |
|
| 34 | +from powerapi.actor import ActorProxy |
34 | 35 | from powerapi.cli.binding_manager import PreProcessorBindingManager |
35 | | -from powerapi.exception import UnsupportedActorTypeException, UnexistingActorException, TargetActorAlreadyUsed |
| 36 | +from powerapi.cli.generator import PreProcessorGenerator, PullerGenerator |
| 37 | +from powerapi.dispatcher import DispatcherActor |
| 38 | +from powerapi.exception import UnexistingActorException, UnsupportedActorTypeException, TargetActorAlreadyUsed |
| 39 | +from powerapi.filter import BroadcastReportFilter |
| 40 | +from powerapi.processor.processor_actor import PreProcessorActor, ProcessorActor |
| 41 | +from powerapi.puller import PullerActor |
36 | 42 |
|
37 | 43 |
|
38 | | -def test_create_pre_processor_binding_manager_with_actors(pre_processor_complete_configuration, pre_processor_pullers_and_processors_dictionaries): |
| 44 | +class NoopPreprocessor(PreProcessorActor): |
39 | 45 | """ |
40 | | - Test that a PreProcessorBindingManager is correctly created when an actor and a processor dictionary are provided |
| 46 | + Pre-processor actor that does nothing, for testing purposes. |
41 | 47 | """ |
42 | | - expected_actors_dictionary = copy.copy(pre_processor_pullers_and_processors_dictionaries[0]) |
43 | | - expected_processors_dictionary = copy.copy(pre_processor_pullers_and_processors_dictionaries[1]) |
44 | 48 |
|
45 | | - binding_manager = PreProcessorBindingManager( |
46 | | - config=pre_processor_complete_configuration, |
47 | | - pullers=pre_processor_pullers_and_processors_dictionaries[0], |
48 | | - processors=pre_processor_pullers_and_processors_dictionaries[1] |
49 | | - ) |
50 | 49 |
|
51 | | - assert binding_manager.actors == expected_actors_dictionary |
52 | | - assert binding_manager.processors == expected_processors_dictionary |
| 50 | +@pytest.fixture |
| 51 | +def preprocessor_config(): |
| 52 | + """ |
| 53 | + Fixture that provides a configuration with a socket puller and a no-op pre-processor. |
| 54 | + """ |
| 55 | + return { |
| 56 | + 'verbose': True, |
| 57 | + 'stream': True, |
| 58 | + 'input': { |
| 59 | + 'pytest-socket-puller': { |
| 60 | + 'type': 'socket', |
| 61 | + 'model': 'HWPCReport', |
| 62 | + 'host': 'localhost', |
| 63 | + 'port': 8889 |
| 64 | + } |
| 65 | + }, |
| 66 | + 'pre-processor': { |
| 67 | + 'pytest-noop-preprocessor': { |
| 68 | + 'type': 'noop', |
| 69 | + 'puller': 'pytest-socket-puller' |
| 70 | + } |
| 71 | + } |
| 72 | + } |
53 | 73 |
|
54 | 74 |
|
55 | | -def test_create_processor_binding_manager_without_actors(): |
| 75 | +@pytest.fixture |
| 76 | +def puller_generator() -> PullerGenerator: |
56 | 77 | """ |
57 | | - Test that a ProcessorBindingManager is correctly created without a dictionary |
| 78 | + Fixture that provides a generator for the puller actors. |
58 | 79 | """ |
59 | | - binding_manager = PreProcessorBindingManager(config={}, pullers=None, processors=None) |
| 80 | + report_filter = BroadcastReportFilter() |
| 81 | + report_filter.register(lambda _: True, Mock(actor_name='pytest-dispatcher', actor_type=DispatcherActor, spec=ActorProxy)) |
60 | 82 |
|
61 | | - assert len(binding_manager.actors) == 0 |
62 | | - assert len(binding_manager.processors) == 0 |
| 83 | + generator = PullerGenerator(report_filter) |
| 84 | + return generator |
63 | 85 |
|
64 | 86 |
|
65 | | -def test_process_bindings_for_pre_processor(pre_processor_complete_configuration, pre_processor_pullers_and_processors_dictionaries): |
| 87 | +@pytest.fixture |
| 88 | +def preprocessor_generator() -> PreProcessorGenerator: |
66 | 89 | """ |
67 | | - Test that the bindings between a puller and a processor are correctly created |
| 90 | + Fixture to return a preprocessor generator with the noop preprocessor available. |
68 | 91 | """ |
69 | | - pullers = pre_processor_pullers_and_processors_dictionaries[0] |
70 | | - processors = pre_processor_pullers_and_processors_dictionaries[1] |
71 | | - binding_manager = PreProcessorBindingManager(pre_processor_complete_configuration, pullers, processors) |
72 | | - |
73 | | - dispatchers = list(pullers['one_puller'].report_filter.dispatchers()) |
74 | | - assert len(dispatchers) == 1 |
75 | | - assert dispatchers[0].actor_name == 'dispatcher' |
| 92 | + generator = PreProcessorGenerator() |
76 | 93 |
|
77 | | - binding_manager.process_bindings() |
78 | | - |
79 | | - dispatchers = list(pullers['one_puller'].report_filter.dispatchers()) |
80 | | - assert len(dispatchers) == 1 |
81 | | - assert dispatchers[0].actor_name == 'my_processor' |
| 94 | + def _noop_processor_factory(_) -> ProcessorActor: |
| 95 | + return NoopPreprocessor('pytest-noop-preprocessor') |
82 | 96 |
|
83 | | - assert len(processors['my_processor'].target_actors) == 1 |
84 | | - assert processors['my_processor'].target_actors[0].actor_name == 'dispatcher' |
| 97 | + generator.add_processor_factory('noop', _noop_processor_factory) |
| 98 | + return generator |
85 | 99 |
|
86 | 100 |
|
87 | | -def test_process_bindings_for_pre_processor_raise_exception_with_wrong_binding_types(pre_processor_binding_manager_with_wrong_binding_types): |
| 101 | +def test_preprocessor_binding_manager_replace_puller_target(puller_generator, preprocessor_generator, preprocessor_config): |
88 | 102 | """ |
89 | | - Test that an exception is raised with a wrong type for the from actor in a binding |
| 103 | + The binding manager should replace the target of the puller actor from a dispatcher actor to the pre-processor actor. |
90 | 104 | """ |
| 105 | + pullers = puller_generator.generate(preprocessor_config) |
| 106 | + processors = preprocessor_generator.generate(preprocessor_config) |
| 107 | + binding_manager = PreProcessorBindingManager(preprocessor_config, pullers, processors) |
91 | 108 |
|
92 | | - with pytest.raises(UnsupportedActorTypeException): |
93 | | - pre_processor_binding_manager_with_wrong_binding_types.process_bindings() |
| 109 | + puller = pullers['pytest-socket-puller'] |
| 110 | + assert isinstance(puller, PullerActor) |
94 | 111 |
|
| 112 | + puller_target_proxy, = puller.report_filter.dispatchers() |
| 113 | + assert issubclass(puller_target_proxy.actor_type, DispatcherActor) |
| 114 | + assert puller_target_proxy.actor_name == 'pytest-dispatcher' |
95 | 115 |
|
96 | | -def test_process_bindings_for_pre_processor_raise_exception_with_no_existing_puller( |
97 | | - pre_processor_binding_manager_with_unexisting_puller): |
98 | | - """ |
99 | | - Test that an exception is raised with a puller that doesn't exist |
100 | | - """ |
| 116 | + binding_manager.process_bindings() |
101 | 117 |
|
102 | | - with pytest.raises(UnexistingActorException): |
103 | | - pre_processor_binding_manager_with_unexisting_puller.process_bindings() |
| 118 | + puller_target_proxy, = puller.report_filter.dispatchers() |
| 119 | + assert issubclass(puller_target_proxy.actor_type, PreProcessorActor) |
| 120 | + assert puller_target_proxy.actor_name == 'pytest-noop-preprocessor' |
104 | 121 |
|
105 | 122 |
|
106 | | -def test_process_bindings_for_pre_processor_raise_exception_with_reused_puller_in_bindings( |
107 | | - pre_processor_binding_manager_with_reused_puller_in_bindings): |
| 123 | +def test_preprocessor_binding_manager_with_empty_preprocessor_config(puller_generator, preprocessor_config): |
108 | 124 | """ |
109 | | - Test that an exception is raised when the same puller is used by several processors |
| 125 | + The binding manager should not replace the target of the puller actor when there is no pre-processor configuration. |
110 | 126 | """ |
| 127 | + preprocessor_config['pre-processor'] = {} |
111 | 128 |
|
112 | | - with pytest.raises(TargetActorAlreadyUsed): |
113 | | - pre_processor_binding_manager_with_reused_puller_in_bindings.process_bindings() |
| 129 | + pullers = puller_generator.generate(preprocessor_config) |
| 130 | + processors = {} |
| 131 | + binding_manager = PreProcessorBindingManager(preprocessor_config, pullers, processors) |
114 | 132 |
|
| 133 | + puller = pullers['pytest-socket-puller'] |
| 134 | + assert isinstance(puller, PullerActor) |
115 | 135 |
|
116 | | -def test_check_processors_targets_are_unique_raise_exception_with_reused_puller_in_bindings( |
117 | | - pre_processor_binding_manager_with_reused_puller_in_bindings): |
118 | | - """ |
119 | | - Test that an exception is raised when the same puller is used by several processors |
120 | | - """ |
121 | | - with pytest.raises(TargetActorAlreadyUsed): |
122 | | - pre_processor_binding_manager_with_reused_puller_in_bindings.check_processors_targets_are_unique() |
| 136 | + puller_target_proxy, = puller.report_filter.dispatchers() |
| 137 | + assert issubclass(puller_target_proxy.actor_type, DispatcherActor) |
| 138 | + assert puller_target_proxy.actor_name == 'pytest-dispatcher' |
123 | 139 |
|
| 140 | + binding_manager.process_bindings() |
124 | 141 |
|
125 | | -def test_check_processors_targets_are_unique_pass_without_reused_puller_in_bindings( |
126 | | - pre_processor_binding_manager): |
127 | | - """ |
128 | | - Test that a correct without repeated target passes the validation |
129 | | - """ |
130 | | - try: |
131 | | - pre_processor_binding_manager.check_processors_targets_are_unique() |
132 | | - except TargetActorAlreadyUsed: |
133 | | - pytest.fail("Processors targets are not unique") |
| 142 | + puller_target_proxy, = puller.report_filter.dispatchers() |
| 143 | + assert issubclass(puller_target_proxy.actor_type, DispatcherActor) |
| 144 | + assert puller_target_proxy.actor_name == 'pytest-dispatcher' |
134 | 145 |
|
135 | 146 |
|
136 | | -def check_all_processors_targets(preprocessor_binding_manager: PreProcessorBindingManager): |
| 147 | +def test_preprocessor_binding_manager_with_invalid_puller_name(puller_generator, preprocessor_generator, preprocessor_config): |
137 | 148 | """ |
138 | | - Helper function that checks the processors targets of the given binding manager. |
| 149 | + The binding manager should raise an exception when the puller name of the pre-processor is invalid. |
139 | 150 | """ |
140 | | - for processor_name, processor in preprocessor_binding_manager.processors.items(): |
141 | | - preprocessor_binding_manager.check_processor_targets(processor_name, processor) |
| 151 | + preprocessor_config['pre-processor']['pytest-noop-preprocessor']['puller'] = 'invalid-puller-target' |
142 | 152 |
|
| 153 | + pullers = puller_generator.generate(preprocessor_config) |
| 154 | + processors = preprocessor_generator.generate(preprocessor_config) |
| 155 | + binding_manager = PreProcessorBindingManager(preprocessor_config, pullers, processors) |
143 | 156 |
|
144 | | -def test_check_processor_targets_raise_exception_with_no_existing_puller(pre_processor_binding_manager_with_unexisting_puller): |
145 | | - """ |
146 | | - Test that an exception is raised with a puller that doesn't exist |
147 | | - """ |
148 | 157 | with pytest.raises(UnexistingActorException): |
149 | | - check_all_processors_targets(pre_processor_binding_manager_with_unexisting_puller) |
| 158 | + binding_manager.process_bindings() |
150 | 159 |
|
151 | 160 |
|
152 | | -def test_check_processor_targets_raise_exception_with_raise_exception_with_wrong_binding_types(pre_processor_binding_manager_with_wrong_binding_types): |
| 161 | +def test_preprocessor_binding_manager_with_invalid_puller_type(puller_generator, preprocessor_generator, preprocessor_config): |
153 | 162 | """ |
154 | | - Test that an exception is raised with a puller that doesn't exist |
| 163 | + The binding manager should raise an exception when the puller type of the pre-processor is invalid. |
155 | 164 | """ |
| 165 | + pullers = puller_generator.generate(preprocessor_config) |
| 166 | + pullers['pytest-socket-puller'] = Mock(name='pytest-socket-puller') |
| 167 | + |
| 168 | + processors = preprocessor_generator.generate(preprocessor_config) |
| 169 | + binding_manager = PreProcessorBindingManager(preprocessor_config, pullers, processors) |
| 170 | + |
156 | 171 | with pytest.raises(UnsupportedActorTypeException): |
157 | | - check_all_processors_targets(pre_processor_binding_manager_with_wrong_binding_types) |
| 172 | + binding_manager.process_bindings() |
158 | 173 |
|
159 | 174 |
|
160 | | -def test_check_processor_targets_pass_with_correct_targets(pre_processor_binding_manager): |
| 175 | +def test_preprocessor_binding_manager_with_duplicate_target(puller_generator, preprocessor_generator, preprocessor_config): |
161 | 176 | """ |
162 | | - Test that validation of a configuration with existing targets of the correct type |
| 177 | + The binding manager should raise an exception when multiple pre-processor have the same target. |
163 | 178 | """ |
164 | | - try: |
165 | | - check_all_processors_targets(pre_processor_binding_manager) |
166 | | - except UnsupportedActorTypeException as e: |
167 | | - pytest.fail(f'Unsupported actor type: {e}') |
168 | | - except UnexistingActorException as e: |
169 | | - pytest.fail(f'Actor does not exist: {e}') |
| 179 | + pre_processors = preprocessor_config['pre-processor'] |
| 180 | + pre_processors['pytest-noop-preprocessor-duplicate'] = pre_processors['pytest-noop-preprocessor'] |
| 181 | + |
| 182 | + pullers = puller_generator.generate(preprocessor_config) |
| 183 | + processors = preprocessor_generator.generate(preprocessor_config) |
| 184 | + binding_manager = PreProcessorBindingManager(preprocessor_config, pullers, processors) |
| 185 | + |
| 186 | + with pytest.raises(TargetActorAlreadyUsed): |
| 187 | + binding_manager.process_bindings() |
0 commit comments