blob: 044d371a1646102ae584f32c5cf07f314b6abbe7 [file] [log] [blame]
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -08001# 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
Scott Baker22b46c52018-11-15 15:15:29 -080015from requests import ConnectionError
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080016import unittest
Matteo Scandolo2ed64b92018-06-18 10:32:56 -070017import functools
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080018from mock import patch, call, Mock, PropertyMock
19import requests_mock
20
21import os, sys
22
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080023test_path=os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080024
Matteo Scandolo2ed64b92018-06-18 10:32:56 -070025def match_json(desired, req):
26 if desired!=req.json():
27 raise Exception("Got request %s, but body is not matching" % req.url)
28 return False
29 return True
30
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080031class TestSyncOLTDevice(unittest.TestCase):
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080032 def setUp(self):
Matteo Scandolo6be6ee92018-05-24 15:07:51 -070033 global DeferredException
Matteo Scandoloce27e9c2018-04-06 10:06:53 -070034 self.sys_path_save = sys.path
Matteo Scandoloce27e9c2018-04-06 10:06:53 -070035
36 # Setting up the config module
37 from xosconfig import Config
Matteo Scandolof7ebb112018-09-18 16:17:22 -070038 config = os.path.join(test_path, "../test_config.yaml")
Matteo Scandoloce27e9c2018-04-06 10:06:53 -070039 Config.clear()
40 Config.init(config, "synchronizer-config-schema.yaml")
Luca Preteca974c82018-05-01 18:06:16 -070041 # END setting up the config module
Matteo Scandoloce27e9c2018-04-06 10:06:53 -070042
Scott Baker47b47302019-01-30 16:55:07 -080043 from xossynchronizer.mock_modelaccessor_build import mock_modelaccessor_config
44 mock_modelaccessor_config(test_path, [("olt-service", "volt.xproto"),
45 ("vsg", "vsg.xproto"),
Matteo Scandoloe04a4882019-02-14 10:22:24 -080046 ("rcord", "rcord.xproto"),])
Matteo Scandolo19466a02018-05-16 17:43:39 -070047
Scott Baker47b47302019-01-30 16:55:07 -080048 import xossynchronizer.modelaccessor
49 reload(xossynchronizer.modelaccessor) # in case nose2 loaded it in a previous test
Matteo Scandolo19466a02018-05-16 17:43:39 -070050
Scott Baker47b47302019-01-30 16:55:07 -080051 from xossynchronizer.modelaccessor import model_accessor
52 self.model_accessor = model_accessor
53
Matteo Scandolo6be6ee92018-05-24 15:07:51 -070054 from sync_olt_device import SyncOLTDevice, DeferredException
Matteo Scandoloce27e9c2018-04-06 10:06:53 -070055 self.sync_step = SyncOLTDevice
56
Matteo Scandolob8621cd2018-04-04 17:12:37 -070057 pon_port = Mock()
58 pon_port.port_id = "00ff00"
Matteo Scandolob8621cd2018-04-04 17:12:37 -070059
Matteo Scandolo2ed64b92018-06-18 10:32:56 -070060 # Create a mock OLTDevice
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080061 o = Mock()
62 o.volt_service.voltha_url = "voltha_url"
Luca Preteca974c82018-05-01 18:06:16 -070063 o.volt_service.voltha_port = 1234
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080064 o.volt_service.voltha_user = "voltha_user"
65 o.volt_service.voltha_pass = "voltha_pass"
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080066
Matteo Scandoloa79395f2018-10-08 13:34:49 -070067 o.volt_service.onos_voltha_port = 4321
68 o.volt_service.onos_voltha_url = "onos"
69 o.volt_service.onos_voltha_user = "karaf"
70 o.volt_service.onos_voltha_pass = "karaf"
71
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080072 o.device_type = "ponsim_olt"
73 o.host = "172.17.0.1"
74 o.port = "50060"
Scott Baker0bbbfd12018-12-11 07:01:06 +000075 o.uplink = "129"
Luca Prete244e6ec2018-07-02 14:30:24 +020076 o.driver = "voltha"
Matteo Scandoloa79395f2018-10-08 13:34:49 -070077 o.name = "Test Device"
Scott Baker09798d82019-01-17 08:34:59 -080078 o.admin_state = "ENABLED"
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080079
Matteo Scandolob8621cd2018-04-04 17:12:37 -070080 # feedback state
81 o.device_id = None
Matteo Scandolob8621cd2018-04-04 17:12:37 -070082 o.oper_status = None
83 o.of_id = None
Matteo Scandolo096a3cf2018-06-20 13:56:13 -070084 o.id = 1
Matteo Scandolob8621cd2018-04-04 17:12:37 -070085
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080086 o.tologdict.return_value = {'name': "Mock VOLTServiceInstance"}
87
Andy Bavier00c573c2019-02-08 16:19:11 -070088 o.save_changed_fields.return_value = "Saved"
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080089
Matteo Scandolo6be6ee92018-05-24 15:07:51 -070090 o.pon_ports.all.return_value = [pon_port]
Matteo Scandolob8621cd2018-04-04 17:12:37 -070091
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080092 self.o = o
93
Matteo Scandolod6fce512018-10-16 10:35:29 -070094 self.voltha_devices_response = {"id": "123", "serial_number": "foobar"}
95
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080096 def tearDown(self):
97 self.o = None
Matteo Scandoloce27e9c2018-04-06 10:06:53 -070098 sys.path = self.sys_path_save
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080099
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800100 @requests_mock.Mocker()
101 def test_get_of_id_from_device(self, m):
102 logical_devices = {
103 "items": [
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700104 {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800105 {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
106 ]
107 }
Luca Preteca974c82018-05-01 18:06:16 -0700108 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800109 self.o.device_id = "123"
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700110 self.o = self.sync_step.get_ids_from_logical_device(self.o)
111 self.assertEqual(self.o.of_id, "0001000ce2314000")
112 self.assertEqual(self.o.dp_id, "of:0000000ce2314000")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800113
114 with self.assertRaises(Exception) as e:
115 self.o.device_id = "idonotexist"
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700116 self.sync_step.get_ids_from_logical_device(self.o)
Matteo Scandolo2c144932018-05-04 14:06:24 -0700117 self.assertEqual(e.exception.message, "Can't find a logical_device for OLT device id: idonotexist")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800118
119 @requests_mock.Mocker()
120 def test_sync_record_fail_add(self, m):
121 """
122 Should print an error if we can't add the device in VOLTHA
123 """
Luca Preteca974c82018-05-01 18:06:16 -0700124 m.post("http://voltha_url:1234/api/v1/devices", status_code=500, text="MockError")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800125
126 with self.assertRaises(Exception) as e:
Scott Baker47b47302019-01-30 16:55:07 -0800127 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo2c144932018-05-04 14:06:24 -0700128 self.assertEqual(e.exception.message, "Failed to add OLT device: MockError")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800129
130 @requests_mock.Mocker()
131 def test_sync_record_fail_no_id(self, m):
132 """
133 Should print an error if VOLTHA does not return the device id
134 """
Luca Preteca974c82018-05-01 18:06:16 -0700135 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json={"id": ""})
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800136
137 with self.assertRaises(Exception) as e:
Scott Baker47b47302019-01-30 16:55:07 -0800138 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo2c144932018-05-04 14:06:24 -0700139 self.assertEqual(e.exception.message, "VOLTHA Device Id is empty. This probably means that the OLT device is already provisioned in VOLTHA")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800140
141 @requests_mock.Mocker()
142 def test_sync_record_fail_enable(self, m):
143 """
144 Should print an error if device.enable fails
145 """
Matteo Scandolod6fce512018-10-16 10:35:29 -0700146 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response)
Luca Preteca974c82018-05-01 18:06:16 -0700147 m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=500, text="EnableError")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800148
149 with self.assertRaises(Exception) as e:
Scott Baker47b47302019-01-30 16:55:07 -0800150 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo2c144932018-05-04 14:06:24 -0700151
152 self.assertEqual(e.exception.message, "Failed to enable OLT device: EnableError")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800153
154 @requests_mock.Mocker()
155 def test_sync_record_success(self, m):
156 """
157 If device.enable succed should fetch the state, retrieve the of_id and push it to ONOS
158 """
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700159
160 expected_conf = {
161 "type": self.o.device_type,
162 "host_and_port": "%s:%s" % (self.o.host, self.o.port)
163 }
164
Matteo Scandolod6fce512018-10-16 10:35:29 -0700165 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response, additional_matcher=functools.partial(match_json, expected_conf))
Luca Preteca974c82018-05-01 18:06:16 -0700166 m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=200)
Matteo Scandolo45876652018-10-16 16:03:17 -0700167 m.get("http://voltha_url:1234/api/v1/devices/123", json={"oper_status": "ACTIVE", "admin_state": "ENABLED", "serial_number": "foobar"})
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800168 logical_devices = {
169 "items": [
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700170 {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800171 {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
172 ]
173 }
Luca Preteca974c82018-05-01 18:06:16 -0700174 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800175
Matteo Scandoloa79395f2018-10-08 13:34:49 -0700176 onos_expected_conf = {
177 "devices": {
178 "of:0000000ce2314000": {
179 "basic": {
180 "name": self.o.name
181 }
182 }
183 }
184 }
185 m.post("http://onos:4321/onos/v1/network/configuration/", status_code=200, json=onos_expected_conf,
186 additional_matcher=functools.partial(match_json, onos_expected_conf))
187
Scott Baker47b47302019-01-30 16:55:07 -0800188 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700189 self.assertEqual(self.o.admin_state, "ENABLED")
190 self.assertEqual(self.o.oper_status, "ACTIVE")
Matteo Scandolo45876652018-10-16 16:03:17 -0700191 self.assertEqual(self.o.serial_number, "foobar")
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700192 self.assertEqual(self.o.of_id, "0001000ce2314000")
Scott Baker09798d82019-01-17 08:34:59 -0800193
194 # One save during preprovision
195 # One save during activation to set backend_status to "Waiting for device to activate"
196 # One save after activation has succeeded
Andy Bavier00c573c2019-02-08 16:19:11 -0700197 self.assertEqual(self.o.save_changed_fields.call_count, 3)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800198
199 @requests_mock.Mocker()
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700200 def test_sync_record_success_mac_address(self, m):
201 """
202 A device should be pre-provisioned via mac_address, the the process is the same
203 """
204
205 del self.o.host
206 del self.o.port
207 self.o.mac_address = "00:0c:e2:31:40:00"
208
209 expected_conf = {
210 "type": self.o.device_type,
211 "mac_address": self.o.mac_address
212 }
213
Matteo Scandoloa79395f2018-10-08 13:34:49 -0700214 onos_expected_conf = {
215 "devices": {
216 "of:0000000ce2314000": {
217 "basic": {
218 "name": self.o.name
219 }
220 }
221 }
222 }
223 m.post("http://onos:4321/onos/v1/network/configuration/", status_code=200, json=onos_expected_conf,
224 additional_matcher=functools.partial(match_json, onos_expected_conf))
225
Matteo Scandolod6fce512018-10-16 10:35:29 -0700226 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response,
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700227 additional_matcher=functools.partial(match_json, expected_conf))
228 m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=200)
Matteo Scandolo45876652018-10-16 16:03:17 -0700229 m.get("http://voltha_url:1234/api/v1/devices/123", json={"oper_status": "ACTIVE", "admin_state": "ENABLED", "serial_number": "foobar"})
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700230 logical_devices = {
231 "items": [
232 {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
233 {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
234 ]
235 }
236 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
237
Scott Baker47b47302019-01-30 16:55:07 -0800238 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700239 self.assertEqual(self.o.admin_state, "ENABLED")
240 self.assertEqual(self.o.oper_status, "ACTIVE")
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700241 self.assertEqual(self.o.of_id, "0001000ce2314000")
Scott Baker09798d82019-01-17 08:34:59 -0800242
243 # One save during preprovision
244 # One save during activation to set backend_status to "Waiting for device to activate"
245 # One save after activation has succeeded
Andy Bavier00c573c2019-02-08 16:19:11 -0700246 self.assertEqual(self.o.save_changed_fields.call_count, 3)
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700247
248 @requests_mock.Mocker()
249 def test_sync_record_enable_timeout(self, m):
250 """
Scott Baker09798d82019-01-17 08:34:59 -0800251 If device activation fails we need to tell the user.
252
253 OLT will be preprovisioned.
254 OLT will return "ERROR" for oper_status during activate and will eventually exceed retries.s
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700255 """
256
257 expected_conf = {
258 "type": self.o.device_type,
259 "host_and_port": "%s:%s" % (self.o.host, self.o.port)
260 }
261
Matteo Scandolod6fce512018-10-16 10:35:29 -0700262 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response,
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700263 additional_matcher=functools.partial(match_json, expected_conf))
264 m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=200)
265 m.get("http://voltha_url:1234/api/v1/devices/123", [
Matteo Scandolo45876652018-10-16 16:03:17 -0700266 {"json": {"oper_status": "ACTIVATING", "admin_state": "ENABLED", "serial_number": "foobar"}, "status_code": 200},
Scott Baker09798d82019-01-17 08:34:59 -0800267 {"json": {"oper_status": "ERROR", "admin_state": "ENABLED", "serial_number": "foobar"}, "status_code": 200}
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700268 ])
269
270 logical_devices = {
271 "items": [
272 {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
273 {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
274 ]
275 }
276 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
277
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700278 with self.assertRaises(Exception) as e:
Scott Baker47b47302019-01-30 16:55:07 -0800279 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700280
281 self.assertEqual(e.exception.message, "It was not possible to activate OLTDevice with id 1")
282 self.assertEqual(self.o.oper_status, "ERROR")
Scott Baker09798d82019-01-17 08:34:59 -0800283 self.assertEqual(self.o.admin_state, "ENABLED")
284 self.assertEqual(self.o.device_id, "123")
285 self.assertEqual(self.o.serial_number, "foobar")
286
287 # One save from preprovision to set device_id, serial_number
288 # One save from activate to set backend_status to "Waiting for device to be activated"
Andy Bavier00c573c2019-02-08 16:19:11 -0700289 self.assertEqual(self.o.save_changed_fields.call_count, 2)
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700290
291 @requests_mock.Mocker()
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700292 def test_sync_record_already_existing_in_voltha(self, m):
Scott Baker09798d82019-01-17 08:34:59 -0800293 """
294 If device.admin_state == "ENABLED" and oper_status == "ACTIVE", then the OLT should not be reactivated.
295 """
296
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700297 # mock device feedback state
298 self.o.device_id = "123"
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700299 self.o.admin_state = "ENABLED"
300 self.o.oper_status = "ACTIVE"
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700301 self.o.dp_id = "of:0000000ce2314000"
Matteo Scandolo2c144932018-05-04 14:06:24 -0700302 self.o.of_id = "0001000ce2314000"
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700303
Matteo Scandoloa79395f2018-10-08 13:34:49 -0700304 expected_conf = {
305 "devices": {
306 self.o.dp_id: {
307 "basic": {
308 "name": self.o.name
309 }
310 }
311 }
312 }
313 m.post("http://onos:4321/onos/v1/network/configuration/", status_code=200, json=expected_conf,
314 additional_matcher=functools.partial(match_json, expected_conf))
315
Scott Baker47b47302019-01-30 16:55:07 -0800316 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700317 self.o.save.assert_not_called()
Andy Bavier00c573c2019-02-08 16:19:11 -0700318 self.o.save_changed_fields.assert_not_called()
319
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700320
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700321 @requests_mock.Mocker()
Scott Baker09798d82019-01-17 08:34:59 -0800322 def test_sync_record_deactivate(self, m):
323 """
324 If device.admin_state == "DISABLED" and oper_status == "ACTIVE", then OLT should be deactivated.
325 """
326
327 expected_conf = {
328 "type": self.o.device_type,
329 "host_and_port": "%s:%s" % (self.o.host, self.o.port)
330 }
331
332 # Make it look like we have an active OLT that we are deactivating.
333 self.o.admin_state = "DISABLED"
334 self.o.oper_status = "ACTIVE"
335 self.o.serial_number = "foobar"
336 self.o.device_id = "123"
337 self.o.of_id = "0001000ce2314000"
338
339 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response, additional_matcher=functools.partial(match_json, expected_conf))
340 m.post("http://voltha_url:1234/api/v1/devices/123/disable", status_code=200)
341
Scott Baker47b47302019-01-30 16:55:07 -0800342 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Scott Baker09798d82019-01-17 08:34:59 -0800343
344 # No saves as state has not changed (will eventually be saved by synchronizer framework to update backend_status)
345 self.assertEqual(self.o.save.call_count, 0)
Andy Bavier00c573c2019-02-08 16:19:11 -0700346 self.assertEqual(self.o.save_changed_fields.call_count, 0)
347
Scott Baker09798d82019-01-17 08:34:59 -0800348
349 # Make sure disable was called
350 urls = [x.url for x in m.request_history]
351 self.assertIn("http://voltha_url:1234/api/v1/devices/123/disable", urls)
352
353 @requests_mock.Mocker()
354 def test_sync_record_deactivate_already_inactive(self, m):
355 """
356 If device.admin_state == "DISABLED" and device.oper_status == "UNKNOWN", then the device is already deactivated
357 and VOLTHA should not be called.
358 """
359
360 expected_conf = {
361 "type": self.o.device_type,
362 "host_and_port": "%s:%s" % (self.o.host, self.o.port)
363 }
364
365 # Make it look like we have an active OLT that we are deactivating.
366 self.o.admin_state = "DISABLED"
367 self.o.oper_status = "UNKNOWN"
368 self.o.serial_number = "foobar"
369 self.o.device_id = "123"
370 self.o.of_id = "0001000ce2314000"
371
372 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response, additional_matcher=functools.partial(match_json, expected_conf))
373
Scott Baker47b47302019-01-30 16:55:07 -0800374 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Scott Baker09798d82019-01-17 08:34:59 -0800375
376 # No saves as state has not changed (will eventually be saved by synchronizer framework to update backend_status)
377 self.assertEqual(self.o.save.call_count, 0)
Andy Bavier00c573c2019-02-08 16:19:11 -0700378 self.assertEqual(self.o.save_changed_fields.call_count, 0)
Scott Baker09798d82019-01-17 08:34:59 -0800379
380 @requests_mock.Mocker()
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800381 def test_delete_record(self, m):
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700382 self.o.of_id = "0001000ce2314000"
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800383 self.o.device_id = "123"
384
Luca Preteca974c82018-05-01 18:06:16 -0700385 m.post("http://voltha_url:1234/api/v1/devices/123/disable", status_code=200)
386 m.delete("http://voltha_url:1234/api/v1/devices/123/delete", status_code=200)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800387
Scott Baker47b47302019-01-30 16:55:07 -0800388 self.sync_step(model_accessor=self.model_accessor).delete_record(self.o)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800389
Matteo Scandolo563891c2018-08-21 11:56:32 -0700390 self.assertEqual(m.call_count, 2)
391
Scott Baker22b46c52018-11-15 15:15:29 -0800392 @patch('requests.post')
393 def test_delete_record_connectionerror(self, m):
394 self.o.of_id = "0001000ce2314000"
395 self.o.device_id = "123"
396
397 m.side_effect = ConnectionError()
398
Scott Baker47b47302019-01-30 16:55:07 -0800399 self.sync_step(model_accessor=self.model_accessor).delete_record(self.o)
Scott Baker22b46c52018-11-15 15:15:29 -0800400
401 # No exception thrown, as ConnectionError will be caught
402
403
Matteo Scandolo563891c2018-08-21 11:56:32 -0700404 @requests_mock.Mocker()
405 def test_delete_unsynced_record(self, m):
406
Scott Baker47b47302019-01-30 16:55:07 -0800407 self.sync_step(model_accessor=self.model_accessor).delete_record(self.o)
Matteo Scandolo563891c2018-08-21 11:56:32 -0700408
409 self.assertEqual(m.call_count, 0)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800410
411if __name__ == "__main__":
Luca Preteca974c82018-05-01 18:06:16 -0700412 unittest.main()