blob: de2b967899bad054f645e6903cbada7f226e9138 [file] [log] [blame]
Matteo Scandolo33523412018-04-12 15:21:13 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import unittest
16from mock import patch, call, Mock, PropertyMock
17import requests_mock
18
19import os, sys
20
Matteo Scandolo33523412018-04-12 15:21:13 -070021test_path=os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
Matteo Scandolo33523412018-04-12 15:21:13 -070022
23class TestSyncOLTDevice(unittest.TestCase):
24
25 def setUp(self):
26 global DeferredException
27
28 self.sys_path_save = sys.path
Matteo Scandolo33523412018-04-12 15:21:13 -070029
30 # Setting up the config module
31 from xosconfig import Config
Matteo Scandolof7ebb112018-09-18 16:17:22 -070032 config = os.path.join(test_path, "../test_config.yaml")
Matteo Scandolo33523412018-04-12 15:21:13 -070033 Config.clear()
34 Config.init(config, "synchronizer-config-schema.yaml")
35 # END Setting up the config module
36
Scott Baker47b47302019-01-30 16:55:07 -080037 from xossynchronizer.mock_modelaccessor_build import mock_modelaccessor_config
38 mock_modelaccessor_config(test_path, [("olt-service", "volt.xproto"),
Matteo Scandolo35207b72019-05-10 08:46:48 -070039 ("rcord", "rcord.xproto")])
Matteo Scandolo19466a02018-05-16 17:43:39 -070040
Scott Baker47b47302019-01-30 16:55:07 -080041 import xossynchronizer.modelaccessor
42 reload(xossynchronizer.modelaccessor) # in case nose2 loaded it in a previous test
43
44 from xossynchronizer.modelaccessor import model_accessor
45 self.model_accessor = model_accessor
46
47 from pull_olts import OLTDevicePullStep
Matteo Scandolo33523412018-04-12 15:21:13 -070048
49 # import all class names to globals
50 for (k, v) in model_accessor.all_model_classes.items():
51 globals()[k] = v
52
53 self.sync_step = OLTDevicePullStep
54
55 # mock volt service
56 self.volt_service = Mock()
57 self.volt_service.id = "volt_service_id"
58 self.volt_service.voltha_url = "voltha_url"
59 self.volt_service.voltha_user = "voltha_user"
60 self.volt_service.voltha_pass = "voltha_pass"
Matteo Scandolo19466a02018-05-16 17:43:39 -070061 self.volt_service.voltha_port = 1234
Matteo Scandolo33523412018-04-12 15:21:13 -070062
63 # mock voltha responses
64 self.devices = {
65 "items": [
66 {
67 "id": "test_id",
68 "type": "simulated_olt",
69 "host_and_port": "172.17.0.1:50060",
70 "admin_state": "ENABLED",
Matteo Scandolod6fce512018-10-16 10:35:29 -070071 "oper_status": "ACTIVE",
72 "serial_number": "serial_number",
Matteo Scandolo33523412018-04-12 15:21:13 -070073 }
74 ]
75 }
76
77 self.logical_devices = {
78 "items": [
79 {
80 "root_device_id": "test_id",
81 "id": "of_id",
82 "datapath_id": "55334486016"
83 }
84 ]
85 }
86
Matteo Scandolo6be6ee92018-05-24 15:07:51 -070087 self.ports = {
88 "items": [
89 {
90 "label": "PON port",
91 "port_no": 1,
92 "type": "PON_OLT",
93 "admin_state": "ENABLED",
94 "oper_status": "ACTIVE"
95 },
96 {
97 "label": "NNI facing Ethernet port",
98 "port_no": 2,
99 "type": "ETHERNET_NNI",
100 "admin_state": "ENABLED",
101 "oper_status": "ACTIVE"
102 }
103 ]
104 }
105
Matteo Scandolo33523412018-04-12 15:21:13 -0700106 def tearDown(self):
107 sys.path = self.sys_path_save
108
109 @requests_mock.Mocker()
110 def test_missing_volt_service(self, m):
111 self.assertFalse(m.called)
112
113 @requests_mock.Mocker()
Matteo Scandolo778fef72019-04-22 13:32:36 -0700114 def test_pull_host_and_port(self, m):
Matteo Scandolo33523412018-04-12 15:21:13 -0700115
116 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
Matteo Scandolo778fef72019-04-22 13:32:36 -0700117 patch.object(OLTDevice, "save", autospec=True) as mock_olt_save, \
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700118 patch.object(PONPort, "save") as mock_pon_save, \
119 patch.object(NNIPort, "save") as mock_nni_save:
Matteo Scandolo33523412018-04-12 15:21:13 -0700120 olt_service_mock.return_value = [self.volt_service]
121
Matteo Scandolo19466a02018-05-16 17:43:39 -0700122 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700123 m.get("http://voltha_url:1234/api/v1/devices/test_id/ports", status_code=200, json=self.ports)
Matteo Scandolo19466a02018-05-16 17:43:39 -0700124 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=self.logical_devices)
Matteo Scandolo33523412018-04-12 15:21:13 -0700125
Scott Baker47b47302019-01-30 16:55:07 -0800126 self.sync_step(model_accessor=self.model_accessor).pull_records()
Matteo Scandolo33523412018-04-12 15:21:13 -0700127
Matteo Scandolo33523412018-04-12 15:21:13 -0700128
Matteo Scandolo778fef72019-04-22 13:32:36 -0700129 saved_olts = mock_olt_save.call_args_list
130 simulated_olt = saved_olts[0][0][0]
131 self.assertEqual(len(saved_olts), 1)
132
133 self.assertEqual(simulated_olt.admin_state, "ENABLED")
134 self.assertEqual(simulated_olt.oper_status, "ACTIVE")
135 self.assertEqual(simulated_olt.volt_service_id, "volt_service_id")
136 self.assertEqual(simulated_olt.device_id, "test_id")
137 self.assertEqual(simulated_olt.of_id, "of_id")
138 self.assertEqual(simulated_olt.dp_id, "of:0000000ce2314000")
139
140
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700141 mock_pon_save.assert_called()
142 mock_nni_save.assert_called()
Matteo Scandolo33523412018-04-12 15:21:13 -0700143
144 @requests_mock.Mocker()
Matteo Scandolo778fef72019-04-22 13:32:36 -0700145 def test_pull_mac_address(self, m):
146 devices = {
147 "items": [
148 {
149 'id': 'tibit_id',
150 'type': 'tibit_olt',
151 'mac_address': '70:b3:d5:52:30:6f',
152 'admin_state': 'ENABLED',
153 'oper_status': 'ACTIVE',
154 'serial_number': 'OLT-70b3d552306f',
155 }
156 ]
157 }
158
159 logical_devices = {
160 "items": [
161 {
162 "root_device_id": "tibit_id",
163 "id": "of_id",
164 "datapath_id": "55334486017"
165 }
166 ]
167 }
168
169 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
170 patch.object(OLTDevice, "save", autospec=True) as mock_olt_save, \
171 patch.object(PONPort, "save") as mock_pon_save, \
172 patch.object(NNIPort, "save") as mock_nni_save:
173 olt_service_mock.return_value = [self.volt_service]
174
175 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=devices)
176 m.get("http://voltha_url:1234/api/v1/devices/tibit_id/ports", status_code=200, json=self.ports)
177 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
178
179
180 self.sync_step(model_accessor=self.model_accessor).pull_records()
181
182
183 saved_olts = mock_olt_save.call_args_list
184 tibit_olt = saved_olts[0][0][0]
185 self.assertEqual(len(saved_olts), 1)
186
187 self.assertEqual(tibit_olt.admin_state, "ENABLED")
188 self.assertEqual(tibit_olt.oper_status, "ACTIVE")
189 self.assertEqual(tibit_olt.volt_service_id, "volt_service_id")
190 self.assertEqual(tibit_olt.device_id, "tibit_id")
191 self.assertEqual(tibit_olt.of_id, "of_id")
192 self.assertEqual(tibit_olt.dp_id, "of:0000000ce2314001")
193
194 mock_pon_save.assert_called()
195 mock_nni_save.assert_called()
196
197
198 @requests_mock.Mocker()
Matteo Scandolo33523412018-04-12 15:21:13 -0700199 def test_pull_existing(self, m):
200
201 existing_olt = Mock()
Scott Baker09798d82019-01-17 08:34:59 -0800202 existing_olt.admin_state = "ENABLED"
Matteo Scandolo33523412018-04-12 15:21:13 -0700203 existing_olt.enacted = 2
204 existing_olt.updated = 1
Scott Baker3581f642019-06-26 14:24:20 -0700205 existing_olt.serial_number = ""
Matteo Scandolo33523412018-04-12 15:21:13 -0700206
207 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700208 patch.object(OLTDevice.objects, "filter") as mock_get, \
209 patch.object(PONPort, "save") as mock_pon_save, \
210 patch.object(NNIPort, "save") as mock_nni_save, \
211 patch.object(existing_olt, "save") as mock_olt_save:
Matteo Scandolo33523412018-04-12 15:21:13 -0700212 olt_service_mock.return_value = [self.volt_service]
213 mock_get.return_value = [existing_olt]
214
Matteo Scandolo19466a02018-05-16 17:43:39 -0700215 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700216 m.get("http://voltha_url:1234/api/v1/devices/test_id/ports", status_code=200, json=self.ports)
Matteo Scandolo19466a02018-05-16 17:43:39 -0700217 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=self.logical_devices)
Matteo Scandolo33523412018-04-12 15:21:13 -0700218
Scott Baker47b47302019-01-30 16:55:07 -0800219 self.sync_step(model_accessor=self.model_accessor).pull_records()
Matteo Scandolo33523412018-04-12 15:21:13 -0700220
221 self.assertEqual(existing_olt.admin_state, "ENABLED")
222 self.assertEqual(existing_olt.oper_status, "ACTIVE")
223 self.assertEqual(existing_olt.volt_service_id, "volt_service_id")
224 self.assertEqual(existing_olt.device_id, "test_id")
225 self.assertEqual(existing_olt.of_id, "of_id")
226 self.assertEqual(existing_olt.dp_id, "of:0000000ce2314000")
Scott Baker3581f642019-06-26 14:24:20 -0700227 self.assertEqual(existing_olt.serial_number, "serial_number")
Matteo Scandolo33523412018-04-12 15:21:13 -0700228
Andy Bavier00c573c2019-02-08 16:19:11 -0700229 # mock_olt_save.assert_called()
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700230 mock_pon_save.assert_called()
231 mock_nni_save.assert_called()
Matteo Scandolo33523412018-04-12 15:21:13 -0700232
233 @requests_mock.Mocker()
Scott Baker3581f642019-06-26 14:24:20 -0700234 def test_pull_existing_empty_voltha_serial(self, m):
235
236 existing_olt = Mock()
237 existing_olt.admin_state = "ENABLED"
238 existing_olt.enacted = 2
239 existing_olt.updated = 1
240 existing_olt.serial_number = "orig_serial"
241
242 self.devices["items"][0]["serial_number"] = ""
243
244 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
245 patch.object(OLTDevice.objects, "filter") as mock_get, \
246 patch.object(PONPort, "save") as mock_pon_save, \
247 patch.object(NNIPort, "save") as mock_nni_save, \
248 patch.object(existing_olt, "save") as mock_olt_save:
249 olt_service_mock.return_value = [self.volt_service]
250 mock_get.return_value = [existing_olt]
251
252 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
253 m.get("http://voltha_url:1234/api/v1/devices/test_id/ports", status_code=200, json=self.ports)
254 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=self.logical_devices)
255
256 self.sync_step(model_accessor=self.model_accessor).pull_records()
257
258 self.assertEqual(existing_olt.admin_state, "ENABLED")
259 self.assertEqual(existing_olt.oper_status, "ACTIVE")
260 self.assertEqual(existing_olt.volt_service_id, "volt_service_id")
261 self.assertEqual(existing_olt.device_id, "test_id")
262 self.assertEqual(existing_olt.of_id, "of_id")
263 self.assertEqual(existing_olt.dp_id, "of:0000000ce2314000")
264 self.assertEqual(existing_olt.serial_number, "orig_serial")
265
266 # mock_olt_save.assert_called()
267 mock_pon_save.assert_called()
268 mock_nni_save.assert_called()
269
270 @requests_mock.Mocker()
271 def test_pull_existing_incorrect_voltha_serial(self, m):
272
273 existing_olt = Mock()
274 existing_olt.admin_state = "ENABLED"
275 existing_olt.enacted = 2
276 existing_olt.updated = 1
277 existing_olt.serial_number = "orig_serial"
278
279 self.devices["items"][0]["serial_number"] = "wrong_serial"
280
281 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
282 patch.object(OLTDevice.objects, "filter") as mock_get, \
283 patch.object(PONPort, "save") as mock_pon_save, \
284 patch.object(NNIPort, "save") as mock_nni_save, \
285 patch.object(existing_olt, "save") as mock_olt_save:
286 olt_service_mock.return_value = [self.volt_service]
287 mock_get.return_value = [existing_olt]
288
289 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
290 m.get("http://voltha_url:1234/api/v1/devices/test_id/ports", status_code=200, json=self.ports)
291 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=self.logical_devices)
292
293 self.sync_step(model_accessor=self.model_accessor).pull_records()
294
295 self.assertEqual(existing_olt.backend_code, 2)
296 self.assertEqual(existing_olt.backend_status, "Incorrect serial number")
297 self.assertEqual(existing_olt.serial_number, "orig_serial")
298
299 @requests_mock.Mocker()
Matteo Scandolo33523412018-04-12 15:21:13 -0700300 def test_pull_existing_do_not_sync(self, m):
301 existing_olt = Mock()
302 existing_olt.enacted = 1
303 existing_olt.updated = 2
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700304 existing_olt.device_id = "test_id"
Matteo Scandolo33523412018-04-12 15:21:13 -0700305
306 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700307 patch.object(OLTDevice.objects, "filter") as mock_get, \
308 patch.object(PONPort, "save") as mock_pon_save, \
309 patch.object(NNIPort, "save") as mock_nni_save, \
310 patch.object(existing_olt, "save") as mock_olt_save:
311
Matteo Scandolo33523412018-04-12 15:21:13 -0700312 olt_service_mock.return_value = [self.volt_service]
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700313 mock_get.return_value = [existing_olt]
Matteo Scandolo33523412018-04-12 15:21:13 -0700314
Matteo Scandolo19466a02018-05-16 17:43:39 -0700315 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700316 m.get("http://voltha_url:1234/api/v1/devices/test_id/ports", status_code=200, json=self.ports)
Matteo Scandolo19466a02018-05-16 17:43:39 -0700317 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=self.logical_devices)
Matteo Scandolo33523412018-04-12 15:21:13 -0700318
Scott Baker47b47302019-01-30 16:55:07 -0800319 self.sync_step(model_accessor=self.model_accessor).pull_records()
Matteo Scandolo33523412018-04-12 15:21:13 -0700320
Matteo Scandolo6be6ee92018-05-24 15:07:51 -0700321 mock_olt_save.assert_not_called()
322 mock_pon_save.assert_called()
323 mock_nni_save.assert_called()
Matteo Scandolo33523412018-04-12 15:21:13 -0700324
Matteo Scandoloa4fb0322018-08-20 17:35:29 -0700325 @requests_mock.Mocker()
326 def test_pull_deleted_object(self, m):
327 existing_olt = Mock()
328 existing_olt.enacted = 2
329 existing_olt.updated = 1
330 existing_olt.device_id = "test_id"
331
332 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json={"items": []})
333
334 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
335 patch.object(OLTDevice.objects, "get_items") as mock_get, \
336 patch.object(existing_olt, "delete") as mock_olt_delete:
337
338 olt_service_mock.return_value = [self.volt_service]
339 mock_get.return_value = [existing_olt]
340
Scott Baker47b47302019-01-30 16:55:07 -0800341 self.sync_step(model_accessor=self.model_accessor).pull_records()
Matteo Scandoloa4fb0322018-08-20 17:35:29 -0700342
343 mock_olt_delete.assert_called()
344
Vijaykumar Kushwaha377d1da2019-03-20 10:29:42 +0530345#[SEBA-367] Unit test for blank response recieved from Voltha
346
347 @requests_mock.Mocker()
348 def test_blank_response_received(self, m):
349
350 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, text="")
351 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
352 patch.object(PONPort, "save") as mock_pon_save, \
353 patch.object(NNIPort, "save") as mock_nni_save, \
354 patch.object(OLTDevice.objects, "get_items") as mock_get:
355
356 olt_service_mock.return_value = [self.volt_service]
357
358 self.sync_step(model_accessor=self.model_accessor).pull_records()
359
360 olt_service_mock.assert_called()
361 mock_pon_save.assert_not_called()
362 mock_nni_save.assert_not_called()
363 mock_get.assert_not_called()
364
365#[SEBA-367] Unit test for invalid json received from Voltha
366
367 @requests_mock.Mocker()
368 def test_invalid_json(self, m):
369
370 m.get("http://voltha_url:1234/api/v1/devices", status_code=200, text="{\"items\" : [host_and_port }")
371 with patch.object(VOLTService.objects, "all") as olt_service_mock, \
372 patch.object(PONPort, "save") as mock_pon_save, \
373 patch.object(NNIPort, "save") as mock_nni_save, \
374 patch.object(OLTDevice.objects, "get_items") as mock_get:
375
376 olt_service_mock.return_value = [self.volt_service]
377
378 self.sync_step(model_accessor=self.model_accessor).pull_records()
379
380 olt_service_mock.assert_called()
381 mock_pon_save.assert_not_called()
382 mock_nni_save.assert_not_called()
383 mock_get.assert_not_called()
Matteo Scandoloa4fb0322018-08-20 17:35:29 -0700384
Matteo Scandolo33523412018-04-12 15:21:13 -0700385if __name__ == "__main__":
Vijaykumar Kushwaha377d1da2019-03-20 10:29:42 +0530386 unittest.main()
387