build.tests.unit.test_main.TestMain.test_execute()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 16
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 16
rs 9.7
c 0
b 0
f 0
cc 1
nop 2
1
"""Test Main methods."""
2
from unittest import TestCase
3
from unittest.mock import MagicMock, PropertyMock, create_autospec, patch
4
5
from pyof.foundation.network_types import Ethernet
6
from pyof.v0x01.controller2switch.common import StatsType
7
from pyof.v0x04.controller2switch.common import MultipartType
8
9
from kytos.core.connection import ConnectionState
10
from kytos.lib.helpers import (get_connection_mock, get_kytos_event_mock,
11
                               get_switch_mock)
12
from napps.kytos.of_core.utils import NegotiationException
13
from tests.helpers import get_controller_mock
14
15
16
# pylint: disable=protected-access, too-many-public-methods
17
class TestMain(TestCase):
18
    """Test the Main class."""
19
20
    def setUp(self):
21
        """Execute steps before each tests.
22
        Set the server_name_url from kytos/of_core
23
        """
24
        self.switch_v0x01 = get_switch_mock("00:00:00:00:00:00:00:01", 0x01)
25
        self.switch_v0x04 = get_switch_mock("00:00:00:00:00:00:00:02", 0x04)
26
        self.switch_v0x01.connection = get_connection_mock(
27
            0x01, get_switch_mock("00:00:00:00:00:00:00:03"))
28
        self.switch_v0x04.connection = get_connection_mock(
29
            0x04, get_switch_mock("00:00:00:00:00:00:00:04"))
30
31
        patch('kytos.core.helpers.run_on_thread', lambda x: x).start()
32
        # pylint: disable=import-outside-toplevel
33
        from napps.kytos.of_core.main import Main
34
        self.addCleanup(patch.stopall)
35
        self.napp = Main(get_controller_mock())
36
37
    @patch('napps.kytos.of_core.v0x01.utils.send_echo')
38
    @patch('napps.kytos.of_core.v0x04.utils.send_echo')
39
    def test_execute(self, *args):
40
        """Test execute."""
41
        (mock_of_core_v0x04_utils, mock_of_core_v0x01_utils) = args
42
        self.switch_v0x01.is_connected.return_value = True
43
        self.switch_v0x04.is_connected.return_value = True
44
        self.napp.controller.switches = {"00:00:00:00:00:00:00:01":
45
                                         self.switch_v0x01}
46
        self.napp.execute()
47
        mock_of_core_v0x01_utils.assert_called()
48
49
        self.napp.controller.switches = {"00:00:00:00:00:00:00:01":
50
                                         self.switch_v0x04}
51
        self.napp.execute()
52
        mock_of_core_v0x04_utils.assert_called()
53
54
    @patch('napps.kytos.of_core.v0x04.utils.update_flow_list')
55
    @patch('napps.kytos.of_core.v0x01.utils.update_flow_list')
56
    def test_request_flow_list(self, *args):
57
        """Test request flow list."""
58
        (mock_update_flow_list_v0x01, mock_update_flow_list_v0x04) = args
59
        mock_update_flow_list_v0x04.return_value = "ABC"
60
        self.napp._request_flow_list(self.switch_v0x01)
61
        mock_update_flow_list_v0x01.assert_called_with(self.napp.controller,
62
                                                       self.switch_v0x01)
63
        self.napp._request_flow_list(self.switch_v0x04)
64
        mock_update_flow_list_v0x04.assert_called_with(self.napp.controller,
65
                                                       self.switch_v0x04)
66
67
    @patch('napps.kytos.of_core.v0x04.utils.update_flow_list')
68
    @patch('napps.kytos.of_core.v0x01.utils.update_flow_list')
69
    def test_on_handshake_completed_request_flow_list(self, *args):
70
        """Test request flow list."""
71
        (mock_update_flow_list_v0x01, mock_update_flow_list_v0x04) = args
72
        mock_update_flow_list_v0x04.return_value = "ABC"
73
        name = 'kytos/of_core.handshake.completed'
74
        content = {"switch": self.switch_v0x01}
75
        event = get_kytos_event_mock(name=name, content=content)
76
        self.napp.on_handshake_completed_request_flow_list(event)
77
        mock_update_flow_list_v0x01.assert_called_with(self.napp.controller,
78
                                                       self.switch_v0x01)
79
        content = {"switch": self.switch_v0x04}
80
        event = get_kytos_event_mock(name=name, content=content)
81
        self.napp.on_handshake_completed_request_flow_list(event)
82
        mock_update_flow_list_v0x04.assert_called_with(self.napp.controller,
83
                                                       self.switch_v0x04)
84
85
    @patch('napps.kytos.of_core.v0x01.flow.Flow.from_of_flow_stats')
86
    def test_handle_stats_reply(self, mock_from_of_flow_stats_v0x01):
87
        """Test handle stats reply."""
88
        mock_from_of_flow_stats_v0x01.return_value = "ABC"
89
90
        flow_msg = MagicMock()
91
        flow_msg.body = "A"
92
        flow_msg.body_type = StatsType.OFPST_FLOW
93
94
        name = 'kytos/of_core.v0x01.messages.in.ofpt_stats_reply'
95
        content = {"source": self.switch_v0x01.connection,
96
                   "message": flow_msg}
97
        event = get_kytos_event_mock(name=name, content=content)
98
        self.napp.handle_stats_reply(event)
99
        mock_from_of_flow_stats_v0x01.assert_called_with(
100
            flow_msg.body, self.switch_v0x01.connection.switch)
101
102
        desc_msg = MagicMock()
103
        desc_msg.body = "A"
104
        desc_msg.body_type = StatsType.OFPST_DESC
105
        content = {"source": self.switch_v0x01.connection,
106
                   "message": desc_msg}
107
        event = get_kytos_event_mock(name=name, content=content)
108
        switch_update = self.switch_v0x01.connection.switch.update_description
109
        self.napp.handle_stats_reply(event)
110
        self.assertEqual(switch_update.call_count, 1)
111
112
    @patch('napps.kytos.of_core.main.Main._handle_multipart_flow_stats')
113
    @patch('napps.kytos.of_core.v0x04.utils.handle_port_desc')
114
    def test_handle_multipart_reply(self, *args):
115
        """Test handle multipart reply."""
116
        (mock_of_core_v0x04_utils, mock_from_of_flow_stats_v0x04) = args
117
118
        flow_msg = MagicMock()
119
        flow_msg.multipart_type = MultipartType.OFPMP_FLOW
120
        name = 'kytos/of_core.v0x04.messages.in.ofpt_multipart_reply'
121
        content = {"source": self.switch_v0x04.connection,
122
                   "message": flow_msg}
123
        event = get_kytos_event_mock(name=name, content=content)
124
125
        self.napp.handle_multipart_reply(event)
126
        mock_from_of_flow_stats_v0x04.assert_called_with(
127
            flow_msg, self.switch_v0x04.connection.switch)
128
129
        ofpmp_port_desc = MagicMock()
130
        ofpmp_port_desc.body = "A"
131
        ofpmp_port_desc.multipart_type = MultipartType.OFPMP_PORT_DESC
132
        content = {"source": self.switch_v0x04.connection,
133
                   "message": ofpmp_port_desc}
134
        event = get_kytos_event_mock(name=name, content=content)
135
        self.napp.handle_multipart_reply(event)
136
        mock_of_core_v0x04_utils.assert_called_with(
137
            self.napp.controller, self.switch_v0x04.connection.switch,
138
            ofpmp_port_desc.body)
139
140
        ofpmp_desc = MagicMock()
141
        ofpmp_desc.body = "A"
142
        ofpmp_desc.multipart_type = MultipartType.OFPMP_DESC
143
        content = {"source": self.switch_v0x04.connection,
144
                   "message": ofpmp_desc}
145
        event = get_kytos_event_mock(name=name, content=content)
146
        switch_update = self.switch_v0x04.connection.switch.update_description
147
        self.napp.handle_multipart_reply(event)
148
        self.assertEqual(switch_update.call_count, 1)
149
150
    @patch('kytos.core.buffers.KytosEventBuffer.put')
151
    @patch('napps.kytos.of_core.v0x04.utils.send_set_config')
152
    @patch('napps.kytos.of_core.v0x01.utils.send_set_config')
153
    @patch('napps.kytos.of_core.v0x04.utils.send_desc_request')
154
    @patch('napps.kytos.of_core.v0x01.utils.send_desc_request')
155
    @patch('napps.kytos.of_core.v0x04.utils.handle_features_reply')
156
    @patch('napps.kytos.of_core.v0x01.utils.handle_features_reply')
157
    def test_handle_features_reply(self, *args):
158
        """Test handle features reply."""
159
        (mock_freply_v0x01, mock_freply_v0x04, mock_send_desc_request_v0x01,
160
         mock_send_desc_request_v0x04, mock_send_set_config_v0x01,
161
         mock_send_set_config_v0x04, mock_buffers_put) = args
162
        mock_freply_v0x01.return_value = self.switch_v0x01.connection.switch
163
        mock_freply_v0x04.return_value = self.switch_v0x04.connection.switch
164
165
        self.switch_v0x01.connection.state = ConnectionState.SETUP
166
        self.switch_v0x01.connection.protocol.state = 'waiting_features_reply'
167
        name = 'kytos/of_core.v0x0[14].messages.in.ofpt_features_reply'
168
        content = {"source": self.switch_v0x01.connection}
169
        event = get_kytos_event_mock(name=name, content=content)
170
        self.napp.handle_features_reply(event)
171
        mock_freply_v0x01.assert_called_with(self.napp.controller, event)
172
        mock_send_desc_request_v0x01.assert_called_with(
173
            self.napp.controller, self.switch_v0x01.connection.switch)
174
        mock_send_set_config_v0x01.assert_called_with(
175
            self.napp.controller, self.switch_v0x01.connection.switch)
176
177
        self.switch_v0x04.connection.state = ConnectionState.SETUP
178
        self.switch_v0x04.connection.protocol.state = 'waiting_features_reply'
179
        content = {"source": self.switch_v0x04.connection}
180
        event = get_kytos_event_mock(name=name, content=content)
181
        self.napp.handle_features_reply(event)
182
        mock_freply_v0x04.assert_called_with(self.napp.controller, event)
183
        mock_send_desc_request_v0x04.assert_called_with(
184
            self.napp.controller, self.switch_v0x04.connection.switch)
185
        mock_send_set_config_v0x04.assert_called_with(
186
            self.napp.controller, self.switch_v0x04.connection.switch)
187
188
        mock_buffers_put.assert_called()
189
190
    @patch('napps.kytos.of_core.main.Main._update_switch_flows')
191
    @patch('napps.kytos.of_core.v0x04.flow.Flow.from_of_flow_stats')
192
    @patch('napps.kytos.of_core.main.Main._is_multipart_reply_ours')
193
    def test_handle_multipart_flow_stats(self, *args):
194
        """Test handle multipart flow stats."""
195
        (mock_is_multipart_reply_ours, mock_from_of_flow_stats_v0x01,
196
         mock_update_switch_flows) = args
197
        mock_is_multipart_reply_ours.return_value = True
198
        mock_from_of_flow_stats_v0x01.return_value = "ABC"
199
200
        flow_msg = MagicMock()
201
        flow_msg.body = "A"
202
        flow_msg.flags.value = 2
203
        flow_msg.body_type = StatsType.OFPST_FLOW
204
205
        self.napp._handle_multipart_flow_stats(flow_msg, self.switch_v0x04)
206
207
        mock_is_multipart_reply_ours.assert_called_with(flow_msg,
208
                                                        self.switch_v0x04,
209
                                                        'flows')
210
        mock_from_of_flow_stats_v0x01.assert_called_with(flow_msg.body,
211
                                                         self.switch_v0x04)
212
        mock_update_switch_flows.assert_called_with(self.switch_v0x04)
213
214
    def test_update_switch_flows(self):
215
        """Test update_switch_flows."""
216
        dpid = '00:00:00:00:00:00:00:01'
217
        mock_switch = get_switch_mock(dpid)
218
        mock_switch.id = dpid
219
        self.napp._multipart_replies_flows = {dpid: mock_switch}
220
        self.napp._multipart_replies_xids = {dpid: {'flows': mock_switch}}
221
        self.napp._update_switch_flows(mock_switch)
222
        self.assertEqual(self.napp._multipart_replies_xids, {dpid: {}})
223
        self.assertEqual(self.napp._multipart_replies_flows, {})
224
225
    def test_is_multipart_reply_ours(self):
226
        """Test _is_multipart_reply_ours."""
227
        dpid_a = '00:00:00:00:00:00:00:01'
228
        dpid_b = '00:00:00:00:00:00:00:02'
229
        mock_switch = get_switch_mock(dpid_a)
230
        mock_reply = MagicMock()
231
        mock_reply.header.xid = mock_switch
232
        type(mock_switch).id = PropertyMock(side_effect=[dpid_a,
233
                                                         dpid_a, dpid_b])
234
        self.napp._multipart_replies_xids = {dpid_a: {'flows': mock_switch}}
235
        response = self.napp._is_multipart_reply_ours(
236
            mock_reply, mock_switch, 'flows')
237
        self.assertEqual(response, True)
238
239
        response = self.napp._is_multipart_reply_ours(
240
            mock_reply, mock_switch, 'flows')
241
        self.assertEqual(response, False)
242
243
    @patch('napps.kytos.of_core.main.of_slicer')
244
    @patch('napps.kytos.of_core.main.Main._negotiate')
245
    @patch('napps.kytos.of_core.main.Main.emit_message_in')
246
    def test_handle_raw_in(self, *args):
247
        """Test handle_raw_in."""
248
        (mock_emit_message_in, mock_negotiate, mock_of_slicer) = args
249
250
        mock_packets = MagicMock()
251
        mock_data = MagicMock()
252
        mock_connection = MagicMock()
253
        mock_connection.is_new.side_effect = [True, False, True, False]
254
        mock_connection.is_during_setup.return_value = False
255
        mock_of_slicer.return_value = [[mock_packets, mock_packets], b'']
256
        name = 'kytos/core.openflow.raw.in'
257
        content = {'source': mock_connection, 'new_data': mock_data}
258
        mock_event = get_kytos_event_mock(name=name, content=content)
259
260
        self.napp.handle_raw_in(mock_event)
261
        mock_negotiate.assert_called()
262
        mock_emit_message_in.assert_called()
263
264
        # Test Fail
265
        mock_negotiate.side_effect = NegotiationException('Foo')
266
        self.napp.handle_raw_in(mock_event)
267
        self.assertEqual(mock_connection.close.call_count, 1)
268
269
        mock_connection.close.call_count = 0
270
        mock_connection.protocol.unpack.side_effect = AttributeError()
271
        self.napp.handle_raw_in(mock_event)
272
        self.assertEqual(mock_connection.close.call_count, 1)
273
274
    @patch('napps.kytos.of_core.main.Main._new_port_stats')
275
    @patch('napps.kytos.of_core.main.Main._is_multipart_reply_ours')
276
    def test_handle_multipart_port_stats(self, *args):
277
        """Test handle multipart flow stats."""
278
        (mock_is_multipart_reply_ours,
279
         mock_new_port_stats) = args
280
        mock_is_multipart_reply_ours.return_value = True
281
282
        port_stats_msg = MagicMock()
283
        port_stats_msg.body = "A"
284
        port_stats_msg.flags.value = 2
285
        port_stats_msg.multipart_type = MultipartType.OFPMP_PORT_STATS
286
287
        self.napp._handle_multipart_port_stats(port_stats_msg,
288
                                               self.switch_v0x04)
289
290
        mock_is_multipart_reply_ours.assert_called_with(port_stats_msg,
291
                                                        self.switch_v0x04,
292
                                                        'ports')
293
        mock_new_port_stats.assert_called_with(self.switch_v0x04)
294
295
    @patch('napps.kytos.of_core.main.Main.update_port_status')
296
    @patch('napps.kytos.of_core.main.Main.update_links')
297
    def test_emit_message_in(self, *args):
298
        """Test emit_message_in."""
299
        (mock_update_links, mock_update_port_status) = args
300
301
        mock_port_connection = MagicMock()
302
        msg_port_mock = MagicMock()
303
        msg_port_mock.header.message_type.name = 'ofpt_port_status'
304
        mock_port_connection.side_effect = True
305
        self.napp.emit_message_in(mock_port_connection,
306
                                  msg_port_mock)
307
        mock_update_port_status.assert_called_with(msg_port_mock,
308
                                                   mock_port_connection)
309
310
        mock_packet_in_connection = MagicMock()
311
        msg_packet_in_mock = MagicMock()
312
        mock_packet_in_connection.side_effect = True
313
        msg_packet_in_mock.header.message_type.name = 'ofpt_packet_in'
314
        self.napp.emit_message_in(mock_packet_in_connection,
315
                                  msg_packet_in_mock)
316
        mock_update_links.assert_called_with(msg_packet_in_mock,
317
                                             mock_packet_in_connection)
318
319
    @patch('napps.kytos.of_core.main.emit_message_out')
320
    def test_emit_message_out(self, mock_emit_message_out):
321
        """Test emit message_out."""
322
        mock_connection = MagicMock()
323
        mock_message = MagicMock()
324
        mock_connection.is_alive.return_value = True
325
        self.napp.emit_message_out(mock_connection, mock_message)
326
        mock_emit_message_out.assert_called()
327
328
    @patch('pyof.utils.v0x04.symmetric.echo_reply.EchoReply')
329
    @patch('napps.kytos.of_core.main.Main.emit_message_out')
330
    def test_handle_echo_request(self, *args):
331
        """Test handle echo request messages."""
332
        (mock_emit_message_out, mock_echo_reply) = args
333
        mock_event = MagicMock()
334
        mock_echo_request = MagicMock()
335
        mock_echo_reply.return_value = "A"
336
        mock_echo_request.header.xid = "A"
337
        mock_echo_request.data = "A"
338
        mock_event.source.protocol.version = 4
339
        mock_event.message = mock_echo_request
340
        self.napp.handle_echo_request(mock_event)
341
        mock_echo_reply.assert_called_with(xid=mock_echo_request.header.xid,
342
                                           data=mock_echo_request.data)
343
        mock_emit_message_out.assert_called_with(mock_event.source, "A")
344
345
    @patch('napps.kytos.of_core.main.Main.send_features_request')
346
    @patch('napps.kytos.of_core.v0x04.utils.say_hello')
347
    @patch('napps.kytos.of_core.main._get_version_from_bitmask')
348
    @patch('napps.kytos.of_core.main._get_version_from_header')
349
    def test_negotiate(self, *args):
350
        """Test negotiate."""
351
        (mock_version_header, mock_version_bitmask, mock_say_hello,
352
         mock_features_request) = args
353
        mock_version_header.return_value = 4
354
        mock_version_bitmask.side_effect = [4, None]
355
        mock_connection = MagicMock()
356
        mock_message = MagicMock()
357
        type(mock_message).versions = PropertyMock(side_effect=[4, 4, 4,
358
                                                                False])
359
360
        self.napp._negotiate(mock_connection, mock_message)
361
        mock_version_bitmask.assert_called_with(mock_message.versions)
362
        mock_say_hello.assert_called_with(self.napp.controller,
363
                                          mock_connection)
364
        mock_features_request.assert_called_with(mock_connection)
365
366
        self.napp._negotiate(mock_connection, mock_message)
367
        mock_say_hello.assert_called_with(self.napp.controller,
368
                                          mock_connection)
369
        mock_features_request.assert_called_with(mock_connection)
370
371
        # Test Fail
372
        with self.assertRaises(NegotiationException):
373
            type(mock_message).versions = PropertyMock(return_value=[4])
374
            self.napp._negotiate(mock_connection, mock_message)
375
376
    @patch('pyof.utils.v0x04.asynchronous.error_msg.ErrorMsg')
377
    @patch('napps.kytos.of_core.main.Main.emit_message_out')
378
    @patch('kytos.core.buffers.KytosEventBuffer.put')
379
    def tests_fail_negotiation(self, *args):
380
        """Test fail_negotiation."""
381
        (mock_event_buffer, mock_emit_message_out,
382
         mock_error_msg) = args
383
        mock_connection = MagicMock()
384
        mock_message = MagicMock()
385
        mock_connection.id = "A"
386
        mock_message.side_effect = 4
387
        self.napp.fail_negotiation(mock_connection, mock_message)
388
        mock_event_buffer.assert_called()
389
        mock_emit_message_out.assert_called_with(mock_connection,
390
                                                 mock_error_msg.return_value)
391
392
    @patch('napps.kytos.of_core.settings.SEND_FEATURES_REQUEST_ON_ECHO')
393
    @patch('napps.kytos.of_core.main.Main.send_features_request')
394
    def test_handle_queued_openflow_echo_reply(self, *args):
395
        """Test handle queued OpenFlow echo reply messages."""
396
        (mock_send_features_request, mock_settings) = args
397
        mock_settings.return_value = True
398
        mock_event = MagicMock()
399
        self.napp.handle_queued_openflow_echo_reply(mock_event)
400
        mock_send_features_request.assert_called_with(mock_event.destination)
401
402
    @patch('pyof.utils.v0x04.controller2switch.'
403
           'features_request.FeaturesRequest')
404
    @patch('napps.kytos.of_core.main.Main.emit_message_out')
405
    def test_send_features_request(self, *args):
406
        """Test send send_features_request."""
407
        (mock_emit_message_out, mock_features_request) = args
408
        mock_destination = MagicMock()
409
        mock_destination.protocol.version = 4
410
        mock_features_request.return_value = "A"
411
        self.napp.send_features_request(mock_destination)
412
        mock_features_request.assert_called()
413
        mock_emit_message_out.assert_called_with(mock_destination, "A")
414
415
    def test_handle_features_request_sent(self):
416
        """Test tests_handle_features_request_sent."""
417
        mock_protocol = MagicMock()
418
        mock_protocol.protocol.state = 'sending_features'
419
        expected = 'waiting_features_reply'
420
        name = 'kytos/of_core.v0x0[14].messages.out.ofpt_features_request'
421
        content = {'destination': mock_protocol}
422
        mock_event = get_kytos_event_mock(name=name, content=content)
423
        self.napp.handle_features_request_sent(mock_event)
424
        self.assertEqual(mock_event.destination.protocol.state, expected)
425
426
    def test_handle_openflow_in_hello_failed(self):
427
        """Test handle_openflow_in_hello_failed."""
428
        mock_destination = MagicMock()
429
        content = {'destination': mock_destination}
430
        mock_event = get_kytos_event_mock(name='kytos/of_core',
431
                                          content=content)
432
        self.napp.handle_openflow_in_hello_failed(mock_event)
433
        self.assertEqual(mock_event.destination.close.call_count, 1)
434
435
    @patch('napps.kytos.of_core.main.log')
436
    def test_shutdown(self, mock_log):
437
        """Test shutdown."""
438
        self.napp.shutdown()
439
        self.assertEqual(mock_log.debug.call_count, 1)
440
441
    @patch('kytos.core.buffers.KytosEventBuffer.put')
442
    @patch('napps.kytos.of_core.main.Ethernet')
443
    def test_update_links(self, *args):
444
        """Test update_links."""
445
        (mock_ethernet, mock_buffer_put) = args
446
        ethernet = create_autospec(Ethernet)
447
        ethernet.ether_type = "A"
448
        mock_ethernet.side_effect = ethernet
449
        mock_message = MagicMock()
450
        mock_s = MagicMock()
451
        mock_s.switch.get_interface_by_port_no.side_effect = [AttributeError(),
452
                                                              True]
453
        self.napp.update_links(mock_message, mock_s)
454
        mock_ethernet.assert_called()
455
        mock_buffer_put.assert_called()
456
457
    @patch('kytos.core.buffers.KytosEventBuffer.put')
458
    def test_send_specific_port_mod(self, mock_buffer_put):
459
        """Test send specific port."""
460
        mock_port = MagicMock()
461
        mock_interface = MagicMock()
462
        type(mock_port.state).value = PropertyMock(side_effect=[0, 1, 2])
463
        current_state = 0
464
        self.napp._send_specific_port_mod(mock_port,
465
                                          mock_interface, current_state)
466
        mock_buffer_put.assert_called()
467
468
        current_state = 1
469
        self.napp._send_specific_port_mod(mock_port,
470
                                          mock_interface, current_state)
471
        mock_buffer_put.assert_called()
472
473
        current_state = 2
474
        self.napp._send_specific_port_mod(mock_port,
475
                                          mock_interface, current_state)
476
        mock_buffer_put.assert_called()
477
478
    @patch('kytos.core.buffers.KytosEventBuffer.put')
479
    @patch('napps.kytos.of_core.main.Interface')
480
    @patch('napps.kytos.of_core.main.Main._send_specific_port_mod')
481
    def test_update_port_status(self, *args):
482
        """Test update_port_status."""
483
        (mock_port_mod, mock_interface, mock_buffer_put) = args
484
        mock_port_status = MagicMock()
485
        mock_source = MagicMock()
486
487
        mock_port_status.reason.value.side_effect = [0, 1, 2]
488
        mock_port_status.reason.enum_ref(0).name = 'OFPPR_ADD'
489
        self.napp.update_port_status(mock_port_status, mock_source)
490
        mock_interface.assert_called()
491
492
        # check OFPRR_MODIFY
493
        mock_port_status.reason.enum_ref(1).name = 'OFPPR_MODIFY'
494
        mock_source.switch.get_interface_by_port_no.return_value = False
495
        self.napp.update_port_status(mock_port_status, mock_source)
496
        mock_port_mod.assert_called()
497
        mock_buffer_put.assert_called()
498
499
        mock_source.switch.get_interface_by_port_no.return_value = MagicMock()
500
        self.napp.update_port_status(mock_port_status, mock_source)
501
        mock_port_mod.assert_called()
502
        mock_buffer_put.assert_called()
503
504
        # check OFPRR_DELETE
505
        mock_port_status.reason.enum_ref(2).name = 'OFPPR_DELETE'
506
        self.napp.update_port_status(mock_port_status, mock_source)
507
        mock_port_mod.assert_called()
508
        mock_buffer_put.assert_called()
509