def test_snmp_interfaces(localhost, creds_all_duts, duthosts, enum_rand_one_per_hwsku_hostname, enum_asic_index): """compare the snmp facts between observed states and target state""" duthost = duthosts[enum_rand_one_per_hwsku_hostname] if duthost.is_supervisor_node(): pytest.skip("interfaces not present on supervisor node") hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] namespace = duthost.get_namespace_from_asic_id(enum_asic_index) config_facts = duthost.config_facts(host=duthost.hostname, source="persistent", namespace=namespace)['ansible_facts'] snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost]["snmp_rocommunity"], wait=True)['ansible_facts'] snmp_ifnames = [ v['name'] for k, v in snmp_facts['snmp_interfaces'].items() ] print snmp_ifnames # Verify all physical ports in snmp interface list for _, alias in config_facts['port_name_to_alias_map'].items(): assert alias in snmp_ifnames, "Interface not found in SNMP facts." # Verify all port channels in snmp interface list for po_name in config_facts.get('PORTCHANNEL', {}): assert po_name in snmp_ifnames, "PortChannel not found in SNMP facts."
def test_snmp_interfaces_mibs(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts, enum_asic_index): """Verify correct behaviour of port MIBs ifIndex, ifMtu, ifSpeed, ifAdminStatus, ifOperStatus, ifAlias, ifHighSpeed, ifType """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] namespace = duthost.get_namespace_from_asic_id(enum_asic_index) hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost]["snmp_rocommunity"], wait=True)['ansible_facts'] config_facts = duthost.config_facts(host=duthost.hostname, source="persistent", namespace=namespace)['ansible_facts'] ports_list = [] for i in ['port_name_to_alias_map', 'PORTCHANNEL']: ports_list.extend(config_facts.get(i, {}).keys()) dut_facts = collect_all_facts(duthost, ports_list, namespace) ports_snmps = verify_port_snmp(dut_facts, snmp_facts) speed_snmp = verify_snmp_speed(dut_facts, snmp_facts, ports_snmps) result = verify_port_ifindex(snmp_facts, speed_snmp) pytest_assert(not result, "Unexpected comparsion of SNMP: {}".format(result))
def get_entity_and_sensor_mib(duthost, localhost, creds_all_duts): """ Get physical entity information from snmp fact :param duthost: DUT host object :param localhost: localhost object :param creds_all_duts: Credential for snmp :return: """ mib_info = {} hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost]["snmp_rocommunity"], wait=True)['ansible_facts'] entity_mib = {} sensor_mib = {} for oid, info in snmp_facts['snmp_physical_entities'].items(): entity_mib[int(oid)] = info for oid, info in snmp_facts['snmp_sensors'].items(): sensor_mib[int(oid)] = info mib_info["entity_mib"] = entity_mib mib_info["sensor_mib"] = sensor_mib return mib_info
def test_snmp_mgmt_interface(localhost, creds_all_duts, duthosts, enum_rand_one_per_hwsku_hostname): """compare the snmp facts between observed states and target state""" duthost = duthosts[enum_rand_one_per_hwsku_hostname] hostip = duthost.host.options['inventory_manager'].get_host(duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts(localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] config_facts = duthost.config_facts(host=duthost.hostname, source="persistent")['ansible_facts'] snmp_ifnames = [ v['name'] for k, v in snmp_facts['snmp_interfaces'].items() ] logger.info('snmp_ifnames: {}'.format(snmp_ifnames)) # Verify management port in snmp interface list for name in config_facts.get('MGMT_INTERFACE', {}): assert name in snmp_ifnames, "Management Interface not found in SNMP facts." # TODO: Remove this check after operational status of mgmt interface # is implemented for multi-asic platform if duthost.num_asics() == 1: ports_list = [] ports_list.extend(config_facts.get('MGMT_INTERFACE', {}).keys()) dut_facts = collect_all_facts(duthost, ports_list) ports_snmps = verify_port_snmp(dut_facts, snmp_facts) speed_snmp = verify_snmp_speed(dut_facts, snmp_facts, ports_snmps) result = verify_port_ifindex(snmp_facts, speed_snmp) pytest_assert(not result, "Unexpected comparsion of SNMP: {}".format(result))
def test_snmp_fdb_send_tagged( ptfadapter, utils_vlan_ports_list, toggle_all_simulator_ports_to_rand_selected_tor_m, duthost, localhost, creds_all_duts): """ Send tagged packets from each port. Verify SNMP FDB entry """ cfg_facts = duthost.config_facts(host=duthost.hostname, source="persistent")['ansible_facts'] config_portchannels = cfg_facts.get('PORTCHANNEL', {}) send_cnt = 0 send_portchannels_cnt = 0 for vlan_port in utils_vlan_ports_list: port_index = vlan_port["port_index"][0] for permit_vlanid in map(int, vlan_port["permit_vlanid"]): dummy_mac = '{}:{:02x}:{:02x}'.format(DUMMY_MAC_PREFIX, (port_index >> 8) & 0xFF, port_index & 0xFF) pkt = build_icmp_packet(permit_vlanid, dummy_mac) logger.info("Send tagged({}) packet from {} ...".format( permit_vlanid, port_index)) logger.info( pkt.sprintf("%Ether.src% %IP.src% -> %Ether.dst% %IP.dst%")) testutils.send(ptfadapter, port_index, pkt) send_cnt += 1 if vlan_port['dev'] in config_portchannels: send_portchannels_cnt += 1 # Flush dataplane ptfadapter.dataplane.flush() hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost]["snmp_rocommunity"], wait=True)['ansible_facts'] assert 'snmp_fdb' in snmp_facts assert 'snmp_interfaces' in snmp_facts dummy_mac_cnt = 0 recv_portchannels_cnt = 0 for key in snmp_facts['snmp_fdb']: # key is string: vlan.mac items = key.split('.') if len(items) != 2: continue logger.info("FDB entry: {}".format(items)) if DUMMY_MAC_PREFIX in items[1]: dummy_mac_cnt += 1 idx = str(snmp_facts['snmp_fdb'][key]) assert idx in snmp_facts['snmp_interfaces'] assert 'name' in snmp_facts['snmp_interfaces'][idx] if snmp_facts['snmp_interfaces'][idx][ 'name'] in config_portchannels: recv_portchannels_cnt += 1 assert send_cnt == dummy_mac_cnt, "Dummy MAC count does not match" assert send_portchannels_cnt == recv_portchannels_cnt, "Portchannels count does not match"
def test_snmp_queues(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts, collect_techsupport_all_duts): duthost = duthosts[enum_rand_one_per_hwsku_hostname] if duthost.is_supervisor_node(): pytest.skip("interfaces not present on supervisor node") hostip = duthost.host.options['inventory_manager'].get_host(duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts(localhost, host=hostip, version="v2c", community=creds_all_duts[duthost]["snmp_rocommunity"], wait=True)['ansible_facts'] for k, v in snmp_facts['snmp_interfaces'].items(): if "Ethernet" in v['description']: if not v.has_key('queues'): pytest.fail("port %s does not have queue counters" % v['name'])
def test_snmp_v2mib(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts): """ Verify SNMPv2-MIB objects are functioning properly """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] host_ip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=host_ip, version="v2c", community=creds_all_duts[duthost]["snmp_rocommunity"], wait=True)['ansible_facts'] dut_facts = duthost.setup()['ansible_facts'] debian_ver = duthost.shell('cat /etc/debian_version')['stdout'] cmd = 'docker exec snmp grep "sysContact" /etc/snmp/snmpd.conf' sys_contact = " ".join(duthost.shell(cmd)['stdout'].split()[1:]) sys_location = duthost.shell( "grep 'snmp_location' /etc/sonic/snmp.yml")['stdout'].split()[-1] expected_res = { 'kernel_version': dut_facts['ansible_kernel'], 'hwsku': duthost.facts['hwsku'], 'os_version': 'SONiC.{}'.format(duthost.os_version), 'debian_version': '{} {}'.format(dut_facts['ansible_distribution'], debian_ver) } #Verify that sysName, sysLocation and sysContact MIB objects functions properly pytest_assert( snmp_facts['ansible_sysname'] == duthost.hostname, "Unexpected MIB result {}".format(snmp_facts['ansible_sysname'])) pytest_assert( snmp_facts['ansible_syslocation'] == sys_location, "Unexpected MIB result {}".format(snmp_facts['ansible_syslocation'])) pytest_assert( snmp_facts['ansible_syscontact'] == sys_contact, "Unexpected MIB result {}".format(snmp_facts['ansible_syscontact'])) #Verify that sysDescr MIB object functions properly missed_values = [] for system_value in expected_res: if expected_res[system_value] not in snmp_facts['ansible_sysdescr']: missed_values.append(expected_res[system_value]) pytest_assert( not missed_values, "System values {} was not found in SNMP facts: {}".format( missed_values, snmp_facts['ansible_sysdescr']))
def test_snmp_default_route(duthosts, enum_rand_one_per_hwsku_frontend_hostname, localhost, creds_all_duts, tbinfo): """compare the snmp facts between observed states and target state""" duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] pytest_require( 'backend' not in tbinfo['topo']['name'], "Skip this testcase since this topology {} has no default routes". format(tbinfo['topo']['name'])) hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] dut_result = duthost.shell('show ip route 0.0.0.0/0 | grep "\*"') dut_result_nexthops = [] # ipCidrRouteEntry MIB for default route will have entries # where next hop are not eth0 interface. for line in dut_result['stdout_lines']: if 'via' in line: ip, interface = line.split('via') ip = ip.strip("*, ") interface = interface.strip("*, ") if interface != "eth0" and 'Ethernet-IB' not in interface and 'Ethernet-BP' not in interface: dut_result_nexthops.append(ip) # If show ip route 0.0.0.0/0 has route only via eth0, # or has no route snmp_facts for ip_cidr_route # will be empty. if len(dut_result_nexthops) == 0: assert 'snmp_cidr_route' not in snmp_facts, 'snmp_cidr_route should not be present in snmp_facts' if len(dut_result_nexthops) != 0: # Test to ensure show ip route 0.0.0.0/0 result matches with SNMP result for ip in dut_result_nexthops: assert ip in snmp_facts[ 'snmp_cidr_route'], "{} ip not found in snmp_facts".format(ip) assert snmp_facts['snmp_cidr_route'][ip][ 'route_dest'] == '0.0.0.0', "Incorrect route_dest for {} ip".format( ip) assert snmp_facts['snmp_cidr_route'][ip][ 'status'] == '1', "Incorrect status for {} ip".format(ip) # Compare the length of routes in CLI output and SNMP facts assert len(snmp_facts['snmp_cidr_route'].keys()) == len(snmp_facts['snmp_cidr_route'].keys()), \ "Number or route entries in SNMP does not match with cli"
def test_snmp_memory(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts): """ Verify if memory MIB equals to data collected from DUT """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] host_ip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] compare = (('ansible_sysTotalFreeMemery', 'MemFree'), ('ansible_sysTotalBuffMemory', 'Buffers'), ('ansible_sysCachedMemory', 'Cached'), ('ansible_sysTotalSharedMemory', 'Shmem')) # Checking memory attributes within a certain percentage is not guarantee to # work 100% of the time. There could always be a big memory change between the # test read from snmp and read from system. # Allow the test to retry a few times before claiming failure. for _ in range(3): snmp_facts = get_snmp_facts( localhost, host=host_ip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] facts = collect_memory(duthost) # Verify correct behaviour of sysTotalMemery pytest_assert( not abs(snmp_facts['ansible_sysTotalMemery'] - int(facts['MemTotal'])), "Unexpected res sysTotalMemery {} v.s. {}".format( snmp_facts['ansible_sysTotalMemery'], facts['MemTotal'])) # Verify correct behaviour of sysTotalFreeMemery, sysTotalBuffMemory, sysCachedMemory, sysTotalSharedMemory new_comp = set() snmp_diff = [] for snmp, sys_data in compare: if CALC_DIFF(snmp_facts[snmp], facts[sys_data]) > percent: snmp_diff.append(snmp) new_comp.add((snmp, sys_data)) compare = new_comp if not snmp_diff: return logging.info("Snmp memory MIBs: {} differs more than {} %".format( snmp_diff, percent)) pytest.fail("Snmp memory MIBs: {} differs more than {} %".format( snmp_diff, percent))
def test_snmp_pfc_counters(duthosts, enum_rand_one_per_hwsku_frontend_hostname, localhost, creds_all_duts): duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] hostip = duthost.host.options['inventory_manager'].get_host(duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts(localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] # Check PFC counters # Ignore management ports, assuming the names starting with 'eth', eg. eth0 for k, v in snmp_facts['snmp_interfaces'].items(): if "Ethernet" in v['description']: if not v.has_key('cpfcIfRequests') or \ not v.has_key('cpfcIfIndications') or \ not v.has_key('requestsPerPriority') or \ not v.has_key('indicationsPerPriority'): pytest.fail("port %s does not have pfc counters" % v['name'])
def test_snmp_numpsu(duthosts, enum_supervisor_dut_hostname, localhost, creds_all_duts): duthost = duthosts[enum_supervisor_dut_hostname] hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] res = duthost.shell("psuutil numpsus") assert int(res[u'rc']) == 0, "Failed to get number of PSUs" numpsus = int(res['stdout']) assert numpsus == len(snmp_facts['snmp_psu'])
def test_snmp_memory_load(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts, load_memory): """ Verify SNMP total free memory matches DUT results in stress test """ # Start memory stress generation duthost = duthosts[enum_rand_one_per_hwsku_hostname] host_ip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=host_ip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] mem_free = duthost.shell( "grep MemFree /proc/meminfo | awk '{print $2}'")['stdout'] pytest_assert( CALC_DIFF(snmp_facts['ansible_sysTotalFreeMemery'], mem_free) < percent, "sysTotalFreeMemery differs by more than {}".format(percent))
def test_snmp_psu_status(duthosts, enum_supervisor_dut_hostname, localhost, creds_all_duts): duthost = duthosts[enum_supervisor_dut_hostname] hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] psus_on = 0 msg = "Unexpected operstatus results {} != {} for PSU {}" for psu_indx, operstatus in snmp_facts['snmp_psu'].items(): get_presence = duthost.shell( "redis-cli -n 6 hget 'PSU_INFO|PSU {}' presence".format(psu_indx)) get_status = duthost.shell( "redis-cli -n 6 hget 'PSU_INFO|PSU {}' status".format(psu_indx)) status = get_status['stdout'] == 'true' presence = get_presence['stdout'] == 'true' if presence and status: pytest_assert( int(operstatus['operstatus']) == PSU_STATUS_OK, msg.format(operstatus['operstatus'], PSU_STATUS_OK, psu_indx)) psus_on += 1 elif presence and not status: pytest_assert( int(operstatus['operstatus']) == PSU_STATUS_FUNCTIONING_FAIL, msg.format(operstatus['operstatus'], PSU_STATUS_FUNCTIONING_FAIL, psu_indx)) elif not presence: pytest_assert( int(operstatus['operstatus']) == PSU_STATUS_MODULE_MISSING, msg.format(operstatus['operstatus'], PSU_STATUS_MODULE_MISSING, psu_indx)) pytest_assert(psus_on >= 1, "At least one PSU should be with operstatus OK")
def test_snmp_loopback(duthosts, enum_rand_one_per_hwsku_frontend_hostname, nbrhosts, tbinfo, localhost, creds_all_duts): """ Test SNMP query to DUT over loopback IP - Send SNMP query over loopback IP from one of the BGP Neighbors - Get SysDescr from snmpfacts - compare result from snmp query over loopback IP and snmpfacts """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] config_facts = duthost.config_facts(host=duthost.hostname, source="persistent")['ansible_facts'] # Get first neighbor VM information nbr = nbrhosts[list(nbrhosts.keys())[0]] # TODO: Fix snmp query over Management IPv6 adderess and add SNMP test over management IPv6 address. for ip in config_facts[u'LOOPBACK_INTERFACE'][u'Loopback0']: loip = ip.split('/')[0] loip = ipaddress.ip_address(loip) # TODO: Fix SNMP query over IPv6 and remove the below check. if not isinstance(loip, ipaddress.IPv4Address): continue result = get_snmp_output(loip, duthost, nbr, creds_all_duts) assert result is not None, 'No result from snmpget' assert len(result[u'stdout_lines']) > 0, 'No result from snmpget' assert "SONiC Software Version" in result[u'stdout_lines'][0][ 0], "Sysdescr not found in SNMP result from IP {}".format(ip) assert snmp_facts['ansible_sysdescr'] in result[u'stdout_lines'][0][ 0], "Sysdescr from IP{} not matching with result from Mgmt IPv4.".format( ip)
def test_snmp_lldp(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts, tbinfo): """ Test checks for ieee802_1ab MIBs: - lldpLocalSystemData 1.0.8802.1.1.2.1.3 - lldpLocPortTable 1.0.8802.1.1.2.1.3.7 - lldpLocManAddrTable 1.0.8802.1.1.2.1.3.8 - lldpRemTable 1.0.8802.1.1.2.1.4.1 - lldpRemManAddrTable 1.0.8802.1.1.2.1.4.2 For local data check if every OID has value For remote values check for availability for at least 80% of minigraph neighbors (similar to lldp test) """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] if duthost.is_supervisor_node(): pytest.skip("LLDP not supported on supervisor node") hostip = duthost.host.options['inventory_manager'].get_host(duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts(localhost, host=hostip, version="v2c", community=creds_all_duts[duthost]["snmp_rocommunity"], wait=True)['ansible_facts'] mg_facts = {} for asic_id in duthost.get_asic_ids(): mg_facts_ns = duthost.asic_instance(asic_id).get_extended_minigraph_facts(tbinfo)['minigraph_neighbors'] if mg_facts_ns is not None: mg_facts.update(mg_facts_ns) print snmp_facts['snmp_lldp'] for k in ['lldpLocChassisIdSubtype', 'lldpLocChassisId', 'lldpLocSysName', 'lldpLocSysDesc']: assert snmp_facts['snmp_lldp'][k] assert "No Such Object currently exists" not in snmp_facts['snmp_lldp'][k] # Check if lldpLocPortTable is present for all ports for k, v in snmp_facts['snmp_interfaces'].items(): if "Ethernet" in v['name'] or "eth" in v['name']: for oid in ['lldpLocPortIdSubtype', 'lldpLocPortId', 'lldpLocPortDesc']: assert v.has_key(oid) assert "No Such Object currently exists" not in v[oid] # Check if lldpLocManAddrTable is present for k in ['lldpLocManAddrLen', \ 'lldpLocManAddrIfSubtype', \ 'lldpLocManAddrIfId', \ 'lldpLocManAddrOID']: assert snmp_facts['snmp_lldp'][k] assert "No Such Object currently exists" not in snmp_facts['snmp_lldp'][k] minigraph_lldp_nei = [] for k, v in mg_facts.items(): if "server" not in v['name'].lower(): minigraph_lldp_nei.append(k) print minigraph_lldp_nei # Check if lldpRemTable is present active_intf = [] for k, v in snmp_facts['snmp_interfaces'].items(): if v.has_key("lldpRemChassisIdSubtype") and \ v.has_key("lldpRemChassisId") and \ v.has_key("lldpRemPortIdSubtype") and \ v.has_key("lldpRemPortId") and \ v.has_key("lldpRemPortDesc") and \ v.has_key("lldpRemSysName") and \ v.has_key("lldpRemSysDesc") and \ v.has_key("lldpRemSysCapSupported") and \ v.has_key("lldpRemSysCapEnabled"): active_intf.append(k) print "lldpRemTable: ", active_intf assert len(active_intf) >= len(minigraph_lldp_nei) * 0.8 # skip neighbors that do not send chassis information via lldp lldp_facts= {} for asic_id in duthost.get_asic_ids(): lldp_facts_ns = duthost.lldpctl_facts(asic_instance_id=asic_id)['ansible_facts']['lldpctl'] if lldp_facts_ns is not None: lldp_facts.update(lldp_facts_ns) pattern = re.compile(r'^eth0|^Ethernet-IB') nei = [k for k, v in lldp_facts.items() if not re.match(pattern, k) and v['chassis'].has_key('mgmt-ip') ] print "neighbors {} send chassis management IP information".format(nei) # Check if lldpRemManAddrTable is present active_intf = [] for k, v in snmp_facts['snmp_interfaces'].items(): if v.has_key("lldpRemManAddrIfSubtype") and \ v.has_key("lldpRemManAddrIfId") and \ v.has_key("lldpRemManAddrOID") and \ v['name'] != 'eth0' and 'Etherent-IB' not in v['name']: active_intf.append(k) print "lldpRemManAddrTable: ", active_intf assert len(active_intf) == len(nei)
def test_snmp_fact(self, localhost, duthost, creds): get_snmp_facts(localhost, host=duthost.mgmt_ip, version="v2c", community=creds['snmp_rocommunity'])
def test_snmp_cpu(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts): """ Test SNMP CPU Utilization - Pulls CPU usage via shell commans - Polls SNMP for CPU usage - Difference should be < 2% (allowing float->int rounding on each result) TODO: abstract the snmp OID by SKU """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] host_facts = duthost.setup()['ansible_facts'] if host_facts.has_key("ansible_processor_vcpus"): host_vcpus = int(host_facts['ansible_processor_vcpus']) else: res = duthost.shell("nproc") host_vcpus = int(res['stdout']) logger.info("found {} cpu on the dut".format(host_vcpus)) # Gather facts with SNMP version 2 snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], is_dell=True, wait=True)['ansible_facts'] assert int(snmp_facts['ansible_ChStackUnitCpuUtil5sec']) try: for i in range(host_vcpus): duthost.shell("nohup yes > /dev/null 2>&1 & sleep 1") # Wait for load to reflect in SNMP time.sleep(20) # Gather facts with SNMP version 2 snmp_facts = get_snmp_facts( localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], is_dell=True, wait=True)['ansible_facts'] # Pull CPU utilization via shell # Explanation: Run top command with 2 iterations, 5sec delay. # Discard the first iteration, then grap the CPU line from the second, # subtract 100% - idle, and round down to integer. output = duthost.shell( "top -bn2 -d5 | awk '/^top -/ { p=!p } { if (!p) print }' | awk '/Cpu/ { cpu = 100 - $8 };END { print cpu }' | awk '{printf \"%.0f\",$1}'" ) logger.info(str(snmp_facts['ansible_ChStackUnitCpuUtil5sec'])) logger.info(str(output['stdout'])) cpu_diff = abs( int(snmp_facts['ansible_ChStackUnitCpuUtil5sec']) - int(output['stdout'])) if cpu_diff > 5: pytest.fail("cpu diff large than 5%%, %d, %d" % (int(snmp_facts['ansible_ChStackUnitCpuUtil5sec']), int(output['stdout']))) duthost.shell("killall yes") except: duthost.shell("killall yes") raise
def test_cacl_function(duthosts, rand_one_dut_hostname, localhost, creds): """Test control plane ACL functionality on a SONiC device""" duthost = duthosts[rand_one_dut_hostname] dut_mgmt_ip = duthost.mgmt_ip # Start an NTP client if NTPLIB_INSTALLED: ntp_client = ntplib.NTPClient() else: logging.warning( "Will not check NTP connection. ntplib is not installed.") # Ensure we can gather basic SNMP facts from the device. Should fail on timeout get_snmp_facts(localhost, host=dut_mgmt_ip, version="v2c", community=creds['snmp_rocommunity'], wait=True, timeout=20, interval=20) # Ensure we can send an NTP request if NTPLIB_INSTALLED: try: ntp_client.request(dut_mgmt_ip) except ntplib.NTPException: pytest.fail("NTP did timed out when expected to succeed!") # Copy config_service_acls.sh to the DuT (this also implicitly verifies we can successfully SSH to the DuT) duthost.copy(src="scripts/config_service_acls.sh", dest="/tmp/config_service_acls.sh", mode="0755") # We run the config_service_acls.sh script in the background because it # will install ACL rules which will only allow control plane traffic # to an unused IP range. Thus, if it works properly, it will sever our # SSH session, but we don't want the script itself to get killed, # because it is also responsible for resetting the control plane ACLs # back to their previous, working state duthost.shell( "nohup /tmp/config_service_acls.sh < /dev/null > /dev/null 2>&1 &") # Wait until we are unable to SSH into the DuT res = localhost.wait_for(host=dut_mgmt_ip, port=SONIC_SSH_PORT, state='stopped', search_regex=SONIC_SSH_REGEX, delay=30, timeout=40, module_ignore_errors=True) pytest_assert(not res.is_failed, "SSH port did not stop. {}".format(res.get('msg', ''))) # Try to SSH back into the DuT, it should time out res = localhost.wait_for(host=dut_mgmt_ip, port=SONIC_SSH_PORT, state='started', search_regex=SONIC_SSH_REGEX, delay=0, timeout=10, module_ignore_errors=True) pytest_assert( res.is_failed, "SSH did not timeout when expected. {}".format(res.get('msg', ''))) # Ensure we CANNOT gather basic SNMP facts from the device res = get_snmp_facts(localhost, host=dut_mgmt_ip, version='v2c', community=creds['snmp_rocommunity'], module_ignore_errors=True) pytest_assert( 'ansible_facts' not in res and "No SNMP response received before timeout" in res.get('msg', '')) # Ensure we cannot send an NTP request to the DUT if NTPLIB_INSTALLED: try: ntp_client.request(dut_mgmt_ip) pytest.fail("NTP did not time out when expected") except ntplib.NTPException: pass # Wait until the original service ACLs are reinstated and the SSH port on the # DUT is open to us once again. Note that the timeout here should be set sufficiently # long enough to allow config_service_acls.sh to reset the ACLs to their original # configuration. res = localhost.wait_for(host=dut_mgmt_ip, port=SONIC_SSH_PORT, state='started', search_regex=SONIC_SSH_REGEX, delay=0, timeout=90, module_ignore_errors=True) pytest_assert( not res.is_failed, "SSH did not start working when expected. {}".format(res.get( 'msg', ''))) # Delete config_service_acls.sh from the DuT duthost.file(path="/tmp/config_service_acls.sh", state="absent") # Ensure we can gather basic SNMP facts from the device once again. Should fail on timeout get_snmp_facts(localhost, host=dut_mgmt_ip, version="v2c", community=creds['snmp_rocommunity'], wait=True, timeout=20, interval=20)