VOL-270: Investigate and support clustering support for xPON protos
* Ensuring global-scope for channel_termination
* Making changes to corresponding itests
Change-Id: I6cceb0dbd5cce138c439a381101bd2cfc3956b2a
diff --git a/tests/itests/voltha/test_dispatcher.py b/tests/itests/voltha/test_dispatcher.py
index 293f6f1..3c58f07 100644
--- a/tests/itests/voltha/test_dispatcher.py
+++ b/tests/itests/voltha/test_dispatcher.py
@@ -1,7 +1,7 @@
from random import randint
from time import time, sleep
-from google.protobuf.json_format import MessageToDict
+from google.protobuf.json_format import MessageToDict, ParseDict
from unittest import main
from voltha.protos.device_pb2 import Device
from tests.itests.voltha.rest_base import RestBase
@@ -18,6 +18,7 @@
from voltha.protos import voltha_pb2
from voltha.core.flow_decomposer import *
from voltha.protos.openflow_13_pb2 import FlowTableUpdate
+from voltha.protos import bbf_fiber_base_pb2 as fb
LOCAL_CONSUL = "localhost:8500"
DOCKER_COMPOSE_FILE = "compose/docker-compose-system-test.yml"
@@ -41,6 +42,29 @@
kafka_kpis="kafkacat -o end -b {} -C -t voltha.kpis -c 5"
)
+xpon_scenario = [
+ {'cterm-add': {
+ 'pb2': fb.ChannelterminationConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "PON port",
+ "description": "Channel Termination for Freedom Tower"
+ },
+ "data": {
+ "channelpair_ref": "",
+ "location": "AT&T WTC OLT"
+ },
+ "name": "PON port"
+ }
+ }
+ },
+ {'cterm-del': {
+ 'pb2': fb.ChannelterminationConfig(),
+ 'rpc': {"name": "PON port"}}
+ }
+]
+
class DispatcherTest(RestBase):
def setUp(self):
@@ -105,6 +129,8 @@
self._get_device_type_rest(dtypes['items'][0]['id'])
alarm_filter = self._create_device_filter_rest(olt_id)
self._remove_device_filter_rest(alarm_filter['id'])
+ channel_termination = self._create_channel_termination_rest(olt_id)
+ self._delete_channel_termination_rest(olt_id)
# TODO: PM APIs test
def test_02_cross_instances_dispatch(self):
@@ -234,6 +260,48 @@
res = self._get_olt_flows_grpc(self.empty_voltha_stub_global,
ponsim_logical_device_id)
+ # Test 8:
+ # A. Create Channel Termination on particular device instance using REST
+ # B. Ensuring that it is present on that specific instance
+ # C. Retrieve Channel Termination from global grpc using empty
+ # voltha instance
+ channel_termination = self._create_channel_termination_rest(
+ ponsim_olt.id)
+ global_cterm = self._get_channel_terminations_rest(ponsim_olt.id)
+ cterm = self._get_channel_terminations_grpc(
+ self.ponsim_voltha_stub_global, ponsim_olt.id)
+ assert global_cterm == MessageToDict(cterm,
+ including_default_value_fields = True,
+ preserving_proto_field_name = True)
+ cterm = self._get_channel_terminations_grpc(
+ self.ponsim_voltha_stub_local, ponsim_olt.id)
+ assert global_cterm == MessageToDict(cterm,
+ including_default_value_fields = True,
+ preserving_proto_field_name = True)
+ #Checking with empty instance
+ cterm = self._get_channel_terminations_grpc(
+ self.empty_voltha_stub_global, ponsim_olt.id)
+ assert global_cterm == MessageToDict(cterm,
+ including_default_value_fields = True,
+ preserving_proto_field_name = True)
+ #Simulated OLT
+ channel_termination = self._create_channel_termination_rest(
+ simulated_olt.id)
+ global_cterm = self._get_channel_terminations_rest(simulated_olt.id)
+ cterm = self._get_channel_terminations_grpc(
+ self.simulated_voltha_stub_global, simulated_olt.id)
+ assert global_cterm == MessageToDict(cterm,
+ including_default_value_fields = True,
+ preserving_proto_field_name = True)
+ cterm = self._get_channel_terminations_grpc(
+ self.simulated_voltha_stub_local, simulated_olt.id)
+ assert global_cterm == MessageToDict(cterm,
+ including_default_value_fields = True,
+ preserving_proto_field_name = True)
+ #Deleting Channel Termination
+ self._delete_channel_termination_rest(ponsim_olt.id)
+ self._delete_channel_termination_rest(simulated_olt.id)
+
# TODO: More tests to be added as new features are added
@@ -701,6 +769,31 @@
res = stub.ListLogicalDeviceFlows(voltha_pb2.ID(id=logical_device_id))
return res
+ #For xPon objects
+ def _get_channel_terminations_rest(self, device_id):
+ res = self.get('/api/v1/devices/{}/channel_terminations'.format(
+ device_id))
+ return res
+
+ def _get_channel_terminations_grpc(self, stub, device_id):
+ res = stub.GetAllChannelterminationConfig(voltha_pb2.ID(id=device_id))
+ return res
+
+ def _create_channel_termination_rest(self, device_id):
+ value = xpon_scenario[0]['cterm-add']
+ ParseDict(value['rpc'], value['pb2'])
+ request = value['pb2']
+ self.post('/api/v1/devices/{}/channel_terminations/{}'.format(
+ device_id, value['rpc']['name']),
+ MessageToDict(request, preserving_proto_field_name = True),
+ expected_code = 200)
+ return request
+
+ def _delete_channel_termination_rest(self, device_id):
+ value = xpon_scenario[1]['cterm-del']
+ self.delete('/api/v1/devices/{}/channel_terminations/{}/delete'.format(
+ device_id, value['rpc']['name']),
+ expected_code = 200)
if __name__ == '__main__':
main()
diff --git a/tests/itests/voltha/test_voltha_xpon.py b/tests/itests/voltha/test_voltha_xpon.py
index ebaed72..af1cabf 100644
--- a/tests/itests/voltha/test_voltha_xpon.py
+++ b/tests/itests/voltha/test_voltha_xpon.py
@@ -8,9 +8,9 @@
from common.utils.consulhelpers import get_endpoint_from_consul
'''
-These tests uses the ponsim OLT to verfiy addition, modification and deletion
-of channelgroups, channelpartition, channelpair, channeltermination, vOntAni, OntAni
-and VEnets for xpon
+These tests uses the ponsim OLT to verfiy addition, modification and deletion
+of channelgroups, channelpartition, channelpair, channeltermination, vOntAni,
+OntAni and VEnets for xpon
The prerequisite for this test are:
1. voltha ensemble is running
docker-compose -f compose/docker-compose-system-test.yml up -d
@@ -24,154 +24,177 @@
host_and_port = '172.17.0.1:50060'
scenario = [
{'cg-add': {
- 'pb2': fb.ChannelgroupConfig(),
- 'rpc': {
- "interface": {
- "enabled": True,
- "name": "Manhattan",
- "description": "Channel Group for Manhattan.."
- },
- "data": {
- "polling_period": 100,
- "system_id": "000000",
- "raman_mitigation": "RAMAN_NONE"
- },
- "name": "Manhattan"
- }
- }
- },
+ 'pb2': fb.ChannelgroupConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "Manhattan",
+ "description": "Channel Group for Manhattan.."
+ },
+ "data": {
+ "polling_period": 100,
+ "system_id": "000000",
+ "raman_mitigation": "RAMAN_NONE"
+ },
+ "name": "Manhattan"
+ }
+ }
+ },
{'cpart-add': {
- 'pb2': fb.ChannelpartitionConfig(),
- 'rpc': {
- "interface": {
- "enabled": True,
- "name": "WTC",
- "description": "Channel Partition for World Trade Center in Manhattan"
- },
- "data": {
- "differential_fiber_distance": 20,
- "closest_ont_distance": 0,
- "fec_downstream": False,
- "multicast_aes_indicator": False,
- "authentication_method": "SERIAL_NUMBER",
- "channelgroup_ref": "Manhattan"
- },
- "name": "WTC"
- }
- }
- },
+ 'pb2': fb.ChannelpartitionConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "WTC",
+ "description": "Channel Partition for World Trade \
+Center in Manhattan"
+ },
+ "data": {
+ "differential_fiber_distance": 20,
+ "closest_ont_distance": 0,
+ "fec_downstream": False,
+ "multicast_aes_indicator": False,
+ "authentication_method": "SERIAL_NUMBER",
+ "channelgroup_ref": "Manhattan"
+ },
+ "name": "WTC"
+ }
+ }
+ },
{'cpair-add': {
- 'pb2': fb.ChannelpairConfig(),
- 'rpc': {
- "interface": {
- "enabled": True,
- "name": "PON port",
- "description": "Channel Pair for Freedom Tower in WTC"
- },
- "data": {
- "channelpair_linerate": "down_10_up_10",
- "channelpair_type": "channelpair",
- "channelgroup_ref": "Manhattan",
- "gpon_ponid_interval": 0,
- "channelpartition_ref": "WTC",
- "gpon_ponid_odn_class": "CLASS_A"
- },
- "name": "PON port"
- }
- }
- },
+ 'pb2': fb.ChannelpairConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "PON port",
+ "description": "Channel Pair for Freedom Tower in WTC"
+ },
+ "data": {
+ "channelpair_linerate": "down_10_up_10",
+ "channelpair_type": "channelpair",
+ "channelgroup_ref": "Manhattan",
+ "gpon_ponid_interval": 0,
+ "channelpartition_ref": "WTC",
+ "gpon_ponid_odn_class": "CLASS_A"
+ },
+ "name": "PON port"
+ }
+ }
+ },
{'cterm-add': {
- 'pb2': fb.ChannelterminationConfig(),
- 'rpc': {
- "interface": {
- "enabled": True,
- "name": "PON port",
- "description": "Channel Termination for Freedom Tower"
- },
- "data": {
- "channelpair_ref": "PON port",
- "location": "AT&T WTC OLT"
- },
- "name": "PON port"
- }
- }
- },
+ 'pb2': fb.ChannelterminationConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "PON port",
+ "description": "Channel Termination for Freedom Tower"
+ },
+ "data": {
+ "channelpair_ref": "PON port",
+ "location": "AT&T WTC OLT"
+ },
+ "name": "PON port"
+ }
+ }
+ },
{'vontani-add': {
- 'pb2': fb.VOntaniConfig(),
- 'rpc': {
- "interface": {
- "enabled": True,
- "name": "ATT Silver User",
- "description": "ATT Silver User in Freedom Tower"
- },
- "data": {
- "preferred_chanpair": "PON port",
- "expected_serial_number": "ALCL00000000",
- "parent_ref": "WTC",
- "onu_id": 1
- },
- "name": "ATT Silver User"
- }
- }
- },
+ 'pb2': fb.VOntaniConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "ATT Golden User",
+ "description": "ATT Golden User in Freedom Tower"
+ },
+ "data": {
+ "preferred_chanpair": "PON port",
+ "expected_serial_number": "ALCL00000000",
+ "parent_ref": "WTC",
+ "onu_id": 1
+ },
+ "name": "ATT Golden User"
+ }
+ }
+ },
{'ontani-add': {
- 'pb2': fb.OntaniConfig(),
- 'rpc': {
- "interface": {
- "enabled": True,
- "name": "ATT Silver User",
- "description": "ATT Silver User in Freedom Tower"
- },
- "data": {
- "upstream_fec_indicator": True,
- "mgnt_gemport_aes_indicator": False
- },
- "name": "ATT Silver User"
- }
- }
- },
+ 'pb2': fb.OntaniConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "ATT Golden User",
+ "description": "ATT Golden User in Freedom Tower"
+ },
+ "data": {
+ "upstream_fec_indicator": True,
+ "mgnt_gemport_aes_indicator": False
+ },
+ "name": "ATT Golden User"
+ }
+ }
+ },
{'venet-add': {
- 'pb2': fb.VEnetConfig(),
- 'rpc': {
- "interface": {
- "enabled": True,
- "name": "ATT SU Enet UNI-1-1",
- "description": "Ethernet port - 1"
- },
- "data": {
- "v_ontani_ref": "ATT Silver User"
- },
- "name": "ATT SU Enet UNI-1-1"
- }
- }
- },
+ 'pb2': fb.VEnetConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "ATT SU Enet UNI-1-1",
+ "description": "Ethernet port - 1"
+ },
+ "data": {
+ "v_ontani_ref": "ATT Golden User"
+ },
+ "name": "ATT SU Enet UNI-1-1"
+ }
+ }
+ },
{'cg-mod': {
- 'pb2': fb.ChannelgroupConfig(),
- 'rpc': {
- "interface": {
- "enabled": True,
- "name": "Manhattan",
- "description": "Channel Group for Manhattan"
- },
- "data": {
- "polling_period": 100,
- "system_id": "000000",
- "raman_mitigation": "RAMAN_NONE"
- },
- "name": "Manhattan"
- }
- }
- },
- {'venet-del': { 'rpc': {"name": "ATT SU Enet UNI-1-1"}, 'pb2': fb.VEnetConfig()}},
- {'ontani-del': { 'rpc': {"name": "ATT Silver User"}, 'pb2': fb.OntaniConfig()}},
- {'vontani-del': { 'rpc': {"name": "ATT Silver User"}, 'pb2': fb.VOntaniConfig()}},
- {'cterm-del': { 'rpc': {"name": "PON port"}, 'pb2': fb.ChannelterminationConfig()}},
- {'cpair-del': { 'rpc': {"name": "PON port"}, 'pb2': fb.ChannelpairConfig()}},
- {'cpart-del': { 'rpc': {"name": "WTC"}, 'pb2': fb.ChannelpartitionConfig()}},
- {'cg-del': { 'rpc': {"name": "Manhattan"}, 'pb2': fb.ChannelgroupConfig()}}
+ 'pb2': fb.ChannelgroupConfig(),
+ 'rpc': {
+ "interface": {
+ "enabled": True,
+ "name": "Manhattan",
+ "description": "Channel Group for Manhattan"
+ },
+ "data": {
+ "polling_period": 100,
+ "system_id": "000000",
+ "raman_mitigation": "RAMAN_NONE"
+ },
+ "name": "Manhattan"
+ }
+ }
+ },
+ {'venet-del': {
+ 'pb2': fb.VEnetConfig(),
+ 'rpc': {"name": "ATT SU Enet UNI-1-1"}}
+ },
+ {'ontani-del': {
+ 'pb2': fb.OntaniConfig(),
+ 'rpc': {"name": "ATT Golden User"}}
+ },
+ {'vontani-del': {
+ 'pb2': fb.VOntaniConfig(),
+ 'rpc': {"name": "ATT Golden User"}}
+ },
+ {'cterm-del': {
+ 'pb2': fb.ChannelterminationConfig(),
+ 'rpc': {"name": "PON port"}}
+ },
+ {'cpair-del': {
+ 'pb2': fb.ChannelpairConfig(),
+ 'rpc': {"name": "PON port"}}
+ },
+ {'cpart-del': {
+ 'pb2': fb.ChannelpartitionConfig(),
+ 'rpc': {"name": "WTC"}}
+ },
+ {'cg-del': {
+ 'pb2': fb.ChannelgroupConfig(),
+ 'rpc': {"name": "Manhattan"}}
+ }
]
-id = 3 #for ordering the test cases
+#for ordering the test cases
+id = 3
LOCAL_CONSUL = "localhost:8500"
# Retrieve details of the REST entry point
rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
@@ -264,12 +287,13 @@
# Retrieve the desired item upon Post message
def verify(self, type):
if(type == 'channel_terminations'):
- return self.get('/api/v1/local/devices/{}/{}'.format(device['id'], type))
+ return self.get('/api/v1/devices/{}/{}'.format(device['id'], type))
return self.get('/api/v1/local/{}'.format(type))
def get_path(self, type, name, operation):
if(type == 'channel_terminations'):
- return 'api/v1/local/devices/{}/{}/{}{}'.format(device['id'], type, name, operation)
+ return 'api/v1/devices/{}/{}/{}{}'.format(device['id'],
+ type, name, operation)
return 'api/v1/local/{}/{}{}'.format(type, name, operation)
# Method to check if the result is same as the change requested
@@ -281,8 +305,10 @@
if(v == dict1['name']):
dict2 = item
break
- itfDiff = [k for k in dict1['interface'] if dict1['interface'][k] != dict2['interface'][k]]
- dataDiff = [k for k in dict1['data'] if dict1['data'][k] != dict2['data'][k]]
+ itfDiff = [k for k in dict1['interface'] if dict1['interface'][k] \
+ != dict2['interface'][k]]
+ dataDiff = [k for k in dict1['data'] if dict1['data'][k] \
+ != dict2['data'][k]]
if(len(itfDiff) == 0 and len(dataDiff) == 0):
return True
return False
@@ -290,14 +316,16 @@
#~~~~~~~~~~~~~~ Function to create test cases on the fly ~~~~~~~~~~~~~~~~
def create_dynamic_method(key, value):
obj_type_config = {
- 'cg': { 'type': 'channel_groups', 'config' : 'channelgroup_config' },
- 'cpart': { 'type': 'channel_partitions', 'config' : 'channelpartition_config' },
- 'cpair': { 'type': 'channel_pairs', 'config' : 'channelpair_config' },
- 'cterm': { 'type': 'channel_terminations', 'config' : 'channeltermination_config' },
- 'vontani': { 'type': 'v_ont_anis', 'config': 'v_ontani_config' },
- 'ontani': { 'type': 'ont_anis', 'config': 'ontani_config' },
- 'venet': { 'type': 'v_enets', 'config': 'v_enet_config' }
- }
+ 'cg':{'type':'channel_groups','config':'channelgroup_config'},
+ 'cpart':{'type':'channel_partitions',
+ 'config':'channelpartition_config'},
+ 'cpair':{'type':'channel_pairs','config':'channelpair_config'},
+ 'cterm':{'type':'channel_terminations',
+ 'config':'channeltermination_config'},
+ 'vontani':{'type':'v_ont_anis','config':'v_ontani_config'},
+ 'ontani':{'type':'ont_anis','config':'ontani_config'},
+ 'venet':{'type':'v_enets','config':'v_enet_config'}
+ }
def _add(self, type, config, req, name):
result, prev_len = self.add(type, config, req, name)
diff --git a/voltha/core/global_handler.py b/voltha/core/global_handler.py
index f681816..08da69f 100644
--- a/voltha/core/global_handler.py
+++ b/voltha/core/global_handler.py
@@ -647,48 +647,84 @@
context)
@twisted_async
+ @inlineCallbacks
def GetAllChannelterminationConfig(self, request, context):
- log.warning('temp-limited-implementation')
- # TODO dispatching to local instead of collecting all
- return self.dispatcher.dispatch(
- self.instance_id,
- VolthaLocalServiceStub,
+ log.info('grpc-request', request=request)
+ response = yield self.dispatcher.dispatch(
'GetAllChannelterminationConfig',
request,
- context)
+ context,
+ id=request.id)
+ log.info('grpc-response', response=response)
+ if isinstance(response, DispatchError):
+ log.info('grpc-error-response', error=response.error_code)
+ context.set_details('Channeltermination \'{}\' error'.format(
+ request.id))
+ context.set_code(response.error_code)
+ returnValue(Empty())
+ else:
+ log.info('grpc-success-response', response=response)
+ returnValue(response)
@twisted_async
+ @inlineCallbacks
def CreateChanneltermination(self, request, context):
- log.warning('temp-limited-implementation')
- # TODO dispatching to local instead of collecting all
- return self.dispatcher.dispatch(
- self.instance_id,
- VolthaLocalServiceStub,
+ log.info('grpc-request', request=request)
+ response = yield self.dispatcher.dispatch(
'CreateChanneltermination',
request,
- context)
+ context,
+ id=request.id)
+ log.info('grpc-response', response=response)
+ if isinstance(response, DispatchError):
+ log.info('grpc-error-response', error=response.error_code)
+ context.set_details('Channeltermination \'{}\' error'.format(
+ request.id))
+ context.set_code(response.error_code)
+ returnValue(Empty())
+ else:
+ log.info('grpc-success-response', response=response)
+ returnValue(response)
@twisted_async
+ @inlineCallbacks
def UpdateChanneltermination(self, request, context):
- log.warning('temp-limited-implementation')
- # TODO dispatching to local instead of collecting all
- return self.dispatcher.dispatch(
- self.instance_id,
- VolthaLocalServiceStub,
+ log.info('grpc-request', request=request)
+ response = yield self.dispatcher.dispatch(
'UpdateChanneltermination',
request,
- context)
+ context,
+ id=request.id)
+ log.info('grpc-response', response=response)
+ if isinstance(response, DispatchError):
+ log.info('grpc-error-response', error=response.error_code)
+ context.set_details('Channeltermination \'{}\' error'.format(
+ request.id))
+ context.set_code(response.error_code)
+ returnValue(Empty())
+ else:
+ log.info('grpc-success-response', response=response)
+ returnValue(response)
@twisted_async
+ @inlineCallbacks
def DeleteChanneltermination(self, request, context):
- log.warning('temp-limited-implementation')
- # TODO dispatching to local instead of collecting all
- return self.dispatcher.dispatch(
- self.instance_id,
- VolthaLocalServiceStub,
+ log.info('grpc-request', request=request)
+ response = yield self.dispatcher.dispatch(
'DeleteChanneltermination',
request,
- context)
+ context,
+ id=request.id)
+ log.info('grpc-response', response=response)
+ if isinstance(response, DispatchError):
+ log.info('grpc-error-response', error=response.error_code)
+ context.set_details('Channeltermination \'{}\' error'.format(
+ request.id))
+ context.set_code(response.error_code)
+ returnValue(Empty())
+ else:
+ log.info('grpc-success-response', response=response)
+ returnValue(response)
@twisted_async
def GetAllOntaniConfig(self, request, context):