Passed
Pull Request — master (#112)
by Rogerio
02:44
created

build.tests.models.test_evc_deploy   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 532
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 401
dl 0
loc 532
rs 10
c 0
b 0
f 0
wmc 16

16 Methods

Rating   Name   Duplication   Size   Complexity  
B TestEVC.test_deploy_fail() 0 47 1
A TestEVC.test_prepare_pop_flow() 0 24 1
A TestEVC.test_should_deploy_case3() 0 15 1
B TestEVC.test_deploy_successfully() 0 52 1
A TestEVC.test_should_deploy_case4() 0 15 1
A TestEVC.test_send_flow_mods_case1() 0 11 1
A TestEVC.test_remove_current_flows() 0 43 1
B TestEVC.test_install_uni_flows() 0 81 1
A TestEVC.test_should_deploy_case1() 0 15 1
B TestEVC.test_deploy_without_path_case1() 0 52 1
A TestEVC.test_should_deploy_case2() 0 15 1
A TestEVC.test_install_nni_flows() 0 54 1
A TestEVC.test_primary_links_zipped() 0 3 1
A TestEVC.test_prepare_push_flow() 0 31 1
A TestEVC.test_prepare_flow_mod() 0 24 1
A TestEVC.test_send_flow_mods_case2() 0 11 1
1
"""Method to thest EVCDeploy class."""
2
import sys
3
from unittest import TestCase
4
from unittest.mock import Mock, patch
5
6
from kytos.core.interface import UNI, Interface
7
from kytos.core.switch import Switch
8
from kytos.core.common import EntityStatus
9
10
# pylint: disable=wrong-import-position
11
sys.path.insert(0, '/var/lib/kytos/napps/..')
12
# pylint: enable=wrong-import-position
13
14
from napps.kytos.mef_eline.models import EVC, Path  # NOQA
15
from napps.kytos.mef_eline.settings import MANAGER_URL  # NOQA
16
from tests.helpers import get_link_mocked,\
17
    get_uni_mocked, get_controller_mock  # NOQA
18
19
20
class TestEVC(TestCase):  # pylint: disable=too-many-public-methods
21
    """Tests to verify EVC class."""
22
23
    def test_primary_links_zipped(self):
24
        """Test primary links zipped method."""
25
        pass
26
27
    @staticmethod
28
    @patch('napps.kytos.mef_eline.models.log')
29
    def test_should_deploy_case1(log_mock):
30
        """Test should deploy method without primary links."""
31
        log_mock.debug.return_value = True
32
        attributes = {
33
            "controller": get_controller_mock(),
34
            "name": "custom_name",
35
            "uni_a": get_uni_mocked(is_valid=True),
36
            "uni_z": get_uni_mocked(is_valid=True)
37
        }
38
39
        evc = EVC(**attributes)
40
        evc.should_deploy()
41
        log_mock.debug.assert_called_with('Path is empty.')
42
43
    @patch('napps.kytos.mef_eline.models.log')
44
    def test_should_deploy_case2(self, log_mock):
45
        """Test should deploy method with disable circuit."""
46
        log_mock.debug.return_value = True
47
        attributes = {
48
            "controller": get_controller_mock(),
49
            "name": "custom_name",
50
            "uni_a": get_uni_mocked(is_valid=True),
51
            "uni_z": get_uni_mocked(is_valid=True),
52
            "primary_links": [get_link_mocked(), get_link_mocked()]
53
        }
54
        evc = EVC(**attributes)
55
56
        self.assertFalse(evc.should_deploy(attributes['primary_links']))
57
        log_mock.debug.assert_called_with(f'{evc} is disabled.')
58
59
    @patch('napps.kytos.mef_eline.models.log')
60
    def test_should_deploy_case3(self, log_mock):
61
        """Test should deploy method with enabled and not active circuit."""
62
        log_mock.debug.return_value = True
63
        attributes = {
64
            "controller": get_controller_mock(),
65
            "name": "custom_name",
66
            "uni_a": get_uni_mocked(is_valid=True),
67
            "uni_z": get_uni_mocked(is_valid=True),
68
            "primary_links": [get_link_mocked(), get_link_mocked()],
69
            "enabled": True
70
        }
71
        evc = EVC(**attributes)
72
        self.assertTrue(evc.should_deploy(attributes['primary_links']))
73
        log_mock.debug.assert_called_with(f'{evc} will be deployed.')
74
75
    @patch('napps.kytos.mef_eline.models.log')
76
    def test_should_deploy_case4(self, log_mock):
77
        """Test should deploy method with enabled and active circuit."""
78
        log_mock.debug.return_value = True
79
        attributes = {
80
            "controller": get_controller_mock(),
81
            "name": "custom_name",
82
            "uni_a": get_uni_mocked(is_valid=True),
83
            "uni_z": get_uni_mocked(is_valid=True),
84
            "primary_links": [get_link_mocked(), get_link_mocked()],
85
            "enabled": True,
86
            "active": True
87
        }
88
        evc = EVC(**attributes)
89
        self.assertFalse(evc.should_deploy(attributes['primary_links']))
90
91
    @patch('napps.kytos.mef_eline.models.requests')
92
    def test_send_flow_mods_case1(self, requests_mock):
93
        """Test if you are sending flow_mods."""
94
        flow_mods = {"id": 20}
95
        switch = Mock(spec=Switch, id=1)
96
        EVC._send_flow_mods(switch, flow_mods)
97
        expected_endpoint = f"{MANAGER_URL}/flows/{switch.id}"
98
        expected_data = {"flows": flow_mods}
99
        self.assertEqual(requests_mock.post.call_count, 1)
100
        requests_mock.post.assert_called_once_with(expected_endpoint,
101
                                                   json=expected_data)
102
103
    @patch('napps.kytos.mef_eline.models.requests')
104
    def test_send_flow_mods_case2(self, requests_mock):
105
        """Test if you are sending flow_mods."""
106
        flow_mods = {"id": 20}
107
        switch = Mock(spec=Switch, id=1)
108
        EVC._send_flow_mods(switch, flow_mods, command='delete')
109
        expected_endpoint = f"{MANAGER_URL}/delete/{switch.id}"
110
        expected_data = {"flows": flow_mods}
111
        self.assertEqual(requests_mock.post.call_count, 1)
112
        requests_mock.post.assert_called_once_with(expected_endpoint,
113
                                                   json=expected_data)
114
115
    def test_prepare_flow_mod(self):
116
        """Test prepare flow_mod method."""
117
        interface_a = Interface('eth0', 1, Mock(spec=Switch))
118
        interface_z = Interface('eth1', 3, Mock(spec=Switch))
119
        attributes = {
120
            "controller": get_controller_mock(),
121
            "name": "custom_name",
122
            "uni_a": get_uni_mocked(is_valid=True),
123
            "uni_z": get_uni_mocked(is_valid=True),
124
            "primary_links": [get_link_mocked(), get_link_mocked()],
125
            "enabled": True,
126
            "active": True
127
        }
128
        evc = EVC(**attributes)
129
        flow_mod = evc._prepare_flow_mod(interface_a, interface_z)
130
        expected_flow_mod = {
131
                           'match': {'in_port': interface_a.port_number},
132
                           'cookie': evc.get_cookie(),
133
                           'actions': [
134
                                       {'action_type': 'output',
135
                                        'port': interface_z.port_number}
136
                           ]
137
        }
138
        self.assertEqual(expected_flow_mod, flow_mod)
139
140
    def test_prepare_pop_flow(self):
141
        """Test prepare pop flow  method."""
142
        attributes = {
143
            "controller": get_controller_mock(),
144
            "name": "custom_name",
145
            "uni_a": get_uni_mocked(interface_port=1, is_valid=True),
146
            "uni_z": get_uni_mocked(interface_port=2, is_valid=True),
147
        }
148
        evc = EVC(**attributes)
149
        interface_a = evc.uni_a.interface
150
        interface_z = evc.uni_z.interface
151
        in_vlan = 10
152
        flow_mod = evc._prepare_pop_flow(interface_a, interface_z, in_vlan)
153
        expected_flow_mod = {
154
            'match': {'in_port': interface_a.port_number, 'dl_vlan': in_vlan},
155
            'cookie': evc.get_cookie(),
156
            'actions': [
157
                        {'action_type': 'pop_vlan'},
158
                        {'action_type': 'output',
159
                         'port': interface_z.port_number
160
                         }
161
            ]
162
        }
163
        self.assertEqual(expected_flow_mod, flow_mod)
164
165
    def test_prepare_push_flow(self):
166
        """Test prepare push flow method."""
167
        attributes = {
168
            "controller": get_controller_mock(),
169
            "name": "custom_name",
170
            "uni_a": get_uni_mocked(interface_port=1, is_valid=True),
171
            "uni_z": get_uni_mocked(interface_port=2, is_valid=True),
172
        }
173
        evc = EVC(**attributes)
174
        interface_a = evc.uni_a.interface
175
        interface_z = evc.uni_z.interface
176
        in_vlan_a = 10
177
        out_vlan_a = 20
178
        in_vlan_z = 3
179
        flow_mod = evc._prepare_push_flow(interface_a, interface_z,
180
                                          in_vlan_a, out_vlan_a, in_vlan_z)
181
        expected_flow_mod = {
182
            'match': {'in_port': interface_a.port_number,
183
                      'dl_vlan': in_vlan_a
184
                      },
185
            'cookie': evc.get_cookie(),
186
            'actions': [
187
                        {'action_type': 'set_vlan', 'vlan_id': in_vlan_z},
188
                        {'action_type': 'push_vlan', 'tag_type': 's'},
189
                        {'action_type': 'set_vlan', 'vlan_id': out_vlan_a},
190
                        {'action_type': 'output',
191
                         'port': interface_z.port_number
192
                         }
193
            ]
194
        }
195
        self.assertEqual(expected_flow_mod, flow_mod)
196
197
    @staticmethod
198
    @patch('napps.kytos.mef_eline.models.EVC._send_flow_mods')
199
    def test_install_uni_flows(send_flow_mods_mock):
200
        """Test install uni flows method.
201
202
        This test will verify the flows send to the send_flow_mods method.
203
        """
204
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
205
                               switch_id="switch_uni_a", is_valid=True)
206
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
207
                               switch_id="switch_uni_z", is_valid=True)
208
209
        attributes = {
210
            "controller": get_controller_mock(),
211
            "name": "custom_name",
212
            "uni_a": uni_a,
213
            "uni_z": uni_z,
214
            "primary_links": [
215
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
216
                                metadata={"s_vlan": 5}),
217
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
218
                                metadata={"s_vlan": 6})
219
            ]
220
        }
221
        evc = EVC(**attributes)
222
        evc._install_uni_flows(attributes['primary_links'])
223
224
        expected_flow_mod_a = [
225
            {'match': {'in_port': uni_a.interface.port_number,
226
                       'dl_vlan': uni_a.user_tag.value},
227
             'cookie': evc.get_cookie(),
228
             'actions': [
229
                {'action_type': 'set_vlan', 'vlan_id': uni_z.user_tag.value},
230
                {'action_type': 'push_vlan', 'tag_type': 's'},
231
                {'action_type': 'set_vlan',
232
                 'vlan_id': evc.primary_links[0].get_metadata('s_vlan').value},
233
                {'action_type': 'output',
234
                 'port': evc.primary_links[0].endpoint_a.port_number}
235
             ]},
236
            {'match': {
237
                'in_port': evc.primary_links[0].endpoint_a.port_number,
238
                'dl_vlan': evc.primary_links[0].get_metadata('s_vlan').value
239
             },
240
             'cookie': evc.get_cookie(),
241
             'actions': [
242
                {'action_type': 'pop_vlan'},
243
                {'action_type': 'output', 'port': uni_a.interface.port_number}
244
             ]
245
             }
246
        ]
247
        send_flow_mods_mock.assert_any_call(uni_a.interface.switch,
248
                                            expected_flow_mod_a)
249
250
        expected_flow_mod_z = [
251
            {'match': {'in_port': uni_z.interface.port_number,
252
                       'dl_vlan': uni_z.user_tag.value},
253
             'cookie': evc.get_cookie(),
254
             'actions': [
255
                {'action_type': 'set_vlan', 'vlan_id': uni_a.user_tag.value},
256
                {'action_type': 'push_vlan', 'tag_type': 's'},
257
                {'action_type': 'set_vlan',
258
                 'vlan_id': evc.primary_links[-1].get_metadata('s_vlan').value
259
                 },
260
                {'action_type': 'output',
261
                 'port': evc.primary_links[-1].endpoint_b.port_number}
262
              ]
263
             },
264
            {'match': {
265
                 'in_port': evc.primary_links[-1].endpoint_b.port_number,
266
                 'dl_vlan': evc.primary_links[-1].get_metadata('s_vlan').value
267
             },
268
             'cookie': evc.get_cookie(),
269
             'actions': [
270
                {'action_type': 'pop_vlan'},
271
                {'action_type': 'output', 'port': uni_z.interface.port_number}
272
              ]
273
             }
274
        ]
275
276
        send_flow_mods_mock.assert_any_call(uni_z.interface.switch,
277
                                            expected_flow_mod_z)
278
279
    @staticmethod
280
    @patch('napps.kytos.mef_eline.models.EVC._send_flow_mods')
281
    def test_install_nni_flows(send_flow_mods_mock):
282
        """Test install nni flows method.
283
284
        This test will verify the flows send to the send_flow_mods method.
285
        """
286
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
287
                               switch_id="switch_uni_a", is_valid=True)
288
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
289
                               switch_id="switch_uni_z", is_valid=True)
290
291
        attributes = {
292
            "controller": get_controller_mock(),
293
            "name": "custom_name",
294
            "uni_a": uni_a,
295
            "uni_z": uni_z,
296
            "primary_links": [
297
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
298
                                metadata={"s_vlan": 5}),
299
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
300
                                metadata={"s_vlan": 6})
301
            ]
302
        }
303
        evc = EVC(**attributes)
304
        evc._install_nni_flows(attributes['primary_links'])
305
306
        in_vlan = evc.primary_links[0].get_metadata('s_vlan').value
307
        out_vlan = evc.primary_links[-1].get_metadata('s_vlan').value
308
309
        in_port = evc.primary_links[0].endpoint_b.port_number
310
        out_port = evc.primary_links[-1].endpoint_a.port_number
311
312
        expected_flow_mods = [
313
            {
314
             'match': {'in_port': in_port, 'dl_vlan': in_vlan},
315
             'cookie': evc.get_cookie(),
316
             'actions': [
317
                    {'action_type': 'set_vlan', 'vlan_id': out_vlan},
318
                    {'action_type': 'output', 'port': out_port}
319
                ]
320
             },
321
            {
322
             'match': {'in_port': out_port, 'dl_vlan': out_vlan},
323
             'cookie': evc.get_cookie(),
324
             'actions': [
325
                {'action_type': 'set_vlan', 'vlan_id': in_vlan},
326
                {'action_type': 'output', 'port': in_port}
327
              ]
328
             }
329
        ]
330
331
        switch = evc.primary_links[0].endpoint_b.switch
332
        send_flow_mods_mock.assert_called_once_with(switch, expected_flow_mods)
333
334
    @patch('napps.kytos.mef_eline.models.log')
335
    @patch('napps.kytos.mef_eline.models.EVC._choose_vlans')
336
    @patch('napps.kytos.mef_eline.models.EVC._install_nni_flows')
337
    @patch('napps.kytos.mef_eline.models.EVC._install_uni_flows')
338
    @patch('napps.kytos.mef_eline.models.EVC.activate')
339
    @patch('napps.kytos.mef_eline.models.EVC.should_deploy')
340
    def test_deploy_successfully(self, *args):
341
        """Test if all methods to deploy are called."""
342
        (should_deploy_mock, activate_mock,
343
         install_uni_flows_mock, install_nni_flows, chose_vlans_mock,
344
         log_mock) = args
345
346
        should_deploy_mock.return_value = True
347
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
348
                               switch_id="switch_uni_a", is_valid=True)
349
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
350
                               switch_id="switch_uni_z", is_valid=True)
351
352
        primary_links = [
353
            get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
354
                            metadata={"s_vlan": 5}),
355
            get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
356
                            metadata={"s_vlan": 6})
357
        ]
358
359
        attributes = {
360
            "controller": get_controller_mock(),
361
            "name": "custom_name",
362
            "uni_a": uni_a,
363
            "uni_z": uni_z,
364
            "primary_links": primary_links
365
        }
366
        # Setup path to deploy
367
        path = Path()
368
        path.append(primary_links[0])
369
        path.append(primary_links[1])
370
371
        evc = EVC(**attributes)
372
373
        #storehouse mock
374
        evc._storehouse.box = Mock()
375
        evc._storehouse.box.data = {}
376
377
        deployed = evc.deploy_to_path(path)
378
379
        self.assertEqual(should_deploy_mock.call_count, 1)
380
        self.assertEqual(activate_mock.call_count, 1)
381
        self.assertEqual(install_uni_flows_mock.call_count, 1)
382
        self.assertEqual(install_nni_flows.call_count, 1)
383
        self.assertEqual(chose_vlans_mock.call_count, 1)
384
        log_mock.info.assert_called_once_with(f"{evc} was deployed.")
385
        self.assertTrue(deployed)
386
387
    @patch('napps.kytos.mef_eline.models.log')
388
    @patch('napps.kytos.mef_eline.models.EVC.discover_new_path', return_value=None)
389
    @patch('napps.kytos.mef_eline.models.EVC._choose_vlans')
390
    @patch('napps.kytos.mef_eline.models.EVC._install_nni_flows')
391
    @patch('napps.kytos.mef_eline.models.EVC._install_uni_flows')
392
    @patch('napps.kytos.mef_eline.models.EVC.activate')
393
    @patch('napps.kytos.mef_eline.models.EVC.should_deploy', return_value = False)
394
    @patch('napps.kytos.mef_eline.models.EVC.sync')
395
    def test_deploy_fail(self, *args):
396
        """Test if all methods is ignored when the should_deploy is false."""
397
        (sync_mock, should_deploy_mock, activate_mock, install_uni_flows_mock,
398
         install_nni_flows, chose_vlans_mock,
399
         discover_new_path, log_mock) = args
400
401
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
402
                               switch_id="switch_uni_a",
403
                               switch_dpid="switch_dpid_uni_a",
404
                               is_valid=True)
405
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
406
                               switch_id="switch_uni_z",
407
                               switch_dpid="switch_dpid_uni_a",
408
                               is_valid=True)
409
410
        attributes = {
411
            "controller": get_controller_mock(),
412
            "name": "custom_name",
413
            "uni_a": uni_a,
414
            "uni_z": uni_z,
415
            "primary_links": [
416
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
417
                                metadata={"s_vlan": 5}),
418
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
419
                                metadata={"s_vlan": 6})
420
            ]
421
        }
422
423
        evc = EVC(**attributes)
424
        deployed = evc.deploy_to_path()
425
426
        self.assertEqual(should_deploy_mock.call_count, 1)
427
        self.assertEqual(activate_mock.call_count, 0)
428
        self.assertEqual(install_uni_flows_mock.call_count, 0)
429
        self.assertEqual(install_nni_flows.call_count, 0)
430
        self.assertEqual(chose_vlans_mock.call_count, 0)
431
        self.assertEqual(log_mock.info.call_count, 0)
432
        self.assertEqual(sync_mock.call_count, 0)
433
        self.assertFalse(deployed)
434
435
436
    @patch('napps.kytos.mef_eline.models.log')
437
    @patch('napps.kytos.mef_eline.models.EVC._choose_vlans')
438
    @patch('napps.kytos.mef_eline.models.EVC._install_nni_flows')
439
    @patch('napps.kytos.mef_eline.models.EVC._install_uni_flows')
440
    @patch('napps.kytos.mef_eline.models.EVC.activate')
441
    @patch('napps.kytos.mef_eline.models.EVC.should_deploy')
442
    @patch('napps.kytos.mef_eline.models.EVC.discover_new_path')
443
    def test_deploy_without_path_case1(self, *args):
444
        """Test if not path is found a dynamic path is used."""
445
        (discover_new_path_mocked, should_deploy_mock, activate_mock,
446
         install_uni_flows_mock, install_nni_flows, chose_vlans_mock,
447
         log_mock) = args
448
449
        should_deploy_mock.return_value = False
450
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
451
                               switch_id="switch_uni_a", is_valid=True)
452
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
453
                               switch_id="switch_uni_z", is_valid=True)
454
455
        attributes = {
456
            "controller": get_controller_mock(),
457
            "name": "custom_name",
458
            "uni_a": uni_a,
459
            "uni_z": uni_z,
460
            "enabled": True,
461
            "dynamic_backup_path": True
462
        }
463
464
        dynamic_backup_path = Path([
465
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
466
                                metadata={"s_vlan": 5}),
467
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
468
                                metadata={"s_vlan": 6})
469
        ])
470
471
        evc = EVC(**attributes)
472
        discover_new_path_mocked.return_value = dynamic_backup_path
473
474
        # storehouse initialization mock
475
        evc._storehouse.box = Mock()
476
        evc._storehouse.box.data = {}
477
478
        deployed = evc.deploy_to_path()
479
480
        self.assertEqual(should_deploy_mock.call_count, 1)
481
        self.assertEqual(discover_new_path_mocked.call_count, 1)
482
        self.assertEqual(activate_mock.call_count, 1)
483
        self.assertEqual(install_uni_flows_mock.call_count, 1)
484
        self.assertEqual(install_nni_flows.call_count, 1)
485
        self.assertEqual(chose_vlans_mock.call_count, 1)
486
        self.assertEqual(log_mock.info.call_count, 1)
487
        self.assertTrue(deployed)
488
489
    @patch('napps.kytos.mef_eline.models.EVC._send_flow_mods')
490
    def test_remove_current_flows(self, send_flow_mods_mocked):
491
        """Test remove current flows."""
492
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
493
                               switch_id="switch_uni_a", is_valid=True)
494
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
495
                               switch_id="switch_uni_z", is_valid=True)
496
497
        switch_a = Switch('00:00:00:00:00:01')
498
        switch_b = Switch('00:00:00:00:00:02')
499
        switch_c = Switch('00:00:00:00:00:03')
500
501
        attributes = {
502
            "controller": get_controller_mock(),
503
            "name": "custom_name",
504
            "uni_a": uni_a,
505
            "uni_z": uni_z,
506
            "active": True,
507
            "enabled": True,
508
            "primary_links": [
509
                get_link_mocked(switch_a=switch_a,
510
                                switch_b=switch_b,
511
                                endpoint_a_port=9, endpoint_b_port=10,
512
                                metadata={"s_vlan": 5}),
513
                get_link_mocked(switch_a=switch_b,
514
                                switch_b=switch_c,
515
                                endpoint_a_port=11, endpoint_b_port=12,
516
                                metadata={"s_vlan": 6})
517
            ]
518
        }
519
520
        evc = EVC(**attributes)
521
        evc.current_path = evc.primary_links
522
        evc.remove_current_flows()
523
524
        self.assertEqual(send_flow_mods_mocked.call_count, 3)
525
        self.assertFalse(evc.is_active())
526
        flows = [{'cookie': evc.get_cookie(),
527
                 'cookie_mask': 18446744073709551615}]
528
        switch_1 = evc.primary_links[0].endpoint_a.switch
529
        switch_2 = evc.primary_links[0].endpoint_b.switch
530
        send_flow_mods_mocked.assert_any_call(switch_1, flows, 'delete')
531
        send_flow_mods_mocked.assert_any_call(switch_2, flows, 'delete')
532