def connect(self, testbed, uut_name): """ common setup subsection: connecting devices """ log.info(banner("aetest common setup connection to device")) # Step 1 self.parameters['testStep'] = 1 log.info( banner("STEP %s: Device Connection" % (self.parameters['testStep']))) # Get the names of devices (uut and stdby) # Grab the device object of the uut device with that name uut = testbed.devices[uut_name] # Save it in parameters to be able to use it from other test sections parameters['uut'] = uut # Connect to the device uut.connect(alias='myuut') # Make sure that the connection went fine if not hasattr(uut.myuut, 'execute'): self.failed() if uut.myuut.execute != uut.connectionmgr.myuut.execute: self.failed() log.info("STEP %s: Device Connection Passed" % (self.parameters['testStep']))
def execution(self, device, **kwargs): # Init status = OK message = '' # Execute command to check for tracebacks - timeout set to 5 mins try: output = device.execute(self.show_cmd, timeout=self.args.alignmentcheck_timeout) except Exception as e: status += CRITICAL(str(e)) return status if not output: return ERRORED('No output from {cmd}'.format(cmd=self.show_cmd)) # Check for alignment errors. Hex values = problems. if '0x' in output: message = "Device {d} Alignment error detected: '{o}'"\ .format(d=device.name, o=output) status += CRITICAL(message) logger.error(banner(message)) # Log message to user if not message: message = "***** No alignment error found *****" status += OK(message) logger.info(banner(message)) # Final status return status
def notify_wait(self, steps): """Activate notification thread and check results.""" notifier = self.active_notifications.get(self) if notifier: if steps.result.code != 1: notifier.stop() del self.active_notifications[self] return notifier.event_triggered = True log.info(banner('NOTIFICATION EVENT TRIGGERED')) wait_for_sample = notifier.sample_interval - 1 cntr = 1.0 while cntr < float(notifier.stream_max): log.info( 'Listening for notifications from subscribe stream, {} seconds elapsed' .format(cntr)) cntr += 1 if notifier.result is not None and wait_for_sample <= 0: notifier.stop() if notifier.result is True: steps.passed('\n' + banner('NOTIFICATION RESPONSE PASSED')) else: steps.failed('\n' + banner('NOTIFICATION RESPONSE FAILED')) break sleep(1) wait_for_sample -= 1 else: notifier.stop() steps.failed('\n' + banner('STREAM TIMED OUT WITHOUT RESPONSE')) if self in self.active_notifications: del self.active_notifications[self]
def _run_condition_with_optional_func(condition_bool, condition, kwargs, description=''): ret_dict = { 'substeps': [], 'run_condition_skipped': not condition_bool, 'action': 'run_condition', 'advanced_action': False, 'condition': condition } if condition_bool: log.info(banner("run condition: {}\n"\ "Condition {} is met, running the actions" .format(description, condition ))) ret_dict.update( {'substeps': list(callback_blitz_dispatcher_gen(**kwargs))}) else: log.info(banner("run condition: {}\n"\ "Condition {} is not met, not running the actions" .format(description, condition ))) return ret_dict
def process_operational_state(self, response, returns, key=False): """Test NETCONF or GNMI operational state response. Args: response (list): List of tuples containing NETCONF - lxml.Element, xpath. GNMI - value, xpath opfields (list): List of dict representing opfields. Returns: bool: True if successful. """ result = True opfields = returns if not opfields: log.error( banner("OPERATIONAL STATE FAILED: No opfields to compare") ) return False if not response: log.error( banner("OPERATIONAL STATE FAILED: Expected data") ) return False if isinstance(response[0], tuple): # yang.connector only returned one list of fields response = [response] for field in returns: if not self.process_one_operational_state(response, field, key): result = False return result
def log_summary(self): log.root.setLevel(0) if self.section_details: log.info(banner("Unittest results")) log.info(' %-70s%10s ' % ('SECTIONS/TESTCASES', 'RESULT'.center(10))) log.info('-' * 80) report = TreeNode('.') for section in self.section_details: failed_build_tree(section, report) if str(report) == '.': log.info(' %-70s%10s ' % ('ALL UNITTESTS', 'PASSED'.center(10))) else: log.info(str(report)) log.info(banner("Summary")) for k in sorted(self.summary.keys()): log.info(' {name:<58}{num:>20} '.format( name='Number of {}'.format(k.upper()), num=self.summary[k])) log.info(' {name:<58}{num:>20} '.format(name='Total Number', num=self.summary.total)) log.info(' {name:<58}{num:>19.1f}% '.format( name='Success Rate', num=self.summary.success_rate)) log.info('-' * 80) if glo_values.missingCount > 0: log.info(' {name:<58}{num:>20} '.format( name='Total Parsers Missing Unittests', num=glo_values.missingCount)) log.info('-' * 80) if glo_values.missingParsers: log.info("\n".join(glo_values.missingParsers), extra={'colour': 'yellow'}) log.info('-' * 80) log.info(' {name:<58}{num:>20} '.format( name='Total Passing Unittests', num=glo_values.parserPassed)) log.info(' {name:<58}{num:>20} '.format( name='Total Failed Unittests', num=glo_values.parserFailed)) log.info(' {name:<58}{num:>20} '.format( name='Total Errored Unittests', num=glo_values.parserErrored)) log.info(' {name:<58}{num:>20} '.format( name='Total Unittests', num=glo_values.parserTotal)) log.info('-' * 80) if (hasattr(glo_values, '_class_exists') and not glo_values._class_exists): parsed_args = _parse_args() log.info(f'`{parsed_args["_class"]}` does not exist', extra={'colour': 'yellow'}) log.info('-' * 80) else: log.info(banner('No Results To Show'))
def run_gnmi(operation, device, steps, datastore, rpc_data, returns, **kwargs): """Form gNMI message and send to testbed.""" log.debug('gNMI MESSAGE') result = True rpc_verify = RpcVerify(log=log, capabilities=[]) if operation == 'edit-config': result = device.set(rpc_data) elif operation == 'get': if not returns: log.error(banner('No gNMI data to compare to GET')) return False response = device.get(rpc_data) if not response: return False for resp in response: update = resp.get('update') if not update: result = False continue if not rpc_verify.process_operational_state(update, returns): result = False return result elif operation == 'get-config': response = device.get_config(rpc_data) deletes = False updates = False result = True for resp in response: if 'update' in resp: updates = True if not rpc_verify.process_operational_state( resp['update'], returns): result = False if 'delete' in resp: deletes = True if not updates and deletes: log.info('All configs were deleted') return True return result elif operation == 'subscribe': format = kwargs.get('format', {}) rpc_data['format'] = format if format.get('request_mode', 'STREAM') == 'ONCE': response = device.subscribe(rpc_data) else: rpc_data['returns'] = returns rpc_data['verifier'] = rpc_verify.process_operational_state return device.subscribe(rpc_data) elif operation == 'capabilities': if not returns: log.error(banner('No gNMI data to compare to GET')) return False resp = device.capabilities() result = in_capabilities(resp, returns) else: log.warning(banner('OPERATION: {0} not allowed'.format(operation))) return result
def process_rpc_reply(self, resp): """Transform XML into elements with associated xpath. Args: resp (list) or (str): list returned from netconf_send or well formed rpc-reply XML. Returns: list: List of tuples (lxml.Element, xpath (str)) """ resp_xml = self._get_resp_xml(resp) if not resp_xml: log.error( banner("OPERATIONAL-VERIFY FAILED: No response to verify.")) return False try: resp = self.et.fromstring(resp_xml.encode('utf-8')) log.info(self.et.tostring(resp, pretty_print=True).decode('utf-8')) except self.et.XMLSyntaxError as e: log.error( banner('OPERATIONAL-VERIFY FAILED: Response XML:\n{0}'.format( str(e)))) return False # if first element of reply is not 'rpc-reply' this is a bad response if self.et.QName(resp).localname != 'rpc-reply': log.error( banner("{0} Response missing rpc-reply:\nTag: {1}".format( 'OPERATIONAL-VERIFY FAILED:', resp[0]))) return False # Associate xpaths with response tags response = [] xpath = [] for el in resp.iter(): if self.et.QName(el).localname == 'rpc-reply': # Don't evaluate rpc-reply tag continue if not response and self.et.QName(el).localname == 'data': # Don't evaluate rpc-reply/data tag continue parent = el.getparent() xpath.append('/' + self.et.QName(el).localname) while True: if parent is not None: xpath.append('/' + self.et.QName(parent).localname) parent = parent.getparent() else: break response.append( (el, ''.join(reversed(xpath)).replace('/rpc-reply/data', ''))) xpath = [] return response
def process_operational_state(self, response, opfields): """Test NETCONF or GNMI operational state response. Args: response (list): List of tuples containing NETCONF - lxml.Element, xpath. GNMI - value, xpath opfields (list): List of dict representing opfields. Returns: bool: True if successful. """ result = True if not opfields: log.error( banner("OPERATIONAL STATE FAILED: No opfields to compare")) return False if not response: log.error(banner("OPERATIONAL STATE FAILED: Expected data")) return False for reply, reply_xpath in response: if self.et.iselement(reply): # NETCONF response value_state = self._process_values(reply, '') value = value_state.get('reply_val', 'empty') name = self.et.QName(reply).localname else: # GNMI response value = reply name = reply_xpath[reply_xpath.rfind('/') + 1:] for field in opfields: if field.get('selected', True) is False: opfields.remove(field) continue if 'xpath' in field and field['xpath'] == reply_xpath and \ name == field['name']: if not self.check_opfield(value, field): result = False opfields.remove(field) break if opfields: # Missing fields in rpc-reply msg = 'OPERATIONAL STATE FAILED: Missing value(s)\n' for opfield in opfields: if opfield.get('selected', True) is False: continue msg += opfield.get('xpath', '') + ' value: ' msg += str(opfield.get('value', '')) msg += '\n' log.error(msg) result = False return result
def format_content(self): report = [] for title, content in self.contents.items(): try: report.append('\n'.join( (banner(title), content.format(instance=self.instance)))) except (IndexError, ValueError): # This can occur if an entry has an embedded {} in it, which # confuses format(). report.append('\n'.join((banner(title), content))) return '\n\n'.join(report)
def execution(self, device, **kwargs): # Init status = OK # create timeout object timeout = Timeout(max_time=int(self.args.cpucheck_timeout), interval=int(self.args.cpucheck_interval)) # loop status loop_stat_ok = True if not hasattr(self, 'PARSER_MODULE'): return WARNING('Does not have CPU related parsers to check') while timeout.iterate(): # Execute command to get five minutes usage percentage try: cpu_dict = self.PARSER_MODULE(device).parse(sort_time='5min', key_word='CPU') except Exception as e: return ERRORED( 'No output from show processes cpu\n{}'.format(e)) # Check 5 minutes percentage smaller than cpucheck_fivemin_pcnt if int(cpu_dict['five_min_cpu']) >= int( self.args.cpucheck_fivemin_pcnt): message = "****** Device {d} *****\n".format(d=device.name) message += "Excessive CPU utilization detected for 5 min interval\n" message += "Allowed: {e}%\n".format( e=self.args.cpucheck_fivemin_pcnt) message += "Measured: FiveMin: {r}%".format( r=cpu_dict['five_min_cpu']) loop_stat_ok = False timeout.sleep() else: message = "***** CPU usage is Expected ***** \n" message += "Allowed threashold: {e} \n"\ .format(e=self.args.cpucheck_fivemin_pcnt) message += "Measured from device: {r}"\ .format(r=cpu_dict['five_min_cpu']) loop_stat_ok = True status += OK(message) logger.info(banner(message)) break if not loop_stat_ok: status += CRITICAL(message) logger.error(banner(message)) # Final status return status
def connect(self): # builder.construct() connects grpc channel and returns client if self.connected: return self.gnmi, self.channel = self.builder.construct(return_channel=True) resp = self.capabilities() if resp: log.info('\ngNMI version: {0} supported encodings: {1}\n\n'.format( resp.get('gNMIVersion', 'unknown'), resp.get('supportedEncodings', 'unknown'))) log.info(banner('gNMI CONNECTED')) else: log.info(banner('gNMI Capabilities not returned')) self.disconnect() raise gNMIException('Connection not successful')
def HQ_DIS1_SHOW_VLAN_BRIEF_CHECK(self, HQ_DIS1): try: # store execution result for later usage result = HQ_DIS1.execute('show vlan brief') results_template = textfsm.TextFSM(template) parsed_results = results_template.ParseText(result) # Will delete information about interfaces from the list vlan10_output = parsed_results[1] vlan10_output.pop() vlan20_output = parsed_results[2] vlan20_output.pop() vlan30_output = parsed_results[3] vlan30_output.pop() vlan40_output = parsed_results[4] vlan40_output.pop() if vlan10_output == vlan10: print('VLAN-10 - [EXISTS and ACTIVE]') else: logger.info(banner('VLAN-10 - [DOES NOT EXIST]')) self.failed() if vlan20_output == vlan20: print('VLAN-20 - [EXISTS and ACTIVE]') else: logger.info(banner('VLAN-20 - [DOES NOT EXIST]')) self.failed() if vlan30_output == vlan30: print('VLAN-30 - [EXISTS and ACTIVE]') else: logger.info(banner('VLAN-30 - [DOES NOT EXIST]')) self.failed() if vlan40_output == vlan40: print('VLAN-40 - [EXISTS and ACTIVE]') else: logger.info(banner('VLAN-40 - [DOES NOT EXIST]')) self.failed() except Exception as e: self.failed('Device {} \'show vlan brief\' failed: ' '{}'.format(HQ_AC1, str(e)), goto=['exit']) else: print('ALL VLANS EXISTS')
def set(self, cmd): """Send any Set data command. Args: cmd (dict): Mapping to namespace, xpath/value. {'namespace': '<prefix>': '<namespace>'}, {'nodes': [{ 'edit-op': '<netconf edit-config operation', 'xpath': '<prefixed Xpath to resource', 'value': <value to set resource to> }]} Returns: (dict): gNMI SetResponse """ if not self.connected: self.connect() try: # Convert xpath to path element responses = [] ns, configs, origin = self.gnmi.xpath_to_path_elem(cmd) updates = configs.get('update') replaces = configs.get('replace') deletes = configs.get('delete') if updates or replaces: responses.append( self.gnmi.set_json(updates, replaces, origin=origin)) if deletes: responses.append(self.gnmi.delete_xpaths(deletes)) # Do fixup on response return responses except Exception as exe: log.error(banner('{0}: {1}'.format(exe.code(), exe.details())))
def _verify_finds_root_interface(ops, requirements, **kwargs): '''Triggers in this file specified verify method. This is to check only 1 interface change to root after change the priority to highest ''' log.info(banner("check only One interface change to root for each vlan")) ret = find([ops], R(requirements), filter_=False) if not ret: raise Exception( 'There is no Root interfaces after changing the priority') group_keys = GroupKeys.group_keys(reqs=[requirements], ret_num={}, source=ret) vlan_dict = {} for item in group_keys: vlan_dict.setdefault(item['vlan'], {}).setdefault(item['interface'], {}) for vlan in vlan_dict: if len(vlan_dict[vlan].keys()) != 1: raise Exception( 'Expect ONE Root interface for vlan {v} but got {i}'.format( v=vlan, i=list(vlan_dict[vlan].keys()))) else: log.info('Find ONE ROOT interface {i} for vlan {v}'.format(i=list( vlan_dict[vlan].keys())[0], v=vlan))
def __init__(self, log=log, rpc_reply=None, rpc_verify=None, capabilities=[]): """Instantiate with optional reply and verify. User has the option to instantiate a series of RpcVerify instances with each containing a different set of reply/verify messages to execute depending on needs. Each instance can use a different log to record actions. Args: log (logging.Logger): Logs internal operations (default, log from module). rpc_reply (str): NETCONF rpc-reply (default None). rpc_verify (str): NETCONF rpc-reply to compare with rpc_reply (default None). capabilities (list): List of NETCONF capabilities from device (default, empty list) """ try: import lxml.etree as et self.et = et except ImportError as e: log.error( banner( 'Make sure you have lxml installed in your virtual env')) raise (e) self.rpc_reply = rpc_reply self.rpc_verify = rpc_verify self.capabilities = capabilities
def connect_to_devices(self, testbed): """Connect to all the devices""" log.info( banner( "Hang on tight - we are about to go on a magic carpet ride!\n.-.\n[.-''-.,\n| //`~\)\n(<|0|>0)\n;\ _/ \\_ _\,\n__\|'._/_ \ '='-,\n/\ \ || )_///_\>>\n( '._ T |\ | _/),-'\n'. '._.-' /'/ |\n| '._ _.'`-.._/\n,\ / '-' |/\n[_/\-----j\n_.--.__[_.--'_\__\n/ `--' '---._\n/ '---. -'. .' _.-- '.\n\_ '--.___ _;.-o /\n'.__ ___/______.__8----'\nc-'----'\n\n\n###___Loading testbed___###" )) testbed.connect()
def new_subsection_in_variant(self): '''New Subsection demonstrating that after inheriting the previous CommonSetup, we can add more sections to it. ''' logger.info(banner('new subsection is now called'))
def common_setup_subsection(self, x, y): """ Common Setup subsection """ log.info(banner(" Aetest Common Setup ")) # Use script args from aetest print("Script args from common setup") print(x) assert x == 1
def print_(self, steps, section, name, continue_=True, processor='', health_uids=None, health_groups=None, health_sections=None, *args, **kwargs): if 'steps' in kwargs: kwargs.pop('steps') for key, value in kwargs.items(): if value.get('type') == 'banner': print_value = 'printing message: {k}\n{v}'.format( k=key, v=banner(str(value['value']))) else: print_value = 'The value of {k}: {v}'.format(k=key, v=value['value']) log.info(print_value)
def print_trigger_local_verifications(parameters): '''Print the trigger local verifications''' if 'verifications' in parameters and parameters['verifications']: log.info(banner("Start trigger local verifications:\n{v}".\ format(v="\n".join( verf for verf in parameters['verifications'].keys()))))
def get(self, cmd, datatype='STATE'): """Send any Get data commmand. Args: cmd (dict): Mapping to namespace, xpath. {{'namespace': '<prefix>': '<namespace>'}, {'nodes': [{'xpath': '<prefixed Xpath to resource'}]} datatype (str): [ ALL | STATE ] (default: STATE) Returns: list: List of dict containing updates, replaces, deletes. Updates and replaces are lists of value/xpath tuples. [{'updates': [(<value>, <xpath"), ...]}] Deletes are a list of xpaths. [<xpath>,...] """ if not self.connected: self.connect() try: # Convert xpath to path element ns, msg, origin = self.gnmi.xpath_to_path_elem(cmd) resp = self.gnmi.get_xpaths(msg.get('get', []), data_type=datatype, origin=origin) log.info('\nGNMI response:\n{0}\n{1}'.format(15 * '=', str(resp))) # Do fixup on response response = self.decode_notification(resp, ns) # TODO: Do we need to send back deletes? return response except Exception as exe: log.error(banner('{0}: {1}'.format(exe.code(), exe.details()))) return []
def asynchronous_save_boot_variable(self, device, device_dict): '''Use asynchronous execution when saving boot variables on devices''' log.info( banner("Check boot information to see if they are consistent\n" "and save bootvar to startup-config on device '{d}'".format( d=device.name))) # get platform pts platform_pts = self.parameters.get('pts', {}).get('platform', {}).get(device.name, None) try: result = Lookup.from_device(device).sdk.libs.abstracted_libs.subsection.\ save_device_information(device=device, platform_pts=platform_pts) except Exception as e: device_dict[device.name] = 'Failed' else: if result == 'Skipped': device_dict[device.name] = 'Skipped' else: device_dict[device.name] = 'Passed' return device_dict
def _pre_action_call_kwargs_update(self, step, action, section, name, kwargs, ret_dict, pre_step_removed_kwargs): """updating keyword arguments of an action pre calling the action """ if 'banner' in kwargs: log.info(banner(kwargs['banner'])) del kwargs['banner'] # The actions were not added as a bounded method # so providing the self kwargs['self'] = self # Checking to replace variables and get those arguments kwargs = get_variable(**kwargs) # updating step to the newly created step # section/name is added to kwargs for extra decorator # by default continue after a failure, specify as False if otherwise is desired kwargs.update({ 'steps': step, 'continue_': pre_step_removed_kwargs['continue_'], 'section': section, 'name': name }) return kwargs
def run_playbook(self, uut, playbook, inventory): log.info(banner("Running Ansible Playbook {}".format(playbook))) r = ansible_runner.run(private_data_dir='.', inventory=inventory, playbook=playbook) log.info("Playbook status: {}".format(r.stats))
def get(self, cmd, datatype='STATE'): """Send any Get data commmand. Args: cmd (dict): Mapping to namespace, xpath. \ {{'namespace': '<prefix>': '<namespace>'}, \ {'nodes': [{'xpath': '<prefixed Xpath to resource'}]} \ datatype (str): [ ALL | STATE ] (default: STATE) \ Returns: list: List of dict containing updates, replaces, deletes. \ Updates and replaces are lists of value/xpath tuples. \ [{'updates': [(<value>, <xpath"), ...]}] \ Deletes are a list of xpaths. \ [<xpath>,...] \ """ if not self.connected: self.connect() try: # Convert xpath to path element ns, msg, origin = xpath_util.xml_path_to_path_elem( cmd, self.support_prefix) resp = self.gnmi.get_xpaths(msg.get('get', []), data_type=datatype) log.info('\nGNMI response:\n{0}\n{1}'.format(15 * '=', str(resp))) # Do fixup on response response = self.decode_notification(resp, ns) # TODO: Do we need to send back deletes? return response except Exception as exc: msg = '' if hasattr(exc, 'details'): msg = exc.details() else: msg = str(exc) log.error(banner('ERROR: {0}'.format(msg))) return []
def set(self, cmd): """Send any Set data command. Args: cmd (dict): Mapping to namespace, xpath/value. \ {'namespace': '<prefix>': '<namespace>'}, \ {'nodes': [{ \ 'edit-op': '<netconf edit-config operation', \ 'xpath': '<prefixed Xpath to resource', \ 'value': <value to set resource to> \ }]} \ Returns: (dict): gNMI SetResponse """ if not self.connected: self.connect() try: # Convert xpath to path element responses = [] ns, configs, origin = xpath_util.xml_path_to_path_elem(cmd) if self.support_prefix: prefix = xpath_util.get_prefix(origin) else: prefix = None updates = configs.get('update') if len(updates) > 1: xpaths = [] for update in updates: xpath = next(iter(update.keys())) xpaths.append(xpath) if os.path.commonprefix(xpaths): updates = xpath_util.get_payload(updates) replaces = configs.get('replace') if len(replaces) > 1: xpaths = [] for replace in replaces: xpath = next(iter(replace.keys())) xpaths.append(xpath) if os.path.commonprefix(xpaths): replaces = xpath_util.get_payload(replaces) deletes = configs.get('delete') if updates or replaces: response = self.gnmi.set_json(updates, replaces, ietf=self.json_ietf, prefix=prefix) responses.append(response) if deletes: response = self.gnmi.delete_xpaths(deletes) responses.append(response) # Do fixup on response return responses except Exception as exc: msg = '' if hasattr(exc, 'details'): msg = exc.details() else: msg = str(exc) log.error(banner('ERROR: {0}'.format(msg)))
def learn_the_system(self, testbed, steps, features=None): """Learn and store the system properties Args: testbed (`obj`): Testbed object steps (`obj`): aetest steps object features (`dict`): dict of components and the feature that contains the component. ex. {'pim': ['autorp',], 'bgp': ['confederationpeers', 'gracefulrestart']} Returns: None Raises: pyATS Results """ log.info( banner('Learn and store platform information, lldp neighbors' ', from PTS if PTS is existed, otherwise from show commands')) # get uut, having a uut is mandatory in Genie uut = testbed.devices['uut'] lookup = Lookup.from_device(uut) # get platform PTS platform_pts = self.parameters.get('pts', {}).get('platform', {}).get('uut', None) with steps.start( "Store and learn platform information from 'show lldp neighbors detail' on {}" .format(self.name)) as step: try: lookup.sdk.libs.abstracted_libs\ .subsection.learn_system(device=uut, steps=steps, platform_pts=platform_pts) except Exception as e: step.passx('Cannot Learn and Store system info', from_exception=e) # learn platform lldp neighbors with steps.start("learn platform lldp neighbors on device {}".format( uut.name)) as step: # inital lldp ops object lldp_ops = lookup.ops.lldp.lldp.Lldp( uut, attributes=['info[interfaces][(.*)][neighbors][(.*)][port_id]']) # learn the lldp ops try: lldp_ops.learn() except Exception as e: step.passx('Cannot learn lldp information', from_exception=e) if not hasattr(lldp_ops, 'info'): step.passx('No LLDP neighbors') # store the lldp information uut.lldp_mapping = lldp_ops.info['interfaces']
def create_genie_statistics_view(section, view_create_interval=30, view_create_iteration=5, disable_tracking=False, disable_port_pair=False): '''Trigger Processor: * Creates GENIE traffic statistics view on traffic generator device * This processor is useful if we want to check compare traffic profile after we do stop_traffic and apply_traffic in a trigger. apply_traffic will delete the existing GENIE statistic view. ''' # Init log.info(banner("processor: 'create_genie_statistics_view'")) # Find TGN devices tgn_devices = section.parameters['testbed'].find_devices(type='tgn') if not tgn_devices: log.info("SKIP: Traffic generator devices not found in testbed YAML") return for dev in tgn_devices: if dev.name not in section.parent.mapping_data['devices']: log.info("Traffic generator devices not specified in --devices") return # Connect to TGN try: dev.connect(via='tgn') except GenieTgnError as e: log.error(e) log.error("Unable to connect to traffic generator device '{}'".\ format(dev.name)) create_genie_statistics_view.result = Failed section.result += create_genie_statistics_view.result else: log.info("Connected to traffic generator device '{}'".\ format(dev.name)) create_genie_statistics_view.result = Passed section.result += create_genie_statistics_view.result # Creating GENIE traffic view on TGN try: dev.create_genie_statistics_view(view_create_interval=view_create_interval, \ view_create_iteration=view_create_iteration, \ disable_tracking=disable_tracking, \ disable_port_pair=disable_port_pair) except GenieTgnError as e: log.error(e) log.error("Unable to create GENIE traffic statistics view on '{}'". format(dev.name)) create_genie_statistics_view.result = Failed else: log.info("Creating GENIE traffic statistic view on '{}'".format( dev.name)) create_genie_statistics_view.result = Passed
def process_operational_state(self, response, opfields): """Test operational state response. Args: response (list): List of tuples containing lxml.Elements with xpath. opfields (list): List of dict representing opfields. Returns: bool: True if successful. """ result = True if not opfields: log.error(banner("OPERATIONAL STATE FAILED: No opfields")) return False if not response: log.error(banner("OPERATIONAL STATE FAILED: No valid rpc-reply")) return False for reply, reply_xpath in response: value_state = self._process_values(reply, '') value = value_state.get('reply_val', 'empty') for field in opfields: if field.get('selected', True) is False: opfields.remove(field) continue if 'xpath' in field and field['xpath'] == reply_xpath and \ self.et.QName(reply).localname == field['name']: if not self.check_opfield(value, field): result = False opfields.remove(field) break if opfields: # Missing fields in rpc-reply msg = 'OPERATIONAL STATE FAILED: Missing value(s)\n' for opfield in opfields: if opfield.get('selected', True) is False: continue msg += opfield.get('xpath', '') + ' value: ' msg += opfield.get('value', '') msg += '\n' log.error(msg) result = False return result