Passed
Pull Request — master (#140)
by Rogerio
03:21
created

TestMain.test_evc_from_dict()   A

Complexity

Conditions 1

Size

Total Lines 37
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 26
nop 3
dl 0
loc 37
rs 9.256
c 0
b 0
f 0
1
"""Module to test the main napp file."""
2
import json
3
from unittest import TestCase
4
from unittest.mock import patch
5
6
from kytos.core.interface import UNI, Interface
7
8
from napps.kytos.mef_eline.main import Main
9
from tests.helpers import get_controller_mock
10
11
12
class TestMain(TestCase):  # pylint: disable=too-many-public-methods
13
    """Test the Main class."""
14
15
    def setUp(self):
16
        """Execute steps before each tests.
17
18
        Set the server_name_url_url from kytos/mef_eline
19
        """
20
        self.server_name_url = 'http://localhost:8181/api/kytos/mef_eline'
21
        self.napp = Main(get_controller_mock())
22
23
    def test_get_event_listeners(self):
24
        """Verify all event listeners registered."""
25
        expected_events = ['kytos/core.shutdown',
26
                           'kytos/core.shutdown.kytos/mef_eline',
27
                           'kytos/topology.link_up',
28
                           'kytos/topology.link_down']
29
        actual_events = self.napp.listeners()
30
31
        for _event in expected_events:
32
            self.assertIn(_event, actual_events, '%s' % _event)
33
34
    def test_verify_api_urls(self):
35
        """Verify all APIs registered."""
36
        expected_urls = [
37
            ({}, {'POST', 'OPTIONS'},
38
             '/api/kytos/mef_eline/v2/evc/'),
39
40
            ({}, {'OPTIONS', 'HEAD', 'GET'},
41
             '/api/kytos/mef_eline/v2/evc/'),
42
43
            ({'circuit_id': '[circuit_id]'}, {'OPTIONS', 'DELETE'},
44
             '/api/kytos/mef_eline/v2/evc/<circuit_id>'),
45
46
            ({'circuit_id': '[circuit_id]'}, {'OPTIONS', 'HEAD', 'GET'},
47
             '/api/kytos/mef_eline/v2/evc/<circuit_id>'),
48
49
            ({'circuit_id': '[circuit_id]'}, {'OPTIONS', 'PATCH'},
50
             '/api/kytos/mef_eline/v2/evc/<circuit_id>'),
51
52
            ({}, {'OPTIONS', 'GET', 'HEAD'},
53
             '/api/kytos/mef_eline/v2/evc/schedule'),
54
55
            ({}, {'POST', 'OPTIONS'},
56
             '/api/kytos/mef_eline/v2/evc/schedule/'),
57
58
            ({'schedule_id': '[schedule_id]'},
59
             {'OPTIONS', 'DELETE'},
60
             '/api/kytos/mef_eline/v2/evc/schedule/<schedule_id>'),
61
62
            ({'schedule_id': '[schedule_id]'},
63
             {'OPTIONS', 'PATCH'},
64
             '/api/kytos/mef_eline/v2/evc/schedule/<schedule_id>')
65
            ]
66
67
        urls = self.get_napp_urls(self.napp)
68
        self.assertCountEqual(expected_urls, urls)
69
70
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
71
    @patch('napps.kytos.mef_eline.models.EVCBase._validate')
72
    def test_evc_from_dict(self, _validate_mock, uni_from_dict_mock):
73
        """
74
        Test the helper method that create an EVN from dict.
75
76
        Verify object creation with circuit data and schedule data.
77
        """
78
        _validate_mock.return_value = True
79
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z']
80
        payload = {
81
            "name": "my evc1",
82
            "uni_a": {
83
                "interface_id": "00:00:00:00:00:00:00:01:1",
84
                "tag": {
85
                    "tag_type": 1,
86
                    "value": 80
87
                }
88
            },
89
            "uni_z": {
90
                "interface_id": "00:00:00:00:00:00:00:02:2",
91
                "tag": {
92
                    "tag_type": 1,
93
                    "value": 1
94
                }
95
            },
96
            "circuit_scheduler": [{
97
                "frequency": "* * * * *",
98
                "action": "create"
99
            }]
100
        }
101
        evc_response = self.napp.evc_from_dict(payload)
102
        self.assertIsNotNone(evc_response)
103
        self.assertIsNotNone(evc_response.uni_a)
104
        self.assertIsNotNone(evc_response.uni_z)
105
        self.assertIsNotNone(evc_response.circuit_scheduler)
106
        self.assertIsNotNone(evc_response.name)
107
108
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
109
    @patch('napps.kytos.mef_eline.models.EVCBase._validate')
110
    @patch('kytos.core.Controller.get_interface_by_id')
111
    def test_evc_from_dict_paths(self, _get_interface_by_id_mock,
112
                                 _validate_mock, uni_from_dict_mock):
113
        """
114
        Test the helper method that create an EVN from dict.
115
116
        Verify object creation with circuit data and schedule data.
117
        """
118
        _get_interface_by_id_mock.return_value = True
119
        _validate_mock.return_value = True
120
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z']
121
        payload = {
122
            "name": "my evc1",
123
            "uni_a": {
124
                "interface_id": "00:00:00:00:00:00:00:01:1",
125
                "tag": {
126
                    "tag_type": 1,
127
                    "value": 80
128
                }
129
            },
130
            "uni_z": {
131
                "interface_id": "00:00:00:00:00:00:00:02:2",
132
                "tag": {
133
                    "tag_type": 1,
134
                    "value": 1
135
                }
136
            },
137
            "current_path": [],
138
            "primary_path": [
139
                {"endpoint_a": {"interface_id": "00:00:00:00:00:00:00:01:1"},
140
                 "endpoint_b": {"interface_id": "00:00:00:00:00:00:00:02:2"}}
141
            ],
142
            "backup_path": []
143
        }
144
145
        evc_response = self.napp.evc_from_dict(payload)
146
        self.assertIsNotNone(evc_response)
147
        self.assertIsNotNone(evc_response.uni_a)
148
        self.assertIsNotNone(evc_response.uni_z)
149
        self.assertIsNotNone(evc_response.circuit_scheduler)
150
        self.assertIsNotNone(evc_response.name)
151
        self.assertEqual(len(evc_response.current_path), 0)
152
        self.assertEqual(len(evc_response.backup_path), 0)
153
        self.assertEqual(len(evc_response.primary_path), 1)
154
155
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
156
    @patch('napps.kytos.mef_eline.models.EVCBase._validate')
157
    @patch('kytos.core.Controller.get_interface_by_id')
158
    def test_evc_from_dict_links(self, _get_interface_by_id_mock,
159
                                 _validate_mock, uni_from_dict_mock):
160
        """
161
        Test the helper method that create an EVN from dict.
162
163
        Verify object creation with circuit data and schedule data.
164
        """
165
        _get_interface_by_id_mock.return_value = True
166
        _validate_mock.return_value = True
167
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z']
168
        payload = {
169
            "name": "my evc1",
170
            "uni_a": {
171
                "interface_id": "00:00:00:00:00:00:00:01:1",
172
                "tag": {
173
                    "tag_type": 1,
174
                    "value": 80
175
                }
176
            },
177
            "uni_z": {
178
                "interface_id": "00:00:00:00:00:00:00:02:2",
179
                "tag": {
180
                    "tag_type": 1,
181
                    "value": 1
182
                }
183
            },
184
            "primary_links": [
185
                {"endpoint_a": {"interface_id": "00:00:00:00:00:00:00:01:1"},
186
                 "endpoint_b": {"interface_id": "00:00:00:00:00:00:00:02:2"}}
187
            ],
188
            "backup_links": []
189
        }
190
191
        evc_response = self.napp.evc_from_dict(payload)
192
        self.assertIsNotNone(evc_response)
193
        self.assertIsNotNone(evc_response.uni_a)
194
        self.assertIsNotNone(evc_response.uni_z)
195
        self.assertIsNotNone(evc_response.circuit_scheduler)
196
        self.assertIsNotNone(evc_response.name)
197
        self.assertEqual(len(evc_response.current_links_cache), 0)
198
        self.assertEqual(len(evc_response.backup_links), 0)
199
        self.assertEqual(len(evc_response.primary_links), 1)
200
201
    def test_list_without_circuits(self):
202
        """Test if list circuits return 'no circuit stored.'."""
203
        api = self.get_app_test_client(self.napp)
204
        url = f'{self.server_name_url}/v2/evc/'
205
        response = api.get(url)
206
        self.assertEqual(response.status_code, 200, response.data)
207
        self.assertEqual(json.loads(response.data.decode()), {})
208
209
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
210
    def test_list_no_circuits_stored(self, storehouse_data_mock):
211
        """Test if list circuits return all circuits stored."""
212
        circuits = {}
213
        storehouse_data_mock.return_value = circuits
214
215
        api = self.get_app_test_client(self.napp)
216
        url = f'{self.server_name_url}/v2/evc/'
217
218
        response = api.get(url)
219
        expected_result = circuits
220
        self.assertEqual(json.loads(response.data), expected_result)
221
222
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
223
    def test_list_with_circuits_stored(self, storehouse_data_mock):
224
        """Test if list circuits return all circuits stored."""
225
        circuits = {'1': {'name': 'circuit_1'},
226
                    '2': {'name': 'circuit_2'}}
227
        storehouse_data_mock.return_value = circuits
228
229
        api = self.get_app_test_client(self.napp)
230
        url = f'{self.server_name_url}/v2/evc/'
231
232
        response = api.get(url)
233
        expected_result = circuits
234
        self.assertEqual(json.loads(response.data), expected_result)
235
236 View Code Duplication
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
237
    def test_circuit_with_valid_id(self, storehouse_data_mock):
238
        """Test if get_circuit return the circuit attributes."""
239
        circuits = {'1': {'name': 'circuit_1'},
240
                    '2': {'name': 'circuit_2'}}
241
        storehouse_data_mock.return_value = circuits
242
243
        api = self.get_app_test_client(self.napp)
244
        url = f'{self.server_name_url}/v2/evc/1'
245
        response = api.get(url)
246
        expected_result = circuits['1']
247
        self.assertEqual(json.loads(response.data), expected_result)
248
249 View Code Duplication
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
250
    def test_circuit_with_invalid_id(self, storehouse_data_mock):
251
        """Test if get_circuit return invalid circuit_id."""
252
        circuits = {'1': {'name': 'circuit_1'},
253
                    '2': {'name': 'circuit_2'}}
254
        storehouse_data_mock.return_value = circuits
255
256
        api = self.get_app_test_client(self.napp)
257
        url = f'{self.server_name_url}/v2/evc/3'
258
        response = api.get(url)
259
        expected_result = {'response': 'circuit_id 3 not found'}
260
        self.assertEqual(json.loads(response.data), expected_result)
261
262
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
263
    @patch('napps.kytos.mef_eline.scheduler.Scheduler.add')
264
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
265
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.save_evc')
266
    @patch('napps.kytos.mef_eline.main.EVC.as_dict')
267
    @patch('napps.kytos.mef_eline.models.EVC._validate')
268
    def test_create_a_circuit_case_1(self, *args):
269
        """Test create a new circuit."""
270
        (validate_mock, evc_as_dict_mock, save_evc_mock,
271
         uni_from_dict_mock, sched_add_mock, storehouse_data_mock) = args
272
273
        validate_mock.return_value = True
274
        save_evc_mock.return_value = True
275
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z']
276
        evc_as_dict_mock.return_value = {}
277
        sched_add_mock.return_value = True
278
        storehouse_data_mock.return_value = {}
279
280
        api = self.get_app_test_client(self.napp)
281
        url = f'{self.server_name_url}/v2/evc/'
282
        payload = {
283
                   "name": "my evc1",
284
                   "frequency": "* * * * *",
285
                   "uni_a": {
286
                     "interface_id": "00:00:00:00:00:00:00:01:1",
287
                     "tag": {
288
                       "tag_type": 1,
289
                       "value": 80
290
                     }
291
                   },
292
                   "uni_z": {
293
                     "interface_id": "00:00:00:00:00:00:00:02:2",
294
                     "tag": {
295
                       "tag_type": 1,
296
                       "value": 1
297
                     }
298
                   }
299
                 }
300
301
        response = api.post(url, data=json.dumps(payload),
302
                            content_type='application/json')
303
        current_data = json.loads(response.data)
304
305
        # verify expected result from request
306
        self.assertEqual(201, response.status_code, response.data)
307
        self.assertIn('circuit_id', current_data)
308
309
        # verify uni called
310
        uni_from_dict_mock.called_twice()
311
        uni_from_dict_mock.assert_any_call(payload['uni_z'])
312
        uni_from_dict_mock.assert_any_call(payload['uni_a'])
313
314
        # verify validation called
315
        validate_mock.assert_called_once()
316
        validate_mock.assert_called_with(frequency='* * * * *',
317
                                         name='my evc1',
318
                                         uni_a='uni_a',
319
                                         uni_z='uni_z')
320
        # verify save method is called
321
        save_evc_mock.assert_called_once()
322
323
        # verify evc as dict is called to save in the box
324
        evc_as_dict_mock.assert_called_once()
325
        # verify add circuit in sched
326
        sched_add_mock.assert_called_once()
327
328
    @staticmethod
329
    def get_napp_urls(napp):
330
        """Return the kytos/mef_eline urls.
331
332
        The urls will be like:
333
334
        urls = [
335
            (options, methods, url)
336
        ]
337
338
        """
339
        controller = napp.controller
340
        controller.api_server.register_napp_endpoints(napp)
341
342
        urls = []
343
        for rule in controller.api_server.app.url_map.iter_rules():
344
            options = {}
345
            for arg in rule.arguments:
346
                options[arg] = "[{0}]".format(arg)
347
348
            if f'{napp.username}/{napp.name}' in str(rule):
349
                urls.append((options, rule.methods, f'{str(rule)}'))
350
351
        return urls
352
353
    @staticmethod
354
    def get_app_test_client(napp):
355
        """Return a flask api test client."""
356
        napp.controller.api_server.register_napp_endpoints(napp)
357
        return napp.controller.api_server.app.test_client()
358
359
    def test_create_a_circuit_case_2(self):
360
        """Test create a new circuit trying to send request without a json."""
361
        api = self.get_app_test_client(self.napp)
362
        url = f'{self.server_name_url}/v2/evc/'
363
364
        response = api.post(url)
365
        current_data = json.loads(response.data)
366
        expected_data = 'Bad request: The request do not have a json.'
367
368
        self.assertEqual(400, response.status_code, response.data)
369
        self.assertEqual(current_data, expected_data)
370
371
    @patch('napps.kytos.mef_eline.scheduler.Scheduler.add')
372
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
373
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.save_evc')
374
    @patch('napps.kytos.mef_eline.models.EVC._validate')
375
    @patch('napps.kytos.mef_eline.main.EVC.as_dict')
376
    def test_create_circuit_already_enabled(self, *args):
377
        """Test create an already created circuit."""
378
        (evc_as_dict_mock, validate_mock, save_evc_mock,
379
         uni_from_dict_mock, sched_add_mock) = args
380
381
        validate_mock.return_value = True
382
        save_evc_mock.return_value = True
383
        sched_add_mock.return_value = True
384
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z', 'uni_a', 'uni_z']
385
        payload1 = {'name': 'circuit_1'}
386
387
        api = self.get_app_test_client(self.napp)
388
        payload2 = {
389
            "name": "my evc1",
390
            "uni_a": {
391
                "interface_id": "00:00:00:00:00:00:00:01:1",
392
                "tag": {
393
                    "tag_type": 1,
394
                    "value": 80
395
                }
396
            },
397
            "uni_z": {
398
                "interface_id": "00:00:00:00:00:00:00:02:2",
399
                "tag": {
400
                    "tag_type": 1,
401
                    "value": 1
402
                }
403
            }
404
        }
405
406
        evc_as_dict_mock.return_value = payload1
407
        response = api.post(f'{self.server_name_url}/v2/evc/',
408
                            data=json.dumps(payload1),
409
                            content_type='application/json')
410
        self.assertEqual(201, response.status_code)
411
412
        evc_as_dict_mock.return_value = payload2
413
        response = api.post(f'{self.server_name_url}/v2/evc/',
414
                            data=json.dumps(payload2),
415
                            content_type='application/json')
416
        self.assertEqual(201, response.status_code)
417
418
        response = api.post(f'{self.server_name_url}/v2/evc/',
419
                            data=json.dumps(payload2),
420
                            content_type='application/json')
421
        current_data = json.loads(response.data)
422
        expected_data = 'Not Acceptable: This evc already exists.'
423
        self.assertEqual(current_data, expected_data)
424
        self.assertEqual(409, response.status_code)
425
426
    def test_list_schedules__no_data(self):
427
        """Test list of schedules."""
428
        api = self.get_app_test_client(self.napp)
429
        url = f'{self.server_name_url}/v2/evc/schedule'
430
        response = api.get(url)
431
        self.assertEqual(response.status_code, 200, response.data)
432
        self.assertEqual(json.loads(response.data.decode()), {})
433
434
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
435
    def test_list_schedules__no_data_stored(self, storehouse_data_mock):
436
        """Test if list circuits return all circuits stored."""
437
        circuits = {}
438
        storehouse_data_mock.return_value = circuits
439
440
        api = self.get_app_test_client(self.napp)
441
        url = f'{self.server_name_url}/v2/evc/schedule'
442
443
        response = api.get(url)
444
        expected_result = circuits
445
446
        self.assertEqual(response.status_code, 200, response.data)
447
        self.assertEqual(json.loads(response.data), expected_result)
448
449
    # pylint: disable=no-self-use
450
    def _add_storehouse_schedule_data(self, storehouse_data_mock):
451
        """Add schedule data to storehouse mock object."""
452
        circuits = {}
453
        payload_1 = {
454
            "id": "aa:aa:aa",
455
            "name": "my evc1",
456
            "uni_a": {
457
                "interface_id": "00:00:00:00:00:00:00:01:1",
458
                "tag": {
459
                    "tag_type": 1,
460
                    "value": 80
461
                }
462
            },
463
            "uni_z": {
464
                "interface_id": "00:00:00:00:00:00:00:02:2",
465
                "tag": {
466
                    "tag_type": 1,
467
                    "value": 1
468
                }
469
            },
470
            "circuit_scheduler": [
471
                {
472
                    "id": "1",
473
                    "frequency": "* * * * *",
474
                    "action": "create"
475
                },
476
                {
477
                    "id": "2",
478
                    "frequency": "1 * * * *",
479
                    "action": "remove"
480
                }
481
            ]
482
        }
483
        circuits.update({"aa:aa:aa": payload_1})
484
        payload_2 = {
485
            "id": "bb:bb:bb",
486
            "name": "my second evc2",
487
            "uni_a": {
488
                "interface_id": "00:00:00:00:00:00:00:01:2",
489
                "tag": {
490
                    "tag_type": 1,
491
                    "value": 90
492
                }
493
            },
494
            "uni_z": {
495
                "interface_id": "00:00:00:00:00:00:00:03:2",
496
                "tag": {
497
                    "tag_type": 1,
498
                    "value": 100
499
                }
500
            },
501
            "circuit_scheduler": [
502
                {
503
                    "id": "3",
504
                    "frequency": "1 * * * *",
505
                    "action": "create"
506
                },
507
                {
508
                    "id": "4",
509
                    "frequency": "2 * * * *",
510
                    "action": "remove"
511
                }
512
            ]
513
        }
514
        circuits.update({"bb:bb:bb": payload_2})
515
        payload_3 = {
516
            "id": "cc:cc:cc",
517
            "name": "my third evc3",
518
            "uni_a": {
519
                "interface_id": "00:00:00:00:00:00:00:03:1",
520
                "tag": {
521
                    "tag_type": 1,
522
                    "value": 90
523
                }
524
            },
525
            "uni_z": {
526
                "interface_id": "00:00:00:00:00:00:00:04:2",
527
                "tag": {
528
                    "tag_type": 1,
529
                    "value": 100
530
                }
531
            }
532
        }
533
        circuits.update({"cc:cc:cc": payload_3})
534
        # Add one circuit to the storehouse.
535
        storehouse_data_mock.return_value = circuits
536
537
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
538
    def test_list_schedules_from_storehouse(self, storehouse_data_mock):
539
        """Test if list circuits return specific circuits stored."""
540
        self._add_storehouse_schedule_data(storehouse_data_mock)
541
542
        api = self.get_app_test_client(self.napp)
543
        url = f'{self.server_name_url}/v2/evc/schedule'
544
545
        # Call URL
546
        response = api.get(url)
547
        # Expected JSON data from response
548
        expected = [{"aa:aa:aa":
549
                    [{"action": "create",
550
                      "frequency": "* * * * *",
551
                      "id": "1"},
552
                     {"action": "remove",
553
                      "frequency": "1 * * * *",
554
                      "id": "2"}]},
555
                    {"bb:bb:bb":
556
                        [{"action": "create",
557
                          "frequency": "1 * * * *",
558
                          "id": "3"},
559
                         {"action": "remove",
560
                          "frequency": "2 * * * *",
561
                          "id": "4"}]}
562
563
                    ]
564
565
        self.assertEqual(response.status_code, 200, response.data)
566
        self.assertEqual(expected, json.loads(response.data))
567
568
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
569
    def test_get_specific_schedule_from_storehouse(self, storehouse_data_mock):
570
        """Test get schedules from a circuit."""
571
        self._add_storehouse_schedule_data(storehouse_data_mock)
572
573
        requested_circuit_id = "bb:bb:bb"
574
        api = self.get_app_test_client(self.napp)
575
        url = f'{self.server_name_url}/v2/evc/{requested_circuit_id}'
576
577
        # Call URL
578
        response = api.get(url)
579
580
        # Expected JSON data from response
581
        expected = [{'action': 'create', 'frequency': '1 * * * *', 'id': '3'},
582
                    {'action': 'remove', 'frequency': '2 * * * *', 'id': '4'}]
583
584
        self.assertEqual(response.status_code, 200)
585
        self.assertEqual(expected,
586
                         json.loads(response.data)["circuit_scheduler"])
587
588
    def test_get_specific_schedules_from_storehouse_not_found(self):
589
        """Test get specific schedule ID that does not exist."""
590
        requested_id = "blah"
591
        api = self.get_app_test_client(self.napp)
592
        url = f'{self.server_name_url}/v2/evc/{requested_id}'
593
594
        # Call URL
595
        response = api.get(url)
596
597
        expected = {'response': 'circuit_id blah not found'}
598
        # Assert response not found
599
        self.assertEqual(response.status_code, 404, response.data)
600
        self.assertEqual(expected, json.loads(response.data))
601
602
    def _uni_from_dict_side_effect(self, uni_dict):
603
        interface_id = uni_dict.get("interface_id")
604
        tag_dict = uni_dict.get("tag")
605
        interface = Interface(interface_id, "0", "switch")
606
        return UNI(interface, tag_dict)
607
608
    @patch('apscheduler.schedulers.background.BackgroundScheduler.add_job')
609
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
610
    @patch('napps.kytos.mef_eline.scheduler.Scheduler.add')
611
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
612
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.save_evc')
613
    @patch('napps.kytos.mef_eline.main.EVC.as_dict')
614
    @patch('napps.kytos.mef_eline.models.EVC._validate')
615
    def test_create_schedule(self, *args):  # pylint: disable=too-many-locals
616
        """Test create a circuit schedule."""
617
        (validate_mock, evc_as_dict_mock, save_evc_mock,
618
         uni_from_dict_mock, sched_add_mock, storehouse_data_mock,
619
         scheduler_add_job_mock) = args
620
621
        validate_mock.return_value = True
622
        save_evc_mock.return_value = True
623
        uni_from_dict_mock.side_effect = self._uni_from_dict_side_effect
624
        evc_as_dict_mock.return_value = {}
625
        sched_add_mock.return_value = True
626
        storehouse_data_mock.return_value = {}
627
628
        self._add_storehouse_schedule_data(storehouse_data_mock)
629
630
        requested_id = "bb:bb:bb"
631
        api = self.get_app_test_client(self.napp)
632
        url = f'{self.server_name_url}/v2/evc/schedule/'
633
634
        payload = {
635
              "circuit_id": requested_id,
636
              "schedule": {
637
                "frequency": "1 * * * *",
638
                "action": "create"
639
              }
640
            }
641
642
        # Call URL
643
        response = api.post(url, data=json.dumps(payload),
644
                            content_type='application/json')
645
646
        response_json = json.loads(response.data)
647
648
        self.assertEqual(response.status_code, 201, response.data)
649
        scheduler_add_job_mock.assert_called_once()
650
        save_evc_mock.assert_called_once()
651
        self.assertEqual(payload["schedule"]["frequency"],
652
                         response_json["frequency"])
653
        self.assertEqual(payload["schedule"]["action"],
654
                         response_json["action"])
655
        self.assertIsNotNone(response_json["id"])
656
657
    @patch('apscheduler.schedulers.background.BackgroundScheduler.remove_job')
658
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
659
    @patch('napps.kytos.mef_eline.scheduler.Scheduler.add')
660
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
661
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.save_evc')
662
    @patch('napps.kytos.mef_eline.main.EVC.as_dict')
663
    @patch('napps.kytos.mef_eline.models.EVC._validate')
664
    def test_update_schedule(self, *args):  # pylint: disable=too-many-locals
665
        """Test create a circuit schedule."""
666
        (validate_mock, evc_as_dict_mock, save_evc_mock,
667
         uni_from_dict_mock, sched_add_mock, storehouse_data_mock,
668
         scheduler_remove_job_mock) = args
669
670
        storehouse_payload_1 = {
671
            "aa:aa:aa": {
672
                "id": "aa:aa:aa",
673
                "name": "my evc1",
674
                "uni_a": {
675
                    "interface_id": "00:00:00:00:00:00:00:01:1",
676
                    "tag": {
677
                        "tag_type": 1,
678
                        "value": 80
679
                    }
680
                },
681
                "uni_z": {
682
                    "interface_id": "00:00:00:00:00:00:00:02:2",
683
                    "tag": {
684
                        "tag_type": 1,
685
                        "value": 1
686
                    }
687
                },
688
                "circuit_scheduler": [{
689
                    "id": "1",
690
                    "frequency": "* * * * *",
691
                    "action": "create"
692
                }
693
                ]
694
            }
695
        }
696
697
        validate_mock.return_value = True
698
        save_evc_mock.return_value = True
699
        sched_add_mock.return_value = True
700
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z']
701
        evc_as_dict_mock.return_value = {}
702
        storehouse_data_mock.return_value = storehouse_payload_1
703
        scheduler_remove_job_mock.return_value = True
704
705
        requested_schedule_id = "1"
706
        api = self.get_app_test_client(self.napp)
707
        url = f'{self.server_name_url}/v2/evc/schedule/{requested_schedule_id}'
708
709
        payload = {
710
            "frequency": "*/1 * * * *",
711
            "action": "create"
712
        }
713
714
        # Call URL
715
        response = api.patch(url, data=json.dumps(payload),
716
                             content_type='application/json')
717
718
        response_json = json.loads(response.data)
719
720
        self.assertEqual(response.status_code, 200, response.data)
721
        scheduler_remove_job_mock.assert_called_once()
722
        save_evc_mock.assert_called_once()
723
        self.assertEqual(payload["frequency"], response_json["frequency"])
724
        self.assertEqual(payload["action"], response_json["action"])
725
        self.assertIsNotNone(response_json["id"])
726
727
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
728
    @patch('napps.kytos.mef_eline.scheduler.Scheduler.add')
729
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
730
    @patch('napps.kytos.mef_eline.main.EVC.as_dict')
731
    @patch('napps.kytos.mef_eline.models.EVC._validate')
732
    def test_update_schedule_archived(self, *args):
733
        """Test create a circuit schedule."""
734
        # pylint: disable=too-many-locals
735
        (validate_mock, evc_as_dict_mock,
736
         uni_from_dict_mock, sched_add_mock, storehouse_data_mock) = args
737
738
        storehouse_payload_1 = {
739
            "aa:aa:aa": {
740
                "id": "aa:aa:aa",
741
                "name": "my evc1",
742
                "archived": True,
743
                "circuit_scheduler": [{
744
                    "id": "1",
745
                    "frequency": "* * * * *",
746
                    "action": "create"
747
                }
748
                ]
749
            }
750
        }
751
752
        validate_mock.return_value = True
753
        sched_add_mock.return_value = True
754
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z']
755
        evc_as_dict_mock.return_value = {}
756
        storehouse_data_mock.return_value = storehouse_payload_1
757
758
        requested_schedule_id = "1"
759
        api = self.get_app_test_client(self.napp)
760
        url = f'{self.server_name_url}/v2/evc/schedule/{requested_schedule_id}'
761
762
        payload = {
763
            "frequency": "*/1 * * * *",
764
            "action": "create"
765
        }
766
767
        # Call URL
768
        response = api.patch(url, data=json.dumps(payload),
769
                             content_type='application/json')
770
771
        self.assertEqual(response.status_code, 403, response.data)
772
773
    @patch('apscheduler.schedulers.background.BackgroundScheduler.remove_job')
774
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
775
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
776
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.save_evc')
777
    @patch('napps.kytos.mef_eline.main.EVC.as_dict')
778
    @patch('napps.kytos.mef_eline.models.EVC._validate')
779
    def test_delete_schedule(self, *args):
780
        """Test create a circuit schedule."""
781
        (validate_mock, evc_as_dict_mock, save_evc_mock,
782
         uni_from_dict_mock, storehouse_data_mock,
783
         scheduler_remove_job_mock) = args
784
785
        storehouse_payload_1 = {
786
            "2": {
787
                "id": "2",
788
                "name": "my evc1",
789
                "uni_a": {
790
                    "interface_id": "00:00:00:00:00:00:00:01:1",
791
                    "tag": {
792
                        "tag_type": 1,
793
                        "value": 80
794
                    }
795
                },
796
                "uni_z": {
797
                    "interface_id": "00:00:00:00:00:00:00:02:2",
798
                    "tag": {
799
                        "tag_type": 1,
800
                        "value": 1
801
                    }
802
                },
803
                "circuit_scheduler": [{
804
                    "id": "1",
805
                    "frequency": "* * * * *",
806
                    "action": "create"
807
                }]
808
            }
809
        }
810
811
        validate_mock.return_value = True
812
        save_evc_mock.return_value = True
813
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z']
814
        evc_as_dict_mock.return_value = {}
815
        storehouse_data_mock.return_value = storehouse_payload_1
816
        scheduler_remove_job_mock.return_value = True
817
818
        requested_schedule_id = "1"
819
        api = self.get_app_test_client(self.napp)
820
        url = f'{self.server_name_url}/v2/evc/schedule/{requested_schedule_id}'
821
822
        # Call URL
823
        response = api.delete(url)
824
825
        self.assertEqual(response.status_code, 200, response.data)
826
        scheduler_remove_job_mock.assert_called_once()
827
        save_evc_mock.assert_called_once()
828
        self.assertIn("Schedule removed", f"{response.data}")
829
830
    @patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data')
831
    @patch('napps.kytos.mef_eline.main.Main.uni_from_dict')
832
    @patch('napps.kytos.mef_eline.main.EVC.as_dict')
833
    @patch('napps.kytos.mef_eline.models.EVC._validate')
834
    def test_delete_schedule_archived(self, *args):
835
        """Test create a circuit schedule."""
836
        (validate_mock, evc_as_dict_mock,
837
         uni_from_dict_mock, storehouse_data_mock) = args
838
839
        storehouse_payload_1 = {
840
            "2": {
841
                "id": "2",
842
                "name": "my evc1",
843
                "archived": True,
844
                "circuit_scheduler": [{
845
                    "id": "1",
846
                    "frequency": "* * * * *",
847
                    "action": "create"
848
                }]
849
            }
850
        }
851
852
        validate_mock.return_value = True
853
        uni_from_dict_mock.side_effect = ['uni_a', 'uni_z']
854
        evc_as_dict_mock.return_value = {}
855
        storehouse_data_mock.return_value = storehouse_payload_1
856
857
        requested_schedule_id = "1"
858
        api = self.get_app_test_client(self.napp)
859
        url = f'{self.server_name_url}/v2/evc/schedule/{requested_schedule_id}'
860
861
        # Call URL
862
        response = api.delete(url)
863
864
        self.assertEqual(response.status_code, 403, response.data)
865