Passed
Push — master ( 99d253...10f509 )
by Humberto
03:29
created

TestMain.test_event_add_flow()   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 11

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nop 2
dl 12
loc 12
rs 9.85
c 0
b 0
f 0
1
"""Test Main methods."""
2
from unittest import TestCase
3
from unittest.mock import MagicMock, patch
4
5
from kytos.lib.helpers import (get_connection_mock, get_controller_mock,
6
                               get_kytos_event_mock, get_switch_mock,
7
                               get_test_client)
8
9
10
# pylint: disable=protected-access, too-many-public-methods
11
class TestMain(TestCase):
12
    """Tests for the Main class."""
13
14
    API_URL = 'http://localhost:8181/api/kytos/flow_manager'
15
16
    def setUp(self):
17
        patch('kytos.core.helpers.run_on_thread', lambda x: x).start()
18
        # pylint: disable=import-outside-toplevel
19
        from napps.kytos.flow_manager.main import Main
20
21
        self.addCleanup(patch.stopall)
22
23
        controller = get_controller_mock()
24
        self.switch_01 = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
25
        self.switch_01.is_enabled.return_value = True
26
        self.switch_01.flows = []
27
28
        self.switch_02 = get_switch_mock("00:00:00:00:00:00:00:02", 0x04)
29
        self.switch_02.is_enabled.return_value = False
30
        self.switch_02.flows = []
31
32
        controller.switches = {"00:00:00:00:00:00:00:01": self.switch_01,
33
                               "00:00:00:00:00:00:00:02": self.switch_02}
34
35
        self.napp = Main(controller)
36
37
    def test_rest_list_without_dpid(self):
38
        """Test list rest method withoud dpid."""
39
        flow_dict = {
40
            "priority": 13,
41
            "cookie": 84114964,
42
            "command": "add",
43
            "match": {"dl_dst": "00:15:af:d5:38:98"},
44
        }
45
        flow_dict_2 = {
46
            "priority": 18,
47
            "cookie": 84114964,
48
            "command": "add",
49
            "match": {"dl_dst": "00:15:af:d5:38:98"},
50
        }
51
        flow_1 = MagicMock()
52
        flow_1.as_dict.return_value = flow_dict
53
        flow_2 = MagicMock()
54
        flow_2.as_dict.return_value = flow_dict_2
55
        self.switch_01.flows.append(flow_1)
56
        self.switch_02.flows.append(flow_2)
57
58
        api = get_test_client(self.napp.controller, self.napp)
59
        url = f'{self.API_URL}/v2/flows'
60
61
        response = api.get(url)
62
        expected = {
63
            '00:00:00:00:00:00:00:01': {'flows': [flow_dict]},
64
            '00:00:00:00:00:00:00:02': {'flows': [flow_dict_2]},
65
        }
66
        self.assertEqual(response.json, expected)
67
        self.assertEqual(response.status_code, 200)
68
69
    def test_rest_list_with_dpid(self):
70
        """Test list rest method with dpid."""
71
        flow_dict = {
72
            "priority": 13,
73
            "cookie": 84114964,
74
            "command": "add",
75
            "match": {"dl_dst": "00:15:af:d5:38:98"},
76
        }
77
        flow_1 = MagicMock()
78
        flow_1.as_dict.return_value = flow_dict
79
        self.switch_01.flows.append(flow_1)
80
81
        api = get_test_client(self.napp.controller, self.napp)
82
        url = f'{self.API_URL}/v2/flows/00:00:00:00:00:00:00:01'
83
84
        response = api.get(url)
85
        expected = {'00:00:00:00:00:00:00:01': {'flows': [flow_dict]}}
86
87
        self.assertEqual(response.json, expected)
88
        self.assertEqual(response.status_code, 200)
89
90
    def test_list_flows_fail_case(self):
91
        """Test the failure case to recover all flows from a switch by dpid.
92
93
        Failure case: Switch not found.
94
        """
95
        api = get_test_client(self.napp.controller, self.napp)
96
        url = f'{self.API_URL}/v2/flows/00:00:00:00:00:00:00:05'
97
        response = api.get(url)
98
        self.assertEqual(response.status_code, 404)
99
100
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
101
    def test_rest_add_and_delete_without_dpid(self, mock_install_flows):
102
        """Test add and delete rest method without dpid."""
103
        api = get_test_client(self.napp.controller, self.napp)
104
105
        for method in ['flows', 'delete']:
106
            url = f'{self.API_URL}/v2/{method}'
107
108
            response_1 = api.post(url, json={'flows': [{"priority": 25}]})
109
            response_2 = api.post(url)
110
111
            self.assertEqual(response_1.status_code, 200)
112
            self.assertEqual(response_2.status_code, 400)
113
114
        self.assertEqual(mock_install_flows.call_count, 2)
115
116
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
117
    def test_rest_add_and_delete_with_dpid(self, mock_install_flows):
118
        """Test add and delete rest method with dpid."""
119
        api = get_test_client(self.napp.controller, self.napp)
120
        data = {'flows': [{"priority": 25}]}
121
        for method in ['flows', 'delete']:
122
            url_1 = f'{self.API_URL}/v2/{method}/00:00:00:00:00:00:00:01'
123
            url_2 = f'{self.API_URL}/v2/{method}/00:00:00:00:00:00:00:02'
124
125
            response_1 = api.post(url_1, json=data)
126
            response_2 = api.post(url_2, json=data)
127
128
            self.assertEqual(response_1.status_code, 200)
129
            if method == 'delete':
130
                self.assertEqual(response_2.status_code, 200)
131
132
        self.assertEqual(mock_install_flows.call_count, 3)
133
134
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
135
    def test_rest_add_and_delete_with_dpi_fail(self, mock_install_flows):
136
        """Test fail case the add and delete rest method with dpid."""
137
        api = get_test_client(self.napp.controller, self.napp)
138
        data = {'flows': [{"priority": 25}]}
139
        for method in ['flows', 'delete']:
140
            url_1 = f'{self.API_URL}/v2/{method}/00:00:00:00:00:00:00:01'
141
            url_2 = f'{self.API_URL}/v2/{method}/00:00:00:00:00:00:00:02'
142
            url_3 = f'{self.API_URL}/v2/{method}/00:00:00:00:00:00:00:03'
143
144
            response_1 = api.post(url_1)
145
            response_2 = api.post(url_2, data=data)
146
            response_3 = api.post(url_2, json={})
147
            response_4 = api.post(url_3, json=data)
148
149
            self.assertEqual(response_1.status_code, 400)
150
            self.assertEqual(response_2.status_code, 415)
151
            self.assertEqual(response_3.status_code, 400)
152
            self.assertEqual(response_4.status_code, 404)
153
154
        self.assertEqual(mock_install_flows.call_count, 0)
155
156
    def test_get_all_switches_enabled(self):
157
        """Test _get_all_switches_enabled method."""
158
        switches = self.napp._get_all_switches_enabled()
159
160
        self.assertEqual(switches, [self.switch_01])
161
162 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._store_changed_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
163
    @patch('napps.kytos.flow_manager.main.Main._send_napp_event')
164
    @patch('napps.kytos.flow_manager.main.Main._add_flow_mod_sent')
165
    @patch('napps.kytos.flow_manager.main.Main._send_flow_mod')
166
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
167
    def test_install_flows(self, *args):
168
        """Test _install_flows method."""
169
        (mock_flow_factory, mock_send_flow_mod, mock_add_flow_mod_sent,
170
         mock_send_napp_event, _) = args
171
        serializer = MagicMock()
172
        flow = MagicMock()
173
        flow_mod = MagicMock()
174
175
        flow.as_of_add_flow_mod.return_value = flow_mod
176
        serializer.from_dict.return_value = flow
177
        mock_flow_factory.return_value = serializer
178
179
        flows_dict = {'flows': [MagicMock()]}
180
        switches = [self.switch_01]
181
        self.napp._install_flows('add', flows_dict, switches)
182
183
        mock_send_flow_mod.assert_called_with(flow.switch, flow_mod)
184
        mock_add_flow_mod_sent.assert_called_with(flow_mod.header.xid,
185
                                                  flow, 'add')
186
        mock_send_napp_event.assert_called_with(self.switch_01, flow, 'add')
187
188 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._store_changed_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
189
    @patch('napps.kytos.flow_manager.main.Main._send_napp_event')
190
    @patch('napps.kytos.flow_manager.main.Main._add_flow_mod_sent')
191
    @patch('napps.kytos.flow_manager.main.Main._send_flow_mod')
192
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
193
    def test_install_flows_with_delete_strict(self, *args):
194
        """Test _install_flows method with strict delete command."""
195
        (mock_flow_factory, mock_send_flow_mod, mock_add_flow_mod_sent,
196
         mock_send_napp_event, _) = args
197
        serializer = MagicMock()
198
        flow = MagicMock()
199
        flow_mod = MagicMock()
200
201
        flow.as_of_strict_delete_flow_mod.return_value = flow_mod
202
        serializer.from_dict.return_value = flow
203
        mock_flow_factory.return_value = serializer
204
205
        flows_dict = {'flows': [MagicMock()]}
206
        switches = [self.switch_01]
207
        self.napp._install_flows('delete_strict', flows_dict, switches)
208
209
        mock_send_flow_mod.assert_called_with(flow.switch, flow_mod)
210
        mock_add_flow_mod_sent.assert_called_with(flow_mod.header.xid,
211
                                                  flow, 'delete_strict')
212
        mock_send_napp_event.assert_called_with(self.switch_01, flow,
213
                                                'delete_strict')
214
215 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
216
    def test_event_add_flow(self, mock_install_flows):
217
        """Test method for installing flows on the switches through events."""
218
        dpid = "00:00:00:00:00:00:00:01"
219
        switch = get_switch_mock(dpid)
220
        self.napp.controller.switches = {dpid: switch}
221
        mock_flow_dict = MagicMock()
222
        event = get_kytos_event_mock(name='kytos.flow_manager.flows.install',
223
                                     content={'dpid': dpid,
224
                                              'flow_dict': mock_flow_dict})
225
        self.napp.event_flows_install_delete(event)
226
        mock_install_flows.assert_called_with('add', mock_flow_dict, [switch])
227
228 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
229
    def test_event_flows_install_delete(self, mock_install_flows):
230
        """Test method for removing flows on the switches through events."""
231
        dpid = "00:00:00:00:00:00:00:01"
232
        switch = get_switch_mock(dpid)
233
        self.napp.controller.switches = {dpid: switch}
234
        mock_flow_dict = MagicMock()
235
        event = get_kytos_event_mock(name='kytos.flow_manager.flows.delete',
236
                                     content={'dpid': dpid,
237
                                              'flow_dict': mock_flow_dict})
238
        self.napp.event_flows_install_delete(event)
239
        mock_install_flows.assert_called_with('delete', mock_flow_dict,
240
                                              [switch])
241
242
    def test_add_flow_mod_sent(self):
243
        """Test _add_flow_mod_sent method."""
244
        xid = 0
245
        flow = MagicMock()
246
247
        self.napp._add_flow_mod_sent(xid, flow, 'add')
248
249
        self.assertEqual(self.napp._flow_mods_sent[xid], (flow, 'add'))
250
251
    @patch('kytos.core.buffers.KytosEventBuffer.put')
252
    def test_send_flow_mod(self, mock_buffers_put):
253
        """Test _send_flow_mod method."""
254
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
255
        flow_mod = MagicMock()
256
257
        self.napp._send_flow_mod(switch, flow_mod)
258
259
        mock_buffers_put.assert_called()
260
261
    @patch('kytos.core.buffers.KytosEventBuffer.put')
262
    def test_send_napp_event(self, mock_buffers_put):
263
        """Test _send_napp_event method."""
264
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
265
        flow = MagicMock()
266
267
        for command in ['add', 'delete', 'delete_strict', 'error']:
268
            self.napp._send_napp_event(switch, flow, command)
269
270
        self.assertEqual(mock_buffers_put.call_count, 4)
271
272
    @patch('napps.kytos.flow_manager.main.Main._send_napp_event')
273
    def test_handle_errors(self, mock_send_napp_event):
274
        """Test handle_errors method."""
275
        flow = MagicMock()
276
        self.napp._flow_mods_sent[0] = (flow, 'add')
277
278
        switch = get_switch_mock("00:00:00:00:00:00:00:01")
279
        switch.connection = get_connection_mock(
280
            0x04, get_switch_mock("00:00:00:00:00:00:00:02"))
281
282
        protocol = MagicMock()
283
        protocol.unpack.return_value = 'error_packet'
284
285
        switch.connection.protocol = protocol
286
287
        message = MagicMock()
288
        message.header.xid.value = 0
289
        message.error_type = 2
290
        message.code = 5
291
        event = get_kytos_event_mock(name='.*.of_core.*.ofpt_error',
292
                                     content={'message': message,
293
                                              'source': switch.connection})
294
        self.napp.handle_errors(event)
295
296
        mock_send_napp_event.assert_called_with(flow.switch, flow, 'error',
297
                                                error_command='add',
298
                                                error_code=5, error_type=2)
299
300
    @patch("napps.kytos.flow_manager.main.StoreHouse.get_data")
301
    def test_load_flows(self, mock_storehouse):
302
        """Test load flows."""
303
        self.napp._load_flows()
304
        mock_storehouse.assert_called()
305
306
    @patch("napps.kytos.flow_manager.main.CONSISTENCY_INTERVAL", -1)
307
    @patch("napps.kytos.flow_manager.main.Main._install_flows")
308
    def test_resend_stored_flows(self, mock_install_flows):
309
        """Test resend stored flows."""
310
        dpid = "00:00:00:00:00:00:00:01"
311
        switch = get_switch_mock(dpid, 0x04)
312
        mock_event = MagicMock()
313
        flow = {"command": "add", "flow": MagicMock()}
314
315
        flows = {"flow_list": [flow]}
316
        mock_event.content = {"switch": switch}
317
        self.napp.controller.switches = {dpid: switch}
318
        self.napp.stored_flows = {dpid: flows}
319
        self.napp.resend_stored_flows(mock_event)
320
        mock_install_flows.assert_called()
321
322
    @patch("napps.kytos.of_core.flow.FlowFactory.get_class")
323
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
324
    def test_store_changed_flows(self, mock_save_flow, _):
325
        """Test store changed flows."""
326
        dpid = "00:00:00:00:00:00:00:01"
327
        switch = get_switch_mock(dpid, 0x04)
328
        switch.id = dpid
329
        flow = {
330
            "priority": 17,
331
            "cookie": 84114964,
332
            "command": "add",
333
            "match": {"dl_dst": "00:15:af:d5:38:98"},
334
        }
335
        match_fields = {
336
            "priority": 17,
337
            "cookie": 84114964,
338
            "command": "add",
339
            "dl_dst": "00:15:af:d5:38:98",
340
        }
341
        flows = {"flow": flow}
342
343
        command = "add"
344
        flow_list = {
345
            "flow_list": [
346
                {"match_fields": match_fields, "command": "delete",
347
                 "flow": flow}
348
            ]
349
        }
350
        self.napp.stored_flows = {dpid: flow_list}
351
        self.napp._store_changed_flows(command, flows, switch)
352
        mock_save_flow.assert_called()
353
354
        self.napp.stored_flows = {}
355
        self.napp._store_changed_flows(command, flows, switch)
356
        mock_save_flow.assert_called()
357
358 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
359
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
360
    def test_check_switch_consistency_add(self, *args):
361
        """Test check_switch_consistency method.
362
363
        This test checks the case when a flow is missing in switch and have the
364
        ADD command.
365
        """
366
        (mock_flow_factory, mock_install_flows) = args
367
        dpid = "00:00:00:00:00:00:00:01"
368
        switch = get_switch_mock(dpid, 0x04)
369
        switch.flows = []
370
371
        flow_1 = MagicMock()
372
        flow_1.as_dict.return_value = {'flow_1': 'data'}
373
374
        flow_list = [{"command": "add",
375
                      "flow": {'flow_1': 'data'}
376
                      }]
377
        serializer = MagicMock()
378
        serializer.flow.cookie.return_value = 0
379
380
        mock_flow_factory.return_value = serializer
381
        self.napp.stored_flows = {dpid: {"flow_list": flow_list}}
382
        self.napp.check_switch_consistency(switch)
383
        mock_install_flows.assert_called()
384
385 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
386
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
387
    def test_check_switch_consistency_delete(self, *args):
388
        """Test check_switch_consistency method.
389
390
        This test checks the case when a flow is missing in switch and have the
391
        DELETE command.
392
        """
393
        (mock_flow_factory, mock_install_flows) = args
394
        dpid = "00:00:00:00:00:00:00:01"
395
        switch = get_switch_mock(dpid, 0x04)
396
397
        flow_1 = MagicMock()
398
        flow_1.as_dict.return_value = {'flow_1': 'data'}
399
400
        flow_list = [{"command": "delete",
401
                      "flow": {'flow_1': 'data'}
402
                      }]
403
        serializer = MagicMock()
404
        serializer.from_dict.return_value = flow_1
405
406
        switch.flows = [flow_1]
407
408
        mock_flow_factory.return_value = serializer
409
        self.napp.stored_flows = {dpid: {"flow_list": flow_list}}
410
        self.napp.check_switch_consistency(switch)
411
        mock_install_flows.assert_called()
412
413 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
414
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
415
    def test_check_storehouse_consistency(self, *args):
416
        """Test check_storehouse_consistency method.
417
418
        This test checks the case when a flow is missing in storehouse.
419
        """
420
        (mock_flow_factory, mock_install_flows) = args
421
        cookie_exception_interval = [(0x2b00000000000011, 0x2b000000000000ff)]
422
        self.napp.cookie_exception_range = cookie_exception_interval
423
        dpid = "00:00:00:00:00:00:00:01"
424
        switch = get_switch_mock(dpid, 0x04)
425
        flow_1 = MagicMock()
426
        flow_1.cookie = 0x2b00000000000010
427
        flow_1.as_dict.return_value = {'flow_1': 'data', 'cookie': 1}
428
429
        switch.flows = [flow_1]
430
431
        flow_list = [{"command": "add",
432
                      "flow": {'flow_2': 'data', 'cookie': 1}
433
                      }]
434
        serializer = flow_1
435
436
        mock_flow_factory.return_value = serializer
437
        self.napp.stored_flows = {dpid: {"flow_list": flow_list}}
438
        self.napp.check_storehouse_consistency(switch)
439
        mock_install_flows.assert_called()
440
441 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
442
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
443
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
444
    def test_no_strict_delete(self, *args):
445
        """Test the non-strict matching method.
446
447
        Test non-strict matching to delete a Flow using a cookie.
448
        """
449
        (mock_save_flow, _, _) = args
450
        dpid = "00:00:00:00:00:00:00:01"
451
        switch = get_switch_mock(dpid, 0x04)
452
        switch.id = dpid
453
        stored_flow = {
454
            "command": "add",
455
            "flow": {
456
                "actions": [{"action_type": "set_vlan", "vlan_id": 300}],
457
                "cookie": 6191162389751548793,
458
                "match": {"dl_vlan": 300, "in_port": 1},
459
            },
460
        }
461
        stored_flow2 = {
462
            "command": "add",
463
            "flow": {
464
                "actions": [],
465
                "cookie": 4961162389751548787,
466
                "match": {"in_port": 2},
467
            },
468
        }
469
        flow_to_install = {
470
            "cookie": 6191162389751548793,
471
            "cookie_mask": 18446744073709551615,
472
        }
473
        flow_list = {"flow_list": [stored_flow, stored_flow2]}
474
        command = "delete"
475
        self.napp.stored_flows = {dpid: flow_list}
476
477
        self.napp._store_changed_flows(command, flow_to_install, switch)
478
        mock_save_flow.assert_called()
479
        self.assertEqual(len(self.napp.stored_flows), 1)
480
481 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
482
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
483
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
484
    def test_no_strict_delete_with_ipv4(self, *args):
485
        """Test the non-strict matching method.
486
487
        Test non-strict matching to delete a Flow using IPv4.
488
        """
489
        (mock_save_flow, _, _) = args
490
        dpid = "00:00:00:00:00:00:00:01"
491
        switch = get_switch_mock(dpid, 0x04)
492
        switch.id = dpid
493
        stored_flow = {
494
            "command": "add",
495
            "flow": {
496
                "priority": 10,
497
                "cookie": 84114904,
498
                "match": {
499
                    "ipv4_src": "192.168.1.120",
500
                    "ipv4_dst": "192.168.0.2",
501
                },
502
                "actions": [],
503
            },
504
        }
505
        stored_flow2 = {
506
            "command": "add",
507
            "flow": {
508
                "actions": [],
509
                "cookie": 4961162389751548787,
510
                "match": {"in_port": 2},
511
            },
512
        }
513
        flow_to_install = {"match": {"ipv4_src": '192.168.1.1/24'}}
514
        flow_list = {"flow_list": [stored_flow, stored_flow2]}
515
        command = "delete"
516
        self.napp.stored_flows = {dpid: flow_list}
517
518
        self.napp._store_changed_flows(command, flow_to_install, switch)
519
        mock_save_flow.assert_called()
520
        self.assertEqual(len(self.napp.stored_flows[dpid]['flow_list']), 2)
521
522 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
523
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
524
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
525
    def test_no_strict_delete_with_ipv4_fail(self, *args):
526
        """Test the non-strict matching method.
527
528
        Test non-strict Fail case matching to delete a Flow using IPv4.
529
        """
530
        (mock_save_flow, _, _) = args
531
        dpid = "00:00:00:00:00:00:00:01"
532
        switch = get_switch_mock(dpid, 0x04)
533
        switch.id = dpid
534
        stored_flow = {
535
            "command": "add",
536
            "flow": {
537
                "priority": 10,
538
                "cookie": 84114904,
539
                "match": {
540
                    "ipv4_src": "192.168.2.1",
541
                    "ipv4_dst": "192.168.0.2",
542
                },
543
                "actions": [],
544
            },
545
        }
546
        stored_flow2 = {
547
            "command": "add",
548
            "flow": {
549
                "actions": [],
550
                "cookie": 4961162389751548787,
551
                "match": {"in_port": 2},
552
            },
553
        }
554
        flow_to_install = {"match": {"ipv4_src": '192.168.1.1/24'}}
555
        flow_list = {"flow_list": [stored_flow, stored_flow2]}
556
        command = "delete"
557
        self.napp.stored_flows = {dpid: flow_list}
558
559
        self.napp._store_changed_flows(command, flow_to_install, switch)
560
        mock_save_flow.assert_called()
561
        self.assertEqual(len(self.napp.stored_flows[dpid]['flow_list']), 3)
562
563
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
564
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
565
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
566
    def test_no_strict_delete_of10(self, *args):
567
        """Test the non-strict matching method.
568
569
        Test non-strict matching to delete a Flow using OF10.
570
        """
571
        (mock_save_flow, _, _) = args
572
        dpid = "00:00:00:00:00:00:00:01"
573
        switch = get_switch_mock(dpid, 0x01)
574
        switch.id = dpid
575
        stored_flow = {
576
            "command": "add",
577
            "flow": {
578
                "actions": [{"max_len": 65535, "port": 6}],
579
                "cookie": 4961162389751548787,
580
                "match": {
581
                    "in_port": 80,
582
                    "dl_src": "00:00:00:00:00:00",
583
                    "dl_dst": "f2:0b:a4:7d:f8:ea",
584
                    "dl_vlan": 0,
585
                    "dl_vlan_pcp": 0,
586
                    "dl_type": 0,
587
                    "nw_tos": 0,
588
                    "nw_proto": 0,
589
                    "nw_src": "192.168.0.1",
590
                    "nw_dst": "0.0.0.0",
591
                    "tp_src": 0,
592
                    "tp_dst": 0,
593
                },
594
                "out_port": 65532,
595
                "priority": 123,
596
            },
597
        }
598
        stored_flow2 = {
599
            "command": "add",
600
            "flow": {
601
                "actions": [],
602
                "cookie": 4961162389751654,
603
                "match": {
604
                    "in_port": 2,
605
                    "dl_src": "00:00:00:00:00:00",
606
                    "dl_dst": "f2:0b:a4:7d:f8:ea",
607
                    "dl_vlan": 0,
608
                    "dl_vlan_pcp": 0,
609
                    "dl_type": 0,
610
                    "nw_tos": 0,
611
                    "nw_proto": 0,
612
                    "nw_src": "192.168.0.1",
613
                    "nw_dst": "0.0.0.0",
614
                    "tp_src": 0,
615
                    "tp_dst": 0,
616
                },
617
                "out_port": 655,
618
                "priority": 1,
619
            },
620
        }
621
        flow_to_install = {"match": {"in_port": 80, "wildcards": 4194303}}
622
        flow_list = {"flow_list": [stored_flow, stored_flow2]}
623
        command = "delete"
624
        self.napp.stored_flows = {dpid: flow_list}
625
626
        self.napp._store_changed_flows(command, flow_to_install, switch)
627
        mock_save_flow.assert_called()
628
        self.assertEqual(len(self.napp.stored_flows[dpid]['flow_list']), 1)
629
630 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
631
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
632
    def test_consistency_cookie_ignored_range(self, *args):
633
        """Test the consistency `cookie` ignored range."""
634
        (mock_flow_factory, mock_install_flows) = args
635
        dpid = "00:00:00:00:00:00:00:01"
636
        switch = get_switch_mock(dpid, 0x04)
637
        cookie_ignored_interval = [(0x2b00000000000011,
638
                                    0x2b000000000000ff), 0x2b00000000000100]
639
        self.napp.cookie_ignored_range = cookie_ignored_interval
640
        flow = MagicMock()
641
        expected = [
642
                    {'cookie': 0x2b00000000000010, 'called': 1},
643
                    {'cookie': 0x2b00000000000013, 'called': 0},
644
                    {'cookie': 0x2b00000000000100, 'called': 0},
645
                    {'cookie': 0x2b00000000000101, 'called': 1}]
646
        # ignored flow
647
        for i in expected:
648
            mock_install_flows.call_count = 0
649
            cookie = i['cookie']
650
            called = i['called']
651
            flow.cookie = cookie
652
            flow.as_dict.return_value = {'flow_1': 'data', 'cookie': cookie}
653
            switch.flows = [flow]
654
            mock_flow_factory.return_value = flow
655
            self.napp.stored_flows = {dpid: {"flow_list": flow}}
656
            self.napp.check_storehouse_consistency(switch)
657
            self.assertEqual(mock_install_flows.call_count, called)
658
659 View Code Duplication
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
660
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
661
    def test_consistency_table_id_ignored_range(self, *args):
662
        """Test the consistency `table_id` ignored range."""
663
        (mock_flow_factory, mock_install_flows) = args
664
        dpid = "00:00:00:00:00:00:00:01"
665
        switch = get_switch_mock(dpid, 0x04)
666
        table_id_ignored_interval = [(1, 2), 3]
667
        self.napp.tab_id_ignored_range = table_id_ignored_interval
668
        flow = MagicMock()
669
        expected = [
670
                    {'table_id': 0, 'called': 1},
671
                    {'table_id': 3, 'called': 0},
672
                    {'table_id': 4, 'called': 1}]
673
        # ignored flow
674
        for i in expected:
675
            table_id = i['table_id']
676
            called = i['called']
677
            mock_install_flows.call_count = 0
678
            flow.table_id = table_id
679
            flow.as_dict.return_value = {'flow_1': 'data', 'cookie': table_id}
680
            switch.flows = [flow]
681
            mock_flow_factory.return_value = flow
682
            self.napp.stored_flows = {dpid: {"flow_list": flow}}
683
            self.napp.check_storehouse_consistency(switch)
684
            self.assertEqual(mock_install_flows.call_count, called)
685