VOL-1604 Implementing storage of MIB entities in etcd.
Updated tests to work and pulled a test update from https://gerrit.opencord.org/#/c/12815/. The functional changes were merged some time ago, but the test was not.
Updated requirements to match those in voltha-openonu-adapter. This fixed an issue where the test would fail on importing the etcd database class
Change-Id: I13787dbf740020eb2d7f2c6498f9eafe1b461cba
diff --git a/.gitignore b/.gitignore
index a5dd45e..07bffa2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,5 @@
# ide workspace
.idea
+
+*.pyc
diff --git a/VERSION b/VERSION
index 1a03094..70426f8 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.9
+0.2.0-dev
diff --git a/pyvoltha/adapters/extensions/omci/database/mib_db_ext.py b/pyvoltha/adapters/extensions/omci/database/mib_db_ext.py
index 7b3bea7..d94ab6d 100644
--- a/pyvoltha/adapters/extensions/omci/database/mib_db_ext.py
+++ b/pyvoltha/adapters/extensions/omci/database/mib_db_ext.py
@@ -18,8 +18,9 @@
MibDeviceData, MibAttributeData, MessageType, ManagedEntity
from pyvoltha.adapters.extensions.omci.omci_entities import *
from pyvoltha.adapters.extensions.omci.omci_fields import *
+from pyvoltha.common.config.config_backend import EtcdStore
from scapy.fields import StrField, FieldListField, PacketField
-
+from pyvoltha.common.utils.registry import registry
class MibDbStatistic(object):
"""
@@ -86,18 +87,17 @@
# Paths from root proxy
MIB_PATH = '/omci_mibs'
- DEVICE_PATH = MIB_PATH + '/{}' # .format(device_id)
+ DEVICE_PATH = '{}' # .format(device_id)
# Classes, Instances, and Attributes as lists from root proxy
- CLASSES_PATH = DEVICE_PATH + '/classes' # .format(device_id)
- INSTANCES_PATH = DEVICE_PATH + '/classes/{}/instances' # .format(device_id, class_id)
- ATTRIBUTES_PATH = DEVICE_PATH + '/classes/{}/instances/{}/attributes' # .format(device_id, class_id, instance_id)
+ CLASS_PATH = DEVICE_PATH + '/classes/{}' # .format(device_id)
+ INSTANCE_PATH = DEVICE_PATH + '/classes/{}/instances/{}' # .format(device_id, class_id)
+ ATTRIBUTE_PATH = DEVICE_PATH + '/classes/{}/instances/{}/attributes/{}' # .format(device_id, class_id, instance_id)
# Single Class, Instance, and Attribute as objects from device proxy
- CLASS_PATH = '/classes/{}' # .format(class_id)
- INSTANCE_PATH = '/classes/{}/instances/{}' # .format(class_id, instance_id)
- ATTRIBUTE_PATH = '/classes/{}/instances/{}/attributes/{}' # .format(class_id, instance_id
- # attribute_name)
+ #CLASS_PATH = '/classes/{}' # .format(class_id)
+ #INSTANCE_PATH = '/classes/{}/instances/{}' # .format(class_id, instance_id)
+ #ATTRIBUTE_PATH = '/classes/{}/instances/{}/attributes/{}' # .format(class_id, instance_id
def __init__(self, omci_agent):
"""
@@ -113,6 +113,9 @@
'create': MibDbStatistic('create'),
'delete': MibDbStatistic('delete')
}
+ self.args = registry('main').get_args()
+ host, port = self.args.etcd.split(':', 1)
+ self._kv_store = EtcdStore(host, port, MibDbExternal.MIB_PATH)
def start(self):
"""
@@ -122,12 +125,9 @@
if not self._started:
super(MibDbExternal, self).start()
- root_proxy = self._core.get_proxy('/')
-
+
try:
- base = root_proxy.get(MibDbExternal.MIB_PATH)
- self.log.info('db-exists', num_devices=len(base))
-
+ self.log.info('db-exists')
except Exception as e:
self.log.exception('start-failure', e=e)
raise
@@ -140,7 +140,7 @@
if self._started:
super(MibDbExternal, self).stop()
- # TODO: Delete this method if nothing else is done except calling the base class
+ # TODO: Delete this method if 6nothing else is done except calling the base class
def _time_to_string(self, time):
return time.strftime(MibDbExternal._TIME_FORMAT) if time is not None else ''
@@ -300,32 +300,34 @@
now = datetime.utcnow()
found = False
- root_proxy = self._core.get_proxy('/')
data = MibDeviceData(device_id=device_id,
created=self._time_to_string(now),
last_sync_time='',
mib_data_sync=0,
version=MibDbExternal.CURRENT_VERSION)
+ path = self._get_device_path(device_id)
+ self.log.debug("add-device-path", device_id=device_id, path=path)
try:
- dev_proxy = self._device_proxy(device_id)
- found = True
+ #raises KeyError if not found
+ device = self._kv_store[path]
+ #device is found at this point
+ found = True
if not overwrite:
# Device already exists
raise KeyError('Device with ID {} already exists in MIB database'.
format(device_id))
- # Overwrite with new data
- data = dev_proxy.get('/', depth=0)
- self._root_proxy.update(MibDbExternal.DEVICE_PATH.format(device_id), data)
+ self._kv_store[path] = data.SerializeToString()
self._modified = now
except KeyError:
+ #KeyError after finding the device should be raised
if found:
raise
# Did not exist, add it now
- root_proxy.add(MibDbExternal.MIB_PATH, data)
+ self._kv_store[path] = data.SerializeToString()
self._created = now
self._modified = now
@@ -344,8 +346,8 @@
raise TypeError('Device ID should be an string')
try:
- # self._root_proxy.get(MibDbExternal.DEVICE_PATH.format(device_id))
- self._root_proxy.remove(MibDbExternal.DEVICE_PATH.format(device_id))
+ path = self._get_device_path(device_id)
+ del self._kv_store[path]
self._modified = datetime.utcnow()
except KeyError:
@@ -356,27 +358,21 @@
self.log.exception('remove-exception', device_id=device_id, e=e)
raise
- @property
- def _root_proxy(self):
- return self._core.get_proxy('/')
+ def _get_device_path(self, device_id):
+ return MibDbExternal.DEVICE_PATH.format(device_id)
- def _device_proxy(self, device_id):
- """
- Return a config proxy to the OMCI MIB_DB leaf for a given device
-
- :param device_id: (str) ONU Device ID
- :return: (ConfigProxy) Configuration proxy rooted at OMCI MIB DB
- :raises KeyError: If the device does not exist in the database
- """
- if not isinstance(device_id, basestring):
- raise TypeError('Device ID should be an string')
-
+ def _get_class_path(self, device_id, class_id):
if not self._started:
raise DatabaseStateError('The Database is not currently active')
- return self._core.get_proxy(MibDbExternal.DEVICE_PATH.format(device_id))
+ if not 0 <= class_id <= 0xFFFF:
+ raise ValueError('class-id is 0..0xFFFF')
- def _class_proxy(self, device_id, class_id, create=False):
+ fmt = MibDbExternal.CLASS_PATH
+ return fmt.format(device_id, class_id)
+
+
+ def _get_class(self, device_id, class_id, create=False):
"""
Get a config proxy to a specific managed entity class
:param device_id: (str) ONU Device ID
@@ -387,17 +383,11 @@
:raises DatabaseStateError: If database is not started
:raises KeyError: If Instance does not exist and 'create' is False
"""
- if not self._started:
- raise DatabaseStateError('The Database is not currently active')
- if not 0 <= class_id <= 0xFFFF:
- raise ValueError('class-id is 0..0xFFFF')
-
- fmt = MibDbExternal.DEVICE_PATH + MibDbExternal.CLASS_PATH
- path = fmt.format(device_id, class_id)
+ path = self._get_class_path(device_id, class_id)
try:
- return self._core.get_proxy(path)
+ return self._kv_store[path]
except KeyError:
if not create:
@@ -412,23 +402,12 @@
# Create class
data = MibClassData(class_id=class_id)
- root_path = MibDbExternal.CLASSES_PATH.format(device_id)
- self._root_proxy.add(root_path, data)
+ root_path = MibDbExternal.CLASS_PATH.format(device_id, class_id)
+ self._kv_store[root_path] = data
- return self._core.get_proxy(path)
+ return data
- def _instance_proxy(self, device_id, class_id, instance_id, create=False):
- """
- Get a config proxy to a specific managed entity instance
- :param device_id: (str) ONU Device ID
- :param class_id: (int) Class ID
- :param instance_id: (int) Instance ID
- :param create: (bool) If true, create default instance (and class)
- :return: (ConfigProxy) Instance configuration proxy
-
- :raises DatabaseStateError: If database is not started
- :raises KeyError: If Instance does not exist and 'create' is False
- """
+ def _get_instance_path(self, device_id, class_id, instance_id):
if not self._started:
raise DatabaseStateError('The Database is not currently active')
@@ -441,11 +420,26 @@
if not 0 <= instance_id <= 0xFFFF:
raise ValueError('instance-id is 0..0xFFFF')
- fmt = MibDbExternal.DEVICE_PATH + MibDbExternal.INSTANCE_PATH
- path = fmt.format(device_id, class_id, instance_id)
+ fmt = MibDbExternal.INSTANCE_PATH
+ return fmt.format(device_id, class_id, instance_id)
+
+ def _get_instance(self, device_id, class_id, instance_id, create=False):
+ """
+ Get a config proxy to a specific managed entity instance
+ :param device_id: (str) ONU Device ID
+ :param class_id: (int) Class ID
+ :param instance_id: (int) Instance ID
+ :param create: (bool) If true, create default instance (and class)
+ :return: (ConfigProxy) Instance configuration proxy
+
+ :raises DatabaseStateError: If database is not started
+ :raises KeyError: If Instance does not exist and 'create' is False
+ """
+
+ path = self._get_instance_path(device_id, class_id, instance_id)
try:
- return self._core.get_proxy(path)
+ return self._kv_store[path]
except KeyError:
if not create:
@@ -459,14 +453,14 @@
raise
# Create instance, first make sure class exists
- self._class_proxy(device_id, class_id, create=True)
+ self._get_class(device_id, class_id, create=True)
now = self._time_to_string(datetime.utcnow())
data = MibInstanceData(instance_id=instance_id, created=now, modified=now)
- root_path = MibDbExternal.INSTANCES_PATH.format(device_id, class_id)
- self._root_proxy.add(root_path, data)
+ root_path = MibDbExternal.INSTANCE_PATH.format(device_id, class_id)
+ self._kv_store[root_path] = data
- return self._core.get_proxy(path)
+ return data
def on_mib_reset(self, device_id):
"""
@@ -478,16 +472,19 @@
"""
self.log.debug('on-mib-reset', device_id=device_id)
- try:
- device_proxy = self._device_proxy(device_id)
- data = device_proxy.get(depth=2)
+ data = MibDeviceData()
- # Wipe out any existing class IDs
+ try:
+ path = self._get_device_path(device_id)
+ data.ParseFromString(self._kv_store[path])
+
+ # data = MibDeviceData(Wipe out any existing class IDs
class_ids = [c.class_id for c in data.classes]
if len(class_ids):
for class_id in class_ids:
- device_proxy.remove(MibDbExternal.CLASS_PATH.format(class_id))
+ classpath = MibDbExternal.CLASS_PATH.format(device_id, class_id)
+ del self._kv_store[classpath]
# Reset MIB Data Sync to zero
now = datetime.utcnow()
@@ -497,14 +494,15 @@
mib_data_sync=0,
version=MibDbExternal.CURRENT_VERSION)
# Update
- self._root_proxy.update(MibDbExternal.DEVICE_PATH.format(device_id),
- data)
+ self._kv_store[path] = data.SerializeToString()
self._modified = now
self.log.debug('mib-reset-complete', device_id=device_id)
except Exception as e:
self.log.exception('mib-reset-exception', device_id=device_id, e=e)
raise
+ except KeyError as e:
+ self.log.debug("mib-reset-no-data-to-reset", device_id=device_id)
def save_mib_data_sync(self, device_id, value):
"""
@@ -522,15 +520,16 @@
if not 0 <= value <= 255:
raise ValueError('Invalid MIB-data-sync value {}. Must be 0..255'.
format(value))
- device_proxy = self._device_proxy(device_id)
- data = device_proxy.get(depth=0)
+ data = MibDeviceData()
+ path = self._get_device_path(device_id)
+
+ data.ParseFromString(self._kv_store[path])
now = datetime.utcnow()
data.mib_data_sync = value
# Update
- self._root_proxy.update(MibDbExternal.DEVICE_PATH.format(device_id),
- data)
+ self._kv_store[path] = data.SerializeToString()
self._modified = now
self.log.debug('save-mds-complete', device_id=device_id)
@@ -548,8 +547,9 @@
self.log.debug('get-mds', device_id=device_id)
try:
- device_proxy = self._device_proxy(device_id)
- data = device_proxy.get(depth=0)
+ data = MibDeviceData()
+ path = get_device_path(device_id)
+ data.ParseFromString(self._kv_store[path])
return int(data.mib_data_sync)
except KeyError:
@@ -572,16 +572,15 @@
if not isinstance(value, datetime):
raise TypeError('Expected a datetime object, got {}'.
format(type(datetime)))
-
- device_proxy = self._device_proxy(device_id)
- data = device_proxy.get(depth=0)
+ data = MibDeviceData()
+ path = self._get_device_path(device_id)
+ data.ParseFromString(self._kv_store[path])
now = datetime.utcnow()
data.last_sync_time = self._time_to_string(value)
# Update
- self._root_proxy.update(MibDbExternal.DEVICE_PATH.format(device_id),
- data)
+ self._kv_store[path] = data.SerializeToString()
self._modified = now
self.log.debug('save-mds-complete', device_id=device_id)
@@ -599,8 +598,9 @@
self.log.debug('get-last-sync', device_id=device_id)
try:
- device_proxy = self._device_proxy(device_id)
- data = device_proxy.get(depth=0)
+ data = MibDeviceData()
+ path = self._get_device_path(device_id)
+ data.ParseFromString(self.kv_store[path])
return self._string_to_time(data.last_sync_time)
except KeyError:
@@ -622,7 +622,7 @@
:returns: (bool) True if the value was saved to the database. False if the
value was identical to the current instance
"""
- self.log.debug('add', device_id=device_id, class_id=class_id,
+ self.log.debug('add-new-class', device_id=device_id, class_id=class_id,
instance_id=instance_id, attributes=attributes)
now = self._time_to_string(datetime.utcnow())
@@ -644,12 +644,13 @@
modified=now,
attributes=attrs)])
- self._root_proxy.add(MibDbExternal.CLASSES_PATH.format(device_id), class_data)
+ classpath = MibDbExternal.CLASS_PATH.format(device_id, class_id)
+ self._kv_store[classpath] = class_data.SerializeToString()
self.log.debug('set-complete', device_id=device_id, class_id=class_id,
entity_id=instance_id, attributes=attributes)
return True
- def _add_new_instance(self, device_id, class_id, instance_id, attributes):
+ def _create_new_instance(self, device_id, class_id, instance_id, attributes):
"""
Create an entry for a instance of an existing class in the external database
@@ -658,10 +659,9 @@
:param instance_id: (int) ME Entity ID
:param attributes: (dict) Attribute dictionary
- :returns: (bool) True if the value was saved to the database. False if the
- value was identical to the current instance
+ :returns: (MibInstanceDate) The new instance object
"""
- self.log.debug('add', device_id=device_id, class_id=class_id,
+ self.log.debug('create-new-instance', device_id=device_id, class_id=class_id,
instance_id=instance_id, attributes=attributes)
now = self._time_to_string(datetime.utcnow())
@@ -682,12 +682,18 @@
modified=now,
attributes=attrs)
- self._root_proxy.add(MibDbExternal.INSTANCES_PATH.format(device_id, class_id),
- instance_data)
+ #update class with instance
+ #class_path = self._get_class_path(device_id, class_id)
+ #class_data = MibClassData()
+ #class_data.ParseFromString(self._kv_store[class_path])
+
+ #class_data.instances.extend([instance_data])
- self.log.debug('set-complete', device_id=device_id, class_id=class_id,
+ #self._kv_store[class_path] = class_data.SerializeToString()
+
+ self.log.debug('create-new-instance-complete', device_id=device_id, class_id=class_id,
entity_id=instance_id, attributes=attributes)
- return True
+ return instance_data
def set(self, device_id, class_id, instance_id, attributes):
"""
@@ -723,65 +729,67 @@
if not self._started:
raise DatabaseStateError('The Database is not currently active')
- # Determine the best strategy to add the information
- dev_proxy = self._device_proxy(device_id)
-
operation = 'set'
start_time = None
try:
- class_data = dev_proxy.get(MibDbExternal.CLASS_PATH.format(class_id), deep=True)
+ class_data = MibClassData()
+ class_path = MibDbExternal.CLASS_PATH.format(device_id, class_id)
+ class_data.ParseFromString(self._kv_store[class_path])
inst_data = next((inst for inst in class_data.instances
if inst.instance_id == instance_id), None)
-
+ modified = False
+ new_data = None
if inst_data is None:
operation = 'create'
start_time = datetime.utcnow()
- return self._add_new_instance(device_id, class_id, instance_id, attributes)
+ new_data = self._create_new_instance(device_id, class_id, instance_id, attributes)
+ modified = True
+ else:
- # Possibly adding to or updating an existing instance
- # Get instance proxy, creating it if needed
+ # Possibly adding to or updating an existing instance
+ # Get instance proxy, creating it if needed
+ new_attributes = []
+ exist_attr_indexes = dict()
+ attr_len = len(inst_data.attributes)
- modified = False
- new_attributes = []
- exist_attr_indexes = dict()
- attr_len = len(inst_data.attributes)
+ for index in xrange(0, attr_len):
+ name = inst_data.attributes[index].name
+ value = inst_data.attributes[index].value
+ exist_attr_indexes[name] = index
+ new_attributes.append(MibAttributeData(name=name, value=value))
- for index in xrange(0, attr_len):
- name = inst_data.attributes[index].name
- value = inst_data.attributes[index].value
- exist_attr_indexes[name] = index
- new_attributes.append(MibAttributeData(name=name, value=value))
+ for k, v in attributes.items():
+ try:
+ old_value = None if k not in exist_attr_indexes \
+ else new_attributes[exist_attr_indexes[k]].value
- for k, v in attributes.items():
- try:
- old_value = None if k not in exist_attr_indexes \
- else new_attributes[exist_attr_indexes[k]].value
+ str_value = self._attribute_to_string(device_id, class_id, k, v, old_value)
- str_value = self._attribute_to_string(device_id, class_id, k, v, old_value)
+ if k not in exist_attr_indexes:
+ new_attributes.append(MibAttributeData(name=k, value=str_value))
+ modified = True
- if k not in exist_attr_indexes:
- new_attributes.append(MibAttributeData(name=k, value=str_value))
- modified = True
+ elif new_attributes[exist_attr_indexes[k]].value != str_value:
+ new_attributes[exist_attr_indexes[k]].value = str_value
+ modified = True
- elif new_attributes[exist_attr_indexes[k]].value != str_value:
- new_attributes[exist_attr_indexes[k]].value = str_value
- modified = True
-
- except Exception as e:
- self.log.exception('save-error', e=e, class_id=class_id,
+ except Exception as e:
+ self.log.exception('save-error', e=e, class_id=class_id,
attr=k, value_type=type(v))
-
- if modified:
now = datetime.utcnow()
start_time = now
new_data = MibInstanceData(instance_id=instance_id,
created=inst_data.created,
modified=self._time_to_string(now),
attributes=new_attributes)
- dev_proxy.remove(MibDbExternal.INSTANCE_PATH.format(class_id, instance_id))
- self._root_proxy.add(MibDbExternal.INSTANCES_PATH.format(device_id,
- class_id), new_data)
+
+ if modified:
+ inst_index = next((index for index in range(len(class_data.instances)) if class_data.instances[index].instance_id == instance_id), None)
+ if not inst_index is None:
+ del class_data.instances[inst_index]
+ class_data.instances.extend([new_data])
+ self._kv_store[class_path] = class_data.SerializeToString()
return modified
except KeyError:
@@ -835,15 +843,17 @@
start_time = datetime.utcnow()
try:
# Remove instance
- self._instance_proxy(device_id, class_id, entity_id).remove('/')
+ instpath = self._get_instance_path(device_id, class_id, entity_id)
+ del self._kv_store[instpath]
now = datetime.utcnow()
# If resulting class has no instance, remove it as well
- class_proxy = self._class_proxy(device_id, class_id)
- class_data = class_proxy.get('/', depth=1)
-
+ classpath = self._get_class_path(device_id, class_id)
+ class_data = MibClassData()
+ class_data.ParseFromString(self._kv_store[classpath])
+
if len(class_data.instances) == 0:
- class_proxy.remove('/')
+ del self._kv_store[classpath]
self._modified = now
return True
@@ -887,16 +897,20 @@
try:
if class_id is None:
# Get full device info
- dev_data = self._device_proxy(device_id).get('/', depth=-1)
+ dev_data = MibDeviceData()
+ device_path = self._get_device_path(device_id)
+ dev_data.ParseFromString(self._kv_store[device_path])
end_time = datetime.utcnow()
data = self._device_to_dict(dev_data)
elif instance_id is None:
# Get all instances of the class
try:
- cls_data = self._class_proxy(device_id, class_id).get('/', depth=-1)
+ class_data = MibClassData()
+ class_path = self._get_class_path(device_id, class_id)
+ class_data.ParseFromString(self._kv_store[class_path])
end_time = datetime.utcnow()
- data = self._class_to_dict(device_id, cls_data)
+ data = self._class_to_dict(device_id, class_data)
except KeyError:
data = dict()
@@ -904,13 +918,14 @@
else:
# Get all attributes of a specific ME
try:
- inst_data = self._instance_proxy(device_id, class_id, instance_id).\
- get('/', depth=-1)
+ instance_data = MibInstanceData()
+ instance_path = self._get_instance_path(device_id, class_id, instance_id)
+ instance_data.ParseFromString(self._kv_store[instance_path])
end_time = datetime.utcnow()
if attributes is None:
# All Attributes
- data = self._instance_to_dict(device_id, class_id, inst_data)
+ data = self._instance_to_dict(device_id, class_id, instance_data)
else:
# Specific attribute(s)
@@ -968,7 +983,6 @@
raise TypeError('{} is not of type MibClassData'.format(type(val)))
data = {
- CLASS_ID_KEY: val.class_id,
}
for instance in val.instances:
data[instance.instance_id] = self._instance_to_dict(device_id,
@@ -1017,16 +1031,15 @@
name=self._managed_entity_to_name(device_id,
class_id))
for class_id in managed_entities]
-
- device_proxy = self._device_proxy(device_id)
- data = device_proxy.get(depth=0)
+ data = MibDeviceData()
+ device_path = self._get_device_path(device_id)
+ data.ParseFromString(self._kv_store[device_path])
now = datetime.utcnow()
data.managed_entities.extend(me_list)
# Update
- self._root_proxy.update(MibDbExternal.DEVICE_PATH.format(device_id),
- data)
+ self._kv_store[device_path] = data.SerializeToString()
self._modified = now
self.log.debug('save-me-list-complete', device_id=device_id)
@@ -1041,18 +1054,16 @@
:param msg_types: (set) Message Type values (ints)
"""
try:
+ now = datetime.utcnow()
msg_type_list = [MessageType(message_type=msg_type.value)
for msg_type in msg_types]
-
- device_proxy = self._device_proxy(device_id)
- data = device_proxy.get(depth=0)
-
- now = datetime.utcnow()
+ data = MibDeviceData()
+ device_path = self._get_device_path(device_id)
+ data.ParseFromString(self._kv_store[device_path])
data.message_types.extend(msg_type_list)
# Update
- self._root_proxy.update(MibDbExternal.DEVICE_PATH.format(device_id),
- data)
+ self._kv_store[device_path] = data.SerializeToString()
self._modified = now
self.log.debug('save-msg-types-complete', device_id=device_id)
diff --git a/requirements.txt b/requirements.txt
index 558f67b..874a801 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,10 +7,7 @@
cython==0.24.1
decorator==4.1.2
docker-py==1.10.6
-etcd3==0.7.0
-flake8==3.7.3
fluent-logger==0.6.0
-gevent==1.4.0
grpc==0.3.post19
grpcio==1.16.0
grpcio-tools==1.16.0
@@ -18,8 +15,8 @@
hexdump==3.3
jinja2==2.8
jsonpatch==1.16
-jsonschema==2.6.0
kafka_python==1.3.5
+kafkaloghandler==0.9.0
klein==17.10.0
kubernetes==5.0.0
netaddr==0.7.19
@@ -32,23 +29,36 @@
protobuf-to-dict==0.1.0
pyflakes==2.1.0
pylint==1.9.4
-python-consul==0.6.2
+#pypcap>=1.1.5
pyOpenSSL==17.3.0
PyYAML==3.12
requests==2.18.4
scapy==2.3.3
service-identity==17.0.0
-setuptools==40.8.0
simplejson==3.12.0
+jsonschema==2.6.0
six==1.12.0
structlog==17.2.0
termcolor==1.1.0
-tox==3.7.0
transitions==0.6.4
treq==17.8.0
-twine==1.12.1
Twisted==18.7.0
txaioetcd==0.3.0
urllib3==1.22
-voltha-protos==0.1.2
+pyang==1.7.3
+lxml==3.6.4
+nosexcover==1.0.11
+zmq==0.0.0
+pyzmq==16.0.3
+txZMQ==0.8.0
+ncclient==0.5.3
+xmltodict==0.11.0
+dicttoxml==1.7.4
+etcd3==0.7.0
+pyparsing==2.2.0
+packaging==17.1
+pexpect==4.6.0
+python-consul==0.6.2
afkak==3.0.0.dev20181106
+pyvoltha==0.1.8
+voltha-protos==0.1.2
diff --git a/setup.py b/setup.py
index 02cf55b..4b60c7e 100644
--- a/setup.py
+++ b/setup.py
@@ -37,7 +37,7 @@
requirements = open(path.join(setup_dir, "requirements.txt")).read().splitlines()
required = [line for line in requirements if not line.startswith("-")]
-print "Required is '{}'".format(required)
+print ("Required is '{}'".format(required))
setup(
name=package,
diff --git a/test/unit/extensions/omci/test_omci_cc.py b/test/unit/extensions/omci/test_omci_cc.py
index ced24b0..992ba2b 100644
--- a/test/unit/extensions/omci/test_omci_cc.py
+++ b/test/unit/extensions/omci/test_omci_cc.py
@@ -625,7 +625,7 @@
# Note: After successful frame decode, a lookup of the corresponding request by
# TID is performed. None should be found, so we should see the Rx Unknown TID
# increment.
- self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'])
+ self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'] + 1)
self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'] + 1)
self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1)
self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'])
@@ -668,27 +668,28 @@
self.assertIsNotNone(decoded_blob)
self.assertEqual(decoded_blob, blob)
- def test_flush(self):
- # Test flush of autonomous ONU queues
+ def test_rx_unknown_me_avc(self):
+ # ME without a known decoder but is and attribute value change
self.setup_one_of_each()
omci_cc = self.onu_handler.omci_cc
omci_cc.enabled = True
snapshot = self._snapshot_stats()
- # TODO: add more
- self.assertTrue(True) # TODO: Implement
+ msg = '0000110aff78000080000e000000' \
+ '00000000000000000000000000000000000000000000000000000' \
+ '00000028'
- def test_avc_rx(self):
- # Test flush of autonomous ONU queues
- self.setup_one_of_each()
+ omci_cc.receive_message(hex2raw(msg))
- omci_cc = self.onu_handler.omci_cc
- omci_cc.enabled = True
- snapshot = self._snapshot_stats()
-
- # TODO: add more
- self.assertTrue(True) # TODO: Implement
+ # Blob decode should work and then it should be passed off to the
+ # ONU Autonomous frame processor
+ self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'])
+ self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'] + 1)
+ self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'])
+ self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'] + 1)
+ self.assertEqual(omci_cc.rx_onu_discards, snapshot['rx_onu_discards'])
+ self.assertEqual(omci_cc.consecutive_errors, 0)
def test_rx_discard_if_disabled(self):
# ME without a known decoder
diff --git a/tox.ini b/tox.ini
index 60d0614..d312d51 100644
--- a/tox.ini
+++ b/tox.ini
@@ -23,7 +23,7 @@
nose
mock
coverage
- -r requirements.txt
+ -rrequirements.txt
[nosetests]
with-xunit=1