summaryrefslogtreecommitdiff
path: root/framework/tester.py
diff options
context:
space:
mode:
authorYong Liu <yong.liu@intel.com>2014-11-24 23:24:55 +0800
committerYong Liu <yong.liu@intel.com>2014-11-24 23:24:55 +0800
commit344f13ed84ab127c6916f81e70c0df5fd726a2aa (patch)
tree539f4bb9d41e8b6969d4bf5ce29418542f7573e1 /framework/tester.py
parentddbe46a51d4d5352737a1077b25cfe283a4d1fb2 (diff)
Multiple changes for offical release on dpdk.org
- change dcts(DPDK compliance test suite) to dts(DPDK test suite) - Add DTS getting started guide document - add IXIA Tcl scripts - Implement DTF framework class and function descriptions - Fix several issue in test suites - change pmd rxtx function by crbs config - support vfio-pci driver - support verbose output paramter
Diffstat (limited to 'framework/tester.py')
-rw-r--r--framework/tester.py148
1 files changed, 139 insertions, 9 deletions
diff --git a/framework/tester.py b/framework/tester.py
index 96a823f..3554271 100644
--- a/framework/tester.py
+++ b/framework/tester.py
@@ -1,8 +1,36 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Interface for bulk traffic generators.
-
"""
import re
@@ -12,15 +40,16 @@ from ssh_connection import SSHConnection
from crb import Crb
from etgen import IxiaPacketGenerator, SoftwarePacketGenerator
from logger import getLogger
-
-"""
-Start the DPDK traffic generator on the machine `target`.
-A config file and pcap file must have previously been copied
-to this machine.
-"""
+from settings import IXIA
class Tester(Crb):
+
+ """
+ Start the DPDK traffic generator on the machine `target`.
+ A config file and pcap file must have previously been copied
+ to this machine.
+ """
PORT_MAP_CACHE_KEY = 'tester_port_map'
PORT_INFO_CACHE_KEY = 'tester_port_info'
CORE_LIST_CACHE_KEY = 'tester_core_list'
@@ -46,17 +75,51 @@ class Tester(Crb):
self.bgItf = ''
def init_ext_gen(self):
+ """
+ Initialize tester packet generator object.
+ """
if self.it_uses_external_generator():
self.ixia_packet_gen = IxiaPacketGenerator(self)
self.packet_gen = SoftwarePacketGenerator(self)
def get_ip_address(self):
+ """
+ Get ip address of tester CRB.
+ """
return self.crb['tester IP']
+ def has_external_traffic_generator(self):
+ """
+ Check whether performance test will base on IXIA equipment.
+ """
+ try:
+ if self.crb[IXIA] is not None:
+ return True
+ except Exception as e:
+ return False
+
+ return False
+
+ def get_external_traffic_generator(self):
+ """
+ Return IXIA object.
+ """
+ return self.crb[IXIA]
+
def it_uses_external_generator(self):
+ """
+ Check whether IXIA generator is ready for performance test.
+ """
return self.want_perf_tests and self.has_external_traffic_generator()
def tester_prerequisites(self):
+ """
+ Prerequest function should be called before execute any test case.
+ Will call function to scan all lcore's information which on Tester.
+ Then call pci scan function to collect nic device information.
+ Then discovery the network topology and save it into cache file.
+ At last setup DUT' environment for validation.
+ """
self.init_core_list()
self.pci_devices_information()
self.restore_interfaces()
@@ -65,15 +128,27 @@ class Tester(Crb):
assert len(self.ports_map) > 0
def get_local_port(self, remotePort):
+ """
+ Return tester local port connect to specified dut port.
+ """
return self.ports_map[remotePort]
def get_local_port_type(self, remotePort):
+ """
+ Return tester local port type connect to specified dut port.
+ """
return self.ports_info[self.get_local_port(remotePort)]['type']
def get_interface(self, localPort):
+ """
+ Return tester local port interface name.
+ """
return self.ports_info[localPort]['intf']
def get_mac(self, localPort):
+ """
+ Return tester local port mac address.
+ """
if self.ports_info[localPort]['type'] == 'ixia':
return "00:00:00:00:00:01"
else:
@@ -81,7 +156,7 @@ class Tester(Crb):
def get_port_status(self, port):
"""
- return link status of eth
+ Return link status of ethernet.
"""
eth = self.ports_info[port]['intf']
out = self.send_expect("ethtool %s" % eth, "# ")
@@ -96,6 +171,9 @@ class Tester(Crb):
return 'down'
def scan_ports(self):
+ """
+ Scan all ports on tester and save port's pci/mac/interface.
+ """
if self.read_cache:
self.ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
@@ -108,6 +186,9 @@ class Tester(Crb):
self.logger.info(self.ports_info)
def scan_ports_uncached(self):
+ """
+ Return tester port pci/mac/interface information.
+ """
self.ports_info = []
self.logger.warning("Skipped: Unknown kernel interface")
@@ -141,12 +222,18 @@ class Tester(Crb):
'mac': macaddr})
def send_ping6(self, localPort, ipv6, mac):
+ """
+ Send ping6 packet from local port with destination ipv6 address.
+ """
if self.ports_info[localPort]['type'] == 'ixia':
return self.ixia_packet_gen.send_ping6(self.ports_info[localPort]['intf'], mac, ipv6)
else:
return self.send_expect("ping6 -w 5 -c 5 -A -I %s %s" % (self.ports_info[localPort]['intf'], ipv6), "# ", 10)
def map_available_ports(self):
+ """
+ Load or generate network connection mapping list.
+ """
if self.read_cache:
self.ports_map = self.serializer.load(self.PORT_MAP_CACHE_KEY)
@@ -156,6 +243,9 @@ class Tester(Crb):
self.logger.warning("DUT PORT MAP: " + str(self.ports_map))
def map_available_ports_uncached(self):
+ """
+ Generate network connection mapping list.
+ """
nrPorts = len(self.dut.ports_info)
if nrPorts == 0:
@@ -183,11 +273,17 @@ class Tester(Crb):
break
def get_port_numa(self, port):
+ """
+ Return tester local port numa.
+ """
pci = self.ports_info[port]['pci']
out = self.send_expect("cat /sys/bus/pci/devices/0000:%s/numa_node" % pci, "#")
return int(out)
def check_port_list(self, portList, ftype='normal'):
+ """
+ Check specified port is IXIA port or normal port.
+ """
dtype = None
plist = set()
for txPort, rxPort, _ in portList:
@@ -208,9 +304,15 @@ class Tester(Crb):
return True
def scapy_append(self, cmd):
+ """
+ Append command into scapy command list.
+ """
self.scapyCmds.append(cmd)
def scapy_execute(self, timeout=60):
+ """
+ Execute scapy command list.
+ """
self.kill_all()
self.send_expect("scapy", ">>> ")
@@ -227,9 +329,16 @@ class Tester(Crb):
self.send_expect("exit()", "# ")
def scapy_background(self):
+ """
+ Configure scapy running in backgroud mode which mainly purpose is
+ that save RESULT into scapyResult.txt.
+ """
self.inBg = True
def scapy_foreground(self):
+ """
+ Running backgroup scapy and convert to foregroup mode.
+ """
self.send_expect("echo -n '' > scapyResult.txt", "# ")
if self.inBg:
self.scapyCmds.append('f = open(\'scapyResult.txt\',\'w\')')
@@ -249,12 +358,18 @@ class Tester(Crb):
self.inBg = False
def scapy_get_result(self):
+ """
+ Return RESULT which saved in scapyResult.txt.
+ """
out = self.send_expect("cat scapyResult.txt", "# ")
self.logger.info('SCAPY Result:\n' + out + '\n\n\n')
return out.rpartition('[')[0]
def traffic_generator_throughput(self, portList, rate_percent=100, delay=5):
+ """
+ Run throughput performance test on specified ports.
+ """
if self.check_port_list(portList, 'ixia'):
return self.ixia_packet_gen.throughput(portList, rate_percent, delay)
if not self.check_port_list(portList):
@@ -263,6 +378,9 @@ class Tester(Crb):
return self.packet_gen.throughput(portList, rate_percent)
def traffic_generator_loss(self, portList, ratePercent):
+ """
+ Run loss performance test on specified ports.
+ """
if self.check_port_list(portList, 'ixia'):
return self.ixia_packet_gen.loss(portList, ratePercent)
elif not self.check_port_list(portList):
@@ -271,12 +389,18 @@ class Tester(Crb):
return self.packet_gen.loss(portList, ratePercent)
def traffic_generator_latency(self, portList, ratePercent=100, delay=5):
+ """
+ Run latency performance test on specified ports.
+ """
if self.check_port_list(portList, 'ixia'):
return self.ixia_packet_gen.latency(portList, ratePercent, delay)
else:
return None
def extend_external_packet_generator(self, clazz, instance):
+ """
+ Update packet generator function, will implement later.
+ """
if self.it_uses_external_generator():
self.ixia_packet_gen.__class__ = clazz
current_attrs = instance.__dict__
@@ -284,11 +408,17 @@ class Tester(Crb):
instance.__dict__.update(current_attrs)
def kill_all(self):
+ """
+ Kill all scapy process and DPDK applications on tester.
+ """
if not self.has_external_traffic_generator():
self.alt_session.send_expect('killall scapy 2>/dev/null; echo tester', '# ', 5)
super(Tester, self).kill_all()
def close(self):
+ """
+ Close ssh session and IXIA tcl session.
+ """
super(Tester, self).close()
if self.it_uses_external_generator():
self.ixia_packet_gen.close()