Passed
Pull Request — master (#697)
by
unknown
04:34
created

TestUtils.test_prepare_delete_flow()   A

Complexity

Conditions 2

Size

Total Lines 31
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 25
nop 1
dl 0
loc 31
ccs 9
cts 9
cp 1
crap 2
rs 9.28
c 0
b 0
f 0
1
"""Module to test the utls.py file."""
2 1
from unittest.mock import MagicMock, Mock
3 1
import pytest
4
5 1
from kytos.core.common import EntityStatus
6 1
from napps.kytos.mef_eline.utils import (compare_endpoint_trace,
7
                                         compare_uni_out_trace,
8
                                         get_vlan_tags_and_masks, map_dl_vlan,
9
                                         merge_flow_dicts, prepare_delete_flow,
10
                                         _does_uni_affect_evc)
11
12
13
# pylint: disable=too-many-public-methods, too-many-lines
14 1
class TestUtils:
15
    """Test utility functions."""
16
17 1
    @pytest.mark.parametrize(
18
        "switch,expected",
19
        [
20
            (
21
                MagicMock(dpid="1234"),
22
                True
23
            ),
24
            (
25
                MagicMock(dpid="2345"),
26
                False
27
            )
28
        ]
29
    )
30 1
    def test_compare_endpoint_trace(self, switch, expected):
31
        """Test method compare_endpoint_trace"""
32 1
        trace = {"dpid": "1234", "port": 2, "vlan": 123}
33
34 1
        endpoint = MagicMock()
35 1
        endpoint.port_number = 2
36 1
        vlan = 123
37 1
        endpoint.switch = switch
38 1
        assert compare_endpoint_trace(endpoint, vlan, trace) == expected
39 1
        assert compare_endpoint_trace(endpoint, None, trace) == expected
40
41 1
    def test_compare_uni_out_trace(self):
42
        """Test compare_uni_out_trace method."""
43
        # case1: trace without 'out' info, should return True
44 1
        interface = MagicMock()
45 1
        assert compare_uni_out_trace(None, interface, {})
46
47
        # case2: trace with valid port and VLAN, should return True
48 1
        interface.port_number = 1
49 1
        tag_value = 123
50 1
        trace = {"out": {"port": 1, "vlan": 123}}
51 1
        assert compare_uni_out_trace(tag_value, interface, trace)
52
53
        # case3: UNI has VLAN but trace dont have, should return False
54 1
        trace = {"out": {"port": 1}}
55 1
        assert compare_uni_out_trace(tag_value, interface, trace) is False
56
57
        # case4: UNI and trace dont have VLAN should return True
58 1
        assert compare_uni_out_trace(None, interface, trace)
59
60
        # case5: UNI dont have VLAN but trace has, should return False
61 1
        trace = {"out": {"port": 1, "vlan": 123}}
62 1
        assert compare_uni_out_trace(None, interface, trace) is False
63
64 1
    def test_map_dl_vlan(self):
65
        """Test map_dl_vlan"""
66 1
        cases = {0: None, "untagged": None, "any": 1, "4096/4096": 1, 10: 10}
67 1
        for value, mapped in cases.items():
68 1
            result = map_dl_vlan(value)
69 1
            assert result == mapped
70
71 1
    @pytest.mark.parametrize(
72
        "vlan_range,expected",
73
        [
74
            (
75
                [[101, 200]],
76
                [
77
                    101,
78
                    "102/4094",
79
                    "104/4088",
80
                    "112/4080",
81
                    "128/4032",
82
                    "192/4088",
83
                    200,
84
                ]
85
            ),
86
            (
87
                [[101, 90]],
88
                []
89
            ),
90
            (
91
                [[34, 34]],
92
                [34]
93
            ),
94
            (
95
                [
96
                    [34, 34],
97
                    [128, 128],
98
                    [130, 135]
99
                ],
100
                [
101
                    34,
102
                    128,
103
                    "130/4094",
104
                    "132/4092"
105
                ]
106
            )
107
        ]
108
    )
109 1
    def test_get_vlan_tags_and_masks(self, vlan_range, expected):
110
        """Test get_vlan_tags_and_masks"""
111 1
        assert get_vlan_tags_and_masks(vlan_range) == expected
112
113 1
    @pytest.mark.parametrize(
114
        "src1,src2,src3,expected",
115
        [
116
            (
117
                {"dpida": [10, 11, 12]},
118
                {"dpida": [11, 20, 21]},
119
                {"dpidb": [30, 31, 32]},
120
                {"dpida": [10, 11, 12, 11, 20, 21], "dpidb": [30, 31, 32]},
121
            ),
122
            (
123
                {"dpida": [10, 11, 12]},
124
                {"dpida": [11, 20, 21], "dpidb": [40, 41, 42]},
125
                {"dpidb": [30, 31, 32]},
126
                {"dpida": [10, 11, 12, 11, 20, 21],
127
                 "dpidb": [40, 41, 42, 30, 31, 32]},
128
            ),
129
        ]
130
    )
131 1
    def test_merge_flow_dicts(self, src1, src2, src3, expected) -> None:
132
        """test merge flow dicts."""
133 1
        assert merge_flow_dicts({}, src1, src2, src3) == expected
134
135 1
    def test_prepare_delete_flow(self):
136
        """Test prepare_delete_flow"""
137 1
        cookie_mask = int(0xffffffffffffffff)
138 1
        flow_mod = {'00:01': [
139
            {
140
                'match': {'in_port': 1, 'dl_vlan': 22},
141
                'cookie': 12275899796742638400,
142
                'actions': [{'action_type': 'pop_vlan'}],
143
                'owner': 'mef_eline',
144
                'table_group': 'evpl',
145
                'table_id': 0,
146
                'priority': 20000
147
            },
148
            {
149
                'match': {'in_port': 3, 'dl_vlan': 1},
150
                'cookie': 12275899796742638400,
151
                'actions': [{'action_type': 'pop_vlan'}],
152
                'owner': 'mef_eline',
153
                'table_group': 'evpl',
154
                'table_id': 0,
155
                'priority': 20000
156
            }
157
        ]}
158 1
        actual_flows = prepare_delete_flow(flow_mod)
159 1
        assert '00:01' in actual_flows
160 1
        for i in range(len(actual_flows['00:01'])):
161 1
            assert (actual_flows['00:01'][i]['cookie'] ==
162
                    flow_mod["00:01"][i]['cookie'])
163 1
            assert (actual_flows['00:01'][i]['match'] ==
164
                    flow_mod["00:01"][i]['match'])
165 1
            assert actual_flows['00:01'][i]['cookie_mask'] == cookie_mask
166
167
    # pylint: disable=too-many-arguments
168 1
    @pytest.mark.parametrize(
169
        "intf_a_status, intf_z_status, is_active, is_uni, event, expected",
170
        [
171
            # link_DOWN
172
            (
173
                EntityStatus.DOWN, EntityStatus.DOWN,
174
                True, True, 'down', True
175
            ),
176
            (
177
                EntityStatus.UP, EntityStatus.UP,
178
                True, True, 'down', False
179
            ),
180
            (
181
                EntityStatus.DOWN, EntityStatus.UP,
182
                False, True, 'down', False
183
            ),
184
            (
185
                EntityStatus.UP, EntityStatus.UP,
186
                False, True, 'down', False
187
            ),
188
            (  # Not UNI
189
                EntityStatus.DOWN, EntityStatus.DOWN,
190
                True, False, 'down', False
191
            ),
192
            # link_up
193
            (
194
                EntityStatus.DOWN, EntityStatus.DOWN,
195
                True, True, 'up', False
196
            ),
197
            (
198
                EntityStatus.UP, EntityStatus.UP,
199
                True, True, 'up', False
200
            ),
201
            (
202
                EntityStatus.DOWN, EntityStatus.UP,
203
                False, True, 'up', False
204
            ),
205
            (
206
                EntityStatus.UP, EntityStatus.UP,
207
                False, True, 'up', True
208
            ),
209
            (  # Not UNI
210
                EntityStatus.UP, EntityStatus.UP,
211
                False, False, 'up', False
212
            ),
213
        ]
214
    )
215 1
    def test_does_uni_affect_evc(
216
        self,
217
        intf_a_status,
218
        intf_z_status,
219
        is_active,
220
        is_uni,
221
        event,
222
        expected
223
    ):
224
        """Test _does_uni_affect_evc when interface."""
225 1
        evc = Mock()
226 1
        evc.uni_a.interface.status = intf_a_status
227 1
        evc.uni_z.interface.status = intf_z_status
228 1
        if is_uni:
229 1
            interface = evc.uni_a.interface
230
        else:
231 1
            interface = Mock()
232 1
        evc.is_active.return_value = is_active
233
        assert _does_uni_affect_evc(evc, interface, event) is expected
234