1
|
|
|
"""Module to test the main napp file.""" |
2
|
1 |
|
from unittest.mock import Mock, patch, MagicMock |
3
|
|
|
|
4
|
|
|
# pylint: disable=import-error,no-name-in-module |
5
|
1 |
|
from kytos.core.events import KytosEvent |
6
|
1 |
|
from kytos.core.buffers import KytosBuffers |
7
|
1 |
|
from kytos.lib.helpers import get_controller_mock, get_test_client |
8
|
1 |
|
from tests.integration.helpers import (get_interface_mock, get_switch_mock) |
9
|
|
|
|
10
|
|
|
|
11
|
|
|
# pylint: disable=import-outside-toplevel |
12
|
1 |
|
class TestMain: |
13
|
|
|
"""Test the Main class.""" |
14
|
|
|
|
15
|
1 |
|
def setup_method(self): |
16
|
|
|
"""Execute steps before each tests. |
17
|
|
|
|
18
|
|
|
Set the server_name_url from kytos/topology |
19
|
|
|
""" |
20
|
1 |
|
patch('kytos.core.helpers.run_on_thread', lambda x: x).start() |
21
|
1 |
|
from napps.kytos.topology.main import Main |
22
|
1 |
|
Main.get_topo_controller = MagicMock() |
23
|
1 |
|
controller = get_controller_mock() |
24
|
1 |
|
self.napp = Main(controller) |
25
|
1 |
|
_ = self.napp.controller.buffers.app.get() |
26
|
1 |
|
self.api_client = get_test_client(controller, self.napp) |
27
|
1 |
|
self.base_endpoint = "kytos/topology/v3" |
28
|
|
|
|
29
|
1 |
|
def test_get_switches_dict(self): |
30
|
|
|
"""Basic test for switch listing.""" |
31
|
|
|
# pylint: disable=protected-access, |
32
|
|
|
# pylint: disable=use-implicit-booleaness-not-comparison |
33
|
1 |
|
switches = self.napp._get_switches_dict() |
34
|
1 |
|
assert isinstance(switches['switches'], dict) |
35
|
1 |
|
assert switches['switches'] == {} |
36
|
|
|
|
37
|
1 |
|
def test_get_event_listeners(self): |
38
|
|
|
"""Verify all event listeners registered.""" |
39
|
1 |
|
actual_events = self.napp.listeners() |
40
|
1 |
|
expected_events = [ |
41
|
|
|
'kytos/core.shutdown', |
42
|
|
|
'kytos/core.shutdown.kytos/topology', |
43
|
|
|
'kytos/.*.liveness.(up|down|disabled)', |
44
|
|
|
'.*.topo_controller.upsert_switch', |
45
|
|
|
'.*.of_lldp.network_status.updated', |
46
|
|
|
'.*.interface.is.nni', |
47
|
|
|
'.*.connection.lost', |
48
|
|
|
'.*.switch.interfaces.created', |
49
|
|
|
'.*.topology.switch.interface.created', |
50
|
|
|
'.*.switch.interface.deleted', |
51
|
|
|
'.*.switch.interface.link_down', |
52
|
|
|
'.*.switch.interface.link_up', |
53
|
|
|
'.*.switch.(new|reconnected)', |
54
|
|
|
'.*.switch.port.created', |
55
|
|
|
'kytos/topology.notify_link_up_if_status', |
56
|
|
|
'topology.interruption.(start|end)', |
57
|
|
|
'kytos/core.interface_tags', |
58
|
|
|
] |
59
|
1 |
|
assert sorted(expected_events) == sorted(actual_events) |
60
|
|
|
|
61
|
1 |
|
async def test_get_interfaces(self): |
62
|
|
|
"""test_get_interfaces.""" |
63
|
1 |
|
dpid = "00:00:00:00:00:00:00:01" |
64
|
1 |
|
switch = get_switch_mock(0x04, dpid=dpid) |
65
|
1 |
|
switch.dpid = dpid |
66
|
1 |
|
switch.metadata = {"lat": 0, "lng": 0} |
67
|
1 |
|
switch.interfaces = {f"{dpid}:1": f"{dpid}:1"} |
68
|
1 |
|
switch.as_dict = lambda: {"dpid": dpid, "metadata": switch.metadata, |
69
|
|
|
"interfaces": switch.interfaces} |
70
|
1 |
|
self.napp.controller.switches = {dpid: switch} |
71
|
1 |
|
endpoint = f"{self.base_endpoint}/interfaces" |
72
|
1 |
|
response = await self.api_client.get(endpoint) |
73
|
1 |
|
assert response.status_code == 200 |
74
|
1 |
|
data = response.json() |
75
|
1 |
|
assert "interfaces" in data |
76
|
1 |
|
assert len(data["interfaces"]) == 1 |
77
|
1 |
|
assert data["interfaces"][f"{dpid}:1"] |
78
|
|
|
|
79
|
1 |
|
async def test_handle_new_switch(self): |
80
|
|
|
"""Test handle new switch.""" |
81
|
1 |
|
self.napp.controller._buffers = KytosBuffers() |
82
|
1 |
|
event_name = '.*.switch.(new|reconnected)' |
83
|
1 |
|
switch = get_switch_mock(0x04) |
84
|
1 |
|
event = KytosEvent(name=event_name, |
85
|
|
|
content={'switch': switch}) |
86
|
1 |
|
self.napp.handle_new_switch(event) |
87
|
1 |
|
event_response = self.napp.controller.buffers.app.get() |
88
|
1 |
|
assert event_response.name == 'kytos/topology.updated' |
89
|
|
|
|
90
|
1 |
|
@patch('napps.kytos.topology.main.log') |
91
|
1 |
|
async def test_handle_interface_deleted(self, mock_log): |
92
|
|
|
"""Test handle interface deleted.""" |
93
|
1 |
|
self.napp.controller._buffers = KytosBuffers() |
94
|
1 |
|
event_name = '.*.switch.interface.deleted' |
95
|
1 |
|
interface = get_interface_mock("interface1", 7) |
96
|
1 |
|
interface.switch.dpid = "00:00:00:00:00:00:00:01" |
97
|
1 |
|
stats_event = KytosEvent(name=event_name, |
98
|
|
|
content={'interface': interface}) |
99
|
1 |
|
self.napp.get_intf_usage = MagicMock(return_value="Usage") |
100
|
1 |
|
self.napp._delete_interface = MagicMock() |
101
|
1 |
|
self.napp.handle_interface_deleted(stats_event) |
102
|
1 |
|
event_updated_response = self.napp.controller.buffers.app.get() |
103
|
1 |
|
assert event_updated_response.name == 'kytos/topology.updated' |
104
|
1 |
|
assert not self.napp._delete_interface.call_count |
105
|
1 |
|
assert mock_log.info.call_count == 1 |
106
|
|
|
|
107
|
1 |
|
self.napp.get_intf_usage.return_value = None |
108
|
1 |
|
self.napp.handle_interface_deleted(stats_event) |
109
|
1 |
|
event_updated_response = self.napp.controller.buffers.app.get() |
110
|
1 |
|
assert event_updated_response.name == 'kytos/topology.updated' |
111
|
1 |
|
assert self.napp._delete_interface.call_count == 1 |
112
|
|
|
|
113
|
1 |
|
async def test_handle_connection_lost(self): |
114
|
|
|
"""Test handle connection lost.""" |
115
|
1 |
|
self.napp.controller._buffers = KytosBuffers() |
116
|
1 |
|
event_name = '.*.connection.lost' |
117
|
1 |
|
source = Mock() |
118
|
1 |
|
stats_event = KytosEvent(name=event_name, |
119
|
|
|
content={'source': source}) |
120
|
1 |
|
self.napp.handle_connection_lost(stats_event) |
121
|
1 |
|
event_updated_response = self.napp.controller.buffers.app.get() |
122
|
|
|
assert event_updated_response.name == 'kytos/topology.updated' |
123
|
|
|
|