Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions tests/common/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ class AnsibleHostBase(object):
on the host.
"""

def __init__(self, ansible_adhoc, hostname):
def __init__(self, ansible_adhoc, hostname, connection=None):
if hostname == 'localhost':
self.host = ansible_adhoc(inventory='localhost', connection='local', host_pattern=hostname)[hostname]
else:
self.host = ansible_adhoc(become=True)[hostname]
if connection is None:
self.host = ansible_adhoc(become=True)[hostname]
else:
logging.debug("connection {} for {}".format(connection, hostname))
self.host = ansible_adhoc(become=True, connection=connection)[hostname]
self.hostname = hostname

def __getattr__(self, item):
Expand Down Expand Up @@ -307,3 +311,18 @@ def get_networking_uptime(self):
except Exception as e:
self.logger.error("Exception raised while getting networking restart time: %s" % repr(e))
return None

class EosHost(AnsibleHostBase):
"""
@summary: Class for Eos switch

For running ansible module on the Eos switch
"""

def __init__(self, ansible_adhoc, hostname, user, passwd, gather_facts=False):
AnsibleHostBase.__init__(self, ansible_adhoc, hostname, connection="network_cli")
evars = { 'ansible_connection':'network_cli', \
'ansible_network_os':'eos', \
'ansible_user': user, \
'ansible_password': passwd }
self.host.options['variable_manager'].extra_vars.update(evars)
28 changes: 19 additions & 9 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
import os
import glob
import json
import tarfile
import logging
import time
Expand All @@ -12,7 +13,7 @@

from ansible_host import AnsibleHost
from collections import defaultdict
from common.devices import SonicHost, Localhost, PTFHost
from common.devices import SonicHost, Localhost, PTFHost, EosHost

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -123,15 +124,8 @@ def testbed_devices(ansible_adhoc, testbed):
ptf_host = dut.host.options["inventory_manager"].get_host(dut.hostname).get_vars()["ptf_host"]
devices["ptf"] = PTFHost(ansible_adhoc, ptf_host)

# In the future, we can implement more classes for interacting with other testbed devices in the lib.devices
# module. Then, in this fixture, we can initialize more instance of the classes and store the objects in the
# devices dict here. For example, we could have
# from common.devices import FanoutHost
# devices["fanout"] = FanoutHost(ansible_adhoc, testbed["dut"])

return devices


def disable_ssh_timout(dut):
'''
@summary disable ssh session on target dut
Expand Down Expand Up @@ -186,6 +180,17 @@ def ptfhost(testbed_devices):

return testbed_devices["ptf"]

@pytest.fixture(scope="module")
def nbrhosts(ansible_adhoc, testbed, creds):
"""
Shortcut fixture for getting PTF host
"""

vm_base = int(testbed['vm_base'][2:])
devices = {}
for k, v in testbed['topo']['properties']['topology']['VMs'].items():
devices[k] = EosHost(ansible_adhoc, "VM%04d" % (vm_base + v['vm_offset']), creds['eos_login'], creds['eos_password'])
return devices

@pytest.fixture(scope='session')
def eos():
Expand All @@ -199,10 +204,15 @@ def eos():
def creds():
""" read and yield lab configuration """
files = glob.glob("../ansible/group_vars/lab/*.yml")
files += glob.glob("../ansible/group_vars/all/*.yml")
creds = {}
for f in files:
with open(f) as stream:
creds.update(yaml.safe_load(stream))
v = yaml.safe_load(stream)
if v is not None:
creds.update(v)
else:
logging.info("skip empty var file {}".format(f))
return creds


Expand Down
57 changes: 47 additions & 10 deletions tests/test_nbr_health.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import pytest
import logging
logger = logging.getLogger(__name__)
Expand All @@ -7,24 +8,60 @@
pytest.mark.disable_loganalyzer,
]

def test_neighbors_health(duthost, testbed_devices, eos):
def check_snmp(hostname, mgmt_addr, localhost, community):
logger.info("Check neighbor {}, mgmt ip {} snmp".format(hostname, mgmt_addr))
res = localhost.snmp_facts(host=mgmt_addr, version='v2c', is_eos=True, community=community)
try:
snmp_data = res['ansible_facts']
except:
return "neighbor {} has no snmp data".format(hostname)
logger.info("Neighbor {}, sysdescr {}".format(hostname, snmp_data['ansible_sysdescr']))

def check_eos_facts(hostname, mgmt_addr, host):
logger.info("Check neighbor {} eos facts".format(hostname))
res = host.eos_facts()
logger.info("facts: {}".format(json.dumps(res, indent=4)))
try:
eos_facts = res['ansible_facts']
except:
return "neighbor {} has no eos_facts".format(hostname)

try:
mgmt_ip = eos_facts['ansible_net_interfaces']['Management0']['ipv4']['address']
except:
return "neighbor {} managment address not assigned".format(hostname)

if mgmt_ip != mgmt_addr:
return "neighbor {} management address {} not correct".format(hostname, mgmt_ip)

def check_bgp_facts(hostname, host):
logger.info("Check neighbor {} bgp facts".format(hostname))
res = host.eos_command(commands=['show ip bgp sum'])
logger.info("bgp: {}".format(res))
if not res.has_key('stdout_lines') or u'BGP summary' not in res['stdout_lines'][0][0]:
return "neighbor {} bgp not configured correctly".format(hostname)

def test_neighbors_health(duthost, testbed_devices, nbrhosts, eos):
"""Check each neighbor device health"""

fails = []
localhost = testbed_devices['localhost']
config_facts = duthost.config_facts(host=duthost.hostname, source="running")['ansible_facts']
nei_meta = config_facts.get('DEVICE_NEIGHBOR_METADATA', {})
for k, v in nei_meta.items():
logger.info("Check neighbor {}, mgmt ip {} snmp".format(k, v['mgmt_addr']))
res = localhost.snmp_facts(host=v['mgmt_addr'], version='v2c', is_eos=True, community=eos['snmp_rocommunity'])
try:
snmp_data = res['ansible_facts']
except:
fails.append("neighbor {} has no snmp data".format(k))
continue
logger.info("Neighbor {}, sysdescr {}".format(k, snmp_data['ansible_sysdescr']))
failmsg = check_snmp(k, v['mgmt_addr'], localhost, eos['snmp_rocommunity'])
if failmsg:
fails.append(failmsg)

eoshost = nbrhosts[k]
failmsg = check_eos_facts(k, v['mgmt_addr'], eoshost)
if failmsg:
fails.append(failmsg)

# TODO: check link, bgp, etc. on
failmsg = check_bgp_facts(k, eoshost)
if failmsg:
fails.append(failmsg)

# TODO: check link, bgp, etc. on
if len(fails) > 0:
pytest.fail("\n".join(fails))
29 changes: 28 additions & 1 deletion tests/veos.vtb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,34 @@ VM0100 ansible_host=10.250.0.51
VM0101 ansible_host=10.250.0.52
VM0102 ansible_host=10.250.0.53
VM0103 ansible_host=10.250.0.54

VM0104 ansible_host=10.250.0.55
VM0105 ansible_host=10.250.0.56
VM0106 ansible_host=10.250.0.57
VM0107 ansible_host=10.250.0.58
VM0108 ansible_host=10.250.0.59
VM0109 ansible_host=10.250.0.60
VM0110 ansible_host=10.250.0.61
VM0111 ansible_host=10.250.0.62
VM0112 ansible_host=10.250.0.63
VM0113 ansible_host=10.250.0.64
VM0114 ansible_host=10.250.0.65
VM0115 ansible_host=10.250.0.66
VM0116 ansible_host=10.250.0.67
VM0117 ansible_host=10.250.0.68
VM0118 ansible_host=10.250.0.69
VM0119 ansible_host=10.250.0.70
VM0120 ansible_host=10.250.0.71
VM0121 ansible_host=10.250.0.72
VM0122 ansible_host=10.250.0.73
VM0123 ansible_host=10.250.0.74
VM0124 ansible_host=10.250.0.75
VM0125 ansible_host=10.250.0.76
VM0126 ansible_host=10.250.0.77
VM0127 ansible_host=10.250.0.78
VM0128 ansible_host=10.250.0.79
VM0129 ansible_host=10.250.0.80
VM0130 ansible_host=10.250.0.81
VM0131 ansible_host=10.250.0.82

[eos:children]
vms_1
Expand Down