diff options
author | Yong Liu <yong.liu@intel.com> | 2014-11-24 23:24:55 +0800 |
---|---|---|
committer | Yong Liu <yong.liu@intel.com> | 2014-11-24 23:24:55 +0800 |
commit | 344f13ed84ab127c6916f81e70c0df5fd726a2aa (patch) | |
tree | 539f4bb9d41e8b6969d4bf5ce29418542f7573e1 /framework/tester.py | |
parent | ddbe46a51d4d5352737a1077b25cfe283a4d1fb2 (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.py | 148 |
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() |