[CORD-3091] Pulling NNI and PON ports
Change-Id: I001782ffd8a092371f4939869c9c6dda2360bf98
diff --git a/samples/olt_device.yaml b/samples/olt_device.yaml
index c83b65c..8277a9b 100644
--- a/samples/olt_device.yaml
+++ b/samples/olt_device.yaml
@@ -44,25 +44,3 @@
- volt_service:
node: service#volt
relationship: tosca.relationships.BelongsToOne
-
- pon_port:
- type: tosca.nodes.PONPort
- properties:
- name: test_olt_port_1
- port_id: ff00ff
- s_tag: 111
- requirements:
- - olt_device:
- node: device#olt
- relationship: tosca.relationships.BelongsToOne
-
- onu:
- type: tosca.nodes.ONUDevice
- properties:
- serial_number: BRCM1234
- vendor: Broadcom
- device_type: broadcom_onu
- requirements:
- - pon_port:
- node: pon_port
- relationship: tosca.relationships.BelongsToOne
diff --git a/samples/pon_port.yaml b/samples/pon_port.yaml
new file mode 100644
index 0000000..d35d0b8
--- /dev/null
+++ b/samples/pon_port.yaml
@@ -0,0 +1,44 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# curl -H "xos-username: admin@opencord.org" -H "xos-password: letmein" -X POST --data-binary @pon_port.yaml http://192.168.99.100:30007/run
+
+tosca_definitions_version: tosca_simple_yaml_1_0
+imports:
+ - custom_types/oltdevice.yaml
+ - custom_types/onudevice.yaml
+ - custom_types/ponport.yaml
+ - custom_types/voltservice.yaml
+description: Create a simulated OLT Device in VOLTHA
+topology_template:
+ node_templates:
+
+ device#olt:
+ type: tosca.nodes.OLTDevice
+ properties:
+ device_type: simulated_olt
+ host: 172.17.0.1
+ port: 50060
+ must-exist: true
+
+ pon_port:
+ type: tosca.nodes.PONPort
+ properties:
+ name: test_olt_port_1
+ port_no: 2
+ s_tag: 222
+ requirements:
+ - olt_device:
+ node: device#olt
+ relationship: tosca.relationships.BelongsToOne
diff --git a/xos/synchronizer/models/models.py b/xos/synchronizer/models/models.py
index eeb5e74..9431488 100644
--- a/xos/synchronizer/models/models.py
+++ b/xos/synchronizer/models/models.py
@@ -12,12 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import random
+
from core.models.xosbase import *
+from xos.exceptions import XOSValidationError
from models_decl import VOLTService_decl
from models_decl import VOLTServiceInstance_decl
from models_decl import OLTDevice_decl
from models_decl import PONPort_decl
+from models_decl import NNIPort_decl
from models_decl import ONUDevice_decl
class VOLTService(VOLTService_decl):
@@ -45,7 +49,44 @@
class PONPort(PONPort_decl):
class Meta:
- proxy = True
+ proxy = True
+
+ def generate_tag(self):
+ # NOTE this method will loop if available c_tags are ended
+ tag = random.randint(16, 4096)
+ if tag in self.get_used_s_tags():
+ return self.generate_tag()
+ return tag
+
+ def get_used_s_tags(self):
+ same_olt_device = OLTDevice.objects.filter(device_id=self.olt_device)
+ return [s.c_tag for s in same_olt_device]
+
+ def save(self, *args, **kwargs):
+ # validate s_tag
+ if hasattr(self, 's_tag') and self.s_tag is not None:
+ is_update_with_same_tag = False
+
+ if not self.is_new:
+ # if it is an update, but the tag is the same, skip validation
+ existing = PONPort.objects.filter(s_tag=self.s_tag)
+
+ if len(existing) > 0 and existing[0].s_tag == self.s_tag and existing[0].id == self.id:
+ is_update_with_same_tag = True
+
+ if self.s_tag in self.get_used_s_tags() and not is_update_with_same_tag:
+ raise XOSValidationError(
+ "The s_tag you specified (%s) has already been used on device %s" % (self.s_tag, self.onu_device))
+
+ if not hasattr(self, "s_tag") or self.s_tag is None:
+ self.s_tag = self.generate_tag()
+
+ super(PONPort, self).save(*args, **kwargs)
+
+
+class NNIPort(NNIPort_decl):
+ class Meta:
+ proxy = True
class ONUDevice(ONUDevice_decl):
diff --git a/xos/synchronizer/models/volt.xproto b/xos/synchronizer/models/volt.xproto
index 79c753e..0eda4e0 100644
--- a/xos/synchronizer/models/volt.xproto
+++ b/xos/synchronizer/models/volt.xproto
@@ -48,13 +48,26 @@
optional string outer_tpid = 19 [help_text = "Outer VLAN id field EtherType", null = False, db_index = False, blank = False];
}
-message PONPort (XOSBase){
+message PortBase (XOSBase){
+ option gui_hidden = True;
+
+ required string name = 1 [db_index = True, null = False, blank = False];
+ required int32 port_no = 3 [help_text = "Port ID", null = False, db_index = False, blank = False];
+
+ optional string admin_state = 4 [help_text = "admin_state", null = True, db_index = False, blank = False, feedback_state = True];
+ optional string oper_status = 5 [help_text = "oper_status", null = True, db_index = False, blank = False, feedback_state = True];
+}
+
+message PONPort (PortBase){
option verbose_name = "PON Port";
- required string name = 1 [db_index = True, null = False, blank = False, unique_with="olt_device"];
- required manytoone olt_device->OLTDevice:ports = 2 [db_index = True, null = False, blank = False];
- required string port_id = 3 [help_text = "Port ID", max_length = 254, null = False, db_index = False, blank = False];
- required int32 s_tag = 4 [help_text = "S Tag", null = False, db_index = False, blank = False];
+ required manytoone olt_device->OLTDevice:pon_ports = 1 [db_index = True, null = False, blank = False];
+ required int32 s_tag = 2 [help_text = "S Tag", null = False, db_index = False, blank = False];
+}
+
+message NNIPort (PortBase) {
+ option verbose_name = "NNI Port";
+ required manytoone olt_device->OLTDevice:nni_ports = 1 [db_index = True, null = False, blank = False];
}
message ONUDevice (XOSBase){
diff --git a/xos/synchronizer/pull_steps/pull_olts.py b/xos/synchronizer/pull_steps/pull_olts.py
index 36cac45..370250d 100644
--- a/xos/synchronizer/pull_steps/pull_olts.py
+++ b/xos/synchronizer/pull_steps/pull_olts.py
@@ -13,7 +13,7 @@
# limitations under the License.
from synchronizers.new_base.pullstep import PullStep
-from synchronizers.new_base.modelaccessor import model_accessor, OLTDevice, VOLTService
+from synchronizers.new_base.modelaccessor import model_accessor, OLTDevice, VOLTService, PONPort, NNIPort
from xosconfig import Config
from multistructlog import create_logger
@@ -79,9 +79,6 @@
# TODO
# [ ] delete OLTS as OLTDevice.objects.all() - updated OLTs
- if r.status_code != 200:
- log.info("It was not possible to fetch devices from VOLTHA")
-
olts_in_voltha = self.create_or_update_olts(devices)
except ConnectionError, e:
@@ -102,10 +99,13 @@
else:
[host, port] = olt["host_and_port"].split(":")
model = OLTDevice.objects.filter(device_type=olt["type"], host=host, port=port)[0]
+
log.debug("OLTDevice already exists, updating it", device_type=olt["type"], host=host, port=port)
if model.enacted < model.updated:
log.info("Skipping pull on OLTDevice %s as enacted < updated" % model.name, name=model.name, id=model.id, enacted=model.enacted, updated=model.updated)
+ # if we are not updating the device we still need to pull ports
+ self.fetch_olt_ports(model)
return
except IndexError:
@@ -115,6 +115,10 @@
if olt["type"] == "simulated_olt":
model.host = "172.17.0.1"
model.port = 50060
+ else:
+ [host, port] = olt["host_and_port"].split(":")
+ model.host = host
+ model.port = int(port)
log.debug("OLTDevice is new, creating it", device_type=olt["type"], host=host, port=port)
@@ -131,10 +135,85 @@
model.save()
+ self.fetch_olt_ports(model)
+
updated_olts.append(model)
return updated_olts
+ def fetch_olt_ports(self, olt):
+ voltha_url = Helpers.get_voltha_info(self.volt_service)['url']
+ voltha_port = Helpers.get_voltha_info(self.volt_service)['port']
+
+ try:
+ r = requests.get("%s:%s/api/v1/devices/%s/ports" % (voltha_url, voltha_port, olt.device_id))
+
+ if r.status_code != 200:
+ log.info("It was not possible to fetch ports from VOLTHA for device %s" % olt.device_id)
+
+ ports = r.json()['items']
+
+ log.debug("received ports", ports=ports, olt=olt.device_id)
+
+ self.create_or_update_ports(ports, olt)
+
+ except ConnectionError, e:
+ log.warn("It was not possible to connect to VOLTHA", reason=e)
+ return
+ except InvalidURL, e:
+ log.warn("VOLTHA url is invalid, is it configured in the VOLTService?", reason=e)
+ return
+ return
+
+ def create_or_update_ports(self, ports, olt):
+ nni_ports = [p for p in ports if "ETHERNET_NNI" in p["type"]]
+ pon_ports = [p for p in ports if "PON_OLT" in p["type"]]
+
+ self.create_or_update_nni_port(nni_ports, olt)
+ self.create_or_update_pon_port(pon_ports, olt)
+
+ def create_or_update_pon_port(self, pon_ports, olt):
+
+ update_ports = []
+
+ for port in pon_ports:
+ try:
+ model = PONPort.objects.filter(port_no=port["port_no"], olt_device_id=olt.id)[0]
+ log.debug("PONPort is new, creating it", port_no=port["port_no"], olt_device_id=olt.id)
+ except IndexError:
+ model = PONPort()
+ model.port_no = port["port_no"]
+ model.olt_device_id = olt.id
+ model.name = port["label"]
+ log.debug("PONPort already exists, updating it", port_no=port["port_no"], olt_device_id=olt.id)
+
+ model.admin_state = port["admin_state"]
+ model.oper_status = port["oper_status"]
+ model.save()
+ update_ports.append(model)
+ return update_ports
+
+ def create_or_update_nni_port(self, nni_ports, olt):
+ update_ports = []
+
+ for port in nni_ports:
+ try:
+ model = NNIPort.objects.filter(port_no=port["port_no"], olt_device_id=olt.id)[0]
+ model.xos_managed = False
+ log.debug("NNIPort is new, creating it", port_no=port["port_no"], olt_device_id=olt.id)
+ except IndexError:
+ model = NNIPort()
+ model.port_no = port["port_no"]
+ model.olt_device_id = olt.id
+ model.name = port["label"]
+ model.xos_managed = False
+ log.debug("NNIPort already exists, updating it", port_no=port["port_no"], olt_device_id=olt.id)
+
+ model.admin_state = port["admin_state"]
+ model.oper_status = port["oper_status"]
+ model.save()
+ update_ports.append(model)
+ return update_ports
diff --git a/xos/synchronizer/pull_steps/pull_onus.py b/xos/synchronizer/pull_steps/pull_onus.py
index cc60ca3..b762297 100644
--- a/xos/synchronizer/pull_steps/pull_onus.py
+++ b/xos/synchronizer/pull_steps/pull_onus.py
@@ -13,7 +13,7 @@
# limitations under the License.
from synchronizers.new_base.pullstep import PullStep
-from synchronizers.new_base.modelaccessor import model_accessor, ONUDevice, VOLTService, OLTDevice
+from synchronizers.new_base.modelaccessor import model_accessor, ONUDevice, VOLTService, OLTDevice, PONPort
from xosconfig import Config
from multistructlog import create_logger
@@ -34,8 +34,6 @@
super(ONUDevicePullStep, self).__init__(observed_model=ONUDevice)
def pull_records(self):
- return
- # FIXME we need to pull PON Ports before
log.info("pulling ONU devices from VOLTHA")
try:
@@ -84,7 +82,7 @@
log.debug("ONUDevice already exists, updating it", serial_number=onu["serial_number"])
if model.enacted < model.updated:
- log.info("Skipping pull on ONUDevice %s as enacted < updated" % model.name, name=model.name, id=model.id, enacted=model.enacted, updated=model.updated)
+ log.info("Skipping pull on ONUDevice %s as enacted < updated" % model.serial_number, serial_number=model.serial_number, id=model.id, enacted=model.enacted, updated=model.updated)
return
except IndexError:
@@ -101,11 +99,13 @@
model.admin_state = onu["admin_state"]
model.oper_status = onu["oper_status"]
model.connect_status = onu["connect_status"]
+ model.xos_managed = False
- # olt = OLTDevice.objects.get(device_id=onu["proxy_address"]["device_id"])
- #
- # model.olt_device = olt
- # model.olt_device_id = olt.id
+ olt = OLTDevice.objects.get(device_id=onu["parent_id"])
+ pon_port = PONPort.objects.get(port_no=onu["parent_port_no"], olt_device_id=olt.id)
+
+ model.pon_port = pon_port
+ model.pon_port_id = pon_port.id
model.save()
diff --git a/xos/synchronizer/pull_steps/test_pull_olts.py b/xos/synchronizer/pull_steps/test_pull_olts.py
index a0ef017..91b64e3 100644
--- a/xos/synchronizer/pull_steps/test_pull_olts.py
+++ b/xos/synchronizer/pull_steps/test_pull_olts.py
@@ -104,6 +104,25 @@
]
}
+ self.ports = {
+ "items": [
+ {
+ "label": "PON port",
+ "port_no": 1,
+ "type": "PON_OLT",
+ "admin_state": "ENABLED",
+ "oper_status": "ACTIVE"
+ },
+ {
+ "label": "NNI facing Ethernet port",
+ "port_no": 2,
+ "type": "ETHERNET_NNI",
+ "admin_state": "ENABLED",
+ "oper_status": "ACTIVE"
+ }
+ ]
+ }
+
def tearDown(self):
sys.path = self.sys_path_save
@@ -115,10 +134,13 @@
def test_pull(self, m):
with patch.object(VOLTService.objects, "all") as olt_service_mock, \
- patch.object(OLTDevice, "save") as mock_save:
+ patch.object(OLTDevice, "save") as mock_olt_save, \
+ patch.object(PONPort, "save") as mock_pon_save, \
+ patch.object(NNIPort, "save") as mock_nni_save:
olt_service_mock.return_value = [self.volt_service]
m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
+ m.get("http://voltha_url:1234/api/v1/devices/test_id/ports", status_code=200, json=self.ports)
m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=self.logical_devices)
self.sync_step().pull_records()
@@ -131,7 +153,9 @@
# self.assertEqual(existing_olt.of_id, "of_id")
# self.assertEqual(existing_olt.dp_id, "of:0000000ce2314000")
- mock_save.assert_called()
+ mock_olt_save.assert_called()
+ mock_pon_save.assert_called()
+ mock_nni_save.assert_called()
@requests_mock.Mocker()
def test_pull_existing(self, m):
@@ -141,12 +165,15 @@
existing_olt.updated = 1
with patch.object(VOLTService.objects, "all") as olt_service_mock, \
- patch.object(OLTDevice.objects, "filter") as mock_get, \
- patch.object(existing_olt, "save") as mock_save:
+ patch.object(OLTDevice.objects, "filter") as mock_get, \
+ patch.object(PONPort, "save") as mock_pon_save, \
+ patch.object(NNIPort, "save") as mock_nni_save, \
+ patch.object(existing_olt, "save") as mock_olt_save:
olt_service_mock.return_value = [self.volt_service]
mock_get.return_value = [existing_olt]
m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
+ m.get("http://voltha_url:1234/api/v1/devices/test_id/ports", status_code=200, json=self.ports)
m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=self.logical_devices)
self.sync_step().pull_records()
@@ -158,26 +185,35 @@
self.assertEqual(existing_olt.of_id, "of_id")
self.assertEqual(existing_olt.dp_id, "of:0000000ce2314000")
- mock_save.assert_called()
+ mock_olt_save.assert_called()
+ mock_pon_save.assert_called()
+ mock_nni_save.assert_called()
@requests_mock.Mocker()
def test_pull_existing_do_not_sync(self, m):
existing_olt = Mock()
existing_olt.enacted = 1
existing_olt.updated = 2
+ existing_olt.device_id = "test_id"
with patch.object(VOLTService.objects, "all") as olt_service_mock, \
- patch.object(OLTDevice.objects, "get") as mock_get, \
- patch.object(existing_olt, "save") as mock_save:
+ patch.object(OLTDevice.objects, "filter") as mock_get, \
+ patch.object(PONPort, "save") as mock_pon_save, \
+ patch.object(NNIPort, "save") as mock_nni_save, \
+ patch.object(existing_olt, "save") as mock_olt_save:
+
olt_service_mock.return_value = [self.volt_service]
- mock_get.return_value = existing_olt
+ mock_get.return_value = [existing_olt]
m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
+ m.get("http://voltha_url:1234/api/v1/devices/test_id/ports", status_code=200, json=self.ports)
m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=self.logical_devices)
self.sync_step().pull_records()
- mock_save.assert_not_called()
+ mock_olt_save.assert_not_called()
+ mock_pon_save.assert_called()
+ mock_nni_save.assert_called()
if __name__ == "__main__":
unittest.main()
\ No newline at end of file
diff --git a/xos/synchronizer/pull_steps/test_pull_onus.py b/xos/synchronizer/pull_steps/test_pull_onus.py
index b8ffa5f..a2b948b 100644
--- a/xos/synchronizer/pull_steps/test_pull_onus.py
+++ b/xos/synchronizer/pull_steps/test_pull_onus.py
@@ -85,6 +85,10 @@
self.olt = Mock()
self.olt.id = 1
+ # mock pon port
+ self.pon_port = Mock()
+ self.pon_port.id = 1
+
# mock voltha responses
self.devices = {
"items": [
@@ -99,9 +103,8 @@
"admin_state": "ENABLED",
"oper_status": "ACTIVE",
"connect_status": "REACHABLE",
- "proxy_address": {
- "device_id": "00010fc93996afea"
- }
+ "parent_id": "00010fc93996afea",
+ "parent_port_no": 1
}
]
}
@@ -114,12 +117,14 @@
self.assertFalse(m.called)
@requests_mock.Mocker()
- def _test_pull(self, m):
+ def test_pull(self, m):
with patch.object(VOLTService.objects, "all") as olt_service_mock, \
patch.object(OLTDevice.objects, "get") as mock_olt_device, \
+ patch.object(PONPort.objects, "get") as mock_pon_port, \
patch.object(ONUDevice, "save") as mock_save:
olt_service_mock.return_value = [self.volt_service]
+ mock_pon_port.return_value = self.pon_port
mock_olt_device.return_value = self.olt
m.get("http://voltha_url:1234/api/v1/devices", status_code=200, json=self.devices)
@@ -134,7 +139,7 @@
# self.assertEqual(existing_olt.of_id, "of_id")
# self.assertEqual(existing_olt.dp_id, "of:0000000ce2314000")
- mock_save.assert_called()
+ mock_save.assert_called_with()
@requests_mock.Mocker()
def _test_pull_existing(self, m):
diff --git a/xos/synchronizer/steps/sync_olt_device.py b/xos/synchronizer/steps/sync_olt_device.py
index 5997de5..8ebef89 100644
--- a/xos/synchronizer/steps/sync_olt_device.py
+++ b/xos/synchronizer/steps/sync_olt_device.py
@@ -17,7 +17,7 @@
import requests
from multistructlog import create_logger
from requests.auth import HTTPBasicAuth
-from synchronizers.new_base.SyncInstanceUsingAnsible import SyncStep
+from synchronizers.new_base.syncstep import SyncStep, DeferredException
from synchronizers.new_base.modelaccessor import OLTDevice, model_accessor
from xosconfig import Config
@@ -115,11 +115,17 @@
def configure_onos(self, model):
+ log.info("Adding OLT device in onos-voltha", object=str(model), **model.tologdict())
+
onos_voltha = Helpers.get_onos_voltha_info(model.volt_service)
onos_voltha_basic_auth = HTTPBasicAuth(onos_voltha['user'], onos_voltha['pass'])
- # For now, we assume that each OLT has only one port
- vlan = model.ports.all()[0].s_tag
+ try:
+ # NOTE For now, we assume that each OLT has only one pon port
+ vlan = model.pon_ports.all()[0].s_tag
+ except Exception as e:
+ raise DeferredException("Waiting for pon_ports to come up")
+
# Add device info to onos-voltha
data = {
@@ -162,34 +168,34 @@
self.configure_onos(model)
- def delete_record(self, o):
- log.info("Deleting OLT device", object=str(o), **o.tologdict())
+ def delete_record(self, model):
+ log.info("Deleting OLT device", object=str(model), **model.tologdict())
- voltha = Helpers.get_voltha_info(o.volt_service)
- onos_voltha = Helpers.get_onos_voltha_info(o.volt_service)
+ voltha = Helpers.get_voltha_info(model.volt_service)
+ onos_voltha = Helpers.get_onos_voltha_info(model.volt_service)
onos_voltha_basic_auth = HTTPBasicAuth(onos_voltha['user'], onos_voltha['pass'])
- if not o.device_id:
- log.error("OLTDevice %s has no device_id" % o.name)
+ if not model.device_id:
+ log.error("OLTDevice %s has no device_id" % model.name)
else:
# Disable the OLT device
- request = requests.post("%s:%d/api/v1/devices/%s/disable" % (voltha['url'], voltha['port'], o.device_id))
+ request = requests.post("%s:%d/api/v1/devices/%s/disable" % (voltha['url'], voltha['port'], model.device_id))
if request.status_code != 200:
- log.error("Failed to disable OLT device in VOLTHA: %s - %s" % (o.name, o.device_id), rest_response=request.text, rest_status_code=request.status_code)
+ log.error("Failed to disable OLT device in VOLTHA: %s - %s" % (model.name, model.device_id), rest_response=request.text, rest_status_code=request.status_code)
raise Exception("Failed to disable OLT device in VOLTHA")
# Delete the OLT device
- request = requests.delete("%s:%d/api/v1/devices/%s/delete" % (voltha['url'], voltha['port'], o.device_id))
+ request = requests.delete("%s:%d/api/v1/devices/%s/delete" % (voltha['url'], voltha['port'], model.device_id))
if request.status_code != 200:
- log.error("Failed to delete OLT device from VOLTHA: %s - %s" % (o.name, o.device_id), rest_response=request.text, rest_status_code=request.status_code)
+ log.error("Failed to delete OLT device from VOLTHA: %s - %s" % (model.name, model.device_id), rest_response=request.text, rest_status_code=request.status_code)
raise Exception("Failed to delete OLT device from VOLTHA")
# Remove the device from ONOS
request = requests.delete("%s:%d/onos/v1/network/configuration/devices/%s" % (
- onos_voltha['url'], onos_voltha['port'], o.of_id), auth=onos_voltha_basic_auth)
+ onos_voltha['url'], onos_voltha['port'], model.of_id), auth=onos_voltha_basic_auth)
if request.status_code != 204:
- log.error("Failed to remove OLT device from ONOS: %s - %s" % (o.name, o.of_id), rest_response=request.text, rest_status_code=request.status_code)
+ log.error("Failed to remove OLT device from ONOS: %s - %s" % (model.name, model.of_id), rest_response=request.text, rest_status_code=request.status_code)
raise Exception("Failed to remove OLT device from ONOS")
diff --git a/xos/synchronizer/steps/test_sync_olt_device.py b/xos/synchronizer/steps/test_sync_olt_device.py
index 55d477e..4d785b5 100644
--- a/xos/synchronizer/steps/test_sync_olt_device.py
+++ b/xos/synchronizer/steps/test_sync_olt_device.py
@@ -53,6 +53,7 @@
class TestSyncOLTDevice(unittest.TestCase):
def setUp(self):
+ global DeferredException
self.sys_path_save = sys.path
sys.path.append(xos_dir)
sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
@@ -74,7 +75,7 @@
get_models_fn("../profiles/rcord", "rcord.xproto")])
import synchronizers.new_base.modelaccessor
- from sync_olt_device import SyncOLTDevice
+ from sync_olt_device import SyncOLTDevice, DeferredException
self.sync_step = SyncOLTDevice
pon_port = Mock()
@@ -108,7 +109,7 @@
o.save.return_value = "Saved"
- o.ports.all.return_value = [pon_port]
+ o.pon_ports.all.return_value = [pon_port]
self.o = o
@@ -221,5 +222,16 @@
# We don't need to assert here if there are no exceptions happening
+ def test_deferred_for_port(self):
+ self.o.pon_ports.all.side_effect = Exception
+ with self.assertRaises(DeferredException) as e:
+ self.sync_step().configure_onos(self.o)
+ self.assertEqual(e.exception.message, "Waiting for pon_ports to come up")
+
+ self.o.pon_ports.all.return_value = []
+ with self.assertRaises(DeferredException) as e:
+ self.sync_step().configure_onos(self.o)
+ self.assertEqual(e.exception.message, "Waiting for pon_ports to come up")
+
if __name__ == "__main__":
unittest.main()