Exemple #1
0
    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']))
Exemple #2
0
    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
Exemple #3
0
    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
Exemple #5
0
    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
Exemple #6
0
    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'))
Exemple #7
0
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
Exemple #8
0
    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
Exemple #9
0
    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)
Exemple #11
0
    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
Exemple #12
0
 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')
Exemple #14
0
    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())))
Exemple #15
0
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))
Exemple #16
0
    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()
Exemple #18
0
    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'))
Exemple #19
0
 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
Exemple #20
0
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)
Exemple #21
0
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()))))
Exemple #22
0
    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 []
Exemple #23
0
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
Exemple #24
0
    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
Exemple #25
0
    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))
Exemple #26
0
    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 []
Exemple #27
0
    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)))
Exemple #28
0
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']
Exemple #29
0
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
Exemple #30
0
    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