Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b53b1cc
[tests/conftest.py] override pytest-ansible fixtures to overcome scop…
Jul 24, 2019
329e67c
[pytest-infra] introduce PtfTestAdapter and ptfadapter fixture to con…
Jul 24, 2019
a003a28
[ptfadapter] add default ptf config
Jul 25, 2019
d5830e1
[conftest] move overridden ansible fixture to seperate file
Jul 25, 2019
7221045
[ptf_runner] rename ptf.py to ptf_runner.py to avoid conflict with pt…
Jul 25, 2019
9328407
[gitignore] update with cpython compiled files
Jul 25, 2019
e890945
[tests/fdb] rewrite fdb test with ptfadapter & fix change_mac.sh script
Jul 25, 2019
a930acb
[tests/ansible_host] rename to AnsibleHost to meet python naming conv…
Jul 25, 2019
1f335c6
[tests/ptfadapter] move qlen/relax to PtfTestAdapter object
Jul 25, 2019
6be1b29
[tests/ptfadapter] non need for disable_* config keys for newer ptf
Jul 25, 2019
45aa8b9
[tests] change ansible_host to AnsibleHost
Jul 25, 2019
37054a0
[conftest] remove extra new line
Jul 25, 2019
f80916f
[tests/fdb] reduce info to debug
Jul 25, 2019
bcf541d
[tests/fdb] cleanup FDB test
Jul 25, 2019
6a1cba1
[tests/ptfadapter] correct on the comment
Jul 25, 2019
e4a7bfe
[pytest] introduce pytest_runner playbook
Jul 25, 2019
bebc1f4
[test_lldp] divide into two test cases and put a TODO about SNMP comm…
Jul 25, 2019
7911f51
[lldp] call py.test to run lldp test; from now on any change/new test…
Jul 25, 2019
46eece9
[tests/bgp_speaker] skip until test is fixed
Jul 25, 2019
d6be436
[tests/ptfadapter] add README.md on how to use ptfadapter
Jul 25, 2019
bfb27c3
[.gitignore] ignore pytest_cached
Jul 29, 2019
a6847d3
[tests/conftest] add shortcut fixtures for DUT and PTF
Jul 29, 2019
20150f1
[tests/fdb] remove __init__.py from fdb test
Jul 29, 2019
0b5c57d
[tests/fdb] use pprint
Jul 29, 2019
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# Compiled Python files
ansible/plugins/filter/*.pyc
*.pyc
__pycache__/
.pytest_cache/
63 changes: 3 additions & 60 deletions ansible/roles/test/tasks/lldp.yml
Original file line number Diff line number Diff line change
@@ -1,61 +1,4 @@
# Gather minigraph facts
- name: Gathering minigraph facts about the device
minigraph_facts:
host: "{{ inventory_hostname }}"

- name: Print neighbors in minigraph
debug: msg="{{ minigraph_neighbors }}"

- name: find minigraph lldp neighbor
set_fact:
minigraph_lldp_nei: "{{ minigraph_lldp_nei|default({}) | combine({ item.key : item.value}) }}"
when: "'server' not in item.value['name'] | lower"
with_dict: minigraph_neighbors

- name: Gather information from LLDP
lldp:
- name: run test
include: roles/test/tasks/pytest_runner.yml
vars:
ansible_shell_type: docker
ansible_python_interpreter: docker exec -i lldp python

- name: Print LLDP information
debug: msg="{{ lldp }}"

- name: Verify LLDP information is available on most interfaces
assert: { that: "{{ lldp|length }} > {{ minigraph_lldp_nei|length * 0.8 }}"}

- name: Compare the LLDP neighbor name with minigraph neigbhor name (exclude the management port)
assert: { that: "'{{ lldp[item]['chassis']['name'] }}' == '{{ minigraph_lldp_nei[item]['name'] }}'" }
with_items: "{{ lldp.keys() }}"
when: item != "eth0"

- name: Compare the LLDP neighbor interface with minigraph neigbhor interface (exclude the management port)
assert: { that: "'{{ lldp[item]['port']['ifname'] }}' == '{{ minigraph_neighbors[item]['port'] }}'" }
with_items: "{{ lldp.keys() }}"
when: item != "eth0"

- block:
- name: Obtain the system description of the DUT chassis
shell: "docker exec -i lldp lldpcli show chassis | grep \"SysDescr:\" | sed -e 's/^\\s*SysDescr:\\s*//g'"
register: result

- name: Store system description of the DUT chassis as a fact
set_fact:
dut_system_description: "{{ result.stdout }}"

###TODO: fix this lldp_neighbor validation, this part is not running
- name: Iterate through each LLDP neighbor and verify the information received by neighbor is correct
add_host:
name: "{{ lldp[item]['chassis']['mgmt-ip'] }}"
groups: "lldp_neighbors,eos"
neighbor_interface: "{{ lldp[item]['port']['ifname'] }}"
dut_interface: "{{ item }}"
hname: "{{ lldp[item]['chassis']['mgmt-ip'] }}"
dut_chassis_id: "0x{{ ansible_eth0['macaddress'] | replace(':', '') }}"
dut_hostname: "{{ inventory_hostname }}"
dut_port_alias: "{{ minigraph_ports[item]['alias'] }}"
dut_port_description: "{{ minigraph_neighbors[item]['name'] }}:{{ minigraph_neighbors[item]['port'] }}"
dut_system_description: "{{ dut_system_description }}"
with_items: "{{ lldp.keys() }}"
when: item != "eth0"

test_node: test_lldp.py
25 changes: 0 additions & 25 deletions ansible/roles/test/tasks/lldp_neighbor.yml

This file was deleted.

64 changes: 64 additions & 0 deletions ansible/roles/test/tasks/pytest_runner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
- name: print a warning
debug:
msg:
- "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
- "!!!!!! Ansible playbook for running {{ testcase_name }} is now deprecated !!!!!!"
- "!!!!!! This playbook is just a wrapper to run py.test in sonic-mgmt/tests !!!!!!"
- "!!!!!!!!!!!!!!!!!!!!!!!!!! Consider using py.test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
- "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

- fail:
msg: Test node is not defined
when: test_node is not defined

- fail:
msg: Testbed is not defined
when: testbed_name is not defined

- name: set py.test command variable
set_fact:
pytest_cmd: 'py.test {{ test_node }}'

- name: append filter expression if needed
set_fact:
pytest_cmd: '{{ pytest_cmd }} -k "{{ test_filter }}"'
when: test_filter is defined

- name: append mark if needed
set_fact:
pytest_cmd: '{{ pytest_cmd }} -m {{ test_mark }}'
when: test_mark is defined

- name: append testbed name
set_fact:
pytest_cmd: '{{ pytest_cmd }} --testbed={{ testbed_name }}'

# We could use ansible_inventory_sources magic variable but it is available in ansible >=2.5
- name: append inventory file
set_fact:
pytest_cmd: '{{ pytest_cmd }} --inventory=../ansible/inventory'

- name: append testbed file
set_fact:
pytest_cmd: '{{ pytest_cmd }} --testbed_file=../ansible/testbed.csv'

- name: append host pattern
set_fact:
pytest_cmd: '{{ pytest_cmd }} --host-pattern={{ testbed_name }}'

- name: append verbosity flag
set_fact:
pytest_cmd: '{{ pytest_cmd }} -v'

- debug: var=pytest_cmd

- name: run py.test
connection: local
shell: '{{ pytest_cmd }}'
args:
chdir: ../tests/
environment:
ANSIBLE_LIBRARY: ../ansible/library/
register: out

- debug: msg='{{ out.stdout_lines }}'
31 changes: 31 additions & 0 deletions tests/ansible_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
""" This module provides few pytest-ansible fixtures overridden """

import pytest

# Here we override ansible_adhoc fixture from pytest-ansible plugin to overcome
# scope limitation issue; since we want to be able to use ansible_adhoc in module/class scope
# fixtures we have to override the scope here in global conftest.py
# Let's have it with module scope for now, so if something really breaks next test module run will have
# this fixture reevaluated
@pytest.fixture(scope='module')
def ansible_adhoc(request):
"""Return an inventory initialization method."""
plugin = request.config.pluginmanager.getplugin("ansible")

def init_host_mgr(**kwargs):
return plugin.initialize(request.config, request, **kwargs)
return init_host_mgr


# Same as for ansible_adhoc, let's have localhost fixture with session scope
# as it feels that during session run the localhost object should persist unchanged.
# Also, we have autouse=True here to force pytest to evaluate localhost fixture to overcome
# some hidden dependency between localhost and ansible_adhoc (even with default scope) (FIXME)
@pytest.fixture(scope='session', autouse=True)
def localhost(request):
"""Return a host manager representing localhost."""
# NOTE: Do not use ansible_adhoc as a dependent fixture since that will assert specific command-line parameters have
# been supplied. In the case of localhost, the parameters are provided as kwargs below.
plugin = request.config.pluginmanager.getplugin("ansible")
return plugin.initialize(request.config, request, inventory='localhost,', connection='local',
host_pattern='localhost').localhost
6 changes: 3 additions & 3 deletions tests/ansible_host.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class ansible_host():
class AnsibleHost(object):
""" wrapper for ansible host object """

def __init__(self, ansible_adhoc, hostname, is_local = False):
def __init__(self, ansible_adhoc, hostname, is_local=False):
if is_local:
self.host = ansible_adhoc(inventory='localhost', connection='local')[hostname]
else:
Expand All @@ -14,7 +15,6 @@ def __getattr__(self, item):
return self._run

def _run(self, *module_args, **complex_args):

res = self.module(*module_args, **complex_args)[self.hostname]
if res.is_failed:
raise Exception("run module {} failed, errmsg {}".format(self.module_name, res))
Expand Down
40 changes: 36 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@
import csv
import ipaddr as ipaddress

class TestbedInfo():
'''
from ansible_host import AnsibleHost


pytest_plugins = ('ptf_fixtures', 'ansible_fixtures')


class TestbedInfo(object):
"""
Parse the CSV file used to describe whole testbed info
Please refer to the example of the CSV file format
CSV file first line is title
The topology name in title is using uniq-name | conf-name
'''
"""

def __init__(self, testbed_file):
self.testbed_filename = testbed_file
self.testbed_topo = {}
Expand All @@ -33,16 +40,41 @@ def __init__(self, testbed_file):
if name:
self.testbed_topo[name] = tb_prop


def pytest_addoption(parser):
parser.addoption("--testbed", action="store", default=None, help="testbed name")
parser.addoption("--testbed_file", action="store", default=None, help="testbed file name")


@pytest.fixture(scope="session")
def testbed(request):
"""
Create and return testbed information
"""
tbname = request.config.getoption("--testbed")
tbfile = request.config.getoption("--testbed_file")
if tbname == None or tbfile == None:
if tbname is None or tbfile is None:
raise ValueError("testbed and testbed_file are required!")

tbinfo = TestbedInfo(tbfile)
return tbinfo.testbed_topo[tbname]


@pytest.fixture(scope="module")
def duthost(ansible_adhoc, testbed):
"""
Shortcut fixture for getting DUT host
"""

hostname = testbed['dut']
return AnsibleHost(ansible_adhoc, hostname)


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

hostname = testbed['ptf']
return AnsibleHost(ansible_adhoc, hostname)
10 changes: 0 additions & 10 deletions tests/fdb/change_mac.sh

This file was deleted.

Empty file added tests/fdb/conftest.py
Empty file.
3 changes: 0 additions & 3 deletions tests/fdb/fdb.j2

This file was deleted.

Loading