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 napps.kytos.mef_eline.main import Main |
7
|
|
|
from tests.helpers import get_controller_mock |
8
|
|
|
|
9
|
|
|
|
10
|
|
|
class TestMain(TestCase): |
11
|
|
|
"""Test the Main class.""" |
12
|
|
|
|
13
|
|
|
def setUp(self): |
14
|
|
|
"""Execute steps before each tests. |
15
|
|
|
|
16
|
|
|
Set the server_name_url_url from kytos/mef_eline |
17
|
|
|
""" |
18
|
|
|
self.server_name_url = 'http://localhost:8181/api/kytos/mef_eline' |
19
|
|
|
self.napp = Main(get_controller_mock()) |
20
|
|
|
|
21
|
|
|
def test_get_event_listeners(self): |
22
|
|
|
"""Verify all event listeners registered.""" |
23
|
|
|
expected_events = ['kytos/core.shutdown', |
24
|
|
|
'kytos/core.shutdown.kytos/mef_eline', |
25
|
|
|
'kytos/topology.updated'] |
26
|
|
|
actual_events = self.napp.listeners() |
27
|
|
|
|
28
|
|
|
for _event in expected_events: |
29
|
|
|
self.assertIn(_event, actual_events, '%s' % _event) |
30
|
|
|
|
31
|
|
|
def test_verify_api_urls(self): |
32
|
|
|
"""Verify all APIs registered.""" |
33
|
|
|
expected_urls = [ |
34
|
|
|
({}, {'OPTIONS', 'POST'}, |
35
|
|
|
'/api/kytos/mef_eline/v2/evc/'), |
36
|
|
|
({}, {'OPTIONS', 'HEAD', 'GET'}, |
37
|
|
|
'/api/kytos/mef_eline/v2/evc/'), |
38
|
|
|
({'circuit_id': '[circuit_id]'}, {'OPTIONS', 'DELETE'}, |
39
|
|
|
'/api/kytos/mef_eline/v2/evc/<circuit_id>'), |
40
|
|
|
({'circuit_id': '[circuit_id]'}, {'OPTIONS', 'HEAD', 'GET'}, |
41
|
|
|
'/api/kytos/mef_eline/v2/evc/<circuit_id>'), |
42
|
|
|
({'circuit_id': '[circuit_id]'}, {'OPTIONS', 'PATCH'}, |
43
|
|
|
'/api/kytos/mef_eline/v2/evc/<circuit_id>')] |
44
|
|
|
urls = self.get_napp_urls(self.napp) |
45
|
|
|
self.assertEqual(expected_urls, urls) |
46
|
|
|
|
47
|
|
|
def test_list_without_circuits(self): |
48
|
|
|
"""Test if list circuits return 'no circuit stored.'.""" |
49
|
|
|
api = self.get_app_test_client(self.napp) |
50
|
|
|
url = f'{self.server_name_url}/v2/evc/' |
51
|
|
|
response = api.get(url) |
52
|
|
|
self.assertEqual(response.status_code, 200) |
53
|
|
|
self.assertEqual(json.loads(response.data.decode()), {}) |
54
|
|
|
|
55
|
|
|
@patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data') |
56
|
|
|
def test_list_with_no_circuits_stored(self, storehouse_data_mock): |
57
|
|
|
"""Test if list circuits return all circuits stored.""" |
58
|
|
|
circuits = {} |
59
|
|
|
storehouse_data_mock.return_value = circuits |
60
|
|
|
|
61
|
|
|
api = self.get_app_test_client(self.napp) |
62
|
|
|
url = f'{self.server_name_url}/v2/evc/' |
63
|
|
|
|
64
|
|
|
response = api.get(url) |
65
|
|
|
expected_result = circuits |
66
|
|
|
self.assertEqual(json.loads(response.data), expected_result) |
67
|
|
|
|
68
|
|
|
@patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data') |
69
|
|
|
def test_list_with_circuits_stored(self, storehouse_data_mock): |
70
|
|
|
"""Test if list circuits return all circuits stored.""" |
71
|
|
|
circuits = {'1': {'name': 'circuit_1'}, |
72
|
|
|
'2': {'name': 'circuit_2'}} |
73
|
|
|
storehouse_data_mock.return_value = circuits |
74
|
|
|
|
75
|
|
|
api = self.get_app_test_client(self.napp) |
76
|
|
|
url = f'{self.server_name_url}/v2/evc/' |
77
|
|
|
|
78
|
|
|
response = api.get(url) |
79
|
|
|
expected_result = circuits |
80
|
|
|
self.assertEqual(json.loads(response.data), expected_result) |
81
|
|
|
|
82
|
|
View Code Duplication |
@patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data') |
|
|
|
|
83
|
|
|
def test_circuit_with_valid_id(self, storehouse_data_mock): |
84
|
|
|
"""Test if get_circuit return the circuit attributes.""" |
85
|
|
|
circuits = {'1': {'name': 'circuit_1'}, |
86
|
|
|
'2': {'name': 'circuit_2'}} |
87
|
|
|
storehouse_data_mock.return_value = circuits |
88
|
|
|
|
89
|
|
|
api = self.get_app_test_client(self.napp) |
90
|
|
|
url = f'{self.server_name_url}/v2/evc/1' |
91
|
|
|
response = api.get(url) |
92
|
|
|
expected_result = circuits['1'] |
93
|
|
|
self.assertEqual(json.loads(response.data), expected_result) |
94
|
|
|
|
95
|
|
View Code Duplication |
@patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data') |
|
|
|
|
96
|
|
|
def test_circuit_with_invalid_id(self, storehouse_data_mock): |
97
|
|
|
"""Test if get_circuit return invalid circuit_id.""" |
98
|
|
|
circuits = {'1': {'name': 'circuit_1'}, |
99
|
|
|
'2': {'name': 'circuit_2'}} |
100
|
|
|
storehouse_data_mock.return_value = circuits |
101
|
|
|
|
102
|
|
|
api = self.get_app_test_client(self.napp) |
103
|
|
|
url = f'{self.server_name_url}/v2/evc/3' |
104
|
|
|
response = api.get(url) |
105
|
|
|
expected_result = {'response': 'circuit_id 3 not found'} |
106
|
|
|
self.assertEqual(json.loads(response.data), expected_result) |
107
|
|
|
|
108
|
|
|
@patch('napps.kytos.mef_eline.storehouse.StoreHouse.get_data') |
109
|
|
|
@patch('napps.kytos.mef_eline.scheduler.Scheduler.add') |
110
|
|
|
@patch('napps.kytos.mef_eline.main.Main.uni_from_dict') |
111
|
|
|
@patch('napps.kytos.mef_eline.storehouse.StoreHouse.save_evc') |
112
|
|
|
@patch('napps.kytos.mef_eline.main.EVC.as_dict') |
113
|
|
|
@patch('napps.kytos.mef_eline.models.EVC._validate') |
114
|
|
|
def test_create_a_circuit_case_1(self, *args): |
115
|
|
|
"""Test create a new circuit.""" |
116
|
|
|
(validate_mock, evc_as_dict_mock, save_evc_mock, |
117
|
|
|
uni_from_dict_mock, sched_add_mock, storehouse_data_mock) = args |
118
|
|
|
|
119
|
|
|
validate_mock.return_value = True |
120
|
|
|
save_evc_mock.return_value = True |
121
|
|
|
uni_from_dict_mock.side_effect = ['uni_a', 'uni_z'] |
122
|
|
|
evc_as_dict_mock.return_value = {} |
123
|
|
|
sched_add_mock.return_value = True |
124
|
|
|
storehouse_data_mock.return_value = {} |
125
|
|
|
|
126
|
|
|
api = self.get_app_test_client(self.napp) |
127
|
|
|
url = f'{self.server_name_url}/v2/evc/' |
128
|
|
|
payload = { |
129
|
|
|
"name": "my evc1", |
130
|
|
|
"frequency": "* * * * *", |
131
|
|
|
"uni_a": { |
132
|
|
|
"interface_id": "00:00:00:00:00:00:00:01:1", |
133
|
|
|
"tag": { |
134
|
|
|
"tag_type": 1, |
135
|
|
|
"value": 80 |
136
|
|
|
} |
137
|
|
|
}, |
138
|
|
|
"uni_z": { |
139
|
|
|
"interface_id": "00:00:00:00:00:00:00:02:2", |
140
|
|
|
"tag": { |
141
|
|
|
"tag_type": 1, |
142
|
|
|
"value": 1 |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
response = api.post(url, data=json.dumps(payload), |
148
|
|
|
content_type='application/json') |
149
|
|
|
current_data = json.loads(response.data) |
150
|
|
|
|
151
|
|
|
# verify expected result from request |
152
|
|
|
self.assertEqual(201, response.status_code, response.data) |
153
|
|
|
self.assertIn('circuit_id', current_data) |
154
|
|
|
|
155
|
|
|
# verify uni called |
156
|
|
|
uni_from_dict_mock.called_twice() |
157
|
|
|
uni_from_dict_mock.assert_any_call(payload['uni_z']) |
158
|
|
|
uni_from_dict_mock.assert_any_call(payload['uni_a']) |
159
|
|
|
|
160
|
|
|
# verify validation called |
161
|
|
|
validate_mock.assert_called_once() |
162
|
|
|
validate_mock.assert_called_with(frequency='* * * * *', |
163
|
|
|
name='my evc1', |
164
|
|
|
uni_a='uni_a', |
165
|
|
|
uni_z='uni_z') |
166
|
|
|
# verify save method is called |
167
|
|
|
save_evc_mock.assert_called_once() |
168
|
|
|
|
169
|
|
|
# verify evc as dict is called to save in the box |
170
|
|
|
evc_as_dict_mock.assert_called_once() |
171
|
|
|
# verify add circuit in sched |
172
|
|
|
sched_add_mock.assert_called_once() |
173
|
|
|
|
174
|
|
|
@staticmethod |
175
|
|
|
def get_napp_urls(napp): |
176
|
|
|
"""Return the kytos/mef_eline urls. |
177
|
|
|
|
178
|
|
|
The urls will be like: |
179
|
|
|
|
180
|
|
|
urls = [ |
181
|
|
|
(options, methods, url) |
182
|
|
|
] |
183
|
|
|
|
184
|
|
|
""" |
185
|
|
|
controller = napp.controller |
186
|
|
|
controller.api_server.register_napp_endpoints(napp) |
187
|
|
|
|
188
|
|
|
urls = [] |
189
|
|
|
for rule in controller.api_server.app.url_map.iter_rules(): |
190
|
|
|
options = {} |
191
|
|
|
for arg in rule.arguments: |
192
|
|
|
options[arg] = "[{0}]".format(arg) |
193
|
|
|
|
194
|
|
|
if f'{napp.username}/{napp.name}' in str(rule): |
195
|
|
|
urls.append((options, rule.methods, f'{str(rule)}')) |
196
|
|
|
|
197
|
|
|
return urls |
198
|
|
|
|
199
|
|
|
@staticmethod |
200
|
|
|
def get_app_test_client(napp): |
201
|
|
|
"""Return a flask api test client.""" |
202
|
|
|
napp.controller.api_server.register_napp_endpoints(napp) |
203
|
|
|
return napp.controller.api_server.app.test_client() |
204
|
|
|
|
205
|
|
|
def test_create_a_circuit_case_2(self): |
206
|
|
|
"""Test create a new circuit trying to send request without a json.""" |
207
|
|
|
api = self.get_app_test_client(self.napp) |
208
|
|
|
url = f'{self.server_name_url}/v2/evc/' |
209
|
|
|
|
210
|
|
|
response = api.post(url) |
211
|
|
|
current_data = json.loads(response.data) |
212
|
|
|
expected_data = 'Bad request: The request do not have a json.' |
213
|
|
|
|
214
|
|
|
self.assertEqual(400, response.status_code) |
215
|
|
|
self.assertEqual(current_data, expected_data) |
216
|
|
|
|