blob: 307cae19d8cf7f51a37186cd28cf31161fdc3047 [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"),
Matteo Scandolo35207b72019-05-10 08:46:48 -070045 ("rcord", "rcord.xproto")])
Matteo Scandolo19466a02018-05-16 17:43:39 -070046
Scott Baker47b47302019-01-30 16:55:07 -080047 import xossynchronizer.modelaccessor
48 reload(xossynchronizer.modelaccessor) # in case nose2 loaded it in a previous test
Matteo Scandolo19466a02018-05-16 17:43:39 -070049
Scott Baker47b47302019-01-30 16:55:07 -080050 from xossynchronizer.modelaccessor import model_accessor
51 self.model_accessor = model_accessor
52
Matteo Scandolo6be6ee92018-05-24 15:07:51 -070053 from sync_olt_device import SyncOLTDevice, DeferredException
Matteo Scandoloce27e9c2018-04-06 10:06:53 -070054 self.sync_step = SyncOLTDevice
55
Matteo Scandolob8621cd2018-04-04 17:12:37 -070056 pon_port = Mock()
57 pon_port.port_id = "00ff00"
Matteo Scandolob8621cd2018-04-04 17:12:37 -070058
Matteo Scandolo0d756f22019-06-10 14:55:55 -070059 # create a mock ONOS Service
60 onos = Mock()
61 onos.name = "ONOS"
62 onos.leaf_model.rest_hostname = "onos"
63 onos.leaf_model.rest_port = 4321
64 onos.leaf_model.rest_username = "karaf"
65 onos.leaf_model.rest_password = "karaf"
66
Matteo Scandolo2ed64b92018-06-18 10:32:56 -070067 # Create a mock OLTDevice
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080068 o = Mock()
69 o.volt_service.voltha_url = "voltha_url"
Luca Preteca974c82018-05-01 18:06:16 -070070 o.volt_service.voltha_port = 1234
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080071 o.volt_service.voltha_user = "voltha_user"
72 o.volt_service.voltha_pass = "voltha_pass"
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080073
Matteo Scandolo0d756f22019-06-10 14:55:55 -070074 o.volt_service.provider_services = [onos]
Matteo Scandoloa79395f2018-10-08 13:34:49 -070075
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080076 o.device_type = "ponsim_olt"
77 o.host = "172.17.0.1"
78 o.port = "50060"
Scott Baker0bbbfd12018-12-11 07:01:06 +000079 o.uplink = "129"
Luca Prete244e6ec2018-07-02 14:30:24 +020080 o.driver = "voltha"
Matteo Scandoloa79395f2018-10-08 13:34:49 -070081 o.name = "Test Device"
Scott Baker09798d82019-01-17 08:34:59 -080082 o.admin_state = "ENABLED"
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080083
Matteo Scandolob8621cd2018-04-04 17:12:37 -070084 # feedback state
85 o.device_id = None
Matteo Scandolob8621cd2018-04-04 17:12:37 -070086 o.oper_status = None
87 o.of_id = None
Matteo Scandolo096a3cf2018-06-20 13:56:13 -070088 o.id = 1
Matteo Scandolob8621cd2018-04-04 17:12:37 -070089
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080090 o.tologdict.return_value = {'name': "Mock VOLTServiceInstance"}
91
Andy Bavier00c573c2019-02-08 16:19:11 -070092 o.save_changed_fields.return_value = "Saved"
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080093
Matteo Scandolo6be6ee92018-05-24 15:07:51 -070094 o.pon_ports.all.return_value = [pon_port]
Matteo Scandolob8621cd2018-04-04 17:12:37 -070095
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080096 self.o = o
97
Matteo Scandolod6fce512018-10-16 10:35:29 -070098 self.voltha_devices_response = {"id": "123", "serial_number": "foobar"}
99
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800100 def tearDown(self):
101 self.o = None
Matteo Scandoloce27e9c2018-04-06 10:06:53 -0700102 sys.path = self.sys_path_save
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800103
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800104 @requests_mock.Mocker()
105 def test_get_of_id_from_device(self, m):
106 logical_devices = {
107 "items": [
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700108 {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800109 {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
110 ]
111 }
Luca Preteca974c82018-05-01 18:06:16 -0700112 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800113 self.o.device_id = "123"
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700114 self.o = self.sync_step.get_ids_from_logical_device(self.o)
115 self.assertEqual(self.o.of_id, "0001000ce2314000")
116 self.assertEqual(self.o.dp_id, "of:0000000ce2314000")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800117
118 with self.assertRaises(Exception) as e:
119 self.o.device_id = "idonotexist"
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700120 self.sync_step.get_ids_from_logical_device(self.o)
Matteo Scandolo2c144932018-05-04 14:06:24 -0700121 self.assertEqual(e.exception.message, "Can't find a logical_device for OLT device id: idonotexist")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800122
123 @requests_mock.Mocker()
124 def test_sync_record_fail_add(self, m):
125 """
126 Should print an error if we can't add the device in VOLTHA
127 """
Luca Preteca974c82018-05-01 18:06:16 -0700128 m.post("http://voltha_url:1234/api/v1/devices", status_code=500, text="MockError")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800129
130 with self.assertRaises(Exception) as e:
Scott Baker47b47302019-01-30 16:55:07 -0800131 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo2c144932018-05-04 14:06:24 -0700132 self.assertEqual(e.exception.message, "Failed to add OLT device: MockError")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800133
134 @requests_mock.Mocker()
135 def test_sync_record_fail_no_id(self, m):
136 """
137 Should print an error if VOLTHA does not return the device id
138 """
Luca Preteca974c82018-05-01 18:06:16 -0700139 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json={"id": ""})
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800140
141 with self.assertRaises(Exception) as e:
Scott Baker47b47302019-01-30 16:55:07 -0800142 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo2c144932018-05-04 14:06:24 -0700143 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 -0800144
145 @requests_mock.Mocker()
146 def test_sync_record_fail_enable(self, m):
147 """
148 Should print an error if device.enable fails
149 """
Matteo Scandolod6fce512018-10-16 10:35:29 -0700150 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response)
Luca Preteca974c82018-05-01 18:06:16 -0700151 m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=500, text="EnableError")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800152
153 with self.assertRaises(Exception) as e:
Scott Baker47b47302019-01-30 16:55:07 -0800154 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo2c144932018-05-04 14:06:24 -0700155
156 self.assertEqual(e.exception.message, "Failed to enable OLT device: EnableError")
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800157
158 @requests_mock.Mocker()
159 def test_sync_record_success(self, m):
160 """
161 If device.enable succed should fetch the state, retrieve the of_id and push it to ONOS
162 """
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700163
164 expected_conf = {
165 "type": self.o.device_type,
166 "host_and_port": "%s:%s" % (self.o.host, self.o.port)
167 }
168
Matteo Scandolod6fce512018-10-16 10:35:29 -0700169 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 -0700170 m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=200)
Matteo Scandolo45876652018-10-16 16:03:17 -0700171 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 -0800172 logical_devices = {
173 "items": [
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700174 {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800175 {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
176 ]
177 }
Luca Preteca974c82018-05-01 18:06:16 -0700178 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800179
Matteo Scandoloa79395f2018-10-08 13:34:49 -0700180 onos_expected_conf = {
181 "devices": {
182 "of:0000000ce2314000": {
183 "basic": {
184 "name": self.o.name
185 }
186 }
187 }
188 }
189 m.post("http://onos:4321/onos/v1/network/configuration/", status_code=200, json=onos_expected_conf,
190 additional_matcher=functools.partial(match_json, onos_expected_conf))
191
Scott Baker47b47302019-01-30 16:55:07 -0800192 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700193 self.assertEqual(self.o.admin_state, "ENABLED")
194 self.assertEqual(self.o.oper_status, "ACTIVE")
Matteo Scandolo45876652018-10-16 16:03:17 -0700195 self.assertEqual(self.o.serial_number, "foobar")
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700196 self.assertEqual(self.o.of_id, "0001000ce2314000")
Scott Baker09798d82019-01-17 08:34:59 -0800197
198 # One save during preprovision
199 # One save during activation to set backend_status to "Waiting for device to activate"
200 # One save after activation has succeeded
Andy Bavier00c573c2019-02-08 16:19:11 -0700201 self.assertEqual(self.o.save_changed_fields.call_count, 3)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800202
203 @requests_mock.Mocker()
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700204 def test_sync_record_success_mac_address(self, m):
205 """
206 A device should be pre-provisioned via mac_address, the the process is the same
207 """
208
209 del self.o.host
210 del self.o.port
211 self.o.mac_address = "00:0c:e2:31:40:00"
212
213 expected_conf = {
214 "type": self.o.device_type,
215 "mac_address": self.o.mac_address
216 }
217
Matteo Scandoloa79395f2018-10-08 13:34:49 -0700218 onos_expected_conf = {
219 "devices": {
220 "of:0000000ce2314000": {
221 "basic": {
222 "name": self.o.name
223 }
224 }
225 }
226 }
227 m.post("http://onos:4321/onos/v1/network/configuration/", status_code=200, json=onos_expected_conf,
228 additional_matcher=functools.partial(match_json, onos_expected_conf))
229
Matteo Scandolod6fce512018-10-16 10:35:29 -0700230 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response,
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700231 additional_matcher=functools.partial(match_json, expected_conf))
232 m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=200)
Matteo Scandolo45876652018-10-16 16:03:17 -0700233 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 -0700234 logical_devices = {
235 "items": [
236 {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
237 {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
238 ]
239 }
240 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
241
Scott Baker47b47302019-01-30 16:55:07 -0800242 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700243 self.assertEqual(self.o.admin_state, "ENABLED")
244 self.assertEqual(self.o.oper_status, "ACTIVE")
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700245 self.assertEqual(self.o.of_id, "0001000ce2314000")
Scott Baker09798d82019-01-17 08:34:59 -0800246
247 # One save during preprovision
248 # One save during activation to set backend_status to "Waiting for device to activate"
249 # One save after activation has succeeded
Andy Bavier00c573c2019-02-08 16:19:11 -0700250 self.assertEqual(self.o.save_changed_fields.call_count, 3)
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700251
252 @requests_mock.Mocker()
253 def test_sync_record_enable_timeout(self, m):
254 """
Scott Baker09798d82019-01-17 08:34:59 -0800255 If device activation fails we need to tell the user.
256
257 OLT will be preprovisioned.
258 OLT will return "ERROR" for oper_status during activate and will eventually exceed retries.s
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700259 """
260
261 expected_conf = {
262 "type": self.o.device_type,
263 "host_and_port": "%s:%s" % (self.o.host, self.o.port)
264 }
265
Matteo Scandolod6fce512018-10-16 10:35:29 -0700266 m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.voltha_devices_response,
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700267 additional_matcher=functools.partial(match_json, expected_conf))
268 m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=200)
269 m.get("http://voltha_url:1234/api/v1/devices/123", [
Matteo Scandolo45876652018-10-16 16:03:17 -0700270 {"json": {"oper_status": "ACTIVATING", "admin_state": "ENABLED", "serial_number": "foobar"}, "status_code": 200},
Scott Baker09798d82019-01-17 08:34:59 -0800271 {"json": {"oper_status": "ERROR", "admin_state": "ENABLED", "serial_number": "foobar"}, "status_code": 200}
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700272 ])
273
274 logical_devices = {
275 "items": [
276 {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
277 {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
278 ]
279 }
280 m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
281
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700282 with self.assertRaises(Exception) as e:
Scott Baker47b47302019-01-30 16:55:07 -0800283 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700284
285 self.assertEqual(e.exception.message, "It was not possible to activate OLTDevice with id 1")
286 self.assertEqual(self.o.oper_status, "ERROR")
Scott Baker09798d82019-01-17 08:34:59 -0800287 self.assertEqual(self.o.admin_state, "ENABLED")
288 self.assertEqual(self.o.device_id, "123")
289 self.assertEqual(self.o.serial_number, "foobar")
290
291 # One save from preprovision to set device_id, serial_number
292 # One save from activate to set backend_status to "Waiting for device to be activated"
Andy Bavier00c573c2019-02-08 16:19:11 -0700293 self.assertEqual(self.o.save_changed_fields.call_count, 2)
Matteo Scandolo2ed64b92018-06-18 10:32:56 -0700294
295 @requests_mock.Mocker()
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700296 def test_sync_record_already_existing_in_voltha(self, m):
Scott Baker09798d82019-01-17 08:34:59 -0800297 """
298 If device.admin_state == "ENABLED" and oper_status == "ACTIVE", then the OLT should not be reactivated.
299 """
300
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700301 # mock device feedback state
302 self.o.device_id = "123"
Matteo Scandolo096a3cf2018-06-20 13:56:13 -0700303 self.o.admin_state = "ENABLED"
304 self.o.oper_status = "ACTIVE"
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700305 self.o.dp_id = "of:0000000ce2314000"
Matteo Scandolo2c144932018-05-04 14:06:24 -0700306 self.o.of_id = "0001000ce2314000"
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700307
Matteo Scandoloa79395f2018-10-08 13:34:49 -0700308 expected_conf = {
309 "devices": {
310 self.o.dp_id: {
311 "basic": {
312 "name": self.o.name
313 }
314 }
315 }
316 }
317 m.post("http://onos:4321/onos/v1/network/configuration/", status_code=200, json=expected_conf,
318 additional_matcher=functools.partial(match_json, expected_conf))
319
Scott Baker47b47302019-01-30 16:55:07 -0800320 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700321 self.o.save.assert_not_called()
Andy Bavier00c573c2019-02-08 16:19:11 -0700322 self.o.save_changed_fields.assert_not_called()
323
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700324
Matteo Scandolob8621cd2018-04-04 17:12:37 -0700325 @requests_mock.Mocker()
Scott Baker09798d82019-01-17 08:34:59 -0800326 def test_sync_record_deactivate(self, m):
327 """
328 If device.admin_state == "DISABLED" and oper_status == "ACTIVE", then OLT should be deactivated.
329 """
330
331 expected_conf = {
332 "type": self.o.device_type,
333 "host_and_port": "%s:%s" % (self.o.host, self.o.port)
334 }
335
336 # Make it look like we have an active OLT that we are deactivating.
337 self.o.admin_state = "DISABLED"
338 self.o.oper_status = "ACTIVE"
339 self.o.serial_number = "foobar"
340 self.o.device_id = "123"
341 self.o.of_id = "0001000ce2314000"
342
343 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))
344 m.post("http://voltha_url:1234/api/v1/devices/123/disable", status_code=200)
345
Scott Baker47b47302019-01-30 16:55:07 -0800346 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Scott Baker09798d82019-01-17 08:34:59 -0800347
348 # No saves as state has not changed (will eventually be saved by synchronizer framework to update backend_status)
349 self.assertEqual(self.o.save.call_count, 0)
Andy Bavier00c573c2019-02-08 16:19:11 -0700350 self.assertEqual(self.o.save_changed_fields.call_count, 0)
351
Scott Baker09798d82019-01-17 08:34:59 -0800352
353 # Make sure disable was called
354 urls = [x.url for x in m.request_history]
355 self.assertIn("http://voltha_url:1234/api/v1/devices/123/disable", urls)
356
357 @requests_mock.Mocker()
358 def test_sync_record_deactivate_already_inactive(self, m):
359 """
360 If device.admin_state == "DISABLED" and device.oper_status == "UNKNOWN", then the device is already deactivated
361 and VOLTHA should not be called.
362 """
363
364 expected_conf = {
365 "type": self.o.device_type,
366 "host_and_port": "%s:%s" % (self.o.host, self.o.port)
367 }
368
369 # Make it look like we have an active OLT that we are deactivating.
370 self.o.admin_state = "DISABLED"
371 self.o.oper_status = "UNKNOWN"
372 self.o.serial_number = "foobar"
373 self.o.device_id = "123"
374 self.o.of_id = "0001000ce2314000"
375
376 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))
377
Scott Baker47b47302019-01-30 16:55:07 -0800378 self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
Scott Baker09798d82019-01-17 08:34:59 -0800379
380 # No saves as state has not changed (will eventually be saved by synchronizer framework to update backend_status)
381 self.assertEqual(self.o.save.call_count, 0)
Andy Bavier00c573c2019-02-08 16:19:11 -0700382 self.assertEqual(self.o.save_changed_fields.call_count, 0)
Scott Baker09798d82019-01-17 08:34:59 -0800383
384 @requests_mock.Mocker()
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800385 def test_delete_record(self, m):
Matteo Scandolof6337eb2018-04-05 15:58:37 -0700386 self.o.of_id = "0001000ce2314000"
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800387 self.o.device_id = "123"
388
Luca Preteca974c82018-05-01 18:06:16 -0700389 m.post("http://voltha_url:1234/api/v1/devices/123/disable", status_code=200)
390 m.delete("http://voltha_url:1234/api/v1/devices/123/delete", status_code=200)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800391
Scott Baker47b47302019-01-30 16:55:07 -0800392 self.sync_step(model_accessor=self.model_accessor).delete_record(self.o)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800393
Matteo Scandolo563891c2018-08-21 11:56:32 -0700394 self.assertEqual(m.call_count, 2)
395
Scott Baker22b46c52018-11-15 15:15:29 -0800396 @patch('requests.post')
397 def test_delete_record_connectionerror(self, m):
398 self.o.of_id = "0001000ce2314000"
399 self.o.device_id = "123"
400
401 m.side_effect = ConnectionError()
402
Scott Baker47b47302019-01-30 16:55:07 -0800403 self.sync_step(model_accessor=self.model_accessor).delete_record(self.o)
Scott Baker22b46c52018-11-15 15:15:29 -0800404
405 # No exception thrown, as ConnectionError will be caught
406
407
Matteo Scandolo563891c2018-08-21 11:56:32 -0700408 @requests_mock.Mocker()
409 def test_delete_unsynced_record(self, m):
410
Scott Baker47b47302019-01-30 16:55:07 -0800411 self.sync_step(model_accessor=self.model_accessor).delete_record(self.o)
Matteo Scandolo563891c2018-08-21 11:56:32 -0700412
413 self.assertEqual(m.call_count, 0)
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -0800414
415if __name__ == "__main__":
Luca Preteca974c82018-05-01 18:06:16 -0700416 unittest.main()