From 5fd2add9bd141d54041890b8a697cfeda37f9c86 Mon Sep 17 00:00:00 2001 From: ekneg54 Date: Thu, 26 Sep 2024 18:46:01 +0200 Subject: [PATCH] add ResultDocumentation --- logprep/abc/processor.py | 15 +++ logprep/framework/pipeline.py | 38 +++++-- tests/unit/framework/test_pipeline.py | 138 +++++++++++++++++++++++++- 3 files changed, 182 insertions(+), 9 deletions(-) diff --git a/logprep/abc/processor.py b/logprep/abc/processor.py index 34243a479..b1980baed 100644 --- a/logprep/abc/processor.py +++ b/logprep/abc/processor.py @@ -37,6 +37,21 @@ class ProcessorResult: """ Result object to be returned by every processor. It contains the processor name, created data and errors (incl. warnings). + + Parameters + ---------- + + + processor_name : str + The name of the processor + event: Optional[dict] + A reference to the event that was processed + data : Optional[list] + The generated extra data + errors : Optional[list] + The errors that occurred during processing + warnings : Optional[list] + The warnings that occurred during processing """ data: list = field(validator=validators.instance_of(list), factory=list) diff --git a/logprep/framework/pipeline.py b/logprep/framework/pipeline.py index c20a211d0..4f774190f 100644 --- a/logprep/framework/pipeline.py +++ b/logprep/framework/pipeline.py @@ -48,24 +48,48 @@ @attrs.define(kw_only=True) class PipelineResult: """Result object to be returned after processing the event. - It contains all results of each processor of the pipeline.""" + It contains all results of each processor of the pipeline. + + Parameters + ---------- + + event : dict + The event that was processed + pipeline : List[Processor] + The pipeline that processed the event + + Returns + ------- + PipelineResult + The result object + """ results: List[ProcessorResult] = attrs.field( validator=[ - attrs.validators.instance_of((list, Generator)), + attrs.validators.instance_of(list), attrs.validators.deep_iterable( member_validator=attrs.validators.instance_of(ProcessorResult) ), - ] + ], + init=False, ) - """List of ProcessorResults""" + """List of ProcessorResults. Is populated in __attrs_post_init__""" event: dict = attrs.field(validator=attrs.validators.instance_of(dict)) """The event that was processed""" event_received: dict = attrs.field( validator=attrs.validators.instance_of(dict), converter=copy.deepcopy ) """The event that was received""" - pipeline: list[Processor] + + pipeline: list[Processor] = attrs.field( + validator=[ + attrs.validators.deep_iterable( + member_validator=attrs.validators.instance_of(Processor), + iterable_validator=attrs.validators.instance_of(list), + ), + attrs.validators.min_len(1), + ] + ) """The pipeline that processed the event""" @cached_property @@ -84,9 +108,7 @@ def data(self) -> List[Tuple[dict, dict]]: return list(itertools.chain(*[result.data for result in self])) def __attrs_post_init__(self): - self.results = list( - (processor.process(self.event) for processor in self.pipeline if self.event) - ) + self.results = [processor.process(self.event) for processor in self.pipeline if self.event] def __iter__(self): return iter(self.results) diff --git a/tests/unit/framework/test_pipeline.py b/tests/unit/framework/test_pipeline.py index 70f6b944b..c01db1509 100644 --- a/tests/unit/framework/test_pipeline.py +++ b/tests/unit/framework/test_pipeline.py @@ -25,7 +25,7 @@ Output, OutputWarning, ) -from logprep.abc.processor import ProcessorResult +from logprep.abc.processor import Processor, ProcessorResult from logprep.factory import Factory from logprep.framework.pipeline import Pipeline, PipelineResult from logprep.processor.base.exceptions import ( @@ -68,6 +68,13 @@ def get_mock_create(): return mock_create +@pytest.fixture(name="mock_processor") +def get_mock_processor(): + mock_processor = mock.create_autospec(spec=Processor) + mock_processor.process.return_value = mock.create_autospec(spec=ProcessorResult) + return mock_processor + + @mock.patch("logprep.factory.Factory.create", new_callable=get_mock_create) class TestPipeline(ConfigurationForTests): def setup_method(self): @@ -743,3 +750,132 @@ def test_health_returns_health_functions_with_multiple_outputs(self): assert isinstance(health, Tuple) assert len(health) > 0 assert all(callable(health_function) for health_function in health) + + +class TestPipelineResult: + + @pytest.mark.parametrize( + "parameters, error, message", + [ + ( + { + "event": {"some": "event"}, + "pipeline": [], + }, + ValueError, + "Length of 'pipeline' must be >= 1", + ), + ( + { + "event": {"some": "event"}, + "pipeline": [], + "results": [], + }, + TypeError, + "got an unexpected keyword argument 'results'", + ), + ( + { + "event": {"some": "event"}, + "pipeline": [ + Factory.create( + { + "dummy": { + "type": "dropper", + "specific_rules": [], + "generic_rules": [], + } + } + ) + ], + "results": [], + }, + TypeError, + "got an unexpected keyword argument 'results'", + ), + ( + { + "event": {"some": "event"}, + "pipeline": [ + Factory.create( + { + "dummy": { + "type": "dropper", + "specific_rules": [], + "generic_rules": [], + } + } + ) + ], + }, + None, + None, + ), + ( + { + "event": {"some": "event"}, + "pipeline": [ + mock.MagicMock(), + ], + }, + TypeError, + "'pipeline' must be