Skip to content

Commit afec8b5

Browse files
committed
proposal
1 parent 3dc3ffd commit afec8b5

File tree

3 files changed

+84
-119
lines changed

3 files changed

+84
-119
lines changed

netcompare/arguments.py

Lines changed: 58 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,79 @@
1+
"""Classes for argument validation."""
2+
3+
# pylint: disable=too-few-public-methods
4+
5+
16
class CheckArguments:
2-
def __init__(self, *args, **kwargs):
7+
"""Class to validate arguments."""
8+
9+
@staticmethod
10+
def validate(**kwargs):
11+
"""Method to validate arguments."""
312
raise NotImplementedError
413

514

615
class CheckArgumentsExactMatch(CheckArguments):
7-
def __init__(self, *args, **kwargs):
8-
self.reference_data = getattr(kwargs, "raw_data")
16+
"""Class to validate arguments."""
17+
18+
@staticmethod
19+
def validate(**kwargs):
20+
"""Method to validate arguments."""
21+
# reference_data = getattr(kwargs, "reference_data")
922

1023

1124
class CheckArgumentsToleranceMatch(CheckArguments):
12-
def __init__(self, *args, **kwargs):
13-
self.reference_data = getattr(kwargs, "raw_data")
14-
self.tolerance = getattr(kwargs, "tolerance")
15-
if not self.tolerance:
25+
"""Class to validate arguments."""
26+
27+
@staticmethod
28+
def validate(**kwargs):
29+
"""Method to validate arguments."""
30+
# reference_data = getattr(kwargs, "reference_data")
31+
tolerance = getattr(kwargs, "tolerance")
32+
if not tolerance:
1633
raise ValueError("Tolerance argument is mandatory for Tolerance Check Type.")
17-
if not isinstance(int, self.tolerance):
18-
raise ValueError(f"Tolerance argument must be an integer, and it's {type(self.tolerance)}.")
34+
if not isinstance(int, tolerance):
35+
raise ValueError(f"Tolerance argument must be an integer, and it's {type(tolerance)}.")
1936

2037

2138
class CheckArgumentsParameterMatch(CheckArguments):
22-
MODE_OPTIONS = ["match", "no-match"]
23-
24-
def __init__(self, *args, **kwargs):
25-
self.params = getattr(kwargs, "params")
26-
if not self.params:
39+
"""Class to validate arguments."""
40+
41+
@staticmethod
42+
def validate(**kwargs):
43+
"""Method to validate arguments."""
44+
mode_options = ["match", "no-match"]
45+
params = getattr(kwargs, "params")
46+
if not params:
2747
raise ValueError("Params argument is mandatory for ParameterMatch Check Type.")
28-
if not isinstance(dict, self.params):
29-
raise ValueError(f"Params argument must be a dict, and it's {type(self.params)}.")
48+
if not isinstance(dict, params):
49+
raise ValueError(f"Params argument must be a dict, and it's {type(params)}.")
3050

31-
self.mode = getattr(kwargs, "mode")
32-
if not self.mode:
51+
mode = getattr(kwargs, "mode")
52+
if not mode:
3353
raise ValueError("Mode argument is mandatory for ParameterMatch Check Type.")
34-
if not isinstance(str, self.mode):
35-
raise ValueError(f"Mode argument must be a string, and it's {type(self.mode)}.")
36-
if self.mode not in self.MODE_OPTIONS:
37-
raise ValueError(f"Mode argument should be {self.MODE_OPTIONS}, and it's {self.mode}")
54+
if not isinstance(str, mode):
55+
raise ValueError(f"Mode argument must be a string, and it's {type(mode)}.")
56+
if mode not in mode_options:
57+
raise ValueError(f"Mode argument should be {mode_options}, and it's {mode}")
3858

3959

4060
class CheckArgumentsRegexMatch(CheckArguments):
41-
MODE_OPTIONS = ["match", "no-match"]
42-
43-
def __init__(self, *args, **kwargs):
44-
self.params = getattr(kwargs, "params")
45-
if not self.params:
46-
raise ValueError("Params argument is mandatory for Regex Match Check Type.")
47-
if not isinstance(str, self.params):
48-
raise ValueError(f"Params argument must be a string, and it's {type(self.params)}.")
49-
50-
self.mode = getattr(kwargs, "mode")
51-
if not self.mode:
52-
raise ValueError("Mode argument is mandatory for Regex Match Check Type.")
53-
if not isinstance(str, self.mode):
54-
raise ValueError(f"Mode argument must be a string, and it's {type(self.mode)}.")
55-
if self.mode not in self.MODE_OPTIONS:
56-
raise ValueError(f"Mode argument should be {self.MODE_OPTIONS}, and it's {self.mode}")
57-
58-
59-
class CheckArgumentsOptionsMatch(CheckArguments):
60-
MODE_OPTIONS = ["is-in", "???"]
61-
62-
def __init__(self, *args, **kwargs):
63-
self.params = getattr(kwargs, "params")
64-
if not self.params:
61+
"""Class to validate arguments."""
62+
63+
@staticmethod
64+
def validate(**kwargs):
65+
"""Method to validate arguments."""
66+
mode_options = ["match", "no-match"]
67+
regex = getattr(kwargs, "regex")
68+
if not regex:
6569
raise ValueError("Params argument is mandatory for Regex Match Check Type.")
66-
if not isinstance(list, self.params):
67-
raise ValueError(f"Params argument must be a list, and it's {type(self.params)}.")
70+
if not isinstance(str, regex):
71+
raise ValueError(f"Params argument must be a string, and it's {type(regex)}.")
6872

69-
self.mode = getattr(kwargs, "mode")
70-
if not self.mode:
73+
mode = getattr(kwargs, "mode")
74+
if not mode:
7175
raise ValueError("Mode argument is mandatory for Regex Match Check Type.")
72-
if not isinstance(str, self.mode):
73-
raise ValueError(f"Mode argument must be a string, and it's {type(self.mode)}.")
74-
if self.mode not in self.MODE_OPTIONS:
75-
raise ValueError(f"Mode argument should be {self.MODE_OPTIONS}, and it's {self.mode}")
76+
if not isinstance(str, mode):
77+
raise ValueError(f"Mode argument must be a string, and it's {type(mode)}.")
78+
if mode not in mode_options:
79+
raise ValueError(f"Mode argument should be {mode_options}, and it's {mode}")

netcompare/check_types.py

Lines changed: 25 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from netcompare.arguments import (
77
CheckArguments,
88
CheckArgumentsExactMatch,
9-
CheckArgumentsParameterMatch,
109
CheckArgumentsRegexMatch,
10+
CheckArgumentsParameterMatch,
1111
CheckArgumentsToleranceMatch,
1212
)
1313

@@ -20,23 +20,21 @@
2020
)
2121
from .utils.data_normalization import exclude_filter, flatten_list
2222
from .evaluators import diff_generator, parameter_evaluator, regex_evaluator
23-
from .check_types import *
23+
24+
# pylint: disable=arguments-differ
2425

2526

2627
class CheckType:
2728
"""Check Type Class."""
2829

2930
class_args = CheckArguments
3031

31-
def __init__(self, *args):
32-
"""Check Type init method."""
33-
3432
@staticmethod
3533
def init(check_type):
3634
"""Factory pattern to get the appropriate CheckType implementation.
3735
3836
Args:
39-
*args: Variable length argument list.
37+
check_type: String to define the type of check.
4038
"""
4139
if check_type == "exact_match":
4240
return ExactMatchType()
@@ -99,58 +97,42 @@ def get_value(output: Union[Mapping, List], path: str, exclude: List = None) ->
9997

10098
return values
10199

102-
def hook_evaluate(self, reference_value: CheckArguments, value_to_compare: Any) -> Tuple[Dict, bool]:
100+
def evaluate(self, value_to_compare: Any, **kwargs) -> Tuple[Dict, bool]:
103101
"""Return the result of the evaluation and a boolean True if it passes it or False otherwise.
104102
105103
This method is the one that each CheckType has to implement.
106104
107105
Args:
108-
reference_value: Can be any structured data or just a simple value.
109106
value_to_compare: Similar value as above to perform comparison.
110107
111108
Returns:
112109
tuple: Dictionary representing check result, bool indicating if differences are found.
113110
"""
114111
raise NotImplementedError
115112

116-
def evaluate(self, reference_value: dict, value_to_compare: Any) -> Tuple[Dict, bool]:
117-
118-
return self.hook_evaluate(self.args_class(reference_value), value_to_compare)
119-
120113

121114
class ExactMatchType(CheckType):
122115
"""Exact Match class docstring."""
123116

124-
args_class = CheckArgumentsExactMatch
117+
validator_class = CheckArgumentsExactMatch
125118

126-
def evaluate(self, reference_value: CheckArgumentsExactMatch, value_to_compare: Any) -> Tuple[Dict, bool]:
119+
def evaluate(self, value_to_compare: Any, reference_data: Any) -> Tuple[Dict, bool]:
127120
"""Returns the difference between values and the boolean."""
128-
evaluation_result = diff_generator(reference_value.reference_data, value_to_compare)
121+
self.validator_class.validate(reference_data=reference_data)
122+
evaluation_result = diff_generator(reference_data, value_to_compare)
129123
return evaluation_result, not evaluation_result
130124

131125

132126
class ToleranceType(CheckType):
133127
"""Tolerance class docstring."""
134128

135-
def __init__(self, *args):
136-
"""Tolerance init method."""
137-
super().__init__()
129+
validator_class = CheckArgumentsToleranceMatch
138130

139-
try:
140-
tolerance = float(args[1])
141-
except IndexError as error:
142-
raise IndexError(f"Tolerance parameter must be defined as float at index 1. You have: {args}") from error
143-
except ValueError as error:
144-
raise ValueError(f"Argument must be convertible to float. You have: {args[1]}") from error
145-
146-
self.tolerance_factor = tolerance / 100
147-
148-
def hook_evaluate(
149-
self, reference_value: CheckArgumentsToleranceMatch, value_to_compare: Mapping
150-
) -> Tuple[Dict, bool]:
131+
def evaluate(self, value_to_compare: Any, reference_data: Any, tolerance: int) -> Tuple[Dict, bool]:
151132
"""Returns the difference between values and the boolean. Overwrites method in base class."""
152-
diff = diff_generator(reference_value.reference_data, value_to_compare)
153-
self._remove_within_tolerance(diff, reference_value.tolerance)
133+
self.validator_class.validate(reference_data=reference_data, tolerance=tolerance)
134+
diff = diff_generator(reference_data, value_to_compare)
135+
self._remove_within_tolerance(diff, tolerance)
154136
return diff, not diff
155137

156138
def _remove_within_tolerance(self, diff: Dict, tolerance: int) -> None:
@@ -174,41 +156,23 @@ def _within_tolerance(*, old_value: float, new_value: float) -> bool:
174156
class ParameterMatchType(CheckType):
175157
"""Parameter Match class implementation."""
176158

177-
def hook_evaluate(
178-
self, reference_value: CheckArgumentsParameterMatch, value_to_compare: Mapping
179-
) -> Tuple[Dict, bool]:
180-
"""Parameter Match evaluator implementation."""
181-
if not isinstance(value_to_compare, dict):
182-
raise TypeError("check_option must be of type dict()")
159+
validator_class = CheckArgumentsParameterMatch
183160

184-
# TODO: update this
185-
evaluation_result = parameter_evaluator(reference_value, value_to_compare)
161+
def evaluate(self, value_to_compare: Mapping, params: Dict, mode: str) -> Tuple[Dict, bool]:
162+
"""Parameter Match evaluator implementation."""
163+
self.validator_class.validate(params=params, mode=mode)
164+
# TODO: we don't use the mode?
165+
evaluation_result = parameter_evaluator(value_to_compare, params)
186166
return evaluation_result, not evaluation_result
187167

188168

189169
class RegexType(CheckType):
190170
"""Regex Match class implementation."""
191171

192-
def hook_evaluate(
193-
self, reference_value: CheckArgumentsRegexMatch, value_to_compare: Mapping
194-
) -> Tuple[Mapping, bool]:
172+
validator_class = CheckArgumentsRegexMatch
173+
174+
def evaluate(self, value_to_compare: Mapping, regex: str, mode: str) -> Tuple[Mapping, bool]:
195175
"""Regex Match evaluator implementation."""
196-
# Check that check value_to_compare is dict.
197-
if not isinstance(value_to_compare, dict):
198-
raise TypeError("check_option must be of type dict().")
199-
200-
# Check that value_to_compare has 'regex' and 'mode' dict keys.
201-
if any(key not in value_to_compare.keys() for key in ("regex", "mode")):
202-
raise KeyError(
203-
"Regex check-type requires check-option. Example: dict(regex='.*UNDERLAY.*', mode='no-match')."
204-
)
205-
206-
# Assert that check option has 'regex' and 'mode' dict keys.\
207-
if value_to_compare["mode"] not in ["match", "no-match"]:
208-
raise ValueError(
209-
"Regex check-type requires check-option. Example: dict(regex='.*UNDERLAY.*', mode='no-match')."
210-
)
211-
212-
# TODO: update this
213-
diff = regex_evaluator(reference_value, value_to_compare)
176+
self.validator_class.validate(regex=regex, mode=mode)
177+
diff = regex_evaluator(value_to_compare, regex, mode)
214178
return diff, not diff

netcompare/evaluators.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,14 @@ def parameter_evaluator(values: Mapping, parameters: Mapping) -> Dict:
7979
return result
8080

8181

82-
def regex_evaluator(values: Mapping, parameter: Mapping) -> Dict:
82+
def regex_evaluator(values: Mapping, regex_expression: str, mode: str) -> Dict:
8383
"""Regex Match evaluator engine."""
8484
# values: [{'7.7.7.7': {'peerGroup': 'EVPN-OVERLAY-SPINE'}}]
8585
# parameter: {'regex': '.*UNDERLAY.*', 'mode': 'include'}
8686
result = {}
8787
if not isinstance(values, list):
8888
raise TypeError("Something went wrong during JMSPath parsing. 'values' must be of type List.")
8989

90-
regex_expression = parameter["regex"]
91-
mode = parameter["mode"]
92-
9390
for item in values:
9491
for founded_value in item.values():
9592
for value in founded_value.values():

0 commit comments

Comments
 (0)