Passed
Pull Request — master (#56)
by Carlos
02:42
created

TestMain.test_rest_get_lldp_interfaces()   A

Complexity

Conditions 1

Size

Total Lines 14
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nop 1
dl 0
loc 14
rs 9.8
c 0
b 0
f 0
1
"""Test Main methods."""
2
from unittest import TestCase
3
from unittest.mock import MagicMock, call, patch
4
5
from kytos.lib.helpers import (get_controller_mock, get_kytos_event_mock,
6
                               get_switch_mock, get_test_client)
7
8
from tests.helpers import get_topology_mock
9
10
11
# pylint: disable=protected-access
12
class TestMain(TestCase):
13
    """Tests for the Main class."""
14
15
    def setUp(self):
16
        """Execute steps before each tests."""
17
        self.server_name_url = 'http://127.0.0.1:8181/api/kytos/of_lldp'
18
19
        patch('kytos.core.helpers.run_on_thread', lambda x: x).start()
20
        # pylint: disable=bad-option-value, import-outside-toplevel
21
        from napps.kytos.of_lldp.main import Main
22
        self.addCleanup(patch.stopall)
23
24
        self.topology = get_topology_mock()
25
        controller = get_controller_mock()
26
        controller.switches = self.topology.switches
27
28
        self.napp = Main(controller)
29
30
    def get_topology_interfaces(self):
31
        """Return interfaces present in topology."""
32
        interfaces = []
33
        for switch in list(self.topology.switches.values()):
34
            interfaces += list(switch.interfaces.values())
35
        return interfaces
36
37
    @patch('kytos.core.buffers.KytosEventBuffer.put')
38
    @patch('napps.kytos.of_lldp.main.Main._build_lldp_packet_out')
39
    @patch('napps.kytos.of_lldp.main.KytosEvent')
40
    @patch('napps.kytos.of_lldp.main.VLAN')
41
    @patch('napps.kytos.of_lldp.main.Ethernet')
42
    @patch('napps.kytos.of_lldp.main.DPID')
43
    @patch('napps.kytos.of_lldp.main.LLDP')
44
    def test_execute(self, *args):
45
        """Test execute method."""
46
        (_, _, mock_ethernet, _, mock_kytos_event, mock_build_lldp_packet_out,
47
         mock_buffer_put) = args
48
49
        ethernet = MagicMock()
50
        ethernet.pack.return_value = 'pack'
51
        interfaces = self.get_topology_interfaces()
52
        po_args = [(interface.switch.connection.protocol.version,
53
                    interface.port_number, 'pack') for interface in interfaces]
54
55
        mock_ethernet.return_value = ethernet
56
        mock_kytos_event.side_effect = po_args
57
58
        self.napp.execute()
59
60
        mock_build_lldp_packet_out.assert_has_calls([call(*(arg))
61
                                                     for arg in po_args])
62
        mock_buffer_put.assert_has_calls([call(arg)
63
                                          for arg in po_args])
64
65
    @patch('requests.delete')
66
    @patch('requests.post')
67
    def test_handle_lldp_flows(self, mock_post, mock_delete):
68
        """Test handle_lldp_flow method."""
69
        dpid = "00:00:00:00:00:00:00:01"
70
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
71
        self.napp.controller.switches = {dpid: switch}
72
        event_post = get_kytos_event_mock(name='kytos/topology.switch.enabled',
73
                                          content={'dpid': dpid})
74
75
        event_del = get_kytos_event_mock(name='kytos/topology.switch.disabled',
76
                                         content={'dpid': dpid})
77
78
        self.napp.handle_lldp_flows(event_post)
79
        mock_post.assert_called()
80
81
        self.napp.handle_lldp_flows(event_del)
82
        mock_delete.assert_called()
83
84
    @patch('kytos.core.buffers.KytosEventBuffer.put')
85
    @patch('napps.kytos.of_lldp.main.KytosEvent')
86
    @patch('kytos.core.controller.Controller.get_switch_by_dpid')
87
    @patch('napps.kytos.of_lldp.main.Main._unpack_non_empty')
88
    @patch('napps.kytos.of_lldp.main.UBInt32')
89
    @patch('napps.kytos.of_lldp.main.DPID')
90
    @patch('napps.kytos.of_lldp.main.LLDP')
91
    @patch('napps.kytos.of_lldp.main.Ethernet')
92
    def test_notify_uplink_detected(self, *args):
93
        """Test notify_uplink_detected method."""
94
        (mock_ethernet, mock_lldp, mock_dpid, mock_ubint32,
95
         mock_unpack_non_empty, mock_get_switch_by_dpid, mock_kytos_event,
96
         mock_buffer_put) = args
97
98
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
99
        message = MagicMock()
100
        message.in_port = 1
101
        message.data = 'data'
102
        event = get_kytos_event_mock(name='kytos/of_core.v0x0[14].messages.in.'
103
                                          'ofpt_packet_in',
104
                                     content={'source': switch.connection,
105
                                              'message': message})
106
107
        ethernet = MagicMock()
108
        ethernet.ether_type = 0x88CC
109
        ethernet.data = 'eth_data'
110
        lldp = MagicMock()
111
        lldp.chassis_id.sub_value = 'chassis_id'
112
        lldp.port_id.sub_value = 'port_id'
113
        dpid = MagicMock()
114
        dpid.value = "00:00:00:00:00:00:00:02"
115
        port_b = MagicMock()
116
117
        mock_unpack_non_empty.side_effect = [ethernet, lldp, dpid, port_b]
118
        mock_get_switch_by_dpid.return_value = get_switch_mock(dpid.value,
119
                                                               0x04)
120
        mock_kytos_event.return_value = 'nni'
121
122
        self.napp.notify_uplink_detected(event)
123
124
        calls = [call(mock_ethernet, message.data),
125
                 call(mock_lldp, ethernet.data),
126
                 call(mock_dpid, lldp.chassis_id.sub_value),
127
                 call(mock_ubint32, lldp.port_id.sub_value)]
128
        mock_unpack_non_empty.assert_has_calls(calls)
129
        mock_buffer_put.assert_called_with('nni')
130
131
    @patch('napps.kytos.of_lldp.main.PO13')
132
    @patch('napps.kytos.of_lldp.main.PO10')
133
    @patch('napps.kytos.of_lldp.main.AO13')
134
    @patch('napps.kytos.of_lldp.main.AO10')
135
    def test_build_lldp_packet_out(self, *args):
136
        """Test _build_lldp_packet_out method."""
137
        (mock_ao10, mock_ao13, mock_po10, mock_po13) = args
138
139
        ao10 = MagicMock()
140
        ao13 = MagicMock()
141
        po10 = MagicMock()
142
        po10.actions = []
143
        po13 = MagicMock()
144
        po13.actions = []
145
146
        mock_ao10.return_value = ao10
147
        mock_ao13.return_value = ao13
148
        mock_po10.return_value = po10
149
        mock_po13.return_value = po13
150
151
        packet_out10 = self.napp._build_lldp_packet_out(0x01, 1, 'data1')
152
        packet_out13 = self.napp._build_lldp_packet_out(0x04, 2, 'data2')
153
        packet_out14 = self.napp._build_lldp_packet_out(0x05, 3, 'data3')
154
155
        self.assertEqual(packet_out10.data, 'data1')
156
        self.assertEqual(packet_out10.actions, [ao10])
157
        self.assertEqual(packet_out10.actions[0].port, 1)
158
159
        self.assertEqual(packet_out13.data, 'data2')
160
        self.assertEqual(packet_out13.actions, [ao13])
161
        self.assertEqual(packet_out13.actions[0].port, 2)
162
163
        self.assertIsNone(packet_out14)
164
165
    @patch('napps.kytos.of_lldp.main.settings')
166
    @patch('napps.kytos.of_lldp.main.EtherType')
167
    @patch('napps.kytos.of_lldp.main.Port13')
168
    @patch('napps.kytos.of_lldp.main.Port10')
169
    def test_build_lldp_flow(self, *args):
170
        """Test _build_lldp_flow method."""
171
        (mock_v0x01_port, mock_v0x04_port, mock_ethertype,
172
         mock_settings) = args
173
        self.napp.vlan_id = None
174
        mock_v0x01_port.OFPP_CONTROLLER = 123
175
        mock_v0x04_port.OFPP_CONTROLLER = 1234
176
177
        mock_ethertype.LLDP = 10
178
        mock_settings.FLOW_VLAN_VID = None
179
        mock_settings.FLOW_PRIORITY = 1500
180
181
        flow = {}
182
        match = {}
183
        flow['priority'] = 1500
184
        match['dl_type'] = 10
185
186
        flow['match'] = match
187
        expected_flow_v0x01 = flow.copy()
188
        expected_flow_v0x04 = flow.copy()
189
190
        expected_flow_v0x01['actions'] = [{'action_type': 'output',
191
                                           'port': 123}]
192
193
        expected_flow_v0x04['actions'] = [{'action_type': 'output',
194
                                           'port': 1234}]
195
196
        flow_mod10 = self.napp._build_lldp_flow(0x01)
197
        flow_mod13 = self.napp._build_lldp_flow(0x04)
198
199
        self.assertDictEqual(flow_mod10, expected_flow_v0x01)
200
        self.assertDictEqual(flow_mod13, expected_flow_v0x04)
201
202
    def test_unpack_non_empty(self):
203
        """Test _unpack_non_empty method."""
204
        desired_class = MagicMock()
205
        data = MagicMock()
206
        data.value = 'data'
207
208
        obj = self.napp._unpack_non_empty(desired_class, data)
209
210
        obj.unpack.assert_called_with('data')
211
212
    def test_get_data(self):
213
        """Test _get_data method."""
214
        req = MagicMock()
215
        interfaces = ['00:00:00:00:00:00:00:01:1', '00:00:00:00:00:00:00:01:2']
216
        req.get_json.return_value = {'interfaces': interfaces}
217
218
        data = self.napp._get_data(req)
219
220
        self.assertEqual(data, interfaces)
221
222
    def test_get_interfaces(self):
223
        """Test _get_interfaces method."""
224
        expected_interfaces = self.get_topology_interfaces()
225
226
        interfaces = self.napp._get_interfaces()
227
228
        self.assertEqual(interfaces, expected_interfaces)
229
230
    def test_get_interfaces_dict(self):
231
        """Test _get_interfaces_dict method."""
232
        interfaces = self.napp._get_interfaces()
233
        expected_interfaces = {inter.id: inter for inter in interfaces}
234
235
        interfaces_dict = self.napp._get_interfaces_dict(interfaces)
236
237
        self.assertEqual(interfaces_dict, expected_interfaces)
238
239
    def test_get_lldp_interfaces(self):
240
        """Test _get_lldp_interfaces method."""
241
        lldp_interfaces = self.napp._get_lldp_interfaces()
242
243
        expected_interfaces = ['00:00:00:00:00:00:00:01:1',
244
                               '00:00:00:00:00:00:00:01:2',
245
                               '00:00:00:00:00:00:00:02:1',
246
                               '00:00:00:00:00:00:00:02:2',
247
                               '00:00:00:00:00:00:00:03:1',
248
                               '00:00:00:00:00:00:00:03:2']
249
250
        self.assertEqual(lldp_interfaces, expected_interfaces)
251
252
    def test_rest_get_lldp_interfaces(self):
253
        """Test get_lldp_interfaces method."""
254
        api = get_test_client(self.napp.controller, self.napp)
255
        url = f'{self.server_name_url}/v1/interfaces'
256
        response = api.open(url, method='GET')
257
258
        expected_data = {"interfaces": ['00:00:00:00:00:00:00:01:1',
259
                                        '00:00:00:00:00:00:00:01:2',
260
                                        '00:00:00:00:00:00:00:02:1',
261
                                        '00:00:00:00:00:00:00:02:2',
262
                                        '00:00:00:00:00:00:00:03:1',
263
                                        '00:00:00:00:00:00:00:03:2']}
264
        self.assertEqual(response.json, expected_data)
265
        self.assertEqual(response.status_code, 200)
266
267
    def test_enable_disable_lldp_200(self):
268
        """Test 200 response for enable_lldp and disable_lldp methods."""
269
        data = {"interfaces": ['00:00:00:00:00:00:00:01:1',
270
                               '00:00:00:00:00:00:00:01:2',
271
                               '00:00:00:00:00:00:00:02:1',
272
                               '00:00:00:00:00:00:00:02:2',
273
                               '00:00:00:00:00:00:00:03:1',
274
                               '00:00:00:00:00:00:00:03:2']}
275
276
        api = get_test_client(self.napp.controller, self.napp)
277
278
        url = f'{self.server_name_url}/v1/interfaces/disable'
279
        disable_response = api.open(url, method='POST', json=data)
280
281
        url = f'{self.server_name_url}/v1/interfaces/enable'
282
        enable_response = api.open(url, method='POST', json=data)
283
284
        self.assertEqual(disable_response.status_code, 200)
285
        self.assertEqual(enable_response.status_code, 200)
286
287
    def test_enable_disable_lldp_404(self):
288
        """Test 404 response for enable_lldp and disable_lldp methods."""
289
        data = {"interfaces": []}
290
291
        self.napp.controller.switches = {}
292
        api = get_test_client(self.napp.controller, self.napp)
293
294
        url = f'{self.server_name_url}/v1/interfaces/disable'
295
        disable_response = api.open(url, method='POST', json=data)
296
297
        url = f'{self.server_name_url}/v1/interfaces/enable'
298
        enable_response = api.open(url, method='POST', json=data)
299
300
        self.assertEqual(disable_response.status_code, 404)
301
        self.assertEqual(enable_response.status_code, 404)
302
303
    def test_enable_disable_lldp_400(self):
304
        """Test 400 response for enable_lldp and disable_lldp methods."""
305
        data = {"interfaces": ['00:00:00:00:00:00:00:01:1',
306
                               '00:00:00:00:00:00:00:01:2',
307
                               '00:00:00:00:00:00:00:02:1',
308
                               '00:00:00:00:00:00:00:02:2',
309
                               '00:00:00:00:00:00:00:03:1',
310
                               '00:00:00:00:00:00:00:03:2',
311
                               '00:00:00:00:00:00:00:04:1']}
312
313
        api = get_test_client(self.napp.controller, self.napp)
314
315
        url = f'{self.server_name_url}/v1/interfaces/disable'
316
        disable_response = api.open(url, method='POST', json=data)
317
318
        url = f'{self.server_name_url}/v1/interfaces/enable'
319
        enable_response = api.open(url, method='POST', json=data)
320
321
        self.assertEqual(disable_response.status_code, 400)
322
        self.assertEqual(enable_response.status_code, 400)
323
324
    def test_get_time(self):
325
        """Test get polling time."""
326
        api = get_test_client(self.napp.controller, self.napp)
327
328
        url = f'{self.server_name_url}/v1/polling_time'
329
        response = api.open(url, method='GET')
330
331
        self.assertEqual(response.status_code, 200)
332
333
    def test_set_time(self):
334
        """Test update polling time."""
335
        data = {"polling_time": 5}
336
337
        api = get_test_client(self.napp.controller, self.napp)
338
339
        url = f'{self.server_name_url}/v1/polling_time'
340
        response = api.open(url, method='POST', json=data)
341
342
        self.assertEqual(response.status_code, 200)
343
        self.assertEqual(self.napp.polling_time, data['polling_time'])
344
345
    def test_set_time_400(self):
346
        """Test fail case the update polling time."""
347
        api = get_test_client(self.napp.controller, self.napp)
348
349
        url = f'{self.server_name_url}/v1/polling_time'
350
351
        data = {'polling_time': 'A'}
352
        response = api.open(url, method='POST', json=data)
353
        self.assertEqual(response.status_code, 400)
354