-
Notifications
You must be signed in to change notification settings - Fork 1k
[ixia/Keysight] sample test cases and fixtures #1819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
06cd811
b6a0963
2a8ad2b
694ae89
b5316e8
663e920
61ff293
721b6b1
4833513
b0f1bf6
7bd3dbd
cbf0235
84f3201
f0098d1
b91dc5e
9ab2d65
b3970a9
fc12785
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # Place for Ixia fixtures. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| """This module contains some auxiliary functions that are required | ||
| to support automation activities. These functions are used for various | ||
| secondary activities like convert the ansible Unicode STDOUT output | ||
| to string, get IP address in a subnet, increment an IP address, get | ||
| VLAN subnet etc. | ||
|
|
||
| This file is also a placeholder for auxiliary function that are | ||
| required for supporting automation with Ixia devices in future: | ||
| like collecting diagnostics, uploading and downloading files | ||
| to/from API server, processing the statistics after obtaining them | ||
| in .csv format etc. | ||
| """ | ||
|
|
||
| import ipaddr | ||
| from netaddr import IPNetwork | ||
|
|
||
| def increment_ip_address (ip, incr=1) : | ||
| """ | ||
| Increment IP address by an integer number. | ||
|
|
||
| Args: | ||
| ip (str): IP address in string format. | ||
| incr (int): Increment by the specified number. | ||
|
|
||
| Return: | ||
| IP address in the argument incremented by the given integer. | ||
| """ | ||
| ipaddress = ipaddr.IPv4Address(ip) | ||
| ipaddress = ipaddress + incr | ||
| return_value = ipaddress._string_from_ip_int(ipaddress._ip) | ||
| return(return_value) | ||
|
|
||
|
|
||
| def ansible_stdout_to_str(ansible_stdout): | ||
| """ | ||
| The stdout of Ansible host is essentially a list of unicode characters. | ||
| This function converts it to a string. | ||
|
|
||
| Args: | ||
| ansible_stdout: stdout of Ansible | ||
|
|
||
| Returns: | ||
| Return a string | ||
| """ | ||
| result = "" | ||
| for x in ansible_stdout: | ||
| result += x.encode('UTF8') | ||
| return result | ||
|
|
||
|
|
||
| def get_vlan_subnet(host_ans): | ||
| """ | ||
| Get VLAN subnet of a T0 device | ||
|
|
||
| Args: | ||
| host_ans: Ansible host instance of the device | ||
|
|
||
| Returns: | ||
neethajohn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| VLAN subnet, e.g., "192.168.1.1/24" where 192.168.1.1 is gateway | ||
| and 24 is prefix length | ||
| """ | ||
| mg_facts = host_ans.minigraph_facts(host=host_ans.hostname)['ansible_facts'] | ||
| mg_vlans = mg_facts['minigraph_vlans'] | ||
|
|
||
| if len(mg_vlans) != 1: | ||
| print 'There should be only one Vlan at the DUT' | ||
| return None | ||
|
|
||
| mg_vlan_intfs = mg_facts['minigraph_vlan_interfaces'] | ||
| prefix_len = mg_vlan_intfs[0]['prefixlen'] | ||
| gw_addr = ansible_stdout_to_str(mg_vlan_intfs[0]['addr']) | ||
| return gw_addr + '/' + str(prefix_len) | ||
|
|
||
|
|
||
| def get_addrs_in_subnet(subnet, number_of_ip): | ||
| """ | ||
| Get N IP addresses in a subnet. | ||
|
|
||
| Args: | ||
| subnet (str): IPv4 subnet, e.g., '192.168.1.1/24' | ||
| number_of_ip (int): Number of IP addresses to get | ||
|
|
||
| Return: | ||
| Return n IPv4 addresses in this subnet in a list. | ||
| """ | ||
| ip_addr = subnet.split('/')[0] | ||
| ip_addrs = [str(x) for x in list(IPNetwork(subnet))] | ||
| ip_addrs.remove(ip_addr) | ||
|
|
||
| """ Try to avoid network and broadcast addresses """ | ||
| if len(ip_addrs) >= number_of_ip + 2: | ||
| del ip_addrs[0] | ||
| del ip_addrs[-1] | ||
|
|
||
| return ip_addrs[:number_of_ip] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| """ | ||
| This module contains the necessary fixtures for running test cases with | ||
| Ixia devices and IxNetwork. If more fixtures are required, they should be | ||
| included in this file. | ||
| """ | ||
|
|
||
| import pytest | ||
| from ixnetwork_restpy import SessionAssistant | ||
|
|
||
| @pytest.fixture(scope = "module") | ||
| def ixia_api_serv_ip(testbed): | ||
| """ | ||
| In an Ixia testbed, there is no PTF docker. | ||
| Hence, we use ptf_ip field to store Ixia API server. | ||
| This fixture returns the IP address of the Ixia API server. | ||
|
|
||
| Args: | ||
| testbed (pytest fixture): The testbed fixture. | ||
|
|
||
| Returns: | ||
| Ixia API server IP | ||
| """ | ||
| return testbed['ptf_ip'] | ||
|
|
||
|
|
||
| @pytest.fixture(scope = "module") | ||
| def ixia_api_serv_user(duthost): | ||
| """ | ||
| Return the username of Ixia API server. | ||
|
|
||
| Args: | ||
| duthost (pytest fixture): The duthost fixture. | ||
|
|
||
| Returns: | ||
neethajohn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Ixia API server username. | ||
| """ | ||
| return duthost.host.options['variable_manager']._hostvars[duthost.hostname]['secret_group_vars']['ixia_api_server']['user'] | ||
|
|
||
|
|
||
| @pytest.fixture(scope = "module") | ||
| def ixia_api_serv_passwd(duthost): | ||
| """ | ||
| Return the password of Ixia API server. | ||
|
|
||
| Args: | ||
| duthost (pytest fixture): The duthost fixture. | ||
|
|
||
| Returns: | ||
neethajohn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Ixia API server password. | ||
| """ | ||
| return duthost.host.options['variable_manager']._hostvars[duthost.hostname]['secret_group_vars']['ixia_api_server']['password'] | ||
|
|
||
|
|
||
| @pytest.fixture(scope = "module") | ||
| def ixia_api_serv_port(duthost): | ||
| """ | ||
| This fixture returns the TCP port for REST API of the ixia API server. | ||
|
|
||
| Args: | ||
| duthost (pytest fixture): The duthost fixture. | ||
|
|
||
| Returns: | ||
neethajohn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Ixia API server REST port. | ||
| """ | ||
| return duthost.host.options['variable_manager']._hostvars[duthost.hostname]['secret_group_vars']['ixia_api_server']['rest_port'] | ||
|
|
||
|
|
||
| @pytest.fixture(scope = "module") | ||
| def ixia_api_serv_session_id(duthost): | ||
| """ | ||
| Ixia API server can spawn multiple session on the same REST port. | ||
| Optional for LINUX, required for windows return the session ID. | ||
|
|
||
| Args: | ||
| duthost (pytest fixture): The duthost fixture. | ||
|
|
||
| Returns: | ||
| Ixia API server session id. | ||
| """ | ||
| return duthost.host.options['variable_manager']._hostvars[duthost.hostname]['secret_group_vars']['ixia_api_server']['session_id'] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if users do not specify session_id in configuration file? What will this function return?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Session Id is presumed as a mandatory parameter in the configuration file. So if it is not there we may get a key error (KeyError: 'session_Id'). If we don’t want to connect to particular session we give "None" as sessionID. No Change is needed. |
||
|
|
||
|
|
||
| @pytest.fixture(scope = "module") | ||
| def ixia_dev(duthost, fanouthosts): | ||
| """ | ||
| Returns the Ixia chassis IP. This fixture can return multiple IPs if | ||
| multiple Ixia chassis are present in the test topology. | ||
|
|
||
| Args: | ||
| duthost (pytest fixture): The duthost fixture. | ||
| fanouthosts (pytest fixture): The fanouthosts fixture. | ||
|
|
||
| Returns: | ||
neethajohn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Dictionary of Ixia Chassis IP/IPs. | ||
| """ | ||
| result = dict() | ||
| ixia_dev_hostnames = fanouthosts.keys() | ||
| for hostname in ixia_dev_hostnames: | ||
| result[hostname] = duthost.host.options['inventory_manager'].get_host(hostname).get_vars()['ansible_host'] | ||
| return result | ||
|
|
||
|
|
||
| @pytest.fixture(scope = "function") | ||
| def ixia_api_server_session( | ||
| ixia_api_serv_ip, | ||
| ixia_api_serv_user, | ||
| ixia_api_serv_passwd, | ||
| ixia_api_serv_port, | ||
| ixia_api_serv_session_id) : | ||
| """ | ||
| Ixia session manager fixture. | ||
|
|
||
| Args: | ||
| ixia_api_serv_ip (pytest fixture): ixia_api_serv_ip fixture | ||
| ixia_api_serv_user (pytest fixture): ixia_api_serv_user fixture. | ||
| ixia_api_serv_passwd (pytest fixture): ixia_api_serv_passwd fixture. | ||
| ixia_api_serv_port (pytest fixture): ixia_api_serv_port fixture. | ||
| ixia_api_serv_session_id (pytest fixture): ixia_api_serv_session_id | ||
| fixture. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to start a new line here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment was crossing 80 line boundary so I put an newline there. So I think no Change is needed here. |
||
|
|
||
| Returns: | ||
neethajohn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| IxNetwork Session | ||
| """ | ||
|
|
||
| if (ixia_api_serv_session_id.lower() != 'none') : | ||
| session = SessionAssistant(IpAddress=ixia_api_serv_ip, | ||
| UserName=ixia_api_serv_user, | ||
| Password=ixia_api_serv_passwd, | ||
| RestPort=ixia_api_serv_port, | ||
| SessionId=ixia_api_serv_session_id) | ||
| else : | ||
| session = SessionAssistant(IpAddress=ixia_api_serv_ip, | ||
| UserName=ixia_api_serv_user, | ||
| Password=ixia_api_serv_passwd, | ||
| RestPort=ixia_api_serv_port) | ||
| ixNetwork = session.Ixnetwork | ||
| ixNetwork.NewConfig() | ||
|
|
||
| yield session | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that ixia_api_server_session can be divided into a fixture and two functions: ixia_api_server_session (return a new session instance), clear_session (use NewConfig to clear this session) and remove_session. Using yield in this function affects the readability.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The “yield” was added based on earlier comments by Neeta, and I think it is good to have there
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think NewConfig() is unnecessary in this function. |
||
|
|
||
| ixNetwork.NewConfig() | ||
neethajohn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| session.Session.remove() | ||
Uh oh!
There was an error while loading. Please reload this page.