Skip to content

[ixia/Keysight] sample test cases and fixtures#1819

Merged
yxieca merged 18 commits intosonic-net:masterfrom
abhijit-dhar:master
Jul 25, 2020
Merged

[ixia/Keysight] sample test cases and fixtures#1819
yxieca merged 18 commits intosonic-net:masterfrom
abhijit-dhar:master

Conversation

@abhijit-dhar
Copy link
Contributor

@abhijit-dhar abhijit-dhar commented Jun 25, 2020

This directory should contain the Ixia ECN and RDMA test cases.
The lib folder contains
* fixtures required to run ixia test cases
* helper function required to write ixia test cases

Description of PR

Summary:
Fixes # (issue)

Type of change

  • Bug fix
  • Testbed and Framework(new/improvement)
  • Test case(new/improvement)

Approach

What is the motivation for this PR?

How did you do it?

How did you verify/test it?

Any platform specific information?

Supported testbed topology if it's a new test case?

Documentation

This directory should contain the Ixia ECN and RDMA test cases.
The lib folder contains
      * fixtures required to run ixia test cases
      *  helper function required to write ixia test cases
@lgtm-com
Copy link

lgtm-com bot commented Jun 25, 2020

This pull request introduces 3 alerts when merging 06cd811 into a25951a - view on LGTM.com

new alerts:

  • 1 for Except block handles 'BaseException'
  • 1 for Unused import
  • 1 for Variable defined multiple times

traffic_item.Generate()
ixNetwork.Traffic.Apply()
ixNetwork.Traffic.Start()
time.sleep(10)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the purpose of this sleep?

I don't see IO being stopped, is that on purpose? If so, will it cause issue for next test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open IO was not intentional. I will modify the the code to add a line to stop traffic. Generally stop the traffic is good practice. But even if traffic is not stopped it wont effect the next test, because those ports will get rebooted during while getting configured fro the next test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue is addressed. I have added ixNetwork.Traffic.Stop() ad the end of the script

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest use a helper with StartFor(5) seconds instead and get stats then if possible.

ixNetwork.Traffic.Apply()
ixNetwork.Traffic.Start()
time.sleep(10)
print(session.StatViewAssistant('Traffic Item Statistics'))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this debug code, or use logger to generate a log entry if necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have address this issue. print statements are replaced by logger.info()

time.sleep(10)
print(session.StatViewAssistant('Traffic Item Statistics'))

print('passed')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this debug code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this print statement


print('passed')

assert 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this no-op code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do that

@yxieca
Copy link
Collaborator

yxieca commented Jun 25, 2020

I suggest move tests/ixia/lib/* to tests/common/ixia/*. test/common is where we put shared code. and I don't think explicit 'lib' in the path is required.

@yxieca
Copy link
Collaborator

yxieca commented Jun 25, 2020

You used lots of 'print' in your test. Can you change them into logger.debug(), logger.info() and/or logger.warning() instead?

from common.reboot import *
from common.platform.device_utils import fanout_switch_port_lookup
from common.helpers import assertions
from ixnetwork_restpy import SessionAssistant, Files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move all the low level IXIA API functions to ixia_helpers.py?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. In fact we are in process of designing those high-level wrapper function. See you soon in PRs and meeting and may be design discussion regarding this. Currently I suggest let it be there, to get the ball rolling. As soon we will formulate the new wrapper API we will remove these and replace these with new wrapper functions (which may be bit delayed). Till then let it be here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have moved some of them to the ixia_fixture.py (mainly connection related). Rest of them is still there. Until we come up with some high level wrapper they suppose to be there. This is only a sample script. This will act as a templet for the engineers who will add test-case to act with ixia devices.
Purpose is the get the activity started. Later we may enhance/change or even remove it (after a considerable RDMA test case is added). Right now to stat the activity it is important.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have also moved the ixia libraries to tests/ixia/lib/* and changed the import statements on the top of the script accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have also moved the ixia libraries to "/sonic-mgmt/tests/common/ixia" and changed the import statements on the top of the script accordingly.

As per review comments given against the 1819 we have to keep the ixia libraries under sonic-mgmt/tests/common/ixia/
@lgtm-com
Copy link

lgtm-com bot commented Jun 26, 2020

This pull request introduces 6 alerts when merging b6a0963 into 815511c - view on LGTM.com

new alerts:

  • 2 for Except block handles 'BaseException'
  • 2 for Unused import
  • 2 for Variable defined multiple times

This file should be in tests/common/ixia folder.
So deleting it from tests/ixia/lib/ folder
This file should be under the folder tests/common/ixia
Hence deleting it form tests/ixia/lib
This file should be under tests/common/ixia
So deleting it from tests/ixia/lib
@lgtm-com
Copy link

lgtm-com bot commented Jun 26, 2020

This pull request introduces 3 alerts when merging b5316e8 into 815511c - view on LGTM.com

new alerts:

  • 1 for Except block handles 'BaseException'
  • 1 for Unused import
  • 1 for Variable defined multiple times

There were many review comment against this file. Some of the comments I have implemented. But some of the comments may be implemented in future. Like "(Wei Bai) Can you move all the low level IXIA API functions to ixia_helpers.py?" or "I have a high level comment. can we design some IXIA wrapper functions (e.g., configure ports, create a PFC traffic item) and only call these high level wrapper functions in py.test scripts without exposing too many IXIA low level details? (Wei Bai)"

This comment may be addressed in future PRs once we come up with the high level wrapper APIs.
@lgtm-com
Copy link

lgtm-com bot commented Jun 26, 2020

This pull request introduces 3 alerts when merging 663e920 into 815511c - view on LGTM.com

new alerts:

  • 1 for Except block handles 'BaseException'
  • 1 for Unused import
  • 1 for Variable defined multiple times

This fixture returns the hostnames and IP addresses of the IXIA chassis in the dictionary format.
"""
@pytest.fixture(scope = "module")
def ixia_dev(duthost, ansible_adhoc, conn_graph_facts, creds):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as discussed in the meeting, this needs to be part of the fanouthosts fixture and abstracted in common/devices.py. Please look at the EosHost or OnyxHost for examples

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this fixture from ixia_fixtures.py, instead I am taking fanout_graph_facts as input and designed new class "IxiaFanoutManager" defined in ixia_helpers.py to handle and extract chassis IP address.


import time

#pytestmark = [pytest.mark.disable_loganalyzer]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleanup. remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have addressed this - the commented line is removed

Comment on lines +83 to +89
cardId = getCard(ixiaports, 0)
PortId1 = getPort(ixiaports, 0)
PortId2 = getPort(ixiaports, 1)
PortId3 = getPort(ixiaports, 2)
PortId4 = getPort(ixiaports, 3)
PortId5 = getPort(ixiaports, 4)
PortId6 = getPort(ixiaports, 5)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless 6 ixia connections exist, this test cannot be used by others, can you make this num_of_ports configurable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this hard codings are removed. I have used "IxiaFanoutManager" class which can handle variable number of physical ports (as comes in fanout_graph_fact) and creates that number of virtual ports in the ixNetwork configuration. Also port assignments are done accordingly.

Password = Password,
RestPort = RestPort)

sessionData = session.Session
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all the test setup/cleanup code, should move to a fixture/separate method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have written a fixture ixia_api_server_session in the ixia_fixtures.py to handle session set up and initial clean up.

@param conn_graph_facts: testbed connectivity graph
@return the port of its neighbor IXIA device or None if we cannot find it
"""
def get_neigh_ixia_port(intf, conn_graph_facts):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have a method to return a set of ports as well

@param ixia_dev: the mapping of hostname to IP address of IXIA devices
@return the management IP address of its neighbor IXIA device or None if we cannot find it
"""
def get_neigh_ixia_mgmt_ip(intf, conn_graph_facts, ixia_dev):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use fanout_graph_facts intead of conn_graph_facts. that will return all the fanouts(ixia chassis) associated with the dut as a dict which will have all the details for each of the fanouts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have used fanout_graph_facts to get chassis/card/port information.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any changes in this method. If we aren't using these, please remove them

Added a new fixture ixia_api_server_session
This class is added to efficiently manage ixia fanout devices
Making ixia directory a package, to access ixia_fixtures.py and ixia_helpers.py
This class is a place holder right now. Ixia fanout devices (chassis) do not require this abstraction layer. Ixia PTF (ixia API server) takes care of all the operation that we can do on the ixia fanout devices (chassis) and hence we execute them via API server only. But it is still nice to have all abstractions in the same location. So future users knows where to find them.
@lgtm-com
Copy link

lgtm-com bot commented Jul 1, 2020

This pull request introduces 3 alerts when merging 7bd3dbd into 1661316 - view on LGTM.com

new alerts:

  • 1 for Missing call to __init__ during object initialization
  • 1 for Syntax error
  • 1 for 'import *' may pollute namespace

Added a new class that should make chassis port management easier
@lgtm-com
Copy link

lgtm-com bot commented Jul 1, 2020

This pull request introduces 2 alerts when merging 84f3201 into 1661316 - view on LGTM.com

new alerts:

  • 1 for Missing call to __init__ during object initialization
  • 1 for 'import *' may pollute namespace

@lgtm-com
Copy link

lgtm-com bot commented Jul 1, 2020

This pull request introduces 6 alerts when merging b91dc5e into 1661316 - view on LGTM.com

new alerts:

  • 3 for Unused import
  • 1 for Unused local variable
  • 1 for Missing call to __init__ during object initialization
  • 1 for 'import *' may pollute namespace

duthost (pytest fixture): The duthost fixture.

Returns:
Ixia PTF server (API server) REST port.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REST port of Ixia API server

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the “PTF Server” from the comment.

@pytest.fixture(scope = "module")
def ixia_api_serv_port(duthost):
"""
Return REST port of the ixia API server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate REST port here? e.g., TCP port for REST API

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed the doc string: "This fixture returns the TCP port for REST API of the ixia API server."

@pytest.fixture(scope = "module")
def ixia_api_serv_session_id(duthost):
"""
Ixia PTF can spawn multiple session on the same REST port.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ixia PTF -> Ixia API server

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the “PTF Server” from the comment.

@pytest.fixture(scope = "module")
def ixia_dev(duthost, fanouthosts):
"""
Returns the Ixia chassis IP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can return multiple IP addresses. We should emphasize this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed the comment section: "This fixture can return multiple IPs if multiple Ixia chassis are present in the test topology."

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to start a new line here

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.


@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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arguments should be aligned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have corrected the alignment according to the PEP-8 guidelines.

fixture.

Returns:
IxNetwork Session Id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should return session instead of session ID

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact this fixture is returning the IxNetwork "session". Return statement in the documentation requires change from "session ID" to session

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected the docstring
Returns: Returns:
IxNetwork Session Id --> IxNetwork Session

Returns:
Ixia PTF server (API server) session id.
"""
return duthost.host.options['variable_manager']._hostvars[duthost.hostname]['secret_group_vars']['ixia_api_server']['session_id']
Copy link
Contributor

Choose a reason for hiding this comment

The 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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Password = ixia_api_serv_passwd,
RestPort = ixia_api_serv_port,
SessionId = ixia_api_serv_session_id,
LogLevel='all')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why loglevel is all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LogLevel='all' is remove from the code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adding loglevel as a function argument?

"""

if (ixia_api_serv_session_id != "None") :
session = SessionAssistant(IpAddress = ixia_api_serv_ip,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Align function arguments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken care aligned the function arguments.

IxNetwork Session Id
"""

if (ixia_api_serv_session_id != "None") :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is "None" rather than None

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can give the value of session_id "None" there, in the configuration file. When session ID is not "None" we connect to given session ID. If it is none then we connect to the respective session ID.

ixNetwork = session.Ixnetwork
ixNetwork.NewConfig()

yield session
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think NewConfig() is unnecessary in this function.

a integer index (starting from 0)

Args:
fanout_data (dict): the dictionary returned by fanout_graph_fact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give a simple example of fanout_data here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have provided an example of fan-out data in the comment section.

Args:
This function takes no argument.

Returns:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returns -> Return

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Google style docstring recommends “Returns” instead of “Return”(https://google.github.io/styleguide/pyguide.html). So, I kept it as it is.

Dictionary of chassis card port information.
"""
retval = []
for ports in self.current_ixia_port_list:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ports -> port

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have change the name from ports to port.

name='Topology 1',
ip_type='ipv4',
ip_start='10.0.0.1',
ip_incr_step='0.0.1.0',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ip_incr_step should be '0.0.0.1'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented.

ip_start='10.0.0.1',
ip_incr_step='0.0.1.0',
gw_start='10.0.0.2',
gw_incr_step='0.0.1.0'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be '0.0.0.0'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented

src_start_port (int): The start port number.
src_port_count (int): The number of ports involved in sending traffic
starting from src_start_port number. Example, if the start port is
port2 and port2 to port5 is sending traffic then src_start_port = 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be 'port2 to port4 are sending'

'example_traffic'.
traffic_type (str, optional): Type of the ip source and destination
(ipv4/ipv6). Default traffic_type is 'ipv4'.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meanings of 'src_first_route_index', 'src_route_count', 'dst_fist_route_index' and 'dst_route_count' are still unclear to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated these comments

@lgtm-com
Copy link

lgtm-com bot commented Jul 21, 2020

This pull request introduces 3 alerts when merging b3970a9 into 64e6f08 - view on LGTM.com

new alerts:

  • 1 for Unused import
  • 1 for Wrong number of arguments in a call
  • 1 for Wrong number of arguments in a class instantiation

Copy link
Contributor

@neethajohn neethajohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some cosmetic comments. Overall looks good. Can you also address the LGTM alerts

@lgtm-com
Copy link

lgtm-com bot commented Jul 22, 2020

This pull request introduces 3 alerts when merging fc12785 into 84f6687 - view on LGTM.com

new alerts:

  • 2 for Wrong name for an argument in a class instantiation
  • 1 for Unused import

@yxieca yxieca merged commit ca0ffd0 into sonic-net:master Jul 25, 2020
kazinator-arista pushed a commit to kazinator-arista/sonic-mgmt that referenced this pull request Mar 4, 2026
57de13b [config] fix interface IPv6 address removal. (sonic-net#1819) (sonic-net#1909)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants