def do_enable(self, line): """ Enable a device. If the <id> is not provided, it will be on the last pre-provisioned device. """ device_id = line or self.default_device_id self.poutput('enabling {}'.format(device_id)) try: stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) stub.EnableDevice(voltha_pb2.ID(id=device_id)) while True: device = stub.GetDevice(voltha_pb2.ID(id=device_id)) # If this is an OLT then acquire logical device id if device.oper_status == voltha_pb2.OperStatus.ACTIVE: if device.type.endswith('_olt'): assert device.parent_id self.default_logical_device_id = device.parent_id self.poutput('success (logical device id = {})'.format( self.default_logical_device_id)) else: self.poutput('success (device id = {})'.format( device.id)) break self.poutput('waiting for device to be enabled...') sleep(.5) except Exception, e: self.poutput('Error enabling {}. Error:{}'.format(device_id, e))
def do_install_eapol_flow(self, line): """ Install an EAPOL flow on the given logical device. If device is not given, it will be applied to logical device of the last pre-provisioned OLT device. """ logical_device_id = line or self.default_logical_device_id # gather NNI and UNI port IDs nni_port_no, unis = self.get_logical_ports(logical_device_id) # construct and push flow rule stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) for uni_port_no, _ in unis: update = FlowTableUpdate( id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=2000, match_fields=[in_port(uni_port_no), eth_type(0x888e)], actions=[ # push_vlan(0x8100), # set_field(vlan_vid(4096 + 4000)), output(ofp.OFPP_CONTROLLER) ])) res = stub.UpdateLogicalDeviceFlowTable(update) self.poutput('success for uni {} ({})'.format(uni_port_no, res))
def do_adapters(self, line): """List loaded adapter""" stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) res = stub.ListAdapters(Empty()) omit_fields = {'config.log_level', 'logical_device_ids'} print_pb_list_as_table('Adapters:', res.items, omit_fields, self.poutput)
def do_install_dhcp_flows(self, line): """ Install all dhcp flows that are representative of the virtualized access scenario in a PON network. """ logical_device_id = line or self.default_logical_device_id # gather NNI and UNI port IDs nni_port_no, unis = self.get_logical_ports(logical_device_id) # construct and push flow rules stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) # Controller-bound flows for uni_port_no, _ in unis: stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=1000, match_fields=[ in_port(uni_port_no), eth_type(0x800), ip_proto(17), udp_dst(67) ], actions=[output(ofp.OFPP_CONTROLLER)]))) self.poutput('success')
def get_stub(self): if self.stub is None: self.stub = \ voltha_pb2.VolthaGlobalServiceStub(self.get_channel()) \ if self.global_request else \ voltha_pb2.VolthaLocalServiceStub(self.get_channel()) return self.stub
def do_create(self, line, opts): if opts.filter_rules: stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) result = stub.CreateAlarmFilter( voltha_pb2.AlarmFilter(rules=opts.filter_rules)) print_pb_list_as_table( "Rules for Filter ID = {}:".format(result.id), result.rules, {}, self.poutput)
def do_delete(self, line, opts): if not opts.filter_id: self.poutput(self.colorize('Error: ', 'red') + 'Specify ' + \ self.colorize(self.colorize('"filter id"', 'blue'), 'bold') + ' to update') return stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) stub.DeleteAlarmFilter(voltha_pb2.ID(id=opts.filter_id))
def do_logical_devices(self, line): """List logical devices in Voltha""" stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) res = stub.ListLogicalDevices(Empty()) omit_fields = { 'desc.mfr_desc', 'desc.hw_desc', 'desc.sw_desc', 'desc.dp_desc', 'desc.serial_number', 'switch_features.capabilities' } print_pb_list_as_table('Logical devices:', res.items, omit_fields, self.poutput)
def do_delete(self, line): """ Deleting a device. ID of the device needs to be provided """ device_id = line or self.default_device_id self.poutput('deleting {}'.format(device_id)) try: stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) stub.DeleteDevice(voltha_pb2.ID(id=device_id)) self.poutput('deleted {}'.format(device_id)) except Exception, e: self.poutput('Error deleting {}. Error:{}'.format(device_id, e))
def do_show(self, line, opts): stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) if not opts.filter_id: result = stub.ListAlarmFilters(Empty()) print_pb_list_as_table("Alarm Filters:", result.filters, {}, self.poutput) else: result = stub.GetAlarmFilter(voltha_pb2.ID(id=opts.filter_id)) print_pb_list_as_table( "Rules for Filter ID = {}:".format(opts.filter_id), result.rules, {}, self.poutput)
def do_update(self, line, opts): if not opts.filter_id: self.poutput(self.colorize('Error: ', 'red') + 'Specify ' + \ self.colorize(self.colorize('"filter id"', 'blue'), 'bold') + ' to update') return if opts.filter_rules: stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) result = stub.UpdateAlarmFilter( voltha_pb2.AlarmFilter(id=opts.filter_id, rules=opts.filter_rules)) print_pb_list_as_table( "Rules for Filter ID = {}:".format(result.id), result.rules, {}, self.poutput)
def do_preprovision_olt(self, line, opts): """Preprovision a new OLT with given device type""" stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) kw = dict(type=opts.device_type) if opts.host_and_port: kw['host_and_port'] = opts.host_and_port elif opts.ip_address: kw['ipv4_address'] = opts.ip_address elif opts.mac_address: kw['mac_address'] = opts.mac_address else: raise Exception('Either IP address or Mac Address is needed') device = voltha_pb2.Device(**kw) device = stub.CreateDevice(device) self.poutput('success (device id = {})'.format(device.id)) self.default_device_id = device.id
def do_install_all_controller_bound_flows(self, line): """ Install all flow rules for controller bound flows, including EAPOL, IGMP and DHCP. If device is not given, it will be applied to logical device of the last pre-provisioned OLT device. """ logical_device_id = line or self.default_logical_device_id # gather NNI and UNI port IDs nni_port_no, unis = self.get_logical_ports(logical_device_id) # construct and push flow rules stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) for uni_port_no, _ in unis: stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate( id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=2000, match_fields=[in_port(uni_port_no), eth_type(0x888e)], actions=[output(ofp.OFPP_CONTROLLER)]))) stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=1000, match_fields=[ in_port(uni_port_no), eth_type(0x800), ip_proto(2) ], actions=[output(ofp.OFPP_CONTROLLER)]))) stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=1000, match_fields=[ in_port(uni_port_no), eth_type(0x800), ip_proto(17), udp_dst(67) ], actions=[output(ofp.OFPP_CONTROLLER)]))) self.poutput('success')
def do_delete_all_flows(self, line): """ Remove all flows and flow groups from given logical device """ logical_device_id = line or self.default_logical_device_id stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=ofp.ofp_flow_mod(command=ofp.OFPFC_DELETE, table_id=ofp.OFPTT_ALL, cookie_mask=0, out_port=ofp.OFPP_ANY, out_group=ofp.OFPG_ANY))) stub.UpdateLogicalDeviceFlowGroupTable( FlowGroupTableUpdate(id=logical_device_id, group_mod=ofp.ofp_group_mod( command=ofp.OFPGC_DELETE, group_id=ofp.OFPG_ALL))) self.poutput('success')
def get_logical_ports(self, logical_device_id): """ Return the NNI port number and the first usable UNI port of logical device, and the vlan associated with the latter. """ stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) ports = stub.ListLogicalDevicePorts( voltha_pb2.ID(id=logical_device_id)).items nni = uni = vlan = None for port in ports: if nni is None and port.root_port: nni = port.ofp_port.port_no if uni is None and not port.root_port: uni = port.ofp_port.port_no uni_device = self.get_device(port.device_id) vlan = uni_device.vlan if nni is not None and uni is not None: return nni, uni, vlan raise Exception('No valid port pair found (no ONUs yet?)')
def do_activate_olt(self, line): """ Activate an OLT. If the <id> is not provided, it will be on the last pre-provisioned OLT. """ device_id = line or self.default_device_id self.poutput('activating {}'.format(device_id)) stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) stub.ActivateDevice(voltha_pb2.ID(id=device_id)) # try to acquire logical device id while True: device = stub.GetDevice(voltha_pb2.ID(id=device_id)) if device.oper_status == voltha_pb2.OperStatus.ACTIVE: assert device.parent_id self.default_logical_device_id = device.parent_id break self.poutput('waiting for device to be activated...') sleep(.5) self.poutput('success (logical device id = {})'.format( self.default_logical_device_id))
def do_disable(self, line): """ Disable a device. ID of the device needs to be provided """ device_id = line self.poutput('disabling {}'.format(device_id)) try: stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) stub.DisableDevice(voltha_pb2.ID(id=device_id)) # Do device query and verify that the device admin status is # DISABLED and Operational Status is unknown device = stub.GetDevice(voltha_pb2.ID(id=device_id)) if device.oper_status == voltha_pb2.OperStatus.UNKNOWN and \ device.admin_state == voltha_pb2.AdminState.DISABLED: self.poutput('disabled successfully {}'.format(device_id)) else: self.poutput('disabling failed {}. Admin State:{} ' 'Operation State: {}'.format( device_id, device.admin_state, device.oper_status)) except Exception, e: self.poutput('Error disabling {}. Error:{}'.format(device_id, e))
def get_logical_ports(self, logical_device_id): """ Return the NNI port number and the first usable UNI port of logical device, and the vlan associated with the latter. """ stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) ports = stub.ListLogicalDevicePorts( voltha_pb2.ID(id=logical_device_id)).items nni = None unis = [] for port in ports: if port.root_port: assert nni is None, "There shall be only one root port" nni = port.ofp_port.port_no else: uni = port.ofp_port.port_no uni_device = self.get_device(port.device_id) vlan = uni_device.vlan unis.append((uni, vlan)) assert nni is not None, "No NNI port found" assert unis, "Not a single UNI?" return nni, unis
def test_02_cross_instances_dispatch(self): def prompt(input_func, text): val = input_func(text) return val def prompt_for_return(text): return raw_input(text) # Start the voltha ensemble with a single voltha instance self._stop_and_remove_all_containers() sleep(5) # A small wait for the system to settle down self.start_all_containers() self.set_rest_endpoint() # Scale voltha to 3 instances and setup the voltha grpc assigments self._scale_voltha(3) sleep(20) # A small wait for the system to settle down voltha_instances = orch.get_all_instances_of_service( vcore_svc_name[orch_env], port_name='grpc') self.assertEqual(len(voltha_instances), 3) self.ponsim_voltha_stub_local = voltha_pb2.VolthaLocalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[2]))) self.ponsim_voltha_stub_global = voltha_pb2.VolthaGlobalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[2]))) self.simulated_voltha_stub_local = voltha_pb2.VolthaLocalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[1]))) self.simulated_voltha_stub_global = voltha_pb2.VolthaGlobalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[1]))) self.empty_voltha_stub_local = voltha_pb2.VolthaLocalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[0]))) self.empty_voltha_stub_global = voltha_pb2.VolthaGlobalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[0]))) if orch_env == ENV_DOCKER_COMPOSE: # Prompt the user to start ponsim # Get the user to start PONSIM as root prompt(prompt_for_return, '\nStart PONSIM as root in another window ...') prompt(prompt_for_return, '\nEnsure port forwarding is set on ponmgnt ...') # Test 1: # A. Get the list of adapters using a global stub # B. Get the list of adapters using a local stub # C. Verify that the two lists are the same adapters_g = self._get_adapters_grpc(self.ponsim_voltha_stub_global) adapters_l = self._get_adapters_grpc(self.empty_voltha_stub_local) assert adapters_g == adapters_l # Test 2: # A. Provision a pomsim olt using the ponsim_voltha_stub # B. Enable the posim olt using the simulated_voltha_stub # C. Wait for onu discovery using the empty_voltha_stub ponsim_olt = self._provision_ponsim_olt_grpc( self.ponsim_voltha_stub_local) ponsim_logical_device_id = self._enable_device_grpc( self.simulated_voltha_stub_global, ponsim_olt.id) self._wait_for_onu_discovery_grpc(self.empty_voltha_stub_global, ponsim_olt.id, count=4) # Test 3: # A. Provision a simulated olt using the simulated_voltha_stub # B. Enable the simulated olt using the ponsim_voltha_stub # C. Wait for onu discovery using the empty_voltha_stub simulated_olt = self._provision_simulated_olt_grpc( self.simulated_voltha_stub_local) simulated_logical_device_id = self._enable_device_grpc( self.ponsim_voltha_stub_global, simulated_olt.id) self._wait_for_onu_discovery_grpc(self.empty_voltha_stub_global, simulated_olt.id, count=4) # Test 4: # Verify that we have at least 8 devices created using the global # REST and also via direct grpc in the empty stub devices_via_rest = self._list_devices_rest(8)['items'] devices_via_global_grpc = self._get_devices_grpc( self.empty_voltha_stub_global) assert len(devices_via_rest) == len(devices_via_global_grpc) # Test 5: # A. Create 2 Alarms filters using REST # B. Ensure it is present across all instances # C. Ensure when requesting the alarm filters we do not get # duplicate results alarm_filter1 = self._create_device_filter_rest(ponsim_olt.id) alarm_filter2 = self._create_device_filter_rest(simulated_olt.id) global_filters = self._get_alarm_filters_rest() filter = self._get_alarm_filters_grpc(self.simulated_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.ponsim_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_global) assert global_filters == MessageToDict(filter) # Test 6: # A. Delete an alarm filter # B. Ensure that filter is deleted from all instances self._remove_device_filter_rest(alarm_filter1['id']) previous_filters = global_filters global_filters = self._get_alarm_filters_rest() assert global_filters != previous_filters filter = self._get_alarm_filters_grpc(self.simulated_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.ponsim_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_global) assert global_filters == MessageToDict(filter) # Test 7: # A. Simulate EAPOL install on ponsim instance using grpc # B. Validate the flows using global REST # C. Retrieve the flows from global grpc using empty voltha instance self._install_eapol_flow_grpc(self.ponsim_voltha_stub_local, ponsim_logical_device_id) self._verify_olt_eapol_flow_rest(ponsim_olt.id) res = self._get_olt_flows_grpc(self.empty_voltha_stub_global, ponsim_logical_device_id) # Test 8: # A. Create xPON objects instance using REST # B. Ensuring that Channeltermination is present on specific instances # C. Ensuring that other xPON objects are present in all instances for item in xpon_scenario: for key, value in item.items(): _obj_action = [val for val in key.split('-')] _type_config = obj_type_config[_obj_action[0]] if _obj_action[1] == "mod": continue if _obj_action[0] == "cterm": if _obj_action[1] == "add": #Ponsim OLT self._create_xpon_object_rest(_type_config, value, ponsim_olt.id) self._verify_xpon_object_on_device( _type_config, self.ponsim_voltha_stub_global, ponsim_olt.id) self._delete_xpon_object_rest(_type_config, value, ponsim_olt.id) #Simulated OLT self._create_xpon_object_rest(_type_config, value, simulated_olt.id) self._verify_xpon_object_on_device( _type_config, self.simulated_voltha_stub_global, simulated_olt.id) self._delete_xpon_object_rest(_type_config, value, simulated_olt.id) elif _obj_action[1] == "del": continue else: if _obj_action[1] == "add": self._create_xpon_object_rest(_type_config, value) #Checking with Ponsim OLT self._verify_xpon_object_on_device( _type_config, self.ponsim_voltha_stub_global) #Checking with empty instance self._verify_xpon_object_on_device( _type_config, self.empty_voltha_stub_global) #Checking with Simulated OLT self._verify_xpon_object_on_device( _type_config, self.simulated_voltha_stub_global) elif _obj_action[1] == "del": self._delete_xpon_object_rest(_type_config, value)
def get_device(self, depth=0): stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) res = stub.GetDevice(voltha_pb2.ID(id=self.device_id), metadata=(('get-depth', str(depth)), )) return res
def do_perf_config(self, line, opts): #print(line) """Show and set the performance monitoring configuration of the device""" device = self.get_device(depth=-1) if not self.pm_config_last: self.pm_config_last = device.pm_configs # Ensure that a valid sub-command was provided if line.strip() not in {"set", "show", "commit", "reset", ""}: self.poutput(self.colorize('Error: ', 'red') + \ self.colorize(self.colorize(line.strip(), 'blue'), 'bold') + ' is not recognized') return # Ensure no options are provided when requesting to view the config if line.strip() == "show" or line.strip() == "": if opts.default_freq or opts.enable or opts.disable: self.poutput(opts.disable) self.poutput(self.colorize('Error: ', 'red') + 'use ' + \ self.colorize(self.colorize('"set"', 'blue'), 'bold') + ' to change settings') return if line.strip() == "set": # Set the supplied values # The defualt frequency if opts.default_freq: self.pm_config_last.default_freq = opts.default_freq self.pm_config_dirty = True # Field or group visibility if self.pm_config_last.grouped: for g in self.pm_config_last.groups: if opts.enable: if g.group_name in opts.enable: g.enabled = True self.pm_config_dirty = True for g in self.pm_config_last.groups: if opts.disable: if g.group_name in opts.disable: g.enabled = False self.pm_config_dirty = True else: for m in self.pm_config_last.metrics: if opts.enable: if m.name in opts.enable: m.enabled = True self.pm_config_dirty = True for m in self.pm_config_last.metrics: if opts.disable: if m.name in opts.disable: m.enabled = False self.pm_config_dirty = True #Frequency overrides. if opts.override: if self.pm_config_last.freq_override: oo = dict() for o in opts.override: oo[o[0]] = o[1] if self.pm_config_last.grouped: for g in self.pm_config_last.groups: if g.group_name in oo: try: g.group_freq = int(oo[g.group_name]) except ValueError: self.poutput(self.colorize('Warning: ', 'yellow') + \ self.colorize(oo[m.name], 'blue') +\ " is not an integer... ignored") del oo[g.group_name] self.pm_config_dirty = True else: for m in self.pm_config_last.metrics: if m.name in oo: try: m.sample_freq = int(oo[m.name]) except ValueError: self.poutput(self.colorize('Warning: ', 'yellow') + \ self.colorize(oo[m.name], 'blue') +\ " is not an integer... ignored") del oo[m.name] self.pm_config_dirty = True # If there's anything left the input was typoed if self.pm_config_last.grouped: field = 'group' else: field = 'metric' for o in oo: self.poutput(self.colorize('Warning: ', 'yellow') + \ 'the parameter' + ' ' + \ self.colorize(o, 'blue') + ' is not ' + \ 'a ' + field + ' name... ignored') if oo: return else: # Frequency overrides not enabled self.poutput(self.colorize('Error: ', 'red') + \ 'Individual overrides are only ' + \ 'supported if ' + \ self.colorize('freq_override', 'blue') + \ ' is set to ' + self.colorize('True', 'blue')) return self.poutput("Success") return elif line.strip() == "commit" and self.pm_config_dirty: stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) stub.UpdateDevicePmConfigs(self.pm_config_last) self.pm_config_last = self.get_device(depth=-1).pm_configs self.pm_config_dirty = False elif line.strip() == "reset" and self.pm_config_dirty: self.pm_config_last = self.get_device(depth=-1).pm_configs self.pm_config_dirty = False omit_fields = {'groups', 'metrics', 'id'} print_pb_as_table('PM Config:', self.pm_config_last, omit_fields, self.poutput, show_nulls=True) if self.pm_config_last.grouped: #self.poutput("Supported metric groups:") for g in self.pm_config_last.groups: if self.pm_config_last.freq_override: omit_fields = {'metrics'} else: omit_fields = {'group_freq', 'metrics'} print_pb_as_table('', g, omit_fields, self.poutput, show_nulls=True) if g.enabled: state = 'enabled' else: state = 'disabled' print_pb_list_as_table('Metric group {} is {}'.format( g.group_name, state), g.metrics, {'enabled', 'sample_freq'}, self.poutput, dividers=100, show_nulls=True) else: if self.pm_config_last.freq_override: omit_fields = {} else: omit_fields = {'sample_freq'} print_pb_list_as_table('Supported metrics:', self.pm_config_last.metrics, omit_fields, self.poutput, dividers=100, show_nulls=True)
def get_device(self, id): stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) return stub.GetDevice(voltha_pb2.ID(id=id))
def get_logical_devices(self): stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) res = stub.ListLogicalDevices(Empty()) return res.items
def do_install_all_sample_flows(self, line): """ Install all flows that are representative of the virtualized access scenario in a PON network. """ logical_device_id = line or self.default_logical_device_id # gather NNI and UNI port IDs nni_port_no, unis = self.get_logical_ports(logical_device_id) # construct and push flow rules stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel()) for uni_port_no, c_vid in unis: # Controller-bound flows stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate( id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=2000, match_fields=[in_port(uni_port_no), eth_type(0x888e)], actions=[ # push_vlan(0x8100), # set_field(vlan_vid(4096 + 4000)), output(ofp.OFPP_CONTROLLER) ]))) stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate( id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=1000, match_fields=[eth_type(0x800), ip_proto(2)], actions=[output(ofp.OFPP_CONTROLLER)]))) stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=1000, match_fields=[ eth_type(0x800), ip_proto(17), udp_dst(67) ], actions=[output(ofp.OFPP_CONTROLLER)]))) # Unicast flows: # Downstream flow 1 stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate( id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=500, match_fields=[ in_port(nni_port_no), vlan_vid(4096 + 1000), metadata(c_vid) # here to mimic an ONOS artifact ], actions=[pop_vlan()], next_table_id=1))) # Downstream flow 2 stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=500, table_id=1, match_fields=[ in_port(nni_port_no), vlan_vid(4096 + c_vid) ], actions=[ set_field(vlan_vid(4096 + 0)), output(uni_port_no) ]))) # Upstream flow 1 for 0-tagged case stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate( id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=500, match_fields=[ in_port(uni_port_no), vlan_vid(4096 + 0) ], actions=[set_field(vlan_vid(4096 + c_vid))], next_table_id=1))) # Upstream flow 1 for untagged case stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate( id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=500, match_fields=[in_port(uni_port_no), vlan_vid(0)], actions=[ push_vlan(0x8100), set_field(vlan_vid(4096 + c_vid)) ], next_table_id=1))) # Upstream flow 2 for s-tag stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=500, table_id=1, match_fields=[ in_port(uni_port_no), vlan_vid(4096 + c_vid) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(4096 + 1000)), output(nni_port_no) ]))) # Push a few multicast flows # 1st with one bucket for our uni 0 stub.UpdateLogicalDeviceFlowGroupTable( FlowGroupTableUpdate( id=logical_device_id, group_mod=mk_multicast_group_mod( group_id=1, buckets=[ ofp.ofp_bucket( actions=[pop_vlan(), output(unis[0][0])]) ]))) stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=1000, match_fields=[ in_port(nni_port_no), eth_type(0x800), vlan_vid(4096 + 140), ipv4_dst(0xe4010101) ], actions=[group(1)]))) # 2nd with one bucket for uni 0 and 1 stub.UpdateLogicalDeviceFlowGroupTable( FlowGroupTableUpdate( id=logical_device_id, group_mod=mk_multicast_group_mod( group_id=2, buckets=[ ofp.ofp_bucket( actions=[pop_vlan(), output(unis[0][0])]) # ofp.ofp_bucket(actions=[pop_vlan(), output(unis[1][0])]) ]))) stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=1000, match_fields=[ in_port(nni_port_no), eth_type(0x800), vlan_vid(4096 + 140), ipv4_dst(0xe4020202) ], actions=[group(2)]))) # 3rd with empty bucket stub.UpdateLogicalDeviceFlowGroupTable( FlowGroupTableUpdate(id=logical_device_id, group_mod=mk_multicast_group_mod(group_id=3, buckets=[]))) stub.UpdateLogicalDeviceFlowTable( FlowTableUpdate(id=logical_device_id, flow_mod=mk_simple_flow_mod( priority=1000, match_fields=[ in_port(nni_port_no), eth_type(0x800), vlan_vid(4096 + 140), ipv4_dst(0xe4030303) ], actions=[group(3)]))) self.poutput('success')
def test_02_cross_instances_dispatch(self): def prompt(input_func, text): val = input_func(text) return val def prompt_for_return(text): return raw_input(text) # Start the voltha ensemble with a single voltha instance self._stop_and_remove_all_containers() sleep(5) # A small wait for the system to settle down self.start_all_containers() self.set_rest_endpoint() self.set_kafka_endpoint() # Scale voltha to 3 instances and setup the voltha grpc assigments self._scale_voltha(3) sleep(10) # A small wait for the system to settle down voltha_instances = get_all_instances_of_service( LOCAL_CONSUL, 'vcore-grpc') self.assertEqual(len(voltha_instances), 3) self.ponsim_voltha_stub_local = voltha_pb2.VolthaLocalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[2]))) self.ponsim_voltha_stub_global = voltha_pb2.VolthaGlobalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[2]))) self.simulated_voltha_stub_local = voltha_pb2.VolthaLocalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[1]))) self.simulated_voltha_stub_global = voltha_pb2.VolthaGlobalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[1]))) self.empty_voltha_stub_local = voltha_pb2.VolthaLocalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[0]))) self.empty_voltha_stub_global = voltha_pb2.VolthaGlobalServiceStub( self.get_channel(self._get_grpc_address(voltha_instances[0]))) # Prompt the user to start ponsim # Get the user to start PONSIM as root prompt(prompt_for_return, '\nStart PONSIM as root in another window ...') prompt(prompt_for_return, '\nEnsure port forwarding is set on ponmgnt ...') # Test 1: # A. Get the list of adapters using a global stub # B. Get the list of adapters using a local stub # C. Verify that the two lists are the same adapters_g = self._get_adapters_grpc(self.ponsim_voltha_stub_global) adapters_l = self._get_adapters_grpc(self.empty_voltha_stub_local) assert adapters_g == adapters_l # Test 2: # A. Provision a pomsim olt using the ponsim_voltha_stub # B. Enable the posim olt using the simulated_voltha_stub # C. Wait for onu discovery using the empty_voltha_stub ponsim_olt = self._provision_ponsim_olt_grpc( self.ponsim_voltha_stub_local) ponsim_logical_device_id = self._enable_device_grpc( self.simulated_voltha_stub_global, ponsim_olt.id) self._wait_for_onu_discovery_grpc(self.empty_voltha_stub_global, ponsim_olt.id, count=4) # Test 3: # A. Provision a simulated olt using the simulated_voltha_stub # B. Enable the simulated olt using the ponsim_voltha_stub # C. Wait for onu discovery using the empty_voltha_stub simulated_olt = self._provision_simulated_olt_grpc( self.simulated_voltha_stub_local) simulated_logical_device_id = self._enable_device_grpc( self.ponsim_voltha_stub_global, simulated_olt.id) self._wait_for_onu_discovery_grpc(self.empty_voltha_stub_global, simulated_olt.id, count=4) # Test 4: # Verify that we have at least 8 devices created using the global # REST and also via direct grpc in the empty stub devices_via_rest = self._list_devices_rest(8)['items'] devices_via_global_grpc = self._get_devices_grpc( self.empty_voltha_stub_global) assert len(devices_via_rest) == len(devices_via_global_grpc) # Test 5: # A. Create 2 Alarms filters using REST # B. Ensure it is present across all instances # C. Ensure when requesting the alarm filters we do not get # duplicate results alarm_filter1 = self._create_device_filter_rest(ponsim_olt.id) alarm_filter2 = self._create_device_filter_rest(simulated_olt.id) global_filters = self._get_alarm_filters_rest() filter = self._get_alarm_filters_grpc(self.simulated_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.ponsim_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_global) assert global_filters == MessageToDict(filter) # Test 6: # A. Delete an alarm filter # B. Ensure that filter is deleted from all instances self._remove_device_filter_rest(alarm_filter1['id']) previous_filters = global_filters global_filters = self._get_alarm_filters_rest() assert global_filters != previous_filters filter = self._get_alarm_filters_grpc(self.simulated_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.ponsim_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_local) assert global_filters == MessageToDict(filter) filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_global) assert global_filters == MessageToDict(filter) # Test 7: # A. Simulate EAPOL install on ponsim instance using grpc # B. Validate the flows using global REST # C. Retrieve the flows from global grpc using empty voltha instance self._install_eapol_flow_grpc(self.ponsim_voltha_stub_local, ponsim_logical_device_id) self._verify_olt_eapol_flow_rest(ponsim_olt.id) res = self._get_olt_flows_grpc(self.empty_voltha_stub_global, ponsim_logical_device_id)