Passed
Pull Request — master (#129)
by Carlos
02:40
created

TestMain.test_event_flows_install_delete()   A

Complexity

Conditions 1

Size

Total Lines 13
Code Lines 12

Duplication

Lines 13
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nop 2
dl 13
loc 13
rs 9.8
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={'data': '123'})
109
            response_2 = api.post(url)
110
111
            self.assertEqual(response_1.status_code, 200)
112
            self.assertEqual(response_2.status_code, 404)
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
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
            url_3 = f'{self.API_URL}/v2/{method}/00:00:00:00:00:00:00:03'
125
126
            response_1 = api.post(url_1)
127
            response_2 = api.post(url_1, json={'data': '123'})
128
            response_3 = api.post(url_2, json={'data': '123'})
129
            response_4 = api.post(url_3, json={'data': '123'})
130
131
            self.assertEqual(response_1.status_code, 404)
132
            self.assertEqual(response_2.status_code, 200)
133
            if method == 'flows':
134
                self.assertEqual(response_3.status_code, 404)
135
            else:
136
                self.assertEqual(response_3.status_code, 200)
137
            self.assertEqual(response_4.status_code, 404)
138
139
        self.assertEqual(mock_install_flows.call_count, 3)
140
141
    def test_get_all_switches_enabled(self):
142
        """Test _get_all_switches_enabled method."""
143
        switches = self.napp._get_all_switches_enabled()
144
145
        self.assertEqual(switches, [self.switch_01])
146
147 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...
148
    @patch('napps.kytos.flow_manager.main.Main._send_napp_event')
149
    @patch('napps.kytos.flow_manager.main.Main._add_flow_mod_sent')
150
    @patch('napps.kytos.flow_manager.main.Main._send_flow_mod')
151
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
152
    def test_install_flows(self, *args):
153
        """Test _install_flows method."""
154
        (mock_flow_factory, mock_send_flow_mod, mock_add_flow_mod_sent,
155
         mock_send_napp_event, _) = args
156
        serializer = MagicMock()
157
        flow = MagicMock()
158
        flow_mod = MagicMock()
159
160
        flow.as_of_add_flow_mod.return_value = flow_mod
161
        serializer.from_dict.return_value = flow
162
        mock_flow_factory.return_value = serializer
163
164
        flows_dict = {'flows': [MagicMock()]}
165
        switches = [self.switch_01]
166
        self.napp._install_flows('add', flows_dict, switches)
167
168
        mock_send_flow_mod.assert_called_with(flow.switch, flow_mod)
169
        mock_add_flow_mod_sent.assert_called_with(flow_mod.header.xid,
170
                                                  flow, 'add')
171
        mock_send_napp_event.assert_called_with(self.switch_01, flow, 'add')
172
173 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...
174
    @patch('napps.kytos.flow_manager.main.Main._send_napp_event')
175
    @patch('napps.kytos.flow_manager.main.Main._add_flow_mod_sent')
176
    @patch('napps.kytos.flow_manager.main.Main._send_flow_mod')
177
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
178
    def test_install_flows_with_delete_strict(self, *args):
179
        """Test _install_flows method with strict delete command."""
180
        (mock_flow_factory, mock_send_flow_mod, mock_add_flow_mod_sent,
181
         mock_send_napp_event, _) = args
182
        serializer = MagicMock()
183
        flow = MagicMock()
184
        flow_mod = MagicMock()
185
186
        flow.as_of_strict_delete_flow_mod.return_value = flow_mod
187
        serializer.from_dict.return_value = flow
188
        mock_flow_factory.return_value = serializer
189
190
        flows_dict = {'flows': [MagicMock()]}
191
        switches = [self.switch_01]
192
        self.napp._install_flows('delete_strict', flows_dict, switches)
193
194
        mock_send_flow_mod.assert_called_with(flow.switch, flow_mod)
195
        mock_add_flow_mod_sent.assert_called_with(flow_mod.header.xid,
196
                                                  flow, 'delete_strict')
197
        mock_send_napp_event.assert_called_with(self.switch_01, flow,
198
                                                'delete_strict')
199
200 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...
201
    def test_event_add_flow(self, mock_install_flows):
202
        """Test method for installing flows on the switches through events."""
203
        dpid = "00:00:00:00:00:00:00:01"
204
        switch = get_switch_mock(dpid)
205
        self.napp.controller.switches = {dpid: switch}
206
        mock_flow_dict = MagicMock()
207
        event = get_kytos_event_mock(name='kytos.flow_manager.flows.install',
208
                                     content={'dpid': dpid,
209
                                              'flow_dict': mock_flow_dict})
210
        self.napp.event_flows_install_delete(event)
211
        mock_install_flows.assert_called_with('add', mock_flow_dict, [switch])
212
213 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...
214
    def test_event_flows_install_delete(self, mock_install_flows):
215
        """Test method for removing flows on the switches through events."""
216
        dpid = "00:00:00:00:00:00:00:01"
217
        switch = get_switch_mock(dpid)
218
        self.napp.controller.switches = {dpid: switch}
219
        mock_flow_dict = MagicMock()
220
        event = get_kytos_event_mock(name='kytos.flow_manager.flows.delete',
221
                                     content={'dpid': dpid,
222
                                              'flow_dict': mock_flow_dict})
223
        self.napp.event_flows_install_delete(event)
224
        mock_install_flows.assert_called_with('delete', mock_flow_dict,
225
                                              [switch])
226
227
    def test_add_flow_mod_sent(self):
228
        """Test _add_flow_mod_sent method."""
229
        xid = 0
230
        flow = MagicMock()
231
232
        self.napp._add_flow_mod_sent(xid, flow, 'add')
233
234
        self.assertEqual(self.napp._flow_mods_sent[xid], (flow, 'add'))
235
236
    @patch('kytos.core.buffers.KytosEventBuffer.put')
237
    def test_send_flow_mod(self, mock_buffers_put):
238
        """Test _send_flow_mod method."""
239
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
240
        flow_mod = MagicMock()
241
242
        self.napp._send_flow_mod(switch, flow_mod)
243
244
        mock_buffers_put.assert_called()
245
246
    @patch('kytos.core.buffers.KytosEventBuffer.put')
247
    def test_send_napp_event(self, mock_buffers_put):
248
        """Test _send_napp_event method."""
249
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
250
        flow = MagicMock()
251
252
        for command in ['add', 'delete', 'delete_strict', 'error']:
253
            self.napp._send_napp_event(switch, flow, command)
254
255
        self.assertEqual(mock_buffers_put.call_count, 4)
256
257
    @patch('napps.kytos.flow_manager.main.Main._send_napp_event')
258
    def test_handle_errors(self, mock_send_napp_event):
259
        """Test handle_errors method."""
260
        flow = MagicMock()
261
        self.napp._flow_mods_sent[0] = (flow, 'add')
262
263
        switch = get_switch_mock("00:00:00:00:00:00:00:01")
264
        switch.connection = get_connection_mock(
265
            0x04, get_switch_mock("00:00:00:00:00:00:00:02"))
266
267
        protocol = MagicMock()
268
        protocol.unpack.return_value = 'error_packet'
269
270
        switch.connection.protocol = protocol
271
272
        message = MagicMock()
273
        message.header.xid.value = 0
274
        message.error_type = 2
275
        message.code = 5
276
        event = get_kytos_event_mock(name='.*.of_core.*.ofpt_error',
277
                                     content={'message': message,
278
                                              'source': switch.connection})
279
        self.napp.handle_errors(event)
280
281
        mock_send_napp_event.assert_called_with(flow.switch, flow, 'error',
282
                                                error_command='add',
283
                                                error_code=5, error_type=2)
284
285
    @patch("napps.kytos.flow_manager.main.StoreHouse.get_data")
286
    def test_load_flows(self, mock_storehouse):
287
        """Test load flows."""
288
        self.napp._load_flows()
289
        mock_storehouse.assert_called()
290
291
    @patch("napps.kytos.flow_manager.main.CONSISTENCY_INTERVAL", -1)
292
    @patch("napps.kytos.flow_manager.main.Main._install_flows")
293
    def test_resend_stored_flows(self, mock_install_flows):
294
        """Test resend stored flows."""
295
        dpid = "00:00:00:00:00:00:00:01"
296
        switch = get_switch_mock(dpid, 0x04)
297
        mock_event = MagicMock()
298
        flow = {"command": "add", "flow": MagicMock()}
299
300
        flows = {"flow_list": [flow]}
301
        mock_event.content = {"switch": switch}
302
        self.napp.controller.switches = {dpid: switch}
303
        self.napp.stored_flows = {dpid: flows}
304
        self.napp.resend_stored_flows(mock_event)
305
        mock_install_flows.assert_called()
306
307
    @patch("napps.kytos.of_core.flow.FlowFactory.get_class")
308
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
309
    def test_store_changed_flows(self, mock_save_flow, _):
310
        """Test store changed flows."""
311
        dpid = "00:00:00:00:00:00:00:01"
312
        switch = get_switch_mock(dpid, 0x04)
313
        switch.id = dpid
314
        flow = {
315
            "priority": 17,
316
            "cookie": 84114964,
317
            "command": "add",
318
            "match": {"dl_dst": "00:15:af:d5:38:98"},
319
        }
320
        match_fields = {
321
            "priority": 17,
322
            "cookie": 84114964,
323
            "command": "add",
324
            "dl_dst": "00:15:af:d5:38:98",
325
        }
326
        flows = {"flow": flow}
327
328
        command = "add"
329
        flow_list = {
330
            "flow_list": [
331
                {"match_fields": match_fields, "command": "delete",
332
                 "flow": flow}
333
            ]
334
        }
335
        self.napp.stored_flows = {dpid: flow_list}
336
        self.napp._store_changed_flows(command, flows, switch)
337
        mock_save_flow.assert_called()
338
339
        self.napp.stored_flows = {}
340
        self.napp._store_changed_flows(command, flows, switch)
341
        mock_save_flow.assert_called()
342
343 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...
344
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
345
    def test_check_switch_consistency_add(self, *args):
346
        """Test check_switch_consistency method.
347
348
        This test checks the case when a flow is missing in switch and have the
349
        ADD command.
350
        """
351
        (mock_flow_factory, mock_install_flows) = args
352
        dpid = "00:00:00:00:00:00:00:01"
353
        switch = get_switch_mock(dpid, 0x04)
354
        switch.flows = []
355
356
        flow_1 = MagicMock()
357
        flow_1.as_dict.return_value = {'flow_1': 'data'}
358
359
        flow_list = [{"command": "add",
360
                      "flow": {'flow_1': 'data'}
361
                      }]
362
        serializer = MagicMock()
363
364
        mock_flow_factory.return_value = serializer
365
        self.napp.stored_flows = {dpid: {"flow_list": flow_list}}
366
        self.napp.check_switch_consistency(switch)
367
        mock_install_flows.assert_called()
368
369 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...
370
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
371
    def test_check_switch_consistency_delete(self, *args):
372
        """Test check_switch_consistency method.
373
374
        This test checks the case when a flow is missing in switch and have the
375
        DELETE command.
376
        """
377
        (mock_flow_factory, mock_install_flows) = args
378
        dpid = "00:00:00:00:00:00:00:01"
379
        switch = get_switch_mock(dpid, 0x04)
380
381
        flow_1 = MagicMock()
382
        flow_1.as_dict.return_value = {'flow_1': 'data'}
383
384
        flow_list = [{"command": "delete",
385
                      "flow": {'flow_1': 'data'}
386
                      }]
387
        serializer = MagicMock()
388
        serializer.from_dict.return_value = flow_1
389
390
        switch.flows = [flow_1]
391
392
        mock_flow_factory.return_value = serializer
393
        self.napp.stored_flows = {dpid: {"flow_list": flow_list}}
394
        self.napp.check_switch_consistency(switch)
395
        mock_install_flows.assert_called()
396
397 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...
398
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
399
    def test_check_storehouse_consistency(self, *args):
400
        """Test check_storehouse_consistency method.
401
402
        This test checks the case when a flow is missing in storehouse.
403
        """
404
        (mock_flow_factory, mock_install_flows) = args
405
        dpid = "00:00:00:00:00:00:00:01"
406
        switch = get_switch_mock(dpid, 0x04)
407
408
        flow_1 = MagicMock()
409
        flow_1.as_dict.return_value = {'flow_1': 'data'}
410
411
        switch.flows = [flow_1]
412
413
        flow_list = [{"command": "add",
414
                      "flow": {'flow_2': 'data'}
415
                      }]
416
        serializer = MagicMock()
417
418
        mock_flow_factory.return_value = serializer
419
        self.napp.stored_flows = {dpid: {"flow_list": flow_list}}
420
        self.napp.check_storehouse_consistency(switch)
421
        mock_install_flows.assert_called()
422
423 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...
424
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
425
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
426
    def test_no_strict_delete(self, *args):
427
        """Test the non-strict matching method.
428
429
        Test non-strict matching to delete a Flow using a cookie.
430
        """
431
        (mock_save_flow, _, _) = args
432
        dpid = "00:00:00:00:00:00:00:01"
433
        switch = get_switch_mock(dpid, 0x04)
434
        switch.id = dpid
435
        stored_flow = {
436
            "command": "add",
437
            "flow": {
438
                "actions": [{"action_type": "set_vlan", "vlan_id": 300}],
439
                "cookie": 6191162389751548793,
440
                "match": {"dl_vlan": 300, "in_port": 1},
441
            },
442
        }
443
        stored_flow2 = {
444
            "command": "add",
445
            "flow": {
446
                "actions": [],
447
                "cookie": 4961162389751548787,
448
                "match": {"in_port": 2},
449
            },
450
        }
451
        flow_to_install = {
452
            "cookie": 6191162389751548793,
453
            "cookie_mask": 18446744073709551615,
454
        }
455
        flow_list = {"flow_list": [stored_flow, stored_flow2]}
456
        command = "delete"
457
        self.napp.stored_flows = {dpid: flow_list}
458
459
        self.napp._store_changed_flows(command, flow_to_install, switch)
460
        mock_save_flow.assert_called()
461
        self.assertEqual(len(self.napp.stored_flows), 1)
462
463 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...
464
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
465
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
466
    def test_no_strict_delete_with_ipv4(self, *args):
467
        """Test the non-strict matching method.
468
469
        Test non-strict matching to delete a Flow using IPv4.
470
        """
471
        (mock_save_flow, _, _) = args
472
        dpid = "00:00:00:00:00:00:00:01"
473
        switch = get_switch_mock(dpid, 0x04)
474
        switch.id = dpid
475
        stored_flow = {
476
            "command": "add",
477
            "flow": {
478
                "priority": 10,
479
                "cookie": 84114904,
480
                "match": {
481
                    "ipv4_src": "192.168.1.120",
482
                    "ipv4_dst": "192.168.0.2",
483
                },
484
                "actions": [],
485
            },
486
        }
487
        stored_flow2 = {
488
            "command": "add",
489
            "flow": {
490
                "actions": [],
491
                "cookie": 4961162389751548787,
492
                "match": {"in_port": 2},
493
            },
494
        }
495
        flow_to_install = {"match": {"ipv4_src": '192.168.1.1/24'}}
496
        flow_list = {"flow_list": [stored_flow, stored_flow2]}
497
        command = "delete"
498
        self.napp.stored_flows = {dpid: flow_list}
499
500
        self.napp._store_changed_flows(command, flow_to_install, switch)
501
        mock_save_flow.assert_called()
502
        self.assertEqual(len(self.napp.stored_flows[dpid]['flow_list']), 2)
503
504 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...
505
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
506
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
507
    def test_no_strict_delete_with_ipv4_fail(self, *args):
508
        """Test the non-strict matching method.
509
510
        Test non-strict Fail case matching to delete a Flow using IPv4.
511
        """
512
        (mock_save_flow, _, _) = args
513
        dpid = "00:00:00:00:00:00:00:01"
514
        switch = get_switch_mock(dpid, 0x04)
515
        switch.id = dpid
516
        stored_flow = {
517
            "command": "add",
518
            "flow": {
519
                "priority": 10,
520
                "cookie": 84114904,
521
                "match": {
522
                    "ipv4_src": "192.168.2.1",
523
                    "ipv4_dst": "192.168.0.2",
524
                },
525
                "actions": [],
526
            },
527
        }
528
        stored_flow2 = {
529
            "command": "add",
530
            "flow": {
531
                "actions": [],
532
                "cookie": 4961162389751548787,
533
                "match": {"in_port": 2},
534
            },
535
        }
536
        flow_to_install = {"match": {"ipv4_src": '192.168.1.1/24'}}
537
        flow_list = {"flow_list": [stored_flow, stored_flow2]}
538
        command = "delete"
539
        self.napp.stored_flows = {dpid: flow_list}
540
541
        self.napp._store_changed_flows(command, flow_to_install, switch)
542
        mock_save_flow.assert_called()
543
        self.assertEqual(len(self.napp.stored_flows[dpid]['flow_list']), 3)
544
545
    @patch('napps.kytos.flow_manager.main.Main._install_flows')
546
    @patch('napps.kytos.flow_manager.main.FlowFactory.get_class')
547
    @patch("napps.kytos.flow_manager.main.StoreHouse.save_flow")
548
    def test_no_strict_delete_of10(self, *args):
549
        """Test the non-strict matching method.
550
551
        Test non-strict matching to delete a Flow using OF10.
552
        """
553
        (mock_save_flow, _, _) = args
554
        dpid = "00:00:00:00:00:00:00:01"
555
        switch = get_switch_mock(dpid, 0x01)
556
        switch.id = dpid
557
        stored_flow = {
558
            "command": "add",
559
            "flow": {
560
                "actions": [{"max_len": 65535, "port": 6}],
561
                "cookie": 4961162389751548787,
562
                "match": {
563
                    "in_port": 80,
564
                    "dl_src": "00:00:00:00:00:00",
565
                    "dl_dst": "f2:0b:a4:7d:f8:ea",
566
                    "dl_vlan": 0,
567
                    "dl_vlan_pcp": 0,
568
                    "dl_type": 0,
569
                    "nw_tos": 0,
570
                    "nw_proto": 0,
571
                    "nw_src": "192.168.0.1",
572
                    "nw_dst": "0.0.0.0",
573
                    "tp_src": 0,
574
                    "tp_dst": 0,
575
                },
576
                "out_port": 65532,
577
                "priority": 123,
578
            },
579
        }
580
        stored_flow2 = {
581
            "command": "add",
582
            "flow": {
583
                "actions": [],
584
                "cookie": 4961162389751654,
585
                "match": {
586
                    "in_port": 2,
587
                    "dl_src": "00:00:00:00:00:00",
588
                    "dl_dst": "f2:0b:a4:7d:f8:ea",
589
                    "dl_vlan": 0,
590
                    "dl_vlan_pcp": 0,
591
                    "dl_type": 0,
592
                    "nw_tos": 0,
593
                    "nw_proto": 0,
594
                    "nw_src": "192.168.0.1",
595
                    "nw_dst": "0.0.0.0",
596
                    "tp_src": 0,
597
                    "tp_dst": 0,
598
                },
599
                "out_port": 655,
600
                "priority": 1,
601
            },
602
        }
603
        flow_to_install = {"match": {"in_port": 80, "wildcards": 4194303}}
604
        flow_list = {"flow_list": [stored_flow, stored_flow2]}
605
        command = "delete"
606
        self.napp.stored_flows = {dpid: flow_list}
607
608
        self.napp._store_changed_flows(command, flow_to_install, switch)
609
        mock_save_flow.assert_called()
610
        self.assertEqual(len(self.napp.stored_flows[dpid]['flow_list']), 1)
611