Passed
Push — master ( 2bb252...8fb14b )
by Vinicius
10:35 queued 04:16
created

TestMain.test_send_flow_disabled()   A

Complexity

Conditions 1

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 12
nop 3
dl 0
loc 15
ccs 11
cts 11
cp 1
crap 1
rs 9.8
c 0
b 0
f 0
1
"""Test Main methods."""
2 1
from unittest.mock import AsyncMock, MagicMock, call, patch
3
4 1
import pytest
5 1
from httpx import RequestError
6 1
from kytos.core.events import KytosEvent
7 1
from kytos.lib.helpers import (get_controller_mock, get_interface_mock,
8
                               get_kytos_event_mock, get_switch_mock,
9
                               get_test_client)
10 1
from napps.kytos.of_lldp.utils import get_cookie
11 1
from tenacity import RetryError
12
13 1
from tests.helpers import get_topology_mock
14
15
16 1 View Code Duplication
@patch('kytos.core.controller.Controller.get_switch_by_dpid')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
17 1
@patch('napps.kytos.of_lldp.main.Main._unpack_non_empty')
18 1
@patch('napps.kytos.of_lldp.main.UBInt32')
19 1
@patch('napps.kytos.of_lldp.main.DPID')
20 1
@patch('napps.kytos.of_lldp.main.LLDP')
21 1
@patch('napps.kytos.of_lldp.main.Ethernet')
22 1
async def test_on_ofpt_packet_in(*args):
23
    """Test on_ofpt_packet_in."""
24 1
    (mock_ethernet, mock_lldp, mock_dpid, mock_ubint32,
25
     mock_unpack_non_empty, mock_get_switch_by_dpid) = args
26
27
    # pylint: disable=bad-option-value, import-outside-toplevel
28 1
    from napps.kytos.of_lldp.main import Main
29 1
    Main.get_liveness_controller = MagicMock()
30 1
    topology = get_topology_mock()
31 1
    controller = get_controller_mock()
32 1
    controller.buffers.app.aput = AsyncMock()
33 1
    controller.switches = topology.switches
34 1
    napp = Main(controller)
35 1
    napp.loop_manager.process_if_looped = AsyncMock()
36 1
    napp.liveness_manager.consume_hello_if_enabled = AsyncMock()
37
38 1
    switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
39 1
    message = MagicMock(in_port=1, data='data')
40 1
    event = KytosEvent('ofpt_packet_in', content={'source': switch.connection,
41
                       'message': message})
42
43 1
    mocked, ethernet, lldp, dpid, port_b = [MagicMock() for _ in range(5)]
44 1
    mocked.value = 1
45 1
    mock_ubint32.return_value = mocked
46 1
    ethernet.ether_type = 0x88CC
47 1
    ethernet.data = 'eth_data'
48 1
    lldp.chassis_id.sub_value = 'chassis_id'
49 1
    lldp.port_id.sub_value = 'port_id'
50 1
    dpid.value = "00:00:00:00:00:00:00:02"
51 1
    port_b.value = 2
52
53 1
    mock_unpack_non_empty.side_effect = [ethernet, lldp, dpid, port_b]
54 1
    mock_get_switch_by_dpid.return_value = get_switch_mock(dpid.value,
55
                                                           0x04)
56 1
    await napp.on_ofpt_packet_in(event)
57
58 1
    calls = [call(mock_ethernet, message.data),
59
             call(mock_lldp, ethernet.data),
60
             call(mock_dpid, lldp.chassis_id.sub_value),
61
             call(mock_ubint32, lldp.port_id.sub_value)]
62 1
    mock_unpack_non_empty.assert_has_calls(calls)
63 1
    assert napp.loop_manager.process_if_looped.call_count == 1
64 1
    assert napp.liveness_manager.consume_hello_if_enabled.call_count == 1
65 1
    assert controller.buffers.app.aput.call_count == 1
66
67
68 1 View Code Duplication
@patch('kytos.core.controller.Controller.get_switch_by_dpid')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
69 1
@patch('napps.kytos.of_lldp.main.Main._unpack_non_empty')
70 1
@patch('napps.kytos.of_lldp.main.UBInt32')
71 1
@patch('napps.kytos.of_lldp.main.DPID')
72 1
@patch('napps.kytos.of_lldp.main.LLDP')
73 1
@patch('napps.kytos.of_lldp.main.Ethernet')
74 1
async def test_on_ofpt_packet_in_early_intf(*args):
75
    """Test on_ofpt_packet_in early intf return."""
76 1
    (mock_ethernet, mock_lldp, mock_dpid, mock_ubint32,
77
     mock_unpack_non_empty, mock_get_switch_by_dpid) = args
78
79
    # pylint: disable=bad-option-value, import-outside-toplevel
80 1
    from napps.kytos.of_lldp.main import Main
81 1
    Main.get_liveness_controller = MagicMock()
82 1
    topology = get_topology_mock()
83 1
    controller = get_controller_mock()
84 1
    controller.buffers.app.aput = AsyncMock()
85 1
    controller.switches = topology.switches
86 1
    napp = Main(controller)
87 1
    napp.loop_manager.process_if_looped = AsyncMock()
88 1
    napp.liveness_manager.consume_hello_if_enabled = AsyncMock()
89
90 1
    switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
91 1
    message = MagicMock(in_port=1, data='data')
92 1
    event = KytosEvent('ofpt_packet_in', content={'source': switch.connection,
93
                       'message': message})
94
95 1
    mocked, ethernet, lldp, dpid, port_b = [MagicMock() for _ in range(5)]
96 1
    mocked.value = 1
97 1
    mock_ubint32.return_value = mocked
98 1
    ethernet.ether_type = 0x88CC
99 1
    ethernet.data = 'eth_data'
100 1
    lldp.chassis_id.sub_value = 'chassis_id'
101 1
    lldp.port_id.sub_value = 'port_id'
102 1
    dpid.value = "00:00:00:00:00:00:00:02"
103 1
    port_b.value = 2
104
105 1
    mock_unpack_non_empty.side_effect = [ethernet, lldp, dpid, port_b]
106 1
    mock_get_switch_by_dpid.return_value = get_switch_mock(dpid.value,
107
                                                           0x04)
108 1
    switch.get_interface_by_port_no = MagicMock(return_value=None)
109 1
    await napp.on_ofpt_packet_in(event)
110
111 1
    calls = [call(mock_ethernet, message.data),
112
             call(mock_lldp, ethernet.data),
113
             call(mock_dpid, lldp.chassis_id.sub_value),
114
             call(mock_ubint32, lldp.port_id.sub_value)]
115 1
    mock_unpack_non_empty.assert_has_calls(calls)
116 1
    switch.get_interface_by_port_no.assert_called()
117
    # early return shouldn't allow these to get called
118 1
    assert napp.loop_manager.process_if_looped.call_count == 0
119 1
    assert napp.liveness_manager.consume_hello_if_enabled.call_count == 0
120 1
    assert controller.buffers.app.aput.call_count == 0
121
122
123 1
async def test_on_table_enabled():
124
    """Test on_table_enabled"""
125
    # pylint: disable=bad-option-value, import-outside-toplevel
126 1
    from napps.kytos.of_lldp.main import Main
127 1
    controller = get_controller_mock()
128 1
    controller.buffers.app.aput = AsyncMock()
129 1
    napp = Main(controller)
130
131
    # Succesfully setting table groups
132 1
    content = {"of_lldp": {"base": 123}}
133 1
    event = KytosEvent(name="kytos/of_multi_table.enable_table",
134
                       content=content)
135 1
    await napp.on_table_enabled(event)
136 1
    assert napp.table_group == content["of_lldp"]
137 1
    assert controller.buffers.app.aput.call_count == 1
138
139
    # Failure at setting table groups
140 1
    content = {"of_lldp": {"unknown": 123}}
141 1
    event = KytosEvent(name="kytos/of_multi_table.enable_table",
142
                       content=content)
143 1
    await napp.on_table_enabled(event)
144 1
    assert controller.buffers.app.aput.call_count == 1
145
146
147
# pylint: disable=protected-access,too-many-public-methods
148 1
class TestMain:
149
    """Tests for the Main class."""
150
151 1
    def setup_method(self):
152
        """Execute steps before each tests."""
153
        # patch('kytos.core.helpers.run_on_thread', lambda x: x).start()
154
        # pylint: disable=bad-option-value, import-outside-toplevel
155 1
        from napps.kytos.of_lldp.main import Main
156 1
        Main.get_liveness_controller = MagicMock()
157 1
        self.topology = get_topology_mock()
158 1
        controller = get_controller_mock()
159 1
        controller.switches = self.topology.switches
160 1
        self.base_endpoint = "kytos/of_lldp/v1"
161 1
        self.napp = Main(controller)
162 1
        self.api_client = get_test_client(controller, self.napp)
163
164 1
    def teardown_method(self) -> None:
165
        """Teardown."""
166 1
        patch.stopall()
167
168 1
    def get_topology_interfaces(self):
169
        """Return interfaces present in topology."""
170 1
        interfaces = []
171 1
        for switch in list(self.topology.switches.values()):
172 1
            interfaces += list(switch.interfaces.values())
173 1
        return interfaces
174
175 1
    @patch('napps.kytos.of_lldp.main.of_msg_prio')
176 1
    @patch('napps.kytos.of_lldp.main.KytosEvent')
177 1
    @patch('napps.kytos.of_lldp.main.VLAN')
178 1
    @patch('napps.kytos.of_lldp.main.Ethernet')
179 1
    @patch('napps.kytos.of_lldp.main.DPID')
180 1
    @patch('napps.kytos.of_lldp.main.LLDP')
181 1
    def test_execute(self, *args):
182
        """Test execute method."""
183 1
        (_, _, mock_ethernet, _, mock_kytos_event, mock_of_msg_prio) = args
184 1
        mock_buffer_put = MagicMock()
185 1
        self.napp.controller.buffers.msg_out.put = mock_buffer_put
186
187 1
        ethernet = MagicMock()
188 1
        ethernet.pack.return_value = 'pack'
189 1
        interfaces = self.get_topology_interfaces()
190 1
        po_args = [(interface.switch.connection.protocol.version,
191
                    interface.port_number, 'pack') for interface in interfaces]
192
193 1
        mock_ethernet.return_value = ethernet
194 1
        mock_kytos_event.side_effect = po_args
195
196 1
        mock_publish_stopped = MagicMock()
197 1
        self.napp.try_to_publish_stopped_loops = mock_publish_stopped
198 1
        self.napp.execute()
199
200 1
        mock_of_msg_prio.assert_called()
201 1
        mock_buffer_put.assert_has_calls([call(arg)
202
                                          for arg in po_args])
203 1
        mock_publish_stopped.assert_called()
204
205 1
    @patch('napps.kytos.of_lldp.main.Main.get_flows_by_switch')
206 1
    @patch('httpx.request')
207 1
    @patch('httpx.post')
208 1
    def test_handle_lldp_flows(self, mock_post, mock_request, mock_flows):
209
        """Test handle_lldp_flow method."""
210 1
        dpid = "00:00:00:00:00:00:00:01"
211 1
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
212 1
        self.napp.controller.switches = {dpid: switch}
213 1
        event_post = get_kytos_event_mock(name='kytos/topology.switch.enabled',
214
                                          content={'dpid': dpid})
215
216 1
        event_del = get_kytos_event_mock(name='kytos/topology.switch.disabled',
217
                                         content={'dpid': dpid})
218
219 1
        mock_post.return_value = MagicMock(status_code=202)
220 1
        mock_request.return_value = MagicMock(status_code=202)
221
222 1
        mock_flows.return_value = {}
223 1
        self.napp._handle_lldp_flows(event_post)
224 1
        mock_post.assert_called()
225
226 1
        mock_flows.return_value = {"flows": "mocked_flows"}
227 1
        self.napp._handle_lldp_flows(event_del)
228 1
        mock_request.assert_called()
229
230 1
    @patch('napps.kytos.of_lldp.main.Main.get_flows_by_switch')
231 1
    @patch("time.sleep")
232 1
    @patch("httpx.post")
233 1
    def test_handle_lldp_flows_retries(self, mock_post, _, mock_flows):
234
        """Test handle_lldp_flow method retries."""
235 1
        dpid = "00:00:00:00:00:00:00:01"
236 1
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
237 1
        mock_flows.return_value = {}
238 1
        self.napp.controller.switches = {dpid: switch}
239 1
        event_post = get_kytos_event_mock(name="kytos/topology.switch.enabled",
240
                                          content={"dpid": dpid})
241
242 1
        mock = MagicMock()
243 1
        mock.request.method = "POST"
244 1
        mock.status_code = 500
245 1
        mock.text = "some_err"
246 1
        mock_post.return_value = mock
247 1
        self.napp._handle_lldp_flows(event_post)
248 1
        assert mock_post.call_count == 3
249
250 1
    @patch('napps.kytos.of_lldp.main.log')
251 1
    @patch('httpx.get')
252 1
    def test_handle_lldp_flows_request_value_error(self, mock_get, mock_log):
253
        """Test _handle_lldp_flows"""
254 1
        dpid = "00:00:00:00:00:00:00:01"
255 1
        mock_get.return_value = MagicMock(
256
            status_code=400, is_server_error=False
257
        )
258 1
        event_post = get_kytos_event_mock(name='kytos/topology.switch.enabled',
259
                                          content={'dpid': dpid})
260 1
        self.napp._handle_lldp_flows(event_post)
261 1
        assert mock_log.error.call_count == 1
262
263 1
    @patch('napps.kytos.of_lldp.main.log')
264 1
    @patch('napps.kytos.of_lldp.main.httpx')
265 1
    def test_handle_lldp_flows_request_error(self, mock_httpx, mock_log):
266
        """Test _handle_lldp_flows"""
267 1
        dpid = "00:00:00:00:00:00:00:01"
268 1
        event_post = get_kytos_event_mock(name='kytos/topology.switch.enabled',
269
                                          content={'dpid': dpid})
270 1
        mock_httpx.get.side_effect = RequestError(message="mocked error")
271 1
        self.napp._handle_lldp_flows(event_post)
272 1
        assert mock_log.error.call_count == 1
273
274 1
    @patch('napps.kytos.of_lldp.main.PO13')
275 1
    @patch('napps.kytos.of_lldp.main.AO13')
276 1
    def test_build_lldp_packet_out(self, *args):
277
        """Test _build_lldp_packet_out method."""
278 1
        (mock_ao13, mock_po13) = args
279
280 1
        ao13 = MagicMock()
281 1
        po13 = MagicMock()
282 1
        po13.actions = []
283
284 1
        mock_ao13.return_value = ao13
285 1
        mock_po13.return_value = po13
286
287 1
        packet_out13 = self.napp._build_lldp_packet_out(0x04, 2, 'data2')
288 1
        packet_out14 = self.napp._build_lldp_packet_out(0x05, 3, 'data3')
289
290 1
        assert packet_out13.data == 'data2'
291 1
        assert packet_out13.actions == [ao13]
292 1
        assert packet_out13.actions[0].port == 2
293 1
        assert packet_out14 is None
294
295 1
    @patch('napps.kytos.of_lldp.main.settings')
296 1
    @patch('napps.kytos.of_lldp.main.EtherType')
297 1
    @patch('napps.kytos.of_lldp.main.Port13')
298 1
    def test_build_lldp_flow(self, *args):
299
        """Test _build_lldp_flow method."""
300 1
        (mock_v0x04_port, mock_ethertype,
301
         mock_settings) = args
302 1
        self.napp.vlan_id = None
303 1
        mock_v0x04_port.OFPP_CONTROLLER = 1234
304
305 1
        mock_ethertype.LLDP = 10
306 1
        mock_settings.FLOW_VLAN_VID = None
307 1
        mock_settings.FLOW_PRIORITY = 1500
308 1
        dpid = "00:00:00:00:00:00:00:01"
309
310 1
        flow = {}
311 1
        match = {}
312 1
        flow['priority'] = 1500
313 1
        flow['table_id'] = 0
314 1
        match['dl_type'] = 10
315
316 1
        flow['match'] = match
317 1
        expected_flow_v0x04 = flow.copy()
318 1
        expected_flow_v0x04['cookie'] = get_cookie(dpid)
319 1
        expected_flow_v0x04['cookie_mask'] = 0xffffffffffffffff
320
321 1
        expected_flow_v0x04['actions'] = [{'action_type': 'output',
322
                                           'port': 1234}]
323 1
        expected_flow_v0x04['table_group'] = 'base'
324 1
        expected_flow_v0x04['owner'] = 'of_lldp'
325
326 1
        flow_mod10 = self.napp._build_lldp_flow(0x01, get_cookie(dpid))
327 1
        flow_mod13 = self.napp._build_lldp_flow(0x04, get_cookie(dpid))
328
329 1
        assert flow_mod10 is None
330 1
        assert flow_mod13 == expected_flow_v0x04
331
332 1
    def test_unpack_non_empty(self):
333
        """Test _unpack_non_empty method."""
334 1
        desired_class = MagicMock()
335 1
        data = MagicMock()
336 1
        data.value = 'data'
337
338 1
        obj = self.napp._unpack_non_empty(desired_class, data)
339
340 1
        obj.unpack.assert_called_with('data')
341
342 1
    def test_get_data(self, monkeypatch):
343
        """Test _get_data method."""
344 1
        interfaces = ['00:00:00:00:00:00:00:01:1', '00:00:00:00:00:00:00:01:2']
345 1
        monkeypatch.setattr("napps.kytos.of_lldp.main.get_json_or_400",
346
                            lambda req, loop: {"interfaces": interfaces})
347 1
        data = self.napp._get_data(MagicMock())
348 1
        assert data == interfaces
349
350 1
    def test_load_liveness(self) -> None:
351
        """Test load_liveness."""
352 1
        self.napp.load_liveness()
353 1
        count = self.napp.liveness_controller.get_enabled_interfaces.call_count
354 1
        assert count == 1
355
356 1
    def test_handle_topology_loaded(self) -> None:
357
        """Test handle_topology_loaded."""
358 1
        event = KytosEvent("kytos/topology.topology_loaded",
359
                           content={"topology": {}})
360 1
        self.napp.load_liveness = MagicMock()
361 1
        self.napp.loop_manager.handle_topology_loaded = MagicMock()
362 1
        self.napp.handle_topology_loaded(event)
363 1
        assert self.napp.loop_manager.handle_topology_loaded.call_count == 1
364 1
        assert self.napp.load_liveness.call_count == 1
365
366 1
    def test_publish_liveness_status(self) -> None:
367
        """Test publish_liveness_status."""
368 1
        self.napp.controller.buffers.app.put = MagicMock()
369 1
        event_suffix, interfaces = "up", [MagicMock(id=1), MagicMock(id=2)]
370 1
        self.napp.publish_liveness_status(event_suffix, interfaces)
371 1
        assert self.napp.controller.buffers.app.put.call_count == 1
372 1
        event = self.napp.controller.buffers.app.put.call_args[0][0]
373 1
        assert event.name == f"kytos/of_lldp.liveness.{event_suffix}"
374 1
        assert event.content["interfaces"] == interfaces
375
376 1
    def test_get_interfaces(self):
377
        """Test _get_interfaces method."""
378 1
        expected_interfaces = self.get_topology_interfaces()
379 1
        interfaces = self.napp._get_interfaces()
380 1
        assert interfaces == expected_interfaces
381
382 1
    def test_get_interfaces_dict(self):
383
        """Test _get_interfaces_dict method."""
384 1
        interfaces = self.napp._get_interfaces()
385 1
        expected_interfaces = {inter.id: inter for inter in interfaces}
386 1
        interfaces_dict = self.napp._get_interfaces_dict(interfaces)
387 1
        assert interfaces_dict == expected_interfaces
388
389 1
    def test_get_lldp_interfaces(self):
390
        """Test _get_lldp_interfaces method."""
391 1
        lldp_interfaces = self.napp._get_lldp_interfaces()
392 1
        expected_interfaces = ['00:00:00:00:00:00:00:01:1',
393
                               '00:00:00:00:00:00:00:01:2',
394
                               '00:00:00:00:00:00:00:02:1',
395
                               '00:00:00:00:00:00:00:02:2']
396 1
        assert lldp_interfaces == expected_interfaces
397
398 1
    async def test_rest_get_lldp_interfaces(self):
399
        """Test get_lldp_interfaces method."""
400 1
        endpoint = f"{self.base_endpoint}/interfaces"
401 1
        response = await self.api_client.get(endpoint)
402 1
        expected_data = {"interfaces": ['00:00:00:00:00:00:00:01:1',
403
                                        '00:00:00:00:00:00:00:01:2',
404
                                        '00:00:00:00:00:00:00:02:1',
405
                                        '00:00:00:00:00:00:00:02:2']}
406 1
        assert response.status_code == 200
407 1
        assert response.json() == expected_data
408
409 1
    async def test_enable_disable_lldp_200(self, event_loop):
410
        """Test 200 response for enable_lldp and disable_lldp methods."""
411 1
        data = {"interfaces": ['00:00:00:00:00:00:00:01:1',
412
                               '00:00:00:00:00:00:00:01:2',
413
                               '00:00:00:00:00:00:00:02:1',
414
                               '00:00:00:00:00:00:00:02:2']}
415 1
        self.napp.controller.loop = event_loop
416 1
        self.napp.publish_liveness_status = MagicMock()
417 1
        endpoint = f"{self.base_endpoint}/interfaces/disable"
418 1
        response = await self.api_client.post(endpoint, json=data)
419 1
        assert response.status_code == 200
420 1
        assert self.napp.liveness_controller.disable_interfaces.call_count == 1
421 1
        assert self.napp.publish_liveness_status.call_count == 1
422 1
        endpoint = f"{self.base_endpoint}/interfaces/enable"
423 1
        response = await self.api_client.post(endpoint, json=data)
424 1
        assert response.status_code == 200
425
426 1
    async def test_enable_disable_lldp_404(self):
427
        """Test 404 response for enable_lldp and disable_lldp methods."""
428 1
        data = {"interfaces": []}
429 1
        self.napp.controller.switches = {}
430 1
        endpoint = f"{self.base_endpoint}/disable"
431 1
        response = await self.api_client.post(endpoint, json=data)
432 1
        assert response.status_code == 404
433 1
        endpoint = f"{self.base_endpoint}/enable"
434 1
        response = await self.api_client.post(endpoint, json=data)
435 1
        assert response.status_code == 404
436
437 1
    async def test_enable_disable_lldp_400(self, event_loop):
438
        """Test 400 response for enable_lldp and disable_lldp methods."""
439 1
        data = {"interfaces": ['00:00:00:00:00:00:00:01:1',
440
                               '00:00:00:00:00:00:00:01:2',
441
                               '00:00:00:00:00:00:00:02:1',
442
                               '00:00:00:00:00:00:00:02:2',
443
                               '00:00:00:00:00:00:00:03:1',
444
                               '00:00:00:00:00:00:00:03:2',
445
                               '00:00:00:00:00:00:00:04:1']}
446 1
        self.napp.controller.loop = event_loop
447 1
        self.napp.publish_liveness_status = MagicMock()
448 1
        url = f'{self.base_endpoint}/interfaces/disable'
449 1
        response = await self.api_client.post(url, json=data)
450 1
        assert response.status_code == 400
451 1
        assert self.napp.publish_liveness_status.call_count == 1
452
453 1
        url = f'{self.base_endpoint}/interfaces/enable'
454 1
        response = await self.api_client.post(url, json=data)
455 1
        assert response.status_code == 400
456
457 1
    async def test_get_time(self):
458
        """Test get polling time."""
459 1
        url = f"{self.base_endpoint}/polling_time"
460 1
        response = await self.api_client.get(url)
461 1
        assert response.status_code == 200
462
463 1
    async def test_set_polling_time(self):
464
        """Test update polling time."""
465 1
        url = f"{self.base_endpoint}/polling_time"
466 1
        data = {'polling_time': 5}
467 1
        response = await self.api_client.post(url, json=data)
468 1
        assert response.status_code == 200
469
470 1
    async def test_set_time_400(self):
471
        """Test fail case the update polling time."""
472 1
        url = f"{self.base_endpoint}/polling_time"
473 1
        data = {'polling_time': 'A'}
474 1
        response = await self.api_client.post(url, json=data)
475 1
        assert response.status_code == 400
476
477 1
    async def test_endpoint_enable_liveness(self, event_loop):
478
        """Test POST v1/liveness/enable."""
479 1
        self.napp.controller.loop = event_loop
480 1
        self.napp.liveness_manager.enable = MagicMock()
481 1
        self.napp.publish_liveness_status = MagicMock()
482 1
        url = f"{self.base_endpoint}/liveness/enable"
483 1
        data = {"interfaces": ["00:00:00:00:00:00:00:01:1"]}
484 1
        response = await self.api_client.post(url, json=data)
485 1
        assert response.status_code == 200
486 1
        assert response.json() == {}
487 1
        assert self.napp.liveness_controller.enable_interfaces.call_count == 1
488 1
        assert self.napp.liveness_manager.enable.call_count == 1
489 1
        assert self.napp.publish_liveness_status.call_count == 1
490
491 1
    async def test_endpoint_disable_liveness(self, event_loop):
492
        """Test POST v1/liveness/disable."""
493 1
        self.napp.controller.loop = event_loop
494 1
        self.napp.liveness_manager.disable = MagicMock()
495 1
        self.napp.publish_liveness_status = MagicMock()
496 1
        url = f"{self.base_endpoint}/liveness/disable"
497 1
        data = {"interfaces": ["00:00:00:00:00:00:00:01:1"]}
498 1
        response = await self.api_client.post(url, json=data)
499 1
        assert response.status_code == 200
500 1
        assert response.json() == {}
501 1
        assert self.napp.liveness_controller.disable_interfaces.call_count == 1
502 1
        assert self.napp.liveness_manager.disable.call_count == 1
503 1
        assert self.napp.publish_liveness_status.call_count == 1
504
505 1
    async def test_endpoint_get_liveness(self):
506
        """Test GET v1/liveness/."""
507 1
        self.napp.liveness_manager.enable = MagicMock()
508 1
        self.napp.publish_liveness_status = MagicMock()
509 1
        url = f"{self.base_endpoint}/liveness/"
510 1
        response = await self.api_client.get(url)
511 1
        assert response.status_code == 200
512 1
        assert response.json() == {"interfaces": []}
513
514 1
    async def test_endpoint_get_pair_liveness(self):
515
        """Test GET v1/liveness//pair."""
516 1
        self.napp.liveness_manager.enable = MagicMock()
517 1
        self.napp.publish_liveness_status = MagicMock()
518 1
        url = f"{self.base_endpoint}/liveness/pair"
519 1
        response = await self.api_client.get(url)
520 1
        assert response.status_code == 200
521 1
        assert response.json() == {"pairs": []}
522
523 1
    def test_set_flow_table_group_owner(self):
524
        """Test set_flow_table_group_owner"""
525 1
        self.napp.table_group = {"base": 2}
526 1
        flow = {}
527 1
        self.napp.set_flow_table_group_owner(flow, "base")
528 1
        assert "table_group" in flow
529 1
        assert "owner" in flow
530 1
        assert flow["table_id"] == 2
531
532 1
    @patch('napps.kytos.of_lldp.main.log')
533 1
    def test_use_vlan(self, mock_log):
534
        """Test use_vlan"""
535 1
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
536 1
        interface_a = get_interface_mock("mock_a", 1, switch)
537 1
        interface_a.use_tags = MagicMock()
538 1
        interface_b = get_interface_mock("mock_b", 2, switch)
539 1
        interface_b.use_tags = MagicMock()
540 1
        switch.interfaces = {1: interface_a, 2: interface_b}
541 1
        self.napp.use_vlan(switch)
542 1
        assert interface_a.use_tags.call_count == 1
543 1
        assert interface_b.use_tags.call_count == 1
544
545 1
        interface_a.use_tags.return_value = False
546 1
        self.napp.use_vlan(switch)
547 1
        assert interface_a.use_tags.call_count == 2
548 1
        assert interface_b.use_tags.call_count == 2
549 1
        assert mock_log.error.call_count == 1
550
551 1
        self.napp.vlan_id = None
552 1
        self.napp.use_vlan(switch)
553 1
        assert interface_a.use_tags.call_count == 2
554 1
        assert interface_b.use_tags.call_count == 2
555
556 1
    @patch('napps.kytos.of_lldp.main.log')
557 1
    def test_make_vlan_available(self, mock_log):
558
        """Test make_vlan_available"""
559 1
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
560 1
        interface_a = get_interface_mock("mock_a", 1, switch)
561 1
        interface_a.make_tags_available = MagicMock()
562 1
        interface_b = get_interface_mock("mock_b", 2, switch)
563 1
        interface_b.make_tags_available = MagicMock()
564 1
        switch.interfaces = {1: interface_a, 2: interface_b}
565 1
        self.napp.make_vlan_available(switch)
566 1
        assert interface_a.make_tags_available.call_count == 1
567 1
        assert interface_b.make_tags_available.call_count == 1
568
569 1
        interface_a.make_tags_available.return_value = False
570 1
        self.napp.make_vlan_available(switch)
571 1
        assert interface_a.make_tags_available.call_count == 2
572 1
        assert interface_b.make_tags_available.call_count == 2
573 1
        assert mock_log.warning.call_count == 1
574
575 1
        self.napp.vlan_id = None
576 1
        self.napp.make_vlan_available(switch)
577 1
        assert interface_a.make_tags_available.call_count == 2
578 1
        assert interface_b.make_tags_available.call_count == 2
579
580 1
    @patch('httpx.get')
581 1
    def test_get_flows_by_switch_retry(self, mock_get):
582
        """Test get_flows_by_switch retry"""
583 1
        dpid = "00:00:00:00:00:00:00:01"
584 1
        mock_get.return_value = MagicMock(
585
            status_code=400, text="mock_error"
586
        )
587 1
        with pytest.raises(RetryError):
588 1
            self.napp.get_flows_by_switch(dpid)
589 1
        assert mock_get.call_count == 3
590
591 1
    @patch('httpx.post')
592 1
    @patch('napps.kytos.of_lldp.main.Main.use_vlan')
593 1
    def test_send_flow_enabled(self, mock_use, mock_post):
594
        """Test send_flows when switch is enabled"""
595 1
        mock_post.return_value = MagicMock(
596
            status_code=202, is_server_error=False
597
        )
598 1
        event_name = 'kytos/topology.switch.enabled'
599 1
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
600 1
        data = {'flows': [{'cookie_mask': "mock_cookie"}]}
601 1
        self.napp.send_flow(switch, event_name, data=data)
602
603 1
        assert mock_use.call_count == 1
604 1
        assert mock_use.call_args[0][0] == switch
605 1
        assert data['flows'] == [{}]
606
607 1
    @patch('httpx.request')
608 1
    @patch('napps.kytos.of_lldp.main.Main.make_vlan_available')
609 1
    def test_send_flow_disabled(self, mock_avaialble, mock_request):
610
        """Test send_flows when switch is disabled"""
611 1
        mock_request.return_value = MagicMock(
612
            status_code=202, is_server_error=False
613
        )
614 1
        event_name = 'kytos/topology.switch.disabled'
615 1
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
616 1
        data = {'flows': [{'cookie_mask': "mock_cookie"}]}
617 1
        self.napp.send_flow(switch, event_name, data=data)
618
619 1
        assert mock_avaialble.call_count == 1
620 1
        assert mock_avaialble.call_args[0][0] == switch
621
        assert data['flows'] == [{'cookie_mask': "mock_cookie"}]
622