Skip to content

Commit 74158fb

Browse files
authored
Merge pull request #3 from networktocode-llc/api-refactor
Fix tests
2 parents 3671f07 + e48ca3a commit 74158fb

File tree

6 files changed

+47
-101
lines changed

6 files changed

+47
-101
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ stages:
44
- "lint"
55
- "test"
66

7-
if: "type IN (pull_request)" # Add in "branch" as an option if desired for branch testing as well
7+
if: "type IN (pull_request)" # Add in "branch" as an option if desired for branch testing as well
88
language: "python"
99
services:
1010
- "docker"
@@ -30,7 +30,7 @@ jobs:
3030
- "pip install invoke toml"
3131
script:
3232
- "invoke black"
33-
- "invoke bandit" # Bandit fails to function on > Py3.8 https://github.com/PyCQA/bandit/issues/639
33+
- "invoke bandit" # Bandit fails to function on > Py3.8 https://github.com/PyCQA/bandit/issues/639
3434
# - "invoke pydocstyle"
3535
- "invoke flake8"
3636
- "invoke yamllint"

netcompare/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Pre/Post Check library."""
2-
from .check_type import compare
2+
# from .check_type import compare
33

44

5-
__all__ = ["compare"]
5+
# __all__ = ["compare"]

netcompare/check_type.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""CheckType Implementation."""
2-
from typing import Mapping, Iterable, Tuple, Union, List
2+
from typing import Mapping, Tuple, Union, List
33
from .evaluator import diff_generator
44
from .runner import extract_values_from_output
55

@@ -29,6 +29,7 @@ def extract_value_from_json_path(
2929
"""Return the value contained into a Mapping for a defined path."""
3030
return extract_values_from_output(value, path, exclude)
3131

32+
# TODO: Refine this typing
3233
def evaluate(self, reference_value: Mapping, value_to_compare: Mapping) -> Tuple[Mapping, bool]:
3334
"""Return the result of the evaluation and a boolean True if it passes it or False otherwise.
3435

netcompare/evaluator.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,17 @@
77
from functools import partial
88
from typing import Mapping, List
99

10-
from .runner import extract_values_from_output
1110

1211
sys.path.append(".")
1312

1413

15-
def diff_generator(pre_data: Mapping, post_data: Mapping, check_definition: Mapping) -> Mapping:
14+
def diff_generator(pre_result: Mapping, post_result: Mapping) -> Mapping:
1615
"""
1716
Generates diff between pre and post data based on check definition.
1817
1918
Args:
20-
pre_data: pre data result.
21-
post_data: post data result.
22-
check_definition: check definitions.
19+
pre_result: pre data result.
20+
post_result: post data result.
2321
2422
Return:
2523
output: diff between pre and post data.
@@ -32,9 +30,6 @@ def diff_generator(pre_data: Mapping, post_data: Mapping, check_definition: Mapp
3230
>>> print(diff_generator(check_definition, post_data, check_definition))
3331
{'10.17.254.2': {'state': {'new_value': 'Up', 'old_value': 'Idle'}}}
3432
"""
35-
pre_result = extract_values_from_output(check_definition, pre_data)
36-
post_result = extract_values_from_output(check_definition, post_data)
37-
3833
diff_result = DeepDiff(pre_result, post_result)
3934

4035
result = diff_result.get("values_changed", {})

tests/test_diff_generator.py

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
from .utility import load_json_file
66
from netcompare.evaluator import diff_generator
7+
from netcompare.runner import extract_values_from_output
78

89
sys.path.append("..")
910

@@ -13,67 +14,40 @@
1314
expected output: {expected_output}
1415
"""
1516

16-
exact_match_of_global_peers_via_napalm_getter = (
17-
"napalm_getter.json",
18-
{
19-
"check_type": "exact_match",
20-
"path": "global.$peers$.*.[is_enabled,is_up]",
21-
# "reference_key_path": "global.peers",
22-
},
23-
)
17+
exact_match_of_global_peers_via_napalm_getter = ("napalm_getter.json", "global.$peers$.*.[is_enabled,is_up]", [])
2418

2519
exact_match_of_bgpPeerCaps_via_api = (
2620
"api.json",
27-
{
28-
"check_type": "exact_match",
29-
"path": "result[0].vrfs.default.peerList[*].[$peerAddress$,state,bgpPeerCaps]",
30-
# "reference_key_path": "result[0].vrfs.default.peerList[*].peerAddress",
31-
},
21+
"result[0].vrfs.default.peerList[*].[$peerAddress$,state,bgpPeerCaps]",
22+
[],
3223
)
3324

34-
exact_match_of_bgp_neigh_via_textfsm = (
35-
"textfsm.json",
36-
{
37-
"check_type": "exact_match",
38-
"path": "result[*].[$bgp_neigh$,state]",
39-
# "reference_key_path": "result[*].bgp_neigh"
40-
},
41-
)
25+
exact_match_of_bgp_neigh_via_textfsm = ("textfsm.json", "result[*].[$bgp_neigh$,state]", [])
4226

4327
raw_diff_of_interface_ma1_via_api_value_exclude = (
4428
"raw_value_exclude.json",
45-
{"check_type": "exact_match", "path": "result[*]", "exclude": ["interfaceStatistics", "interfaceCounters"]},
29+
"result[*]",
30+
["interfaceStatistics", "interfaceCounters"],
4631
)
4732

4833
raw_diff_of_interface_ma1_via_api_novalue_exclude = (
4934
"raw_novalue_exclude.json",
50-
{"check_type": "exact_match", "exclude": ["interfaceStatistics", "interfaceCounters"]},
35+
None,
36+
["interfaceStatistics", "interfaceCounters"],
5137
)
5238

53-
raw_diff_of_interface_ma1_via_api_novalue_noexclude = (
54-
"raw_novalue_noexclude.json",
55-
{"check_type": "exact_match"},
56-
)
39+
raw_diff_of_interface_ma1_via_api_novalue_noexclude = ("raw_novalue_noexclude.json", None, [])
5740

58-
exact_match_missing_item = (
59-
"napalm_getter_missing_peer.json",
60-
{"check_type": "exact_match"},
61-
)
41+
exact_match_missing_item = ("napalm_getter_missing_peer.json", None, [])
6242

63-
exact_match_additional_item = ("napalm_getter_additional_peer.json", {"check_type": "exact_match"})
43+
exact_match_additional_item = ("napalm_getter_additional_peer.json", None, [])
6444

65-
exact_match_changed_item = (
66-
"napalm_getter_changed_peer.json",
67-
{"check_type": "exact_match"},
68-
)
45+
exact_match_changed_item = ("napalm_getter_changed_peer.json", None, [])
6946

7047
exact_match_multi_nested_list = (
7148
"exact_match_nested.json",
72-
{
73-
"check_type": "exact_match",
74-
"path": "global.$peers$.*.*.ipv4.[accepted_prefixes,received_prefixes]",
75-
# "reference_key_path": "global.peers",
76-
},
49+
"global.$peers$.*.*.ipv4.[accepted_prefixes,received_prefixes]",
50+
[],
7751
)
7852

7953
eval_tests = [
@@ -90,13 +64,14 @@
9064
]
9165

9266

93-
@pytest.mark.parametrize("filename, path", eval_tests)
94-
def test_eval(filename, path):
67+
@pytest.mark.parametrize("filename, path, exclude", eval_tests)
68+
def test_eval(filename, path, exclude):
9569

9670
pre_data = load_json_file("pre", filename)
9771
post_data = load_json_file("post", filename)
9872
expected_output = load_json_file("results", filename)
99-
100-
output = diff_generator(pre_data, post_data, path)
73+
pre_value = extract_values_from_output(pre_data, path, exclude)
74+
post_value = extract_values_from_output(post_data, path, exclude)
75+
output = diff_generator(pre_value, post_value)
10176

10277
assert expected_output == output, assertion_failed_message.format(output=output, expected_output=expected_output)

tests/test_type_check.py

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,17 @@ def test_CheckType_raises_NotImplementedError_for_invalid_check_type():
2121
CheckType.init("does_not_exist")
2222

2323

24-
def test_CheckType_raises_NotImplementedError_when_calling_check_logic_method():
25-
"""Validate that CheckType raises a NotImplementedError when passed a non-existant check_type."""
26-
with pytest.raises(NotImplementedError):
27-
CheckType().check_logic()
28-
29-
3024
exact_match_test_values_no_change = (
3125
("exact_match",),
3226
"api.json",
33-
{
34-
"path": "result[0].vrfs.default.peerList[*].[$peerAddress$,establishedTransitions]",
35-
# "reference_key_path": "result[0].vrfs.default.peerList[*].peerAddress",
36-
},
27+
"result[0].vrfs.default.peerList[*].[$peerAddress$,establishedTransitions]",
3728
({}, True),
3829
)
3930

4031
exact_match_test_values_changed = (
4132
("exact_match",),
4233
"api.json",
43-
{
44-
"path": "result[0].vrfs.default.peerList[*].[$peerAddress$,prefixesSent]",
45-
# "reference_key_path": "result[0].vrfs.default.peerList[*].peerAddress",
46-
},
34+
"result[0].vrfs.default.peerList[*].[$peerAddress$,prefixesSent]",
4735
(
4836
{
4937
"10.1.0.0": {"prefixesSent": {"new_value": 52, "old_value": 50}},
@@ -56,30 +44,21 @@ def test_CheckType_raises_NotImplementedError_when_calling_check_logic_method():
5644
tolerance_test_values_no_change = (
5745
("tolerance", 10),
5846
"api.json",
59-
{
60-
"path": "result[0].vrfs.default.peerList[*].[$peerAddress$,establishedTransitions]",
61-
# "reference_key_path": "result[0].vrfs.default.peerList[*].peerAddress",
62-
},
47+
"result[0].vrfs.default.peerList[*].[$peerAddress$,establishedTransitions]",
6348
({}, True),
6449
)
6550

6651
tolerance_test_values_within_threshold = (
6752
("tolerance", 10),
6853
"api.json",
69-
{
70-
"path": "result[0].vrfs.default.peerList[*].[$peerAddress$,prefixesSent]",
71-
# "reference_key_path": "result[0].vrfs.default.peerList[*].peerAddress",
72-
},
54+
"result[0].vrfs.default.peerList[*].[$peerAddress$,prefixesSent]",
7355
({}, True),
7456
)
7557

7658
tolerance_test_values_beyond_threshold = (
7759
("tolerance", 10),
7860
"api.json",
79-
{
80-
"path": "result[0].vrfs.default.peerList[*].[$peerAddress$,prefixesReceived]",
81-
# "reference_key_path": "result[0].vrfs.default.peerList[*].peerAddress",
82-
},
61+
"result[0].vrfs.default.peerList[*].[$peerAddress$,prefixesReceived]",
8362
(
8463
{
8564
"10.1.0.0": {"prefixesReceived": {"new_value": 120, "old_value": 100}},
@@ -104,41 +83,34 @@ def test_check_type_results(check_type_args, filename, path, expected_results):
10483
check = CheckType.init(*check_type_args)
10584
pre_data = load_json_file("pre", filename)
10685
post_data = load_json_file("post", filename)
107-
actual_results = check.evaluate(pre_data, post_data, path)
86+
pre_value = check.extract_value_from_json_path(pre_data, path)
87+
post_value = check.extract_value_from_json_path(post_data, path)
88+
actual_results = check.evaluate(pre_value, post_value)
10889
assert actual_results == expected_results
10990

11091

11192
napalm_bgp_neighbor_status = (
11293
"napalm_get_bgp_neighbors.json",
11394
("exact_match",),
114-
{
115-
"path": "global.$peers$.*.[is_enabled,is_up]",
116-
# "reference_key_path": "global.peers"
117-
},
95+
"global.$peers$.*.[is_enabled,is_up]",
11896
0,
11997
)
12098

12199
napalm_bgp_neighbor_prefixes_ipv4 = (
122100
"napalm_get_bgp_neighbors.json",
123101
("tolerance", 10),
124-
{
125-
"path": "global.$peers$.*.*.ipv4.[accepted_prefixes,received_prefixes,sent_prefixes]",
126-
# "reference_key_path": "global.peers",
127-
},
102+
"global.$peers$.*.*.ipv4.[accepted_prefixes,received_prefixes,sent_prefixes]",
128103
1,
129104
)
130105

131106
napalm_bgp_neighbor_prefixes_ipv6 = (
132107
"napalm_get_bgp_neighbors.json",
133108
("tolerance", 10),
134-
{
135-
"path": "global.$peers$.*.*.ipv6.[accepted_prefixes,received_prefixes,sent_prefixes]",
136-
# "reference_key_path": "global.peers",
137-
},
109+
"global.$peers$.*.*.ipv6.[accepted_prefixes,received_prefixes,sent_prefixes]",
138110
2,
139111
)
140112

141-
napalm_get_lldp_neighbors_exact_raw = ("napalm_get_lldp_neighbors.json", ("exact_match",), {}, 0)
113+
napalm_get_lldp_neighbors_exact_raw = ("napalm_get_lldp_neighbors.json", ("exact_match",), None, 0)
142114

143115
check_tests = [
144116
napalm_bgp_neighbor_status,
@@ -151,10 +123,13 @@ def test_check_type_results(check_type_args, filename, path, expected_results):
151123
@pytest.mark.parametrize("filename, check_args, path, result_index", check_tests)
152124
def test_checks(filename, check_args, path, result_index):
153125
"""Validate multiple checks on the same data to catch corner cases."""
126+
check = CheckType.init(*check_args)
154127
pre_data = load_json_file("pre", filename)
155128
post_data = load_json_file("post", filename)
156129
result = load_json_file("results", filename)
157130

158-
check = CheckType.init(*check_args)
159-
check_output = check.evaluate(pre_data, post_data, path)
160-
assert list(check_output) == result[result_index]
131+
pre_value = check.extract_value_from_json_path(pre_data, path)
132+
post_value = check.extract_value_from_json_path(post_data, path)
133+
actual_results = check.evaluate(pre_value, post_value)
134+
135+
assert list(actual_results) == result[result_index]

0 commit comments

Comments
 (0)