* [dts] [‘dts-v1’ 0/9]
@ 2015-05-18 5:07 sjiajiax
2015-05-18 5:07 ` [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice sjiajiax
` (9 more replies)
0 siblings, 10 replies; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
This patch set includes some virtual modules in the framework
and a suite to test the framework
sjiajiax (9):
Abstract the NIC device as the single class NetDevice
Optimize ssh connection
Add some params and functions related to the virtual test
Add VM class and the virtual DUT class and the virtual resource module
Add qemu-agent-guest for QEMU VM
Add a global virtual configure
add some pmd functions for tester to code the testpmd cases
Add two tar files for ACL testing
Add a suite to test SRIOV mirror with KVM
conf/sriov_kvm.cfg | 77 +++
conf/virt_global.cfg | 24 +
dep/QMP/qemu-ga-client | 299 +++++++++
dep/QMP/qmp.py | 193 ++++++
dep/aclpcap.tgz | Bin 0 -> 82103 bytes
dep/aclrule.tgz | Bin 0 -> 161037 bytes
framework/config.py | 171 ++++-
framework/crb.py | 135 ++--
framework/dts.py | 92 +--
framework/dut.py | 268 +++++++-
framework/exception.py | 27 +
framework/logger.py | 69 +-
framework/main.py | 7 +-
framework/net_device.py | 600 +++++++++++++++++
framework/pmd_output.py | 104 ++-
framework/project_dpdk.py | 62 +-
framework/qemu_kvm.py | 912 +++++++++++++++++++++++++
framework/settings.py | 43 ++
framework/ssh_connection.py | 5 +
framework/ssh_pexpect.py | 63 +-
framework/test_case.py | 3 +-
framework/tester.py | 51 +-
framework/utils.py | 77 +++
framework/virt_base.py | 250 +++++++
framework/virt_dut.py | 239 +++++++
framework/virt_resource.py | 486 ++++++++++++++
test_plans/sriov_kvm_test_plan.rst | 756 +++++++++++++++++++++
tests/TestSuite_sriov_kvm.py | 1291 ++++++++++++++++++++++++++++++++++++
28 files changed, 6062 insertions(+), 242 deletions(-)
create mode 100644 conf/sriov_kvm.cfg
create mode 100644 conf/virt_global.cfg
create mode 100644 dep/QMP/qemu-ga-client
create mode 100644 dep/QMP/qmp.py
create mode 100644 dep/aclpcap.tgz
create mode 100644 dep/aclrule.tgz
mode change 100755 => 100644 framework/config.py
create mode 100644 framework/net_device.py
create mode 100644 framework/qemu_kvm.py
create mode 100644 framework/utils.py
create mode 100644 framework/virt_base.py
create mode 100644 framework/virt_dut.py
create mode 100644 framework/virt_resource.py
create mode 100644 test_plans/sriov_kvm_test_plan.rst
create mode 100644 tests/TestSuite_sriov_kvm.py
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 7:46 ` Xu, HuilongX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 2/9] Optimize ssh connection sjiajiax
` (8 subsequent siblings)
9 siblings, 1 reply; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/crb.py | 135 +++++++----
framework/dut.py | 268 ++++++++++++++++++---
framework/net_device.py | 600 ++++++++++++++++++++++++++++++++++++++++++++++++
framework/settings.py | 43 ++++
framework/test_case.py | 3 +-
framework/tester.py | 51 +++-
6 files changed, 1006 insertions(+), 94 deletions(-)
create mode 100644 framework/net_device.py
diff --git a/framework/crb.py b/framework/crb.py
index a699bfc..2eb2033 100644
--- a/framework/crb.py
+++ b/framework/crb.py
@@ -69,6 +69,12 @@ class Crb(object):
return self.session.send_expect(cmds, expected, timeout, verify)
+ def get_session_output(self, timeout=TIMEOUT):
+ """
+ Get session output message before timeout
+ """
+ return self.session.get_session_before(timeout)
+
def set_test_types(self, func_tests, perf_tests):
"""
Enable or disable function/performance test.
@@ -80,7 +86,9 @@ class Crb(object):
"""
Get the huge page number of CRB.
"""
- huge_pages = self.send_expect("awk '/HugePages_Total/ { print $2 }' /proc/meminfo", "# ")
+ huge_pages = self.send_expect(
+ "awk '/HugePages_Total/ { print $2 }' /proc/meminfo",
+ "# ", alt_session=True)
if huge_pages != "":
return int(huge_pages)
return 0
@@ -115,6 +123,9 @@ class Crb(object):
"""
self.base_dir = base_dir
+ def set_virttype(self, virttype):
+ self.virttype = virttype
+
def admin_ports(self, port, status):
"""
Force set port's interface status.
@@ -127,13 +138,15 @@ class Crb(object):
Force set remote interface link status in FreeBSD.
"""
eth = self.ports_info[port]['intf']
- self.send_expect("ifconfig %s %s" % (eth, status), "# ")
+ self.send_expect("ifconfig %s %s" %
+ (eth, status), "# ", alt_session=True)
def admin_ports_linux(self, eth, status):
"""
Force set remote interface link status in Linux.
"""
- self.send_expect("ip link set %s %s" % (eth, status), "# ")
+ self.send_expect("ip link set %s %s" %
+ (eth, status), "# ", alt_session=True)
def pci_devices_information(self):
"""
@@ -157,8 +170,9 @@ class Crb(object):
"""
Look for the NIC's information (PCI Id and card type).
"""
- out = self.send_expect("lspci -nn | grep -i eth", "# ")
- rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) Ethernet .*?([\da-f]{4}:[\da-f]{4})"
+ out = self.send_expect(
+ "lspci -nn | grep -i eth", "# ", alt_session=True)
+ rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) .*Eth.*?ernet .*?([\da-f]{4}:[\da-f]{4})"
pattern = re.compile(rexp)
match = pattern.findall(out)
self.pci_devices_info = []
@@ -169,7 +183,7 @@ class Crb(object):
"""
Look for the NIC's information (PCI Id and card type).
"""
- out = self.send_expect("pciconf -l", "# ")
+ out = self.send_expect("pciconf -l", "# ", alt_session=True)
rexp = r"pci0:([\da-f]{1,3}:[\da-f]{1,2}:\d{1}):\s*class=0x020000.*chip=0x([\da-f]{4})8086"
pattern = re.compile(rexp)
match = pattern.findall(out)
@@ -179,66 +193,69 @@ class Crb(object):
card_type = "8086:%s" % match[i][1]
self.pci_devices_info.append((match[i][0], card_type))
- def get_interface_name(self, bus_id, devfun_id=''):
- """
- Get interface name of specified pci device.
- """
- get_interface_name = getattr(self, 'get_interface_name_%s' % self.get_os_type())
- return get_interface_name(bus_id, devfun_id)
-
- def get_interface_name_linux(self, bus_id, devfun_id):
+ def get_pci_dev_driver(self, bus_id, devfun_id):
"""
- Get interface name of specified pci device on linux.
+ Get the driver of specified pci device.
"""
- command = 'ls --color=never /sys/bus/pci/devices/0000:%s:%s/net' % (bus_id, devfun_id)
- out = self.send_expect(command, '# ', verify=True)
- if out == -1:
- name = ""
- else:
- name = out.split()[0]
- return name
+ get_pci_dev_driver = getattr(
+ self, 'get_pci_dev_driver_%s' % self.get_os_type())
+ return get_pci_dev_driver(bus_id, devfun_id)
- def get_interface_name_freebsd(self, bus_id, devfun_id):
+ def get_pci_dev_driver_linux(self, bus_id, devfun_id):
"""
- Get interface name of specified pci device on Freebsd.
+ Get the driver of specified pci device on linux.
"""
- out = self.send_expect("pciconf -l", "# ")
- rexp = r"(\w*)@pci0:%s" % bus_id
+ out = self.send_expect("cat /sys/bus/pci/devices/0000\:%s\:%s/uevent" %
+ (bus_id, devfun_id), "# ", alt_session=True)
+ rexp = r"DRIVER=(.+?)\r"
pattern = re.compile(rexp)
- match = pattern.findall(out)
- return match[0]
+ match = pattern.search(out)
+ if not match:
+ return None
+ return match.group(1)
- def get_mac_addr(self, intf, bus_id='', devfun_id=''):
+ def get_pci_dev_driver_freebsd(self, bus_id, devfun_id):
"""
- Get mac address of specified pci device.
+ Get the driver of specified pci device.
"""
- get_mac_addr = getattr(self, 'get_mac_addr_%s' % self.get_os_type())
- return get_mac_addr(intf, bus_id, devfun_id)
+ return True
- def get_mac_addr_linux(self, intf, bus_id, devfun_id):
+ def get_pci_dev_id(self, bus_id, devfun_id):
"""
- Get mac address of specified pci device on linux.
+ Get the pci id of specified pci device.
"""
- command = ('cat /sys/bus/pci/devices/0000:%s:%s/net/%s/address' %
- (bus_id, devfun_id, intf))
- return self.send_expect(command, '# ')
+ get_pci_dev_id = getattr(
+ self, 'get_pci_dev_id_%s' % self.get_os_type())
+ return get_pci_dev_id(bus_id, devfun_id)
- def get_mac_addr_freebsd(self, intf, bus_id, devfun_id):
+ def get_pci_dev_id_linux(self, bus_id, devfun_id):
"""
- Get mac address of specified pci device on Freebsd.
+ Get the pci id of specified pci device on linux.
"""
- out = self.send_expect('ifconfig %s' % intf, '# ')
- rexp = r"ether ([\da-f:]*)"
+ out = self.send_expect("cat /sys/bus/pci/devices/0000\:%s\:%s/uevent" %
+ (bus_id, devfun_id), "# ", alt_session=True)
+ rexp = r"PCI_ID=(.+)"
pattern = re.compile(rexp)
- match = pattern.findall(out)
- return match[0]
+ match = re.search(out)
+ if not match:
+ return None
+ return match.group(1)
def get_device_numa(self, bus_id, devfun_id):
"""
- Get numa id of specified pci device
+ Get numa number of specified pci device.
+ """
+ get_device_numa = getattr(
+ self, "get_device_numa_%s" % self.get_os_type())
+ return get_device_numa(bus_id, devfun_id)
+
+ def get_device_numa_linux(self, bus_id, devfun_id):
+ """
+ Get numa number of specified pci device on Linux.
"""
- numa = self.send_expect("cat /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
- (bus_id, devfun_id), "# ")
+ numa = self.send_expect(
+ "cat /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
+ (bus_id, devfun_id), "# ", alt_session=True)
try:
numa = int(numa)
@@ -259,14 +276,14 @@ class Crb(object):
Get ipv6 address of specified pci device on linux.
"""
out = self.send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
- % intf, "# ")
+ % intf, "# ", alt_session=True)
return out.split('/')[0]
def get_ipv6_addr_freebsd(self, intf):
"""
Get ipv6 address of specified pci device on Freebsd.
"""
- out = self.send_expect('ifconfig %s' % intf, '# ')
+ out = self.send_expect('ifconfig %s' % intf, '# ', alt_session=True)
rexp = r"inet6 ([\da-f:]*)%"
pattern = re.compile(rexp)
match = pattern.findall(out)
@@ -275,6 +292,22 @@ class Crb(object):
return match[0]
+ def disable_ipv6(self, intf):
+ """
+ Disable ipv6 of of specified interface
+ """
+ if intf != 'N/A':
+ self.send_expect("sysctl net.ipv6.conf.%s.disable_ipv6=1" %
+ intf, "# ", alt_session=True)
+
+ def enable_ipv6(self, intf):
+ """
+ Enable ipv6 of of specified interface
+ """
+ if intf != 'N/A':
+ self.send_expect("sysctl net.ipv6.conf.%s.disable_ipv6=0" %
+ intf, "# ", alt_session=True)
+
def create_file(self, contents, fileName):
"""
Create file with contents and copy it to CRB.
@@ -318,7 +351,7 @@ class Crb(object):
if isinstance(self, Dut) and self.get_os_type() == 'freebsd':
expected = 'FreeBSD.*#'
- self.send_expect('uname', expected, 2)
+ self.send_expect('uname', expected, 2, alt_session=True)
def init_core_list(self):
"""
@@ -378,7 +411,9 @@ class Crb(object):
self.cores = []
cpuinfo = \
- self.send_expect("grep \"processor\\|physical id\\|core id\\|^$\" /proc/cpuinfo", "#")
+ self.send_expect(
+ "grep --color=never \"processor\\|physical id\\|core id\\|^$\" /proc/cpuinfo",
+ "#", alt_session=True)
cpuinfo = cpuinfo.split('\r\n\r\n')
for line in cpuinfo:
m = re.search("processor\t: (\d+)\r\n" +
diff --git a/framework/dut.py b/framework/dut.py
index 5b7aba2..247b01c 100644
--- a/framework/dut.py
+++ b/framework/dut.py
@@ -33,11 +33,17 @@ import os
import re
import time
import dts
-from config import UserConf
-from settings import NICS
+import settings
+from config import PortConf
+from settings import NICS, LOG_NAME_SEP
from ssh_connection import SSHConnection
from crb import Crb
+from net_device import NetDevice
from logger import getLogger
+from virt_resource import VirtResource
+from utils import RED
+
+
class Dut(Crb):
@@ -60,20 +66,36 @@ class Dut(Crb):
def __init__(self, crb, serializer):
super(Dut, self).__init__(crb, serializer)
self.NAME = 'dut'
+
+ self.host_init_flag = 0
self.logger = getLogger(self.NAME)
self.session = SSHConnection(self.get_ip_address(), self.NAME,
self.get_password())
self.session.init_log(self.logger)
- self.alt_session = SSHConnection(self.get_ip_address(), self.NAME + '_alt',
- self.get_password())
+ self.alt_session = SSHConnection(
+ self.get_ip_address(),
+ self.NAME + '_alt',
+ self.get_password())
self.alt_session.init_log(self.logger)
self.number_of_cores = 0
self.tester = None
self.cores = []
self.architecture = None
self.ports_info = None
- self.conf = UserConf()
+ self.conf = PortConf()
self.ports_map = []
+ self.virt_pool = None
+
+ def init_host_session(self):
+ if self.host_init_flag:
+ pass
+ else:
+ self.host_session = SSHConnection(
+ self.get_ip_address(),
+ self.NAME + '_host',
+ self.get_password())
+ self.host_session.init_log(self.logger)
+ self.host_init_flag = 1
def change_config_option(self, target, parameter, value):
"""
@@ -82,12 +104,12 @@ class Dut(Crb):
self.send_expect("sed -i 's/%s=.*$/%s=%s/' config/defconfig_%s" %
(parameter, parameter, value, target), "# ")
- def set_nic_type(self, nic):
+ def set_nic_type(self, nic_type):
"""
Set CRB NICS ready to validated.
"""
- self.nic = nic
- if 'cfg' in nic:
+ self.nic_type = nic_type
+ if 'cfg' in nic_type:
self.conf.load_ports_config(self.get_ip_address())
def set_toolchain(self, target):
@@ -167,11 +189,17 @@ class Dut(Crb):
self.mount_procfs()
# auto detect network topology
self.map_available_ports()
+ # disable tester port ipv6
+ self.disable_tester_ipv6()
# print latest ports_info
- self.logger.info(dts.pprint(self.ports_info))
+ for port_info in self.ports_info:
+ self.logger.info(port_info)
if self.ports_map is None or len(self.ports_map) == 0:
raise ValueError("ports_map should not be empty, please check all links")
+ # initialize virtualization resource pool
+ self.virt_pool = VirtResource(self)
+
def restore_interfaces(self):
"""
Restore all ports's interfaces.
@@ -195,20 +223,22 @@ class Dut(Crb):
pci_bus = port['pci']
pci_id = port['type']
# get device driver
- driver = dts.get_nic_driver(pci_id)
+ driver = settings.get_nic_driver(pci_id)
if driver is not None:
# unbind device driver
addr_array = pci_bus.split(':')
bus_id = addr_array[0]
devfun_id = addr_array[1]
+ port = NetDevice(self, bus_id, devfun_id)
+
self.send_expect('echo 0000:%s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind'
% (pci_bus, bus_id, devfun_id), '# ')
# bind to linux kernel driver
self.send_expect('modprobe %s' % driver, '# ')
self.send_expect('echo 0000:%s > /sys/bus/pci/drivers/%s/bind'
% (pci_bus, driver), '# ')
- itf = self.get_interface_name(addr_array[0], addr_array[1])
+ itf = port.get_interface_name()
self.send_expect("ifconfig %s up" % itf, "# ")
else:
self.logger.info("NOT FOUND DRIVER FOR PORT (%s|%s)!!!" % (pci_bus, pci_id))
@@ -228,7 +258,10 @@ class Dut(Crb):
"""
Setup Linux hugepages.
"""
- hugepages_size = self.send_expect("awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
+ if self.virttype == 'xen':
+ return
+ hugepages_size = self.send_expect(
+ "awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
if int(hugepages_size) < (1024 * 1024):
if self.architecture == "x86_64":
@@ -265,6 +298,20 @@ class Dut(Crb):
return 'taskset %s ' % core
+ def is_ssh_session_port(self, pci_bus):
+ """
+ Check if the pci device is the dut SSH session port.
+ """
+ port = None
+ for port_info in self.ports_info:
+ if pci_bus == port_info['pci']:
+ port = port_info['port']
+ break
+ if port and port.get_ipv4_addr() == crbs['IP'].strip():
+ return True
+ else:
+ return False
+
def bind_interfaces_linux(self, driver='igb_uio', nics_to_bind=None):
"""
Bind the interfaces to the selected driver. nics_to_bind can be None
@@ -275,12 +322,17 @@ class Dut(Crb):
current_nic = 0
for (pci_bus, pci_id) in self.pci_devices_info:
- if dts.accepted_nic(pci_id):
+ if settings.accepted_nic(pci_id):
+ if self.is_ssh_session_port(pci_bus):
+ continue
if nics_to_bind is None or current_nic in nics_to_bind:
binding_list += '%s ' % (pci_bus)
current_nic += 1
+ if current_nic == 0:
+ self.logger.info("Not nic need bind driver: %s" % driver)
+ return
self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ')
@@ -293,13 +345,19 @@ class Dut(Crb):
current_nic = 0
for (pci_bus, pci_id) in self.pci_devices_info:
- if dts.accepted_nic(pci_id):
+ if settings.accepted_nic(pci_id):
+ if self.is_ssh_session_port(pci_bus):
+ continue
if nics_to_bind is None or current_nic in nics_to_bind:
binding_list += '%s ' % (pci_bus)
current_nic += 1
+ if current_nic == 0:
+ self.logger.info("Not nic need unbind driver")
+ return
+
self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ', 30)
def get_ports(self, nic_type='any', perf=None, socket=None):
@@ -314,14 +372,17 @@ class Dut(Crb):
perf = self.want_perf_tests
nictypes = []
- if nic_type == 'any':
+ if self.nic_type == 'any':
for portid in range(len(self.ports_info)):
ports.append(portid)
return ports
- elif nic_type == 'cfg':
+ elif self.nic_type == 'cfg':
for portid in range(len(self.ports_info)):
if self.ports_info[portid]['source'] == 'cfg':
- ports.append(portid)
+ if (socket is None or
+ self.ports_info[portid]['numa'] == -1 or
+ socket == self.ports_info[portid]['numa']):
+ ports.append(portid)
return ports
else:
for portid in range(len(self.ports_info)):
@@ -440,36 +501,38 @@ class Dut(Crb):
Check that whether auto scanned ports ready to use
"""
pci_addr = "%s:%s" % (pci_bus, pci_id)
- if self.nic == 'any':
+ if self.nic_type == 'any':
return True
- elif self.nic == 'cfg':
+ elif self.nic_type == 'cfg':
if self.conf.check_port_available(pci_bus) is True:
return True
- elif self.nic not in NICS.keys():
- self.logger.warning("NOT SUPPORTED NIC TYPE: %s" % self.nic)
+ elif self.nic_type not in NICS.keys():
+ self.logger.warning("NOT SUPPORTED NIC TYPE: %s" % self.nic_type)
else:
- codename = NICS[self.nic]
+ codename = NICS[self.nic_type]
if pci_id == codename:
return True
return False
def rescan_ports(self):
- unknow_interface = dts.RED('Skipped: unknow_interface')
+ unknow_interface = RED('Skipped: unknow_interface')
for port_info in self.ports_info:
pci_bus = port_info['pci']
addr_array = pci_bus.split(':')
bus_id = addr_array[0]
devfun_id = addr_array[1]
- intf = self.get_interface_name(bus_id, devfun_id)
+
+ port = NetDevice(self, bus_id, devfun_id)
+ intf = port.get_interface_name()
if "No such file" in intf:
self.logger.info("DUT: [0000:%s] %s" % (pci_bus, unknow_interface))
out = self.send_expect("ip link show %s" % intf, "# ")
if "DOWN" in out:
self.send_expect("ip link set %s up" % intf, "# ")
time.sleep(5)
- macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
+ macaddr = port.get_mac_addr()
out = self.send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
% intf, "# ")
ipv6 = out.split('/')[0]
@@ -481,16 +544,32 @@ class Dut(Crb):
port_info['intf'] = intf
port_info['ipv6'] = ipv6
+ def load_serializer_ports(self):
+ self.ports_info = []
+ cached_ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
+ if cached_ports_info is None:
+ return
+ for port in cached_ports_info:
+ self.ports_info.append({'pci': port['pci'], 'type': port['type'],
+ 'numa': port['numa']})
+
+ def save_serializer_ports(self):
+ cached_ports_info = []
+ for port in self.ports_info:
+ cached_ports_info.append({'pci': port['pci'], 'type': port['type'],
+ 'numa': port['numa']})
+ self.serializer.save(self.PORT_INFO_CACHE_KEY, cached_ports_info)
+
def scan_ports(self):
"""
Scan ports information or just read it from cache file.
"""
if self.read_cache:
- self.ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
+ self.load_serializer_ports()
if not self.read_cache or self.ports_info is None:
self.scan_ports_uncached()
- self.serializer.save(self.PORT_INFO_CACHE_KEY, self.ports_info)
+ self.save_serializer_ports()
def scan_ports_uncached(self):
"""
@@ -505,8 +584,8 @@ class Dut(Crb):
"""
self.ports_info = []
- skipped = dts.RED('Skipped: Unknown/not selected')
- unknow_interface = dts.RED('Skipped: unknow_interface')
+ skipped = RED('Skipped: Unknown/not selected')
+ unknow_interface = RED('Skipped: unknow_interface')
for (pci_bus, pci_id) in self.pci_devices_info:
if self.check_ports_available(pci_bus, pci_id) is False:
@@ -518,9 +597,11 @@ class Dut(Crb):
bus_id = addr_array[0]
devfun_id = addr_array[1]
+ port = NetDevice(self, bus_id, devfun_id)
numa = self.get_device_numa(bus_id, devfun_id)
# store the port info to port mapping
- self.ports_info.append({'pci': pci_bus, 'type': pci_id, 'numa': numa})
+ self.ports_info.append(
+ {'port': port, 'pci': pci_bus, 'type': pci_id, 'numa': numa})
def scan_ports_uncached_freebsd(self):
"""
@@ -528,16 +609,17 @@ class Dut(Crb):
"""
self.ports_info = []
- skipped = dts.RED('Skipped: Unknown/not selected')
+ skipped = RED('Skipped: Unknown/not selected')
for (pci_bus, pci_id) in self.pci_devices_info:
- if not dts.accepted_nic(pci_id):
+ if not setttings.accepted_nic(pci_id):
self.logger.info("DUT: [%s %s] %s" % (pci_bus, pci_id,
skipped))
continue
- intf = self.get_interface_name(pci_bus)
+ port = NetDevice(self, pci_bus, '')
+ intf = port.get_interface_name(pci_bus)
macaddr = self.get_mac_addr(intf)
ipv6 = self.get_ipv6_addr(intf)
@@ -560,9 +642,93 @@ class Dut(Crb):
pci_str = "%s:%s.%s" % (pci_bus_id, pci_dev_str, pci_split[2])
# store the port info to port mapping
- self.ports_info.append({'pci': pci_str, 'type': pci_id, 'intf':
+ self.ports_info.append({'port': port, 'pci': pci_str, 'type': pci_id, 'intf':
intf, 'mac': macaddr, 'ipv6': ipv6, 'numa': -1})
+ def generate_sriov_vfs_by_port(self, port_id, vf_num, driver='default'):
+ """
+ Generate SRIOV VFs with default driver it is bound now or specifid driver.
+ """
+ port = self.ports_info[port_id]['port']
+ port_driver = port.get_nic_driver()
+
+ if driver == 'default':
+ if not port_driver:
+ self.logger.info(
+ "No driver on specified port, can not generate SRIOV VF.")
+ return None
+ else:
+ if port_driver != driver:
+ port.bind_driver(driver)
+ port.generate_sriov_vfs(vf_num)
+
+ # append the VF PCIs into the ports_info
+ sriov_vfs_pci = port.get_sriov_vfs_pci()
+ self.ports_info[port_id]['sriov_vfs_pci'] = sriov_vfs_pci
+
+ # instantiate the VF with NetDevice
+ vfs_port = []
+ for vf_pci in sriov_vfs_pci:
+ addr_array = vf_pci.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+ vf_port = NetDevice(self, bus_id, devfun_id)
+ vfs_port.append(vf_port)
+ self.ports_info[port_id]['vfs_port'] = vfs_port
+
+ pci = self.ports_info[port_id]['pci']
+ self.virt_pool.add_vf_on_pf(pf_pci=pci, vflist=sriov_vfs_pci)
+
+ def destroy_sriov_vfs_by_port(self, port_id):
+ port = self.ports_info[port_id]['port']
+ vflist = []
+ port_driver = port.get_nic_driver()
+ if 'sriov_vfs_pci' in self.ports_info[port_id] and \
+ self.ports_info[port_id]['sriov_vfs_pci']:
+ vflist = self.ports_info[port_id]['sriov_vfs_pci']
+ else:
+ if not port.get_sriov_vfs_pci():
+ return
+
+ if not port_driver:
+ self.logger.info(
+ "No driver on specified port, skip destroy SRIOV VF.")
+ else:
+ sriov_vfs_pci = port.destroy_sriov_vfs()
+ self.ports_info[port_id]['sriov_vfs_pci'] = []
+ self.ports_info[port_id]['vfs_port'] = []
+
+ pci = self.ports_info[port_id]['pci']
+ self.virt_pool.del_vf_on_pf(pf_pci=pci, vflist=vflist)
+
+ def get_vm_core_list(self):
+ return VMCORELIST[self.crb['VM CoreList']]
+
+ def create_blacklist_string(self, target, nic):
+ create_blacklist_string = getattr(
+ self, 'create_blacklist_string_%s' % self.get_os_type())
+ return create_blacklist_string(target, nic)
+
+ def create_blacklist_string_linux(self, target, nic):
+ blacklist = ''
+ dutPorts = self.get_ports(nic)
+ self.restore_interfaces()
+ if dts.drivername == "igb_uio":
+ self.send_expect('insmod ./%s/kmod/igb_uio.ko ' % target, '# ')
+ elif dts.drivername == "vfio-pci":
+ self.send_expect("modprobe vfio", '# ')
+ self.send_expect("modprobe vfio-pci", '# ')
+ self.bind_interfaces_linux(dts.drivername)
+ for port in range(0, len(self.ports_info)):
+ if(port not in dutPorts):
+ blacklist += '-b 0000:%s ' % self.ports_info[port]['pci']
+ return blacklist
+
+ def create_blacklist_string_freebsd(self, target, nic):
+ blacklist = ''
+ # No blacklist option in FreeBSD
+ return blacklist
+
def load_portconf(self):
"""
Load port configurations for ports_info. If manually configured infor
@@ -637,7 +803,11 @@ class Dut(Crb):
if ipv6 == "Not connected":
continue
- out = self.tester.send_ping6(remotePort, ipv6, self.get_mac_address(dutPort))
+ if getattr(self, 'send_ping6', None):
+ self.send_ping6(
+ dutPort, self.tester.ports_info[remotePort]['ipv6'])
+ out = self.tester.send_ping6(
+ remotePort, ipv6, self.get_mac_address(dutPort))
if ('64 bytes from' in out):
self.logger.info("PORT MAP: [dut %d: tester %d]" % (dutPort, remotePort))
@@ -656,3 +826,31 @@ class Dut(Crb):
for port in remove:
self.ports_info.remove(port)
+
+ def disable_tester_ipv6(self):
+ for tester_port in self.ports_map:
+ intf = self.tester.get_interface(tester_port)
+ self.tester.disable_ipv6(intf)
+
+ def enable_tester_ipv6(self):
+ for tester_port in self.ports_map:
+ intf = self.tester.get_interface(tester_port)
+ self.tester.enable_ipv6(intf)
+
+ def check_port_occupied(self, port):
+ out = self.alt_session.send_expect('lsof -i:%d' % port, '# ')
+ if out == '':
+ return False
+ else:
+ return True
+
+ def get_maximal_vnc_num(self):
+ out = self.send_expect("ps aux | grep '\-vnc' | grep -v grep", '# ')
+ if out:
+ ports = re.findall(r'-vnc .*?:(\d+)', out)
+ for num in range(len(ports)):
+ ports[num] = int(ports[num])
+ ports.sort()
+ else:
+ ports = [0, ]
+ return ports[-1]
diff --git a/framework/net_device.py b/framework/net_device.py
new file mode 100644
index 0000000..c04d442
--- /dev/null
+++ b/framework/net_device.py
@@ -0,0 +1,600 @@
+import os
+import re
+from functools import wraps
+import time
+import pdb
+
+import settings
+from crb import Crb
+from settings import TIMEOUT
+
+
+class NetDevice(object):
+
+ """
+ Abstract the device which is PF or VF.
+ """
+
+ def __init__(self, crb, bus_id, devfun_id):
+ if not isinstance(crb, Crb):
+ raise Exception(" Please input the instance of Crb!!!")
+ self.crb = crb
+ self.bus_id = bus_id
+ self.devfun_id = devfun_id
+ self.pci = bus_id + ':' + devfun_id
+ self.pci_id = self.get_pci_id(bus_id, devfun_id)
+ self.default_driver = settings.get_nic_driver(self.pci_id)
+ # bind to default driver
+ current_driver = self.get_nic_driver()
+ if self.default_driver != current_driver:
+ self.bind_driver()
+ if self.nic_is_pf():
+ self.default_vf_driver = ''
+ self.intf_name = self.get_interface_name()
+
+ def __send_expect(self, cmds, expected, timeout=TIMEOUT, alt_session=True):
+ """
+ Wrap the crb`s session as private session for sending expect.
+ """
+ return self.crb.send_expect(cmds, expected, timeout=timeout, alt_session=alt_session)
+
+ def __get_os_type(self):
+ """
+ Get OS type.
+ """
+ return self.crb.get_os_type()
+
+ def nic_is_pf(self):
+ """
+ It is the method that you can check if the nic is PF.
+ """
+ return True
+
+ def nic_has_driver(func):
+ """
+ Check if the NIC has a driver.
+ """
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ nic_instance = args[0]
+ nic_instance.current_driver = nic_instance.get_nic_driver()
+ if not nic_instance.current_driver:
+ return ''
+ return func(*args, **kwargs)
+ return wrapper
+
+ def get_nic_driver(self):
+ """
+ Get the NIC driver.
+ """
+ return self.crb.get_pci_dev_driver(self.bus_id, self.devfun_id)
+
+ @nic_has_driver
+ def get_interface_name(self):
+ """
+ Get interface name of specified pci device.
+ """
+ get_interface_name = getattr(
+ self, 'get_interface_name_%s' %
+ self.__get_os_type())
+ return get_interface_name(self.bus_id, self.devfun_id, self.current_driver)
+
+ def get_interface_name_linux(self, bus_id, devfun_id, driver):
+ """
+ Get interface name of specified pci device on linux.
+ """
+ try:
+ get_interface_name_linux = getattr(
+ self,
+ 'get_interface_name_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_interface_name_linux = getattr(self,
+ 'get_interface_name_linux_%s' % generic_driver)
+
+ return get_interface_name_linux(bus_id, devfun_id)
+
+ def get_interface_name_linux_generic(self, bus_id, devfun_id):
+ """
+ Get the interface name by the default way on linux.
+ """
+ command = 'ls --color=never /sys/bus/pci/devices/0000\:%s\:%s/net' % (
+ bus_id, devfun_id)
+ return self.__send_expect(command, '# ')
+
+ def get_interface_name_freebsd(self, bus_id, devfun_id, driver):
+ """
+ Get interface name of specified pci device on Freebsd.
+ """
+ try:
+ get_interface_name_linux = getattr(self,
+ 'get_interface_name_freebsd_%s' % driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_interface_name_linux = getattr(self,
+ 'get_interface_name_freebsd_%s' % generic_driver)
+
+ return get_interface_name_freebsd(bus_id, devfun_id)
+
+ def get_interface_name_freebsd_generic(self, bus_id, devfun_id):
+ """
+ Get the interface name by the default way on freebsd.
+ """
+ out = self.__send_expect("pciconf -l", "# ")
+ rexp = r"(\w*)@pci0:%s" % bus_id
+ pattern = re.compile(rexp)
+ match = pattern.findall(out)
+ return match[0]
+
+ @nic_has_driver
+ def get_mac_addr(self):
+ """
+ Get mac address of specified pci device.
+ """
+ get_mac_addr = getattr(self, 'get_mac_addr_%s' % self.__get_os_type())
+ return get_mac_addr(self.intf_name, self.bus_id, self.devfun_id, self.current_driver)
+
+ def get_mac_addr_linux(self, intf, bus_id, devfun_id, driver):
+ """
+ Get mac address of specified pci device on linux.
+ """
+ try:
+ get_mac_addr_linux = getattr(
+ self,
+ 'get_mac_addr_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_mac_addr_linux = getattr(
+ self,
+ 'get_mac_addr_linux_%s' %
+ generic_driver)
+
+ return get_mac_addr_linux(intf, bus_id, devfun_id, driver)
+
+ def get_pci_id(self, bus_id, devfun_id):
+ command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/vendor' %
+ (bus_id, devfun_id))
+ out = self.__send_expect(command, '# ')
+ vender = out[2:]
+ command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/device' %
+ (bus_id, devfun_id))
+ out = self.__send_expect(command, '# ')
+ device = out[2:]
+ return "%s:%s" % (vender, device)
+
+ def get_mac_addr_linux_generic(self, intf, bus_id, devfun_id, driver):
+ """
+ Get MAC by the default way on linux.
+ """
+ command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/net/%s/address' %
+ (bus_id, devfun_id, intf))
+ return self.__send_expect(command, '# ')
+
+ def get_mac_addr_freebsd(self, intf, bus_id, devfun_id, driver):
+ """
+ Get mac address of specified pci device on Freebsd.
+ """
+ try:
+ get_mac_addr_freebsd = getattr(
+ self,
+ 'get_mac_addr_freebsd_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_mac_addr_freebsd = getattr(
+ self,
+ 'get_mac_addr_freebsd_%s' %
+ generic_driver)
+
+ return get_mac_addr_freebsd(intf, bus_id, devfun_id, driver)
+
+ def get_mac_addr_freebsd_generic(self, intf, bus_id, devfun_id):
+ """
+ Get the MAC by the default way on Freebsd.
+ """
+ out = self.__send_expect('ifconfig %s' % intf, '# ')
+ rexp = r"ether ([\da-f:]*)"
+ pattern = re.compile(rexp)
+ match = pattern.findall(out)
+ return match[0]
+
+ @nic_has_driver
+ def get_ipv4_addr(self):
+ """
+ Get ipv4 address of specified pci device.
+ """
+ get_ipv4_addr = getaddr(
+ self, 'get_ipv4_addr_%s' % self.__get_os_type())
+ return get_ipv4_addr(self.intf_name, self.currenct_driver)
+
+ def get_ipv4_addr_linux(self, intf, driver):
+ """
+ Get ipv4 address of specified pci device on linux.
+ """
+ try:
+ get_ipv4_addr_linux = getattr(self, 'get_ipv4_linux_%s' % driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_ipv4_addr_linux = getattr(
+ self, 'get_ipv4_linux_%s' %
+ generic_driver)
+
+ return get_ipv4_addr_linux(intf, bus_id, devfun_id, driver)
+
+ def get_ipv4_addr_linux_generic(self, intf):
+ """
+ Get IPv4 address by the default way on linux.
+ """
+ out = self.__send_expect("ip -family inet address show dev %s | awk '/inet/ { print $2 }'"
+ % intf, "# ")
+ return out.split('/')[0]
+
+ def get_ipv4_addr_freebsd(self, intf, driver):
+ """
+ Get ipv4 address of specified pci device on Freebsd.
+ """
+ try:
+ get_ipv4_addr_freebsd = getattr(
+ self,
+ 'get_ipv4_addr_freebsd_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_ipv4_addr_freebsd = getattr(
+ self,
+ 'get_ipv4_addr_freebsd_%s' %
+ generic_driver)
+
+ return get_ipv4_addr_freebsd(intf, bus_id, devfun_id)
+
+ def get_ipv4_addr_freebsd_generic(self, intf):
+ """
+ Get the IPv4 address by the default way on Freebsd.
+ """
+ out = self.__send_expect('ifconfig %s' % intf, '# ')
+ rexp = r"inet ([\d:]*)%"
+ pattern = re.compile(rexp)
+ match = pattern.findall(out)
+ if len(match) == 0:
+ return None
+
+ return match[0]
+
+ @nic_has_driver
+ def get_ipv6_addr(self):
+ """
+ Get ipv6 address of specified pci device.
+ """
+ get_ipv6_addr = getattr(
+ self, 'get_ipv6_addr_%s' % self.__get_os_type())
+ return get_ipv6_addr(self.intf_name, self.current_driver)
+
+ def get_ipv6_addr_linux(self, intf, driver):
+ """
+ Get ipv6 address of specified pci device on linux.
+ """
+ try:
+ get_ipv6_addr_linux = getattr(
+ self,
+ 'get_ipv6_addr_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_ipv6_addr_linux = getattr(
+ self,
+ 'get_ipv6_addr_linux_%s' %
+ generic_driver)
+
+ return get_ipv6_addr_linux(intf)
+
+ def get_ipv6_addr_linux_generic(self, intf):
+ """
+ Get the IPv6 address by the default way on linux.
+ """
+ out = self.__send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
+ % intf, "# ")
+ return out.split('/')[0]
+
+ def get_ipv6_addr_freebsd(self, intf, driver):
+ """
+ Get ipv6 address of specified pci device on Freebsd.
+ """
+ try:
+ get_ipv6_addr_freebsd = getattr(
+ self,
+ 'get_ipv6_addr_freebsd_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_ipv6_addr_freebsd = getattr(
+ self,
+ 'get_ipv6_addr_freebsd_%s' %
+ generic_driver)
+
+ return get_ipv6_addr_freebsd(intf)
+
+ def get_ipv6_addr_freebsd_generic(self, intf):
+ """
+ Get the IPv6 address by the default way on Freebsd.
+ """
+ out = self.__send_expect('ifconfig %s' % intf, '# ')
+ rexp = r"inet6 ([\da-f:]*)%"
+ pattern = re.compile(rexp)
+ match = pattern.findall(out)
+ if len(match) == 0:
+ return None
+
+ return match[0]
+
+ def get_nic_numa(self):
+ """
+ Get numa number of specified pci device.
+ """
+ self.crb.get_nic_numa(self.bus_id, self.devfun_id)
+
+ def get_card_type(self):
+ """
+ Get card type of specified pci device.
+ """
+ return self.crb.get_pci_dev_id(self.bus_id, self.devfun_id)
+
+ @nic_has_driver
+ def get_sriov_vfs_pci(self):
+ """
+ Get all SRIOV VF pci bus of specified pci device.
+ """
+ get_sriov_vfs_pci = getattr(
+ self, 'get_sriov_vfs_pci_%s' % self.__get_os_type())
+ return get_sriov_vfs_pci(self.bus_id, self.devfun_id, self.current_driver)
+
+ def get_sriov_vfs_pci_linux(self, bus_id, devfun_id, driver):
+ """
+ Get all SRIOV VF pci bus of specified pci device on linux.
+ """
+ try:
+ get_sriov_vfs_pci_linux = getattr(
+ self,
+ 'get_sriov_vfs_pci_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_sriov_vfs_pci_linux = getattr(
+ self,
+ 'get_sriov_vfs_pci_linux_%s' %
+ generic_driver)
+
+ return get_sriov_vfs_pci_linux(bus_id, devfun_id)
+
+ def get_sriov_vfs_pci_linux_generic(self, bus_id, devfun_id):
+ """
+ Get all the VF PCIs of specified PF by the default way on linux.
+ """
+ sriov_numvfs = self.__send_expect(
+ "cat /sys/bus/pci/devices/0000\:%s\:%s/sriov_numvfs" %
+ (bus_id, devfun_id), "# ")
+ sriov_vfs_pci = []
+ if int(sriov_numvfs) == 0:
+ pass
+ else:
+ try:
+ virtfns = self.__send_expect(
+ "ls -d /sys/bus/pci/devices/0000\:%s\:%s/virtfn*" %
+ (bus_id, devfun_id), "# ")
+ for virtfn in virtfns.split():
+ vf_uevent = self.__send_expect(
+ "cat %s" %
+ os.path.join(virtfn, "uevent"), "# ")
+ vf_pci = re.search(
+ r"PCI_SLOT_NAME=0000:([0-9a-f]+:[0-9a-f]+\.[0-9a-f]+)",
+ vf_uevent).group(1)
+ sriov_vfs_pci.append(vf_pci)
+ except Exception as e:
+ print "Scan linux port [0000:%s.%s] sriov vf failed: %s" % (bus_id, devfun_id, e)
+
+ return sriov_vfs_pci
+
+ @nic_has_driver
+ def generate_sriov_vfs(self, vf_num):
+ """
+ Generate some numbers of SRIOV VF.
+ """
+ if vf_num == 0:
+ self.bind_vf_driver()
+ generate_sriov_vfs = getattr(
+ self, 'generate_sriov_vfs_%s' %
+ self.__get_os_type())
+ generate_sriov_vfs(
+ self.bus_id,
+ self.devfun_id,
+ vf_num,
+ self.current_driver)
+ if vf_num != 0:
+ self.sriov_vfs_pci = self.get_sriov_vfs_pci()
+
+ vf_pci = self.sriov_vfs_pci[0]
+ addr_array = vf_pci.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+
+ self.default_vf_driver = self.crb.get_pci_dev_driver(
+ bus_id, devfun_id)
+ else:
+ self.sriov_vfs_pci = []
+ time.sleep(1)
+
+ def generate_sriov_vfs_linux(self, bus_id, devfun_id, vf_num, driver):
+ """
+ Generate some numbers of SRIOV VF.
+ """
+ try:
+ generate_sriov_vfs_linux = getattr(
+ self,
+ 'generate_sriov_vfs_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ generate_sriov_vfs_linux = getattr(
+ self,
+ 'generate_sriov_vfs_linux_%s' %
+ generic_driver)
+
+ return generate_sriov_vfs_linux(bus_id, devfun_id, vf_num)
+
+ def generate_sriov_vfs_linux_generic(self, bus_id, devfun_id, vf_num):
+ """
+ Generate SRIOV VFs by the default way on linux.
+ """
+ nic_driver = self.get_nic_driver()
+
+ if not nic_driver:
+ return None
+
+ vf_reg_file = "sriov_numvfs"
+ vf_reg_path = os.path.join("/sys/bus/pci/devices/0000:%s:%s" %
+ (bus_id, devfun_id), vf_reg_file)
+ self.__send_expect("echo %d > %s" %
+ (int(vf_num), vf_reg_path), "# ")
+
+ def generate_sriov_vfs_linux_igb_uio(self, bus_id, devfun_id, vf_num):
+ """
+ Generate SRIOV VFs by the special way of igb_uio driver on linux.
+ """
+ nic_driver = self.get_nic_driver()
+
+ if not nic_driver:
+ return None
+
+ vf_reg_file = "max_vfs"
+ vf_reg_path = os.path.join("/sys/bus/pci/devices/0000:%s:%s" %
+ (bus_id, devfun_id), vf_reg_file)
+ self.__send_expect("echo %d > %s" %
+ (int(vf_num), vf_reg_path), "# ")
+
+ def destroy_sriov_vfs(self):
+ """
+ Destroy the SRIOV VFs.
+ """
+ self.generate_sriov_vfs(0)
+
+ def bind_vf_driver(self, pci='', driver=''):
+ """
+ Bind the specified driver to VF.
+ """
+ bind_vf_driver = getattr(self, 'bind_driver_%s' % self.__get_os_type())
+ if not driver:
+ if not self.default_vf_driver:
+ print "Must specify a driver because default VF driver is NULL!"
+ return
+ driver = self.default_vf_driver
+
+ if not pci:
+ if not self.sriov_vfs_pci:
+ print "No VFs on the nic [%s]!" % self.pci
+ return
+ for vf_pci in self.sriov_vfs_pci:
+ addr_array = vf_pci.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+
+ bind_vf_driver(bus_id, devfun_id, driver)
+ else:
+ addr_array = pci.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+
+ bind_vf_driver(bus_id, devfun_id, driver)
+
+ def bind_driver(self, driver=''):
+ """
+ Bind specified driver to PF.
+ """
+ bind_driver = getattr(self, 'bind_driver_%s' % self.__get_os_type())
+ if not driver:
+ if not self.default_driver:
+ print "Must specify a driver because default driver is NULL!"
+ return
+ driver = self.default_driver
+ ret = bind_driver(self.bus_id, self.devfun_id, driver)
+ time.sleep(1)
+ return ret
+
+ def bind_driver_linux(self, bus_id, devfun_id, driver):
+ """
+ Bind NIC port to specified driver on linux.
+ """
+ driver_alias = driver.replace('-', '_')
+ try:
+ bind_driver_linux = getattr(
+ self,
+ 'bind_driver_linux_%s' %
+ driver_alias)
+ return bind_driver_linux(bus_id, devfun_id)
+ except Exception as e:
+ driver_alias = 'generic'
+ bind_driver_linux = getattr(
+ self,
+ 'bind_driver_linux_%s' %
+ driver_alias)
+ return bind_driver_linux(bus_id, devfun_id, driver)
+
+ def bind_driver_linux_generic(self, bus_id, devfun_id, driver):
+ """
+ Bind NIC port to specified driver by the default way on linux.
+ """
+ nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind" %
+ (nic_pci_num, bus_id, devfun_id), "# ")
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/drivers/%s/bind" %
+ (nic_pci_num, driver), "# ")
+
+ def bind_driver_linux_pci_stub(self, bus_id, devfun_id):
+ """
+ Bind NIC port to the pci-stub driver on linux.
+ """
+ nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
+ pci_id = self.get_card_type()
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/drivers/pci-stub/new_id" %
+ nic_pci_num, "# ")
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind" %
+ (nic_pci_num, bus_id, devfun_id), "# ")
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/drivers/pci-stub/bind" %
+ nic_pci_num, "# ")
+
+ @nic_has_driver
+ def unbind_driver(self, driver=''):
+ """
+ Unbind driver.
+ """
+ unbind_driver = getattr(
+ self, 'unbind_driver_%s' %
+ self.__get_os_type())
+ if not driver:
+ driver = 'generic'
+ ret = unbind_driver(self.bus_id, self.devfun_id, driver)
+ time.sleep(1)
+ return ret
+
+ def unbind_driver_linux(self, bus_id, devfun_id, driver):
+ """
+ Unbind driver on linux.
+ """
+ driver_alias = driver.replace('-', '_')
+
+ unbind_driver_linux = getattr(
+ self, 'unbind_driver_linux_%s' % driver_alias)
+ return unbind_driver_linux(bus_id, devfun_id)
+
+ def unbind_driver_linux_generic(self, bus_id, devfun_id):
+ """
+ Unbind driver by the default way on linux.
+ """
+ nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
+ cmd = "echo %s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind"
+ self.send_expect(cmd % (nic_pci_num, bus_id, devfun_id), "# ")
diff --git a/framework/settings.py b/framework/settings.py
index feb6fa5..2eccc64 100644
--- a/framework/settings.py
+++ b/framework/settings.py
@@ -48,6 +48,7 @@ NICS = {
'powerville': '8086:1521',
'ophir': '8086:105e',
'niantic': '8086:10fb',
+ 'niantic_vf': '8086:10ed',
'ironpond': '8086:151c',
'twinpond': '8086:1528',
'twinville': '8086:1512',
@@ -77,6 +78,7 @@ DRIVERS = {
'powerville': 'igb',
'ophir': 'igb',
'niantic': 'ixgbe',
+ 'niantic_vf': 'ixgbevf',
'ironpond': 'ixgbe',
'twinpond': 'ixgbe',
'twinville': 'ixgbe',
@@ -137,6 +139,17 @@ Global macro for dts.
"""
IXIA = "ixia"
+"""
+The root path of framework configs.
+"""
+CONFIG_ROOT_PATH = "./conf/"
+
+"""
+The log name seperater.
+"""
+LOG_NAME_SEP = '.'
+
+
def nic_name_from_type(type):
"""
strip nic code name by nic type
@@ -145,3 +158,33 @@ def nic_name_from_type(type):
if nic_type == type:
return name
return 'Unknown'
+
+
+def get_nic_driver(pci_id):
+ """
+ Return linux driver for specified pci device
+ """
+ driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
+ try:
+ driver = DRIVERS[driverlist[pci_id]]
+ except Exception as e:
+ driver = None
+ return driver
+
+
+def accepted_nic(pci_id):
+ """
+ Return True if the pci_id is a known NIC card in the settings file and if
+ it is selected in the execution file, otherwise it returns False.
+ """
+ if pci_id not in NICS.values():
+ return False
+
+ if nic is 'any':
+ return True
+
+ else:
+ if pci_id == NICS[nic]:
+ return True
+
+ return False
diff --git a/framework/test_case.py b/framework/test_case.py
index 3d2e2dc..a519691 100644
--- a/framework/test_case.py
+++ b/framework/test_case.py
@@ -40,10 +40,11 @@ from settings import DRIVERS, NICS, nic_name_from_type
class TestCase(object):
- def __init__(self, dut, tester, target):
+ def __init__(self, dut, tester, target, suite):
self.dut = dut
self.tester = tester
self.target = target
+ self.suite = suite
self.nics = []
for portid in range(len(self.dut.ports_info)):
nic_type = self.dut.ports_info[portid]['type']
diff --git a/framework/tester.py b/framework/tester.py
index aba0356..ce136e4 100644
--- a/framework/tester.py
+++ b/framework/tester.py
@@ -38,6 +38,7 @@ from time import sleep
from settings import NICS
from ssh_connection import SSHConnection
from crb import Crb
+from net_device import NetDevice
from etgen import IxiaPacketGenerator, SoftwarePacketGenerator
from logger import getLogger
from settings import IXIA
@@ -152,6 +153,7 @@ class Tester(Crb):
index += 1
if pci == port['pci']:
return index
+ return -1
def get_pci(self, localPort):
"""
@@ -163,6 +165,9 @@ class Tester(Crb):
"""
Return tester local port interface name.
"""
+ if 'intf' not in self.ports_info[localPort]:
+ return 'N/A'
+
return self.ports_info[localPort]['intf']
def get_mac(self, localPort):
@@ -202,26 +207,51 @@ class Tester(Crb):
try:
for (pci_bus, pci_id) in self.pci_devices_info:
addr_array = pci_bus.split(':')
- itf = self.get_interface_name(addr_array[0], addr_array[1])
+ port = NetDevice(self, addr_array[0], addr_array[1])
+ itf = port.get_interface_name()
+ self.enable_ipv6(itf)
self.send_expect("ifconfig %s up" % itf, "# ")
except Exception as e:
self.logger.error(" !!! Restore ITF: " + e.message)
+ sleep(2)
+
+ def load_serializer_ports(self):
+ self.ports_info = []
+ cached_ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
+ if cached_ports_info is None:
+ return
+
+ # now not save netdev object, will implemented later
+ self.ports_info = cached_ports_info
+
+ def save_serializer_ports(self):
+ cached_ports_info = []
+ for port in self.ports_info:
+ port_info = {}
+ for key in port.keys():
+ if type(port[key]) is str:
+ port_info[key] = port[key]
+ # need save netdev objects
+ cached_ports_info.append(port_info)
+ self.serializer.save(self.PORT_INFO_CACHE_KEY, cached_ports_info)
+
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)
+ self.load_serializer_ports()
if not self.read_cache or self.ports_info is None:
self.scan_ports_uncached()
if self.it_uses_external_generator():
self.ports_info.extend(self.ixia_packet_gen.get_ports())
- self.serializer.save(self.PORT_INFO_CACHE_KEY, self.ports_info)
+ self.save_serializer_ports()
- self.logger.info(self.ports_info)
+ for port_info in self.ports_info:
+ self.logger.info(port_info)
def scan_ports_uncached(self):
"""
@@ -240,7 +270,8 @@ class Tester(Crb):
bus_id = addr_array[0]
devfun_id = addr_array[1]
- intf = self.get_interface_name(bus_id, devfun_id)
+ port = NetDevice(self, bus_id, devfun_id)
+ intf = port.get_interface_name()
if "No such file" in intf:
self.logger.info("Tester: [000:%s %s] %s" % (pci_bus, pci_id,
@@ -248,13 +279,17 @@ class Tester(Crb):
continue
self.logger.info("Tester: [000:%s %s] %s" % (pci_bus, pci_id, intf))
- macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
+ macaddr = port.get_mac_addr()
+
+ ipv6 = port.get_ipv6_addr()
# store the port info to port mapping
- self.ports_info.append({'pci': pci_bus,
+ self.ports_info.append({'port': port,
+ 'pci': pci_bus,
'type': pci_id,
'intf': intf,
- 'mac': macaddr})
+ 'mac': macaddr,
+ 'ipv6': ipv6})
def send_ping6(self, localPort, ipv6, mac):
"""
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 2/9] Optimize ssh connection
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
2015-05-18 5:07 ` [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 7:06 ` Liu, Yong
2015-05-18 5:07 ` [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test sjiajiax
` (7 subsequent siblings)
9 siblings, 1 reply; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Optimize configure parse
Move some functions in dts to an common utils module
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/config.py | 171 +++++++++++++++++++++++++++++++++++---------
framework/ssh_connection.py | 5 ++
framework/ssh_pexpect.py | 63 +++++++++++++---
framework/utils.py | 77 ++++++++++++++++++++
4 files changed, 270 insertions(+), 46 deletions(-)
mode change 100755 => 100644 framework/config.py
create mode 100644 framework/utils.py
diff --git a/framework/config.py b/framework/config.py
old mode 100755
new mode 100644
index d2548e8..927c846
--- a/framework/config.py
+++ b/framework/config.py
@@ -37,45 +37,133 @@ import re
import ConfigParser # config parse module
import argparse # prase arguments module
-portconf = "conf/ports.cfg"
-crbconf = "conf/crbs.cfg"
+PORTCONF = "conf/ports.cfg"
+CRBCONF = "conf/crbs.cfg"
+VIRTCONF = "conf/virt_global.cfg"
class UserConf():
- def __init__(self, port_conf=portconf, crb_conf=crbconf):
- self.port_config = port_conf
- self.crb_config = crb_conf
+ def __init__(self, config):
+ self.conf = ConfigParser.SafeConfigParser()
+ load_files = self.conf.read(config)
+ if load_files == []:
+ print "FAILED LOADING %s!!!" % config
+ self.conf = None
+ raise
+
+ def get_sections(self):
+ if self.conf is None:
+ return None
+
+ return self.conf.sections()
+
+ def load_section(self, section):
+ if self.conf is None:
+ return None
+
+ items = None
+ for conf_sect in self.conf.sections():
+ if conf_sect == section:
+ items = self.conf.items(section)
+
+ return items
+
+ def load_config(self, item):
+ confs = [conf.strip() for conf in item.split(';')]
+ if '' in confs:
+ confs.remove('')
+ return confs
+
+ def load_param(self, conf):
+ paramDict = dict()
+
+ for param in conf.split(','):
+ (key, _, value) = param.partition('=')
+ paramDict[key] = value
+ return paramDict
+
+
+class VirtConf(UserConf):
+
+ def __init__(self, virt_conf=VIRTCONF):
+ self.config_file = virt_conf
+ self.virt_cfg = {}
+ try:
+ self.virt_conf = UserConf(self.config_file)
+ except Exception as e:
+ print "FAILED LOADING VIRT CONFIG!!!"
+ self.virt_conf = None
+
+ def load_virt_config(self, name):
+ self.virt_cfgs = []
+
+ try:
+ virt_confs = self.virt_conf.load_section(name)
+ except:
+ print "FAILED FIND SECTION %s!!!" % name
+ return
+
+ for virt_conf in virt_confs:
+ virt_cfg = {}
+ virt_params = []
+ key, config = virt_conf
+ confs = self.virt_conf.load_config(config)
+ for config in confs:
+ virt_params.append(self.load_virt_param(config))
+ virt_cfg[key] = virt_params
+ self.virt_cfgs.append(virt_cfg)
+
+ def get_virt_config(self):
+ return self.virt_cfgs
+
+ def load_virt_param(self, config):
+ cfg_params = self.virt_conf.load_param(config)
+ return cfg_params
+
+
+class PortConf(UserConf):
+
+ def __init__(self, port_conf=PORTCONF):
+ self.config_file = port_conf
self.ports_cfg = {}
self.pci_regex = "([\da-f]{2}:[\da-f]{2}.\d{1})$"
try:
- self.port_conf = ConfigParser.SafeConfigParser()
- self.port_conf.read(self.port_config)
+ self.port_conf = UserConf(self.config_file)
except Exception as e:
print "FAILED LOADING PORT CONFIG!!!"
+ self.port_conf = None
def load_ports_config(self, crbIP):
- ports = []
- for crb in self.port_conf.sections():
- if crb != crbIP:
- continue
- ports = [port.strip()
- for port in self.port_conf.get(crb, 'ports').split(';')]
+ self.ports_cfg = {}
+ if self.port_conf is None:
+ return
+
+ ports = self.port_conf.load_section(crbIP)
+ if ports is None:
+ return
+ key, config = ports[0]
+ confs = self.port_conf.load_config(config)
+
+ for config in confs:
+ port_param = self.port_conf.load_param(config)
- for port in ports:
- port_cfg = self.__parse_port_param(port)
# check pci BDF validity
- if 'pci' not in port_cfg:
+ if 'pci' not in port_param:
print "NOT FOUND CONFIG FOR NO PCI ADDRESS!!!"
continue
- m = re.match(self.pci_regex, port_cfg['pci'])
+ m = re.match(self.pci_regex, port_param['pci'])
if m is None:
print "INVALID CONFIG FOR NO PCI ADDRESS!!!"
continue
- keys = port_cfg.keys()
+ keys = port_param.keys()
keys.remove('pci')
- self.ports_cfg[port_cfg['pci']] = {key: port_cfg[key] for key in keys}
+ self.ports_cfg[port_param['pci']] = {
+ key: port_param[key] for key in keys}
+ if 'numa' in self.ports_cfg[port_param['pci']]:
+ numa_str = self.ports_cfg[port_param['pci']]['numa']
+ self.ports_cfg[port_param['pci']]['numa'] = int(numa_str)
def get_ports_config(self):
return self.ports_cfg
@@ -86,23 +174,36 @@ class UserConf():
else:
return False
- def __parse_port_param(self, port):
- portDict = dict()
-
- for param in port.split(','):
- (key, _, value) = param.partition('=')
- if key == 'numa':
- portDict[key] = int(value)
- else:
- portDict[key] = value
- return portDict
+
if __name__ == '__main__':
- parser = argparse.ArgumentParser(description="Load DTS configuration files")
- parser.add_argument("-p", "--portconf", default=portconf)
- parser.add_argument("-c", "--crbconf", default=crbconf)
+ parser = argparse.ArgumentParser(
+ description="Load DTS configuration files")
+ parser.add_argument("-p", "--portconf", default=PORTCONF)
+ parser.add_argument("-c", "--crbconf", default=CRBCONF)
+ parser.add_argument("-v", "--virtconf", default=VIRTCONF)
args = parser.parse_args()
- conf = UserConf()
- conf.load_ports_config('192.168.1.1')
- conf.check_port_available('0000:86:00.0')
+
+ # not existed configuration file
+ VirtConf('/tmp/not-existed.cfg')
+
+ # example for basic use configuration file
+ conf = UserConf(PORTCONF)
+ for section in conf.get_sections():
+ items = conf.load_section(section)
+ key, value = items[0]
+ confs = conf.load_config(value)
+ for config in confs:
+ conf.load_param(config)
+
+ # example for port configuration file
+ portconf = PortConf(PORTCONF)
+ portconf.load_ports_config('DUT IP')
+ print portconf.get_ports_config()
+ portconf.check_port_available('86:00.0')
+
+ # example for global virtualization configuration file
+ virtconf = VirtConf(VIRTCONF)
+ virtconf.load_virt_config('LIBVIRT')
+ print virtconf.get_virt_config()
diff --git a/framework/ssh_connection.py b/framework/ssh_connection.py
index 18a6517..7286b14 100644
--- a/framework/ssh_connection.py
+++ b/framework/ssh_connection.py
@@ -62,6 +62,11 @@ class SSHConnection(object):
self.logger.debug(out)
return out
+ def get_session_before(self, timeout=15):
+ out = self.session.get_session_before(timeout)
+ self.logger.debug(out)
+ return out
+
def close(self):
self.session.close()
diff --git a/framework/ssh_pexpect.py b/framework/ssh_pexpect.py
index 735df44..4193020 100644
--- a/framework/ssh_pexpect.py
+++ b/framework/ssh_pexpect.py
@@ -2,7 +2,8 @@ import time
import pexpect
import pxssh
from debugger import ignore_keyintr, aware_keyintr
-from exception import TimeoutException, SSHConnectionException
+from exception import TimeoutException, SSHConnectionException, SSHSessionDeadException
+from utils import RED, GREEN
"""
Module handle ssh sessions between tester and DUT.
@@ -14,16 +15,28 @@ Aslo support transfer files to tester or DUT.
class SSHPexpect(object):
def __init__(self, host, username, password):
- self.magic_prompt = "[MAGIC PROMPT]"
+ self.magic_prompt = "MAGIC PROMPT"
try:
self.session = pxssh.pxssh()
- self.username = username
self.host = host
+ self.username = username
self.password = password
- self.session.login(self.host, self.username,
- self.password, original_prompt='[$#>]')
+ if ':' in host:
+ self.ip = host.split(':')[0]
+ self.port = int(host.split(':')[1])
+ self.session.login(self.ip, self.username,
+ self.password, original_prompt='[$#>]',
+ port=self.port, login_timeout=20)
+ else:
+ self.session.login(self.host, self.username,
+ self.password, original_prompt='[$#>]')
self.send_expect('stty -echo', '# ', timeout=2)
- except Exception:
+ except Exception, e:
+ print RED(e)
+ if getattr(self, 'port', None):
+ suggestion = "\nSuggession: Check if the fireware on [ %s ] " % \
+ self.ip + "is stoped\n"
+ print GREEN(suggestion)
raise SSHConnectionException(host)
def init_log(self, logger, name):
@@ -33,7 +46,7 @@ class SSHPexpect(object):
def send_expect_base(self, command, expected, timeout=15):
ignore_keyintr()
- self.__flush() # clear buffer
+ self.__flush() # clear buffer
self.session.PROMPT = expected
self.__sendline(command)
self.__prompt(command, timeout)
@@ -45,7 +58,7 @@ class SSHPexpect(object):
def send_expect(self, command, expected, timeout=15, verify=False):
ret = self.send_expect_base(command, expected, timeout)
if verify:
- ret_status = self.send_expect_base("echo $?", expected)
+ ret_status = self.send_expect_base("echo $?", expected, timeout)
if not int(ret_status):
return ret
else:
@@ -54,21 +67,44 @@ class SSHPexpect(object):
else:
return ret
- def __flush(self):
+ def get_session_before(self, timeout=15):
+ """
+ Get all output before timeout
+ """
+ ignore_keyintr()
self.session.PROMPT = self.magic_prompt
- self.session.prompt(0.1)
+ try:
+ self.session.prompt(timeout)
+ except Exception as e:
+ pass
+
+ aware_keyintr()
+ before = self.get_output_before()
+ self.__flush()
+ return before
+
+ def __flush(self):
+ """
+ Clear all session buffer
+ """
+ self.session.buffer = ""
+ self.session.before = ""
def __prompt(self, command, timeout):
if not self.session.prompt(timeout):
raise TimeoutException(command, self.get_output_all())
def __sendline(self, command):
+ if not self.isalive():
+ raise SSHSessionDeadException(self.host)
if len(command) == 2 and command.startswith('^'):
self.session.sendcontrol(command[1])
else:
self.session.sendline(command)
def get_output_before(self):
+ if not self.isalive():
+ raise SSHSessionDeadException(self.host)
self.session.flush()
before = self.session.before.rsplit('\r\n', 1)
if before[0] == "[PEXPECT]":
@@ -103,7 +139,12 @@ class SSHPexpect(object):
"""
Sends a local file to a remote place.
"""
- command = 'scp {0} {1}@{2}:{3}'.format(src, self.username, self.host, dst)
+ if ':' in self.host:
+ command = 'scp -P {0} -o NoHostAuthenticationForLocalhost=yes {1} {2}@{3}:{4}'.format(
+ str(self.port), src, self.username, self.ip, dst)
+ else:
+ command = 'scp {0} {1}@{2}:{3}'.format(
+ src, self.username, self.host, dst)
if password == '':
self._spawn_scp(command, self.password)
else:
diff --git a/framework/utils.py b/framework/utils.py
new file mode 100644
index 0000000..57eb988
--- /dev/null
+++ b/framework/utils.py
@@ -0,0 +1,77 @@
+# 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.
+
+import json # json format
+import re
+
+
+def RED(text):
+ return "\x1B[" + "31;1m" + str(text) + "\x1B[" + "0m"
+
+
+def BLUE(text):
+ return "\x1B[" + "36;1m" + str(text) + "\x1B[" + "0m"
+
+
+def GREEN(text):
+ return "\x1B[" + "32;1m" + str(text) + "\x1B[" + "0m"
+
+
+def pprint(some_dict):
+ """
+ Print JSON format dictionary object.
+ """
+ return json.dumps(some_dict, sort_keys=True, indent=4)
+
+
+def regexp(s, to_match, allString=False):
+ """
+ Ensure that the re `to_match' only has one group in it.
+ """
+
+ scanner = re.compile(to_match, re.DOTALL)
+ if allString:
+ return scanner.findall(s)
+ m = scanner.search(s)
+ if m is None:
+ print RED("Failed to match " + to_match + " in the string " + s)
+ return None
+ return m.group(1)
+
+
+def get_obj_funcs(obj, func_name_regex):
+ """
+ Return function list which name matched regex.
+ """
+ for func_name in dir(obj):
+ func = getattr(obj, func_name)
+ if callable(func) and re.match(func_name_regex, func.__name__):
+ yield func
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
2015-05-18 5:07 ` [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice sjiajiax
2015-05-18 5:07 ` [dts] [‘dts-v1’ 2/9] Optimize ssh connection sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 7:26 ` Liu, Yong
2015-05-18 7:59 ` Xu, HuilongX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module sjiajiax
` (6 subsequent siblings)
9 siblings, 2 replies; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/dts.py | 92 +++++++++++------------------------------------
framework/exception.py | 27 ++++++++++++++
framework/logger.py | 69 +++++++++++++++++++++++++++++------
framework/main.py | 7 +++-
framework/project_dpdk.py | 62 ++++++++++++++++++++++----------
5 files changed, 157 insertions(+), 100 deletions(-)
diff --git a/framework/dts.py b/framework/dts.py
index c9ecccb..c0df4e9 100644
--- a/framework/dts.py
+++ b/framework/dts.py
@@ -49,6 +49,7 @@ from test_case import TestCase
from test_result import Result
from stats_reporter import StatsReporter
from excel_reporter import ExcelReporter
+from utils import *
from exception import TimeoutException
from logger import getLogger
import logger
@@ -57,6 +58,7 @@ import sys
reload(sys)
sys.setdefaultencoding('UTF8')
+PROJECT_MODULE_PREFIX = 'project_'
debug_mode = False
config = None
@@ -73,44 +75,12 @@ result = None
excel_report = None
stats = None
log_handler = None
+Package = ''
+Patches = []
drivername = ""
interrupttypr = ""
-def RED(text):
- return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
-
-
-def BLUE(text):
- return "\x1B[" + "36;1m" + text + "\x1B[" + "0m"
-
-
-def GREEN(text):
- return "\x1B[" + "32;1m" + text + "\x1B[" + "0m"
-
-
-def regexp(s, to_match, allString=False):
- """
- Ensure that the re `to_match' only has one group in it.
- """
-
- scanner = re.compile(to_match, re.DOTALL)
- if allString:
- return scanner.findall(s)
- m = scanner.search(s)
- if m is None:
- log_handler.warning("Failed to match " + to_match + " in the string " + s)
- return None
- return m.group(1)
-
-
-def pprint(some_dict):
- """
- Print JSON format dictionary object.
- """
- return json.dumps(some_dict, sort_keys=True, indent=4)
-
-
def report(text, frame=False, annex=False):
"""
Save report text into rst file.
@@ -132,36 +102,6 @@ def close_crb_sessions():
log_handler.info("DTS ended")
-def get_nic_driver(pci_id):
- """
- Return linux driver for specified pci device
- """
- driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
- try:
- driver = DRIVERS[driverlist[pci_id]]
- except Exception as e:
- driver = None
- return driver
-
-
-def accepted_nic(pci_id):
- """
- Return True if the pci_id is a known NIC card in the settings file and if
- it is selected in the execution file, otherwise it returns False.
- """
- if pci_id not in NICS.values():
- return False
-
- if nic is 'any':
- return True
-
- else:
- if pci_id == NICS[nic]:
- return True
-
- return False
-
-
def get_crb_os(crb):
if 'OS' in crb:
return crb['OS']
@@ -220,9 +160,10 @@ def get_project_obj(project_name, super_class, crbInst, serializer):
"""
Load project module and return crb instance.
"""
+ global PROJECT_MODULE_PREFIX
project_obj = None
try:
- project_module = __import__("project_" + project_name)
+ project_module = __import__(PROJECT_MODULE_PREFIX + project_name)
for project_subclassname, project_subclass in get_subclasses(project_module, super_class):
project_obj = project_subclass(crbInst, serializer)
@@ -267,19 +208,20 @@ def dts_log_execution(log_handler):
pass
-def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir, nic):
+def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir, nic, virttype):
"""
Create dts dut/tester instance and initialize them.
"""
global dut
global tester
- serializer.set_serialized_filename('../.%s.cache' % crbInst['IP'])
+ serializer.set_serialized_filename('.%s.cache' % crbInst['IP'])
serializer.load_from_file()
dut = get_project_obj(project, Dut, crbInst, serializer)
tester = get_project_obj(project, Tester, crbInst, serializer)
dut.tester = tester
tester.dut = dut
+ dut.set_virttype(virttype)
dut.set_speedup_options(read_cache, skip_setup)
dut.set_directory(base_dir)
dut.set_nic_type(nic)
@@ -337,7 +279,6 @@ def dts_run_target(crbInst, targets, test_suites, nic):
if 'nic_type' not in paramDict:
paramDict['nic_type'] = 'any'
nic = 'any'
- result.nic = nic
dts_run_suite(crbInst, test_suites, target, nic)
@@ -359,7 +300,9 @@ def dts_run_suite(crbInst, test_suites, target, nic):
test_module = __import__('TestSuite_' + test_suite)
for test_classname, test_class in get_subclasses(test_module, TestCase):
- test_suite = test_class(dut, tester, target)
+ test_suite = test_class(dut, tester, target, test_suite)
+ result.nic = test_suite.nic
+
dts_log_testsuite(test_suite, log_handler, test_classname)
log_handler.info("\nTEST SUITE : " + test_classname)
@@ -386,7 +329,7 @@ def dts_run_suite(crbInst, test_suites, target, nic):
def run_all(config_file, pkgName, git, patch, skip_setup,
read_cache, project, suite_dir, test_cases,
- base_dir, output_dir, verbose, debug):
+ base_dir, output_dir, verbose, virttype, debug):
"""
Main process of DTS, it will run all test suites in the config file.
"""
@@ -400,6 +343,12 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
global stats
global log_handler
global debug_mode
+ global Package
+ global Patches
+
+ # save global variable
+ Package = pkgName
+ Patches = patch
# prepare the output folder
if not os.path.exists(output_dir):
@@ -466,7 +415,8 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
result.dut = dutIP
# init dut, tester crb
- dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir, nics)
+ dts_crbs_init(
+ crbInst, skip_setup, read_cache, project, base_dir, nics, virttype)
# Run DUT prerequisites
if dts_run_prerequisties(pkgName, patch) is False:
diff --git a/framework/exception.py b/framework/exception.py
index be38c16..98dedf4 100644
--- a/framework/exception.py
+++ b/framework/exception.py
@@ -46,3 +46,30 @@ class SSHConnectionException(Exception):
def __str__(self):
return 'Error trying to connect with %s' % self.host
+
+
+class SSHSessionDeadException(Exception):
+
+ """
+ SSH session is not alive.
+ It can no longer be used.
+ """
+
+ def __init__(self, host):
+ self.host = host
+
+ def __str__(self):
+ return 'SSH session with %s has been dead' % self.host
+
+
+class StartVMFailedException(Exception):
+
+ """
+ Start VM failed.
+ """
+
+ def __init__(self, error):
+ self.error = error
+
+ def __str__(self):
+ return repr(self.error)
diff --git a/framework/logger.py b/framework/logger.py
index 1829e18..5597e33 100644
--- a/framework/logger.py
+++ b/framework/logger.py
@@ -35,6 +35,9 @@ import sys
import inspect
import re
+from settings import LOG_NAME_SEP
+from utils import RED
+
"""
DTS logger module with several log level. DTS framwork and TestSuite log
will saved into different log files.
@@ -58,6 +61,9 @@ logging.SUITE_TESTER_OUTPUT = logging.DEBUG + 4
logging.DTS_IXIA_CMD = logging.INFO + 5
logging.DTS_IXIA_OUTPUT = logging.DEBUG + 5
+logging.DTS_VIRTDUT_CMD = logging.INFO + 6
+logging.DTS_VIRTDUT_OUTPUT = logging.DEBUG + 6
+
logging.addLevelName(logging.DTS_DUT_CMD, 'DTS_DUT_CMD')
logging.addLevelName(logging.DTS_DUT_OUTPUT, 'DTS_DUT_OUTPUT')
logging.addLevelName(logging.DTS_DUT_RESULT, 'DTS_DUT_RESUTL')
@@ -66,6 +72,12 @@ logging.addLevelName(logging.DTS_TESTER_CMD, 'DTS_TESTER_CMD')
logging.addLevelName(logging.DTS_TESTER_OUTPUT, 'DTS_TESTER_OUTPUT')
logging.addLevelName(logging.DTS_TESTER_RESULT, 'DTS_TESTER_RESULT')
+logging.addLevelName(logging.DTS_IXIA_CMD, 'DTS_IXIA_CMD')
+logging.addLevelName(logging.DTS_IXIA_OUTPUT, 'DTS_IXIA_OUTPUT')
+
+logging.addLevelName(logging.DTS_VIRTDUT_CMD, 'VIRTDUT_CMD')
+logging.addLevelName(logging.DTS_VIRTDUT_OUTPUT, 'VIRTDUT_OUTPUT')
+
logging.addLevelName(logging.SUITE_DUT_CMD, 'SUITE_DUT_CMD')
logging.addLevelName(logging.SUITE_DUT_OUTPUT, 'SUITE_DUT_OUTPUT')
@@ -82,15 +94,18 @@ stream_fmt = '%(color)s%(levelname)20s: %(message)s' + RESET_COLOR
log_dir = None
-def RED(text):
- return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
-
-
def set_verbose():
global verbose
verbose = True
+def add_salt(salt, msg):
+ if not salt:
+ return msg
+ else:
+ return '[%s] ' % salt + str(msg)
+
+
class BaseLoggerAdapter(logging.LoggerAdapter):
"""
Upper layer of original logging module.
@@ -132,6 +147,12 @@ class BaseLoggerAdapter(logging.LoggerAdapter):
def dts_ixia_output(self, msg, *args, **kwargs):
self.log(logging.DTS_IXIA_OUTPUT, msg, *args, **kwargs)
+ def dts_virtdut_cmd(self, msg, *args, **kwargs):
+ self.log(logging.DTS_VIRTDUT_CMD, msg, *args, **kwargs)
+
+ def dts_virtdut_output(self, msg, *args, **kwargs):
+ self.log(logging.DTS_VIRTDUT_OUTPUT, msg, *args, **kwargs)
+
class ColorHandler(logging.StreamHandler):
"""
@@ -150,6 +171,8 @@ class ColorHandler(logging.StreamHandler):
logging.SUITE_TESTER_CMD: '', # SYSTEM
logging.DTS_IXIA_CMD: '', # SYSTEM
logging.DTS_IXIA_OUTPUT: '', # SYSTEM
+ logging.DTS_VIRTDUT_CMD: '', # SYSTEM
+ logging.DTS_VIRTDUT_OUTPUT: '', # SYSTEM
logging.WARN: '\033[01;33m', # BOLD YELLOW
logging.DTS_DUT_RESULT: '\033[01;34m', # BOLD BLUE
logging.DTS_TESTER_RESULT: '\033[01;34m', # BOLD BLUE
@@ -189,6 +212,8 @@ class DTSLOG(BaseLoggerAdapter):
self.crb = crb
super(DTSLOG, self).__init__(self.logger, dict(crb=self.crb))
+ self.salt = ''
+
self.fh = None
self.ch = None
@@ -221,24 +246,28 @@ class DTSLOG(BaseLoggerAdapter):
"""
DTS warnning level log function.
"""
+ message = add_salt(self.salt, message)
self.logger.log(self.warn_lvl, message)
def info(self, message):
"""
DTS information level log function.
"""
+ message = add_salt(self.salt, message)
self.logger.log(self.info_lvl, message)
def error(self, message):
"""
DTS error level log function.
"""
+ message = add_salt(self.salt, message)
self.logger.log(self.error_lvl, message)
def debug(self, message):
"""
DTS debug level log function.
"""
+ message = add_salt(self.salt, message)
self.logger.log(self.debug_lvl, message)
def set_logfile_path(self, path):
@@ -270,17 +299,34 @@ class DTSLOG(BaseLoggerAdapter):
ch = ColorHandler()
self.__log_hander(fh, ch)
- if crb == "dut":
+ def set_salt(crb, start_flag):
+ if LOG_NAME_SEP in crb:
+ old = '%s%s' % (start_flag, LOG_NAME_SEP)
+ if not self.salt:
+ self.salt = crb.replace(old, '', 1)
+
+ if crb.startswith('dut'):
self.info_lvl = logging.DTS_DUT_CMD
self.debug_lvl = logging.DTS_DUT_OUTPUT
self.warn_lvl = logging.DTS_DUT_RESULT
- elif crb == "tester":
+
+ set_salt(crb, 'dut')
+ elif crb.startswith('tester'):
self.info_lvl = logging.DTS_TESTER_CMD
self.debug_lvl = logging.DTS_TESTER_OUTPUT
self.warn_lvl = logging.DTS_TESTER_RESULT
- elif crb == "ixia":
+
+ set_salt(crb, 'tester')
+ elif crb.startswith('ixia'):
self.info_lvl = logging.DTS_IXIA_CMD
self.debug_lvl = logging.DTS_IXIA_OUTPUT
+
+ set_salt(crb, 'ixia')
+ elif crb.startswith('virtdut'):
+ self.info_lvl = logging.DTS_VIRTDUT_CMD
+ self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
+
+ set_salt(crb, 'virtdut')
else:
self.error_lvl = logging.ERROR
self.warn_lvl = logging.WARNING
@@ -296,15 +342,18 @@ class DTSLOG(BaseLoggerAdapter):
ch = ColorHandler()
self.__log_hander(fh, ch)
- if crb == "dut":
+ if crb == 'dut':
self.info_lvl = logging.SUITE_DUT_CMD
self.debug_lvl = logging.SUITE_DUT_OUTPUT
- elif crb == "tester":
+ elif crb == 'tester':
self.info_lvl = logging.SUITE_TESTER_CMD
self.debug_lvl = logging.SUITE_TESTER_OUTPUT
- elif crb == "ixia":
+ elif crb == 'ixia':
self.info_lvl = logging.DTS_IXIA_CMD
self.debug_lvl = logging.DTS_IXIA_OUTPUT
+ elif crb == 'virtdut':
+ self.info_lvl = logging.DTS_VIRTDUT_CMD
+ self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
def logger_exit(self):
"""
diff --git a/framework/main.py b/framework/main.py
index 3e467d0..0496b20 100755
--- a/framework/main.py
+++ b/framework/main.py
@@ -117,6 +117,10 @@ parser.add_argument('-v', '--verbose',
action='store_true',
help='enable verbose output, all message output on screen')
+parser.add_argument('--virttype',
+ default='kvm',
+ help='set virt type,support libvirt,xen,kvm')
+
parser.add_argument('--debug',
action='store_true',
help='enable debug mode, user can enter debug mode in process')
@@ -136,4 +140,5 @@ if args.git is not None:
dts.run_all(args.config_file, args.snapshot, args.git,
args.patch, args.skip_setup, args.read_cache,
args.project, args.suite_dir, args.test_cases,
- args.dir, args.output, args.verbose, args.debug)
+ args.dir, args.output, args.verbose,args.virttype,
+ args.debug)
diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py
index 8963924..67bd492 100644
--- a/framework/project_dpdk.py
+++ b/framework/project_dpdk.py
@@ -39,7 +39,7 @@ from crb import Crb
from dut import Dut
from tester import Tester
from logger import getLogger
-from settings import IXIA
+from settings import IXIA, accepted_nic
class DPDKdut(Dut):
@@ -50,8 +50,9 @@ class DPDKdut(Dut):
"""
def __init__(self, crb, serializer):
- self.NAME = 'dut'
+
super(DPDKdut, self).__init__(crb, serializer)
+ self.testpmd = None
def set_target(self, target):
"""
@@ -60,6 +61,7 @@ class DPDKdut(Dut):
Set hugepage on DUT and install modules required by DPDK.
Configure default ixgbe PMD function.
"""
+ self.target = target
self.set_toolchain(target)
# set env variable
@@ -99,7 +101,16 @@ class DPDKdut(Dut):
out = self.send_expect("lsmod | grep igb_uio", "#")
if "igb_uio" in out:
self.send_expect("rmmod -f igb_uio", "#", 70)
- self.send_expect("insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
+ if "rte_dom0_mm" in self.send_expect("lsmod |grep rte_dom0_mm", "#"):
+ self.send_expect("rmmod -f rte_dmo0_mm", "#", 70)
+ self.send_expect(
+ "insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
+ if self.virttype == 'xen':
+ self.send_expect(
+ "insmod ./" + target + "/kmod/rte_dom0_mm.ko", "#", 60)
+ self.send_expect(
+ r'echo 1024 > /sys/kernel/mm/dom0-mm/memsize-mB/memsize', "#", 70)
+
out = self.send_expect("lsmod | grep igb_uio", "#")
assert ("igb_uio" in out), "Failed to insmod igb_uio"
@@ -110,7 +121,7 @@ class DPDKdut(Dut):
binding_list = ''
for (pci_bus, pci_id) in self.pci_devices_info:
- if dts.accepted_nic(pci_id):
+ if accepted_nic(pci_id):
binding_list += '%s,' % (pci_bus)
self.send_expect("kldunload if_ixgbe.ko", "#")
@@ -158,6 +169,9 @@ class DPDKdut(Dut):
"""
# clean all
self.send_expect("rm -rf " + target, "#")
+ if self.virttype == 'xen':
+ self.send_expect("sed -i -e 's/CONFIG_RTE_LIBRTE_XEN_DOM0=.*$/"
+ + "CONFIG_RTE_LIBRTE_XEN_DOM0=y/' config/common_linuxapp", "# ", 30)
# compile
out = self.send_expect("make -j install T=%s %s" % (target, extra_options), "# ", 120)
@@ -178,9 +192,9 @@ class DPDKdut(Dut):
self.send_expect("rm -rf " + target, "#")
# compile
- out = self.send_expect("make -j %d install T=%s CC=gcc48" % (self.number_of_cores,
- target),
- "#", 120)
+ out = self.send_expect(
+ "make -j %d install T=%s CC=gcc48" %
+ (self.number_of_cores, target), "#", 120)
if("Error" in out or "No rule to make" in out):
self.logger.error("ERROR - try without '-j'")
@@ -191,10 +205,7 @@ class DPDKdut(Dut):
assert ("Error" not in out), "Compilation error..."
assert ("No rule to make" not in out), "No rule to make error..."
- def prerequisites(self, pkgName, patch):
- """
- Copy DPDK package to DUT and apply patch files.
- """
+ def prepare_package(self, pkgName, patch):
if not self.skip_setup:
assert (os.path.isfile(pkgName) is True), "Invalid package"
@@ -202,7 +213,7 @@ class DPDKdut(Dut):
# ToDo: make this configurable
dst_dir = "/tmp/"
- out = self.send_expect("ls %s && cd %s" % (dst_dir, p_dir),
+ out = self.send_expect("ll %s && cd %s" % (dst_dir, p_dir),
"#", verify=True)
if out == -1:
raise ValueError("Directiry %s or %s does not exist,"
@@ -249,6 +260,17 @@ class DPDKdut(Dut):
(self.base_dir, dst_dir + p), "# ")
assert "****" not in out
+ self.session.copy_file_to("dep/aclrule.tgz", dst_dir)
+ # unpack acl rule
+ out = self.send_expect("tar zxf %saclrule.tgz -C %s" % (dst_dir, p_dir), "# ", 20, verify=True)
+ if out == -1:
+ raise ValueError("acl rule extract failure!!!")
+
+ def prerequisites(self, pkgName, patch):
+ """
+ Copy DPDK package to DUT and apply patch files.
+ """
+ self.prepare_package(pkgName, patch)
self.dut_prerequisites()
def bind_interfaces_linux(self, driver='igb_uio', nics_to_bind=None):
@@ -354,16 +376,20 @@ class DPDKtester(Tester):
total_huge_pages = self.get_total_huge_pages()
if total_huge_pages == 0:
self.mount_huge_pages()
- self.set_huge_pages(4096)
+ self.set_huge_pages(1024)
self.session.copy_file_to("dep/tgen.tgz")
self.session.copy_file_to("dep/tclclient.tgz")
+ self.session.copy_file_to("dep/aclpcap.tgz")
# unpack tgen
out = self.send_expect("tar zxf tgen.tgz", "# ")
assert "Error" not in out
# unpack tclclient
out = self.send_expect("tar zxf tclclient.tgz", "# ")
assert "Error" not in out
+ # unpacl ACL pcap files
+ out = self.send_expect("tar zxf aclpcap.tgz", "# ")
+ assert "Error" not in out
self.send_expect("modprobe uio", "# ")
@@ -386,10 +412,10 @@ class DPDKtester(Tester):
"""
hugepages_size = self.send_expect("awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
- if int(hugepages_size) < (1024 * 1024):
- arch_huge_pages = hugepages if hugepages > 0 else 4096
+ if int(hugepages_size) < (2048 * 2048):
+ arch_huge_pages = hugepages if hugepages > 0 else 2048
total_huge_pages = self.get_total_huge_pages()
- self.mount_huge_pages()
- if total_huge_pages != arch_huge_pages:
- self.set_huge_pages(arch_huge_pages)
+ self.mount_huge_pages()
+ if total_huge_pages != arch_huge_pages:
+ self.set_huge_pages(arch_huge_pages)
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
` (2 preceding siblings ...)
2015-05-18 5:07 ` [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 8:23 ` Xu, HuilongX
2015-05-18 13:57 ` Liu, Yong
2015-05-18 5:07 ` [dts] [‘dts-v1’ 5/9] Add qemu-agent-guest for QEMU VM sjiajiax
` (5 subsequent siblings)
9 siblings, 2 replies; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/qemu_kvm.py | 912 +++++++++++++++++++++++++++++++++++++++++++++
framework/virt_base.py | 250 +++++++++++++
framework/virt_dut.py | 239 ++++++++++++
framework/virt_resource.py | 486 ++++++++++++++++++++++++
4 files changed, 1887 insertions(+)
create mode 100644 framework/qemu_kvm.py
create mode 100644 framework/virt_base.py
create mode 100644 framework/virt_dut.py
create mode 100644 framework/virt_resource.py
diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py
new file mode 100644
index 0000000..5f5f665
--- /dev/null
+++ b/framework/qemu_kvm.py
@@ -0,0 +1,912 @@
+# <COPYRIGHT_TAG>
+
+import time
+import re
+import os
+
+from virt_base import VirtBase
+from exception import StartVMFailedException
+
+# This name is derictly defined in the qemu guest serivce
+# So you can not change it except it is changed by the service
+QGA_DEV_NAME = 'org.qemu.guest_agent.0'
+# This path defines an socket path on the host connected with
+# a specified VM
+QGA_SOCK_PATH_TEMPLATE = '/tmp/%(vm_name)s_qga0.sock'
+
+
+class QEMUKvm(VirtBase):
+
+ DEFAULT_BRIDGE = 'br0'
+ QEMU_IFUP = """#!/bin/sh
+
+set -x
+
+switch=%(switch)s
+
+if [ -n "$1" ];then
+ tunctl -t $1
+ ip link set $1 up
+ sleep 0.5s
+ brctl addif $switch $1
+ exit 0
+else
+ echo "Error: no interface specified"
+ exit 1
+fi
+"""
+ QEMU_IFUP_PATH = '/etc/qemu-ifup'
+
+ def __init__(self, dut, vm_name, suite_name):
+ super(QEMUKvm, self).__init__(dut, vm_name, suite_name)
+ self.set_vm_name(self.vm_name)
+ self.set_vm_enable_kvm()
+ self.set_vm_qga()
+ self.set_vm_daemon()
+
+ # initialize qemu emulator, example: qemu-system-x86_64
+ self.qemu_emulator = self.get_qemu_emulator()
+
+ # initialize qemu boot command line
+ # example: qemu-system-x86_64 -name vm1 -m 2048 -vnc :1 -daemonize
+ self.whole_qemu_kvm_boot_line = ''
+
+ self.init_vm_request_resource()
+
+ QGA_CLI_PATH = '-r dep/QMP/'
+ self.host_session.copy_file_to(QGA_CLI_PATH)
+
+ def init_vm_request_resource(self):
+ """
+ initialize vcpus what will be pinned to the VM.
+ If specify this param, the specified vcpus will
+ be pinned to VM by the command 'taskset' when
+ starting the VM.
+ example:
+ vcpus_pinned_to_vm = '1 2 3 4'
+ taskset -c 1,2,3,4 qemu-boot-command-line
+ """
+ self.vcpus_pinned_to_vm = ''
+
+ # initialize assigned PCI
+ self.assigned_pcis = []
+
+ def get_virt_type(self):
+ """
+ Get the virtual type.
+ """
+ return 'KVM'
+
+ def get_qemu_emulator(self):
+ """
+ Get the qemu emulator based on the crb.
+ """
+ arch = self.host_session.send_expect('uname -m', '# ')
+ return 'qemu-system-' + arch
+
+ def set_qemu_emulator(self, qemu_emulator):
+ """
+ Set the qemu emulator explicitly.
+ """
+ out = self.host_session.send_expect(
+ 'whereis %s' % str(qemu_emulator), '[.*')
+ command_paths = out.split(':')[1:]
+ if command_paths[0].lstrip():
+ print "No emulator [ %s ] on the DUT [ %s ]" % \
+ (qemu_emulator, self.host_dut.get_ip_address())
+ return None
+ self.qemu_emulator = qemu_emulator
+
+ def has_virtual_ability(self):
+ """
+ Check if host has the virtual ability.
+ """
+ out = self.host_session.send_expect('lsmod | grep kvm', '# ')
+ if 'kvm' in out and 'kvm_intel' in out:
+ return True
+ else:
+ return False
+
+ def enable_virtual_ability(self):
+ """
+ Load the virutal module of kernel to enable the virutal ability.
+ """
+ self.host_session.send_expect('modprobe kvm', '# ')
+ self.host_session.send_expect('modprobe kvm_intel', '# ')
+ return True
+
+ def disk_image_is_ok(self, image):
+ """
+ Check if the image is OK and no error.
+ """
+ pass
+
+ def image_is_used(self, image_path):
+ """
+ Check if the image has been used on the host.
+ """
+ qemu_cmd_lines = self.host_session.send_expect(
+ "ps aux | grep qemu | grep -v grep", "# ")
+
+ image_name_flag = '/' + image_path.strip().split('/')[-1] + ' '
+ if image_path in qemu_cmd_lines or \
+ image_name_flag in qemu_cmd_lines:
+ return True
+ return False
+
+ def __add_boot_line(self, option_boot_line):
+ """
+ Add boot option into the boot line.
+ """
+ separator = ' '
+ self.whole_qemu_kvm_boot_line += separator + option_boot_line
+
+ def set_vm_enable_kvm(self, enable='yes'):
+ """
+ Set VM boot option to enable the option 'enable-kvm'.
+ """
+ self.params.append({'enable_kvm': [{'enable': '%s' % enable}]})
+
+ def add_vm_enable_kvm(self, **options):
+ """
+ 'enable': 'yes'
+ """
+ if 'enable' in options.keys() and \
+ options['enable'] == 'yes':
+ enable_kvm_boot_line = '-enable-kvm'
+ self.__add_boot_line(enable_kvm_boot_line)
+
+ def set_vm_name(self, vm_name):
+ """
+ Set VM name.
+ """
+ self.params.append({'name': [{'name': '%s' % vm_name}]})
+
+ def add_vm_name(self, **options):
+ """
+ name: vm1
+ """
+ if 'name' in options.keys() and \
+ options['name']:
+ name_boot_line = '-name %s' % options['name']
+ self.__add_boot_line(name_boot_line)
+
+ def add_vm_cpu(self, **options):
+ """
+ model: [host | core2duo | ...]
+ usage:
+ choose model value from the command
+ qemu-system-x86_64 -cpu help
+ number: '4' #number of vcpus
+ cpupin: '3 4 5 6' # host cpu list
+ """
+ if 'model' in options.keys() and \
+ options['model']:
+ cpu_boot_line = '-cpu %s' % options['model']
+ self.__add_boot_line(cpu_boot_line)
+ if 'number' in options.keys() and \
+ options['number']:
+ smp_cmd_line = '-smp %d' % int(options['number'])
+ self.__add_boot_line(smp_cmd_line)
+ if 'cpupin' in options.keys() and \
+ options['cpupin']:
+ self.vcpus_pinned_to_vm = str(options['cpupin'])
+
+ def add_vm_mem(self, **options):
+ """
+ size: 1024
+ """
+ if 'size' in options.keys():
+ mem_boot_line = '-m %s' % options['size']
+ self.__add_boot_line(mem_boot_line)
+
+ def add_vm_disk(self, **options):
+ """
+ file: /home/image/test.img
+ """
+ if 'file' in options.keys():
+ disk_boot_line = '-drive file=%s' % options['file']
+ self.__add_boot_line(disk_boot_line)
+
+ def add_vm_net(self, **options):
+ """
+ Add VM net device.
+ type: [nic | user | tap | bridge | ...]
+ opt_[vlan | fd | br | mac | ...]
+ note:the sub-option will be decided according to the net type.
+ """
+ if 'type' in options.keys():
+ if 'opt_vlan' not in options.keys():
+ options['opt_vlan'] = '0'
+ if options['type'] == 'nic':
+ self.__add_vm_net_nic(**options)
+ if options['type'] == 'user':
+ self.__add_vm_net_user(**options)
+ if options['type'] == 'tap':
+ self.__add_vm_net_tap(**options)
+
+ if options['type'] == 'user':
+ self.net_type = 'hostfwd'
+ elif options['type'] in ['tap', 'bridge']:
+ self.net_type = 'bridge'
+
+ def __add_vm_net_nic(self, **options):
+ """
+ type: nic
+ opt_vlan: 0
+ note: Default is 0.
+ opt_macaddr: 00:00:00:00:01:01
+ note: if creating a nic, it`s better to specify a MAC,
+ else it will get a random number.
+ opt_model:["e1000" | "virtio" | "i82551" | ...]
+ note: Default is e1000.
+ opt_name: 'nic1'
+ opt_addr: ''
+ note: PCI cards only.
+ opt_vectors:
+ note: This option currently only affects virtio cards.
+ """
+ net_boot_line = '-net nic'
+ separator = ','
+ if 'opt_vlan' in options.keys() and \
+ options['opt_vlan']:
+ net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
+
+ # add MAC info
+ if 'opt_macaddr' in options.keys() and \
+ options['opt_macaddr']:
+ mac = options['opt_macaddr']
+ else:
+ mac = self.generate_unique_mac()
+ net_boot_line += separator + 'macaddr=%s' % mac
+
+ if 'opt_model' in options.keys() and \
+ options['opt_model']:
+ net_boot_line += separator + 'model=%s' % options['opt_model']
+ if 'opt_name' in options.keys() and \
+ options['opt_name']:
+ net_boot_line += separator + 'name=%s' % options['opt_name']
+ if 'opt_addr' in options.keys() and \
+ options['opt_addr']:
+ net_boot_line += separator + 'addr=%s' % options['opt_addr']
+ if 'opt_vectors' in options.keys() and \
+ options['opt_vectors']:
+ net_boot_line += separator + 'vectors=%s' % options['opt_vectors']
+
+ if self.__string_has_multi_fields(net_boot_line, separator):
+ self.__add_boot_line(net_boot_line)
+
+ def __add_vm_net_user(self, **options):
+ """
+ type: user
+ opt_vlan: 0
+ note: default is 0.
+ opt_hostfwd: [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport
+ """
+ net_boot_line = '-net user'
+ separator = ','
+ if 'opt_vlan' in options.keys() and \
+ options['opt_vlan']:
+ net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
+ if 'opt_hostfwd' in options.keys() and \
+ options['opt_hostfwd']:
+ self.__check_net_user_opt_hostfwd(options['opt_hostfwd'])
+ opt_hostfwd = options['opt_hostfwd']
+ else:
+ opt_hostfwd = '::-:'
+ hostfwd_line = self.__parse_net_user_opt_hostfwd(opt_hostfwd)
+ net_boot_line += separator + 'hostfwd=%s' % hostfwd_line
+
+ if self.__string_has_multi_fields(net_boot_line, separator):
+ self.__add_boot_line(net_boot_line)
+
+ def __check_net_user_opt_hostfwd(self, opt_hostfwd):
+ """
+ Use regular expression to check if hostfwd value format is correct.
+ """
+ regx_ip = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
+ regx_hostfwd = r'["tcp" | "udp"]?:%s?:\d+-%s?:\d+' % (regx_ip, regx_ip)
+ if not re.match(regx_hostfwd, opt_hostfwd):
+ raise Exception("Option opt_hostfwd format is not correct,\n" +
+ "it is %s,\n " % opt_hostfwd +
+ "it should be [tcp|udp]:[hostaddr]:hostport-" +
+ "[guestaddr]:guestport.\n")
+
+ def __parse_net_user_opt_hostfwd(self, opt_hostfwd):
+ """
+ Parse the boot option 'hostfwd'.
+ """
+ separator = ':'
+ field = lambda option, index, separator=':': \
+ option.split(separator)[index]
+
+ # get the forword type
+ fwd_type = field(opt_hostfwd, 0)
+ if not fwd_type:
+ fwd_type = 'tcp'
+
+ # get the host addr
+ host_addr = field(opt_hostfwd, 1)
+ if not host_addr:
+ host_addr = str(self.host_dut.get_ip_address())
+
+ # get the host port in the option
+ host_port = field(opt_hostfwd, 2).split('-')[0]
+ if not host_port:
+ host_port = str(self.virt_pool.alloc_port(self.vm_name))
+ self.redir_port = host_port
+
+ # get the guest addr
+ try:
+ guest_addr = str(field(opt_hostfwd, 2).split('-')[1])
+ except IndexError as e:
+ guest_addr = ''
+
+ # get the guest port in the option
+ guest_port = str(field(opt_hostfwd, 3))
+ if not guest_port:
+ guest_port = '22'
+
+ hostfwd_line = fwd_type + separator + \
+ host_addr + separator + \
+ host_port + \
+ '-' + \
+ guest_addr + separator + \
+ guest_port
+
+ # init the redirect incoming TCP or UDP connections
+ # just combine host address and host port, it is enough
+ # for using ssh to connect with VM
+ self.hostfwd_addr = host_addr + separator + host_port
+
+ return hostfwd_line
+
+ def __add_vm_net_tap(self, **options):
+ """
+ type: tap
+ opt_vlan: 0
+ note: default is 0.
+ opt_br: br0
+ note: if choosing tap, need to specify bridge name,
+ else it will be br0.
+ opt_script: QEMU_IFUP_PATH
+ note: if not specified, default is self.QEMU_IFUP_PATH.
+ opt_downscript: QEMU_IFDOWN_PATH
+ note: if not specified, default is self.QEMU_IFDOWN_PATH.
+ """
+ net_boot_line = '-net tap'
+ separator = ','
+
+ # add bridge info
+ if 'opt_br' in options.keys() and \
+ options['opt_br']:
+ bridge = options['opt_br']
+ else:
+ bridge = self.DEFAULT_BRIDGE
+ self.__generate_net_config_script(str(bridge))
+
+ if 'opt_vlan' in options.keys() and \
+ options['opt_vlan']:
+ net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
+
+ # add network configure script path
+ if 'opt_script' in options.keys() and \
+ options['opt_script']:
+ script_path = options['opt_script']
+ else:
+ script_path = self.QEMU_IFUP_PATH
+ net_boot_line += separator + 'script=%s' % script_path
+
+ # add network configure downscript path
+ if 'opt_downscript' in options.keys() and \
+ options['opt_downscript']:
+ net_boot_line += separator + \
+ 'downscript=%s' % options['opt_downscript']
+
+ if self.__string_has_multi_fields(net_boot_line, separator):
+ self.__add_boot_line(net_boot_line)
+
+ def __generate_net_config_script(self, switch=DEFAULT_BRIDGE):
+ """
+ Generate a script for qemu emulator to build a tap device
+ between host and guest.
+ """
+ qemu_ifup = self.QEMU_IFUP % {'switch': switch}
+ file_name = os.path.basename(self.QEMU_IFUP_PATH)
+ tmp_file_path = '/tmp/%s' % file_name
+ self.host_dut.create_file(qemu_ifup, tmp_file_path)
+ self.host_session.send_expect('mv -f ~/%s %s' % (file_name,
+ self.QEMU_IFUP_PATH), '# ')
+ self.host_session.send_expect(
+ 'chmod +x %s' % self.QEMU_IFUP_PATH, '# ')
+
+ def set_vm_device(self, driver='pci-assign', **props):
+ """
+ Set VM device with specified driver.
+ """
+ props['driver'] = driver
+ index = self.find_option_index('device')
+ if index:
+ self.params[index]['device'].append(props)
+ else:
+ self.params.append({'device': [props]})
+
+ def add_vm_device(self, **options):
+ """
+ driver: [pci-assign | virtio-net-pci | ...]
+ prop_[host | addr | ...]: value
+ note:the sub-property will be decided according to the driver.
+ """
+ if 'driver' in options.keys() and \
+ options['driver']:
+ if options['driver'] == 'pci-assign':
+ self.__add_vm_pci_assign(**options)
+ elif options['driver'] == 'virtio-net-pci':
+ self.__add_vm_virtio_net_pci(**options)
+
+ def __add_vm_pci_assign(self, **options):
+ """
+ driver: pci-assign
+ prop_host: 08:00.0
+ prop_addr: 00:00:00:00:01:02
+ """
+ dev_boot_line = '-device pci-assign'
+ separator = ','
+ if 'prop_host' in options.keys() and \
+ options['prop_host']:
+ dev_boot_line += separator + 'host=%s' % options['prop_host']
+ if 'prop_addr' in options.keys() and \
+ options['prop_addr']:
+ dev_boot_line += separator + 'addr=%s' % options['prop_addr']
+ self.assigned_pcis.append(options['prop_addr'])
+
+ if self.__string_has_multi_fields(dev_boot_line, separator):
+ self.__add_boot_line(dev_boot_line)
+
+ def __add_vm_virtio_net_pci(self, **options):
+ """
+ driver: virtio-net-pci
+ prop_netdev: mynet1
+ prop_id: net1
+ prop_mac: 00:00:00:00:01:03
+ prop_bus: pci.0
+ prop_addr: 0x3
+ """
+ dev_boot_line = '-device virtio-net-pci'
+ separator = ','
+ if 'prop_netdev' in options.keys() and \
+ options['prop_netdev']:
+ dev_boot_line += separator + 'netdev=%s' % options['prop_netdev']
+ if 'prop_id' in options.keys() and \
+ options['prop_id']:
+ dev_boot_line += separator + 'id=%s' % options['prop_id']
+ if 'prop_mac' in options.keys() and \
+ options['prop_mac']:
+ dev_boot_line += separator + 'mac=%s' % options['prop_mac']
+ if 'prop_bus' in options.keys() and \
+ options['prop_bus']:
+ dev_boot_line += separator + 'bus=%s' % options['prop_bus']
+ if 'prop_addr' in options.keys() and \
+ options['prop_addr']:
+ dev_boot_line += separator + 'addr=%s' % options['prop_addr']
+
+ if self.__string_has_multi_fields(self, string, separator):
+ self.__add_boot_line(dev_boot_line)
+
+ def __string_has_multi_fields(self, string, separator, field_num=2):
+ """
+ Check if string has multiple fields which is splited with
+ specified separator.
+ """
+ fields = string.split(separator)
+ number = 0
+ for field in fields:
+ if field:
+ number += 1
+ if number >= field_num:
+ return True
+ else:
+ return False
+
+ def add_vm_monitor(self, **options):
+ """
+ port: 6061 # if adding monitor to vm, need to specicy
+ this port, else it will get a free port
+ on the host machine.
+ """
+ if 'port' in options.keys():
+ if options['port']:
+ port = options['port']
+ else:
+ port = self.virt_pool.alloc_port(self.vm_name)
+
+ monitor_boot_line = '-monitor tcp::%d,server,nowait' % int(port)
+ self.__add_boot_line(monitor_boot_line)
+
+ def set_vm_qga(self, enable='yes'):
+ """
+ Set VM qemu-guest-agent.
+ """
+ index = self.find_option_index('qga')
+ if index:
+ self.params[index] = {'qga': [{'enable': '%s' % enable}]}
+ else:
+ self.params.append({'qga': [{'enable': '%s' % enable}]})
+ QGA_SOCK_PATH = QGA_SOCK_PATH_TEMPLATE % {'vm_name': self.vm_name}
+ self.qga_sock_path = QGA_SOCK_PATH
+
+ def add_vm_qga(self, **options):
+ """
+ enable: 'yes'
+ """
+ QGA_DEV_ID = '%(vm_name)s_qga0' % {'vm_name': self.vm_name}
+ QGA_SOCK_PATH = QGA_SOCK_PATH_TEMPLATE % {'vm_name': self.vm_name}
+
+ separator = ' '
+
+ if 'enable' in options.keys():
+ if options['enable'] == 'yes':
+ qga_boot_block = '-chardev socket,path=%(SOCK_PATH)s,server,nowait,id=%(ID)s' + \
+ separator + '-device virtio-serial' + separator + \
+ '-device virtserialport,chardev=%(ID)s,name=%(DEV_NAME)s'
+ qga_boot_line = qga_boot_block % {'SOCK_PATH': QGA_SOCK_PATH,
+ 'DEV_NAME': QGA_DEV_NAME,
+ 'ID': QGA_DEV_ID}
+ self.__add_boot_line(qga_boot_line)
+ self.qga_sock_path = QGA_SOCK_PATH
+ else:
+ self.qga_sock_path = ''
+
+ def add_vm_serial_port(self, **options):
+ """
+ enable: 'yes'
+ """
+ SERAIL_SOCK_PATH = "/tmp/%s_serial.sock" % self.vm_name
+ if 'enable' in options.keys():
+ if options['enable'] == 'yes':
+ serial_boot_line = '-serial unix:%s,server,nowait' % SERIAL_SOCK_PATH
+ self.__add_boot_line(serial_boot_line)
+ else:
+ pass
+
+ def add_vm_vnc(self, **options):
+ """
+ displayNum: 1
+ """
+ if 'displayNum' in options.keys() and \
+ options['displayNum']:
+ display_num = options['displayNum']
+ else:
+ display_num = self.virt_pool.alloc_vnc_num(self.vm_name)
+
+ vnc_boot_line = '-vnc :%d' % int(display_num)
+ self.__add_boot_line(vnc_boot_line)
+
+ def set_vm_daemon(self, enable='yes'):
+ """
+ Set VM daemon option.
+ """
+ index = self.find_option_index('daemon')
+ if index:
+ self.params[index] = {'daemon': [{'enable': '%s' % enable}]}
+ else:
+ self.params.append({'daemon': [{'enable': '%s' % enable}]})
+
+ def add_vm_daemon(self, **options):
+ """
+ enable: 'yes'
+ note:
+ By default VM will start with the daemonize status.
+ Not support starting it on the stdin now.
+ """
+ if 'daemon' in options.keys() and \
+ options['enable'] == 'no':
+ pass
+ else:
+ daemon_boot_line = '-daemonize'
+ self.__add_boot_line(daemon_boot_line)
+
+ def start_vm(self):
+ """
+ Start VM.
+ """
+ qemu_emulator = self.qemu_emulator
+
+ self.__alloc_assigned_pcis()
+
+ if self.vcpus_pinned_to_vm.strip():
+ vcpus = self.__alloc_vcpus()
+
+ if vcpus.strip():
+ whole_qemu_kvm_boot_line = 'taskset -c %s ' % vcpus + \
+ qemu_emulator + ' ' + \
+ self.whole_qemu_kvm_boot_line
+ else:
+ whole_qemu_kvm_boot_line = qemu_emulator + ' ' + \
+ self.whole_qemu_kvm_boot_line
+
+ # Start VM using the qemu command
+ out = self.host_session.send_expect(whole_qemu_kvm_boot_line, '# ')
+ time.sleep(30)
+ if out:
+ raise StartVMFailedException(out)
+
+ def __alloc_vcpus(self):
+ """
+ Allocate virtual CPUs for VM.
+ """
+ req_cpus = self.vcpus_pinned_to_vm.split()
+ cpus = self.virt_pool.alloc_cpu(vm=self.vm_name, corelist=req_cpus)
+
+ vcpus_pinned_to_vm = ''
+ for cpu in cpus:
+ vcpus_pinned_to_vm += ',' + cpu
+ vcpus_pinned_to_vm = vcpus_pinned_to_vm.lstrip(',')
+
+ if len(req_cpus) != len(cpus):
+ print "WARNING: Just pin vcpus [ %s ] to VM!" % vcpus_pinned_to_vm
+
+ return vcpus_pinned_to_vm
+
+ def __alloc_assigned_pcis(self):
+ """
+ Record the PCI device info
+ Struct: {dev pci: {'is_vf': [True | False],
+ 'pf_pci': pci}}
+ example:
+ {'08:10.0':{'is_vf':True, 'pf_pci': 08:00.0}}
+ """
+ assigned_pcis_info = {}
+ for pci in self.assigned_pcis:
+ assigned_pcis_info[pci] = {}
+ if self.__is_vf_pci(pci):
+ assigned_pcis_info[pci]['is_vf'] = True
+ pf_pci = self.__map_vf_to_pf(pci)
+ assgined_pcis_info[pci]['pf_pci'] = pf_pci
+ if self.virt_pool.alloc_vf_from_pf(vm=self.vm_name,
+ pf_pci=pf_pci,
+ *[pci]):
+ port = self.__get_vf_port(pci)
+ port.unbind_driver()
+ port.bind_driver('pci-stub')
+ else:
+ # check that if any VF of specified PF has been
+ # used, raise exception
+ vf_pci = self.__vf_has_been_assinged(pci, **assinged_pcis_info)
+ if vf_pci:
+ raise Exception(
+ "Error: A VF [%s] generated by PF [%s] has " %
+ (vf_pci, pci) +
+ "been assigned to VM, so this PF can not be " +
+ "assigned to VM again!")
+ # get the port instance of PF
+ port = self.__get_net_device_by_pci(pci)
+
+ if self.virt_pool.alloc_pf(vm=self.vm_name,
+ *[pci]):
+ port.unbind_driver()
+
+ def __is_vf_pci(self, dev_pci):
+ """
+ Check if the specified PCI dev is a VF.
+ """
+ for port_info in self.host_dut.ports_info:
+ if 'sriov_vfs_pci' in port_info.keys():
+ if dev_pci in port_info['sriov_vfs_pci']:
+ return True
+ return False
+
+ def __map_vf_to_pf(self, dev_pci):
+ """
+ Map the specified VF to PF.
+ """
+ for port_info in self.host_dut.ports_info:
+ if 'sriov_vfs_pci' in port_info.keys():
+ if dev_pci in port_info['sriov_vfs_pci']:
+ return port_info['pci']
+ return None
+
+ def __get_vf_port(self, dev_pci):
+ """
+ Get the NetDevice instance of specified VF.
+ """
+ for port_info in self.host_dut.ports_info:
+ if 'vfs_port' in port_info.keys():
+ for port in port_info['vfs_port']:
+ if dev_pci == port.pci:
+ return port
+ return None
+
+ def __vf_has_been_assigned(self, pf_pci, **assigned_pcis_info):
+ """
+ Check if the specified VF has been used.
+ """
+ for pci in assigned_pcis_info.keys():
+ if assigned_pcis_info[pci]['is_vf'] and \
+ assigned_pcis_info[pci]['pf_pci'] == pf_pci:
+ return pci
+ return False
+
+ def __get_net_device_by_pci(self, net_device_pci):
+ """
+ Get NetDevice instance by the specified PCI bus number.
+ """
+ port_info = self.host_dut.get_port_info(net_device_pci)
+ return port_info['port']
+
+ def get_vm_ip(self):
+ """
+ Get VM IP.
+ """
+ get_vm_ip = getattr(self, "get_vm_ip_%s" % self.net_type)
+ return get_vm_ip()
+
+ def get_vm_ip_hostfwd(self):
+ """
+ Get IP which VM is connected by hostfwd.
+ """
+ return self.hostfwd_addr
+
+ def get_vm_ip_bridge(self):
+ """
+ Get IP which VM is connected by bridge.
+ """
+ out = self.__control_session('ping', '60')
+ if not out:
+ time.sleep(10)
+ out = self.__control_session('ifconfig')
+ ips = re.findall(r'inet (\d+\.\d+\.\d+\.\d+)', out)
+
+ if '127.0.0.1' in ips:
+ ips.remove('127.0.0.1')
+
+ num = 3
+ for ip in ips:
+ out = self.host_session.send_expect(
+ 'ping -c %d %s' % (num, ip), '# ')
+ if '0% packet loss' in out:
+ return ip
+ return ''
+
+ def __control_session(self, command, *args):
+ """
+ Use the qemu guest agent service to control VM.
+ Note:
+ :command: there are these commands as below:
+ cat, fsfreeze, fstrim, halt, ifconfig, info,\
+ ping, powerdown, reboot, shutdown, suspend
+ :args: give different args by the different commands.
+ """
+ if not self.qga_sock_path:
+ self.host_logger.info(
+ "No QGA service between host [ %s ] and guest [ %s ]" %
+ (self.host_dut.Name, self.vm_name))
+ return None
+
+ cmd_head = '~/QMP/' + \
+ "qemu-ga-client " + \
+ "--address=%s %s" % \
+ (self.qga_sock_path, command)
+
+ cmd = cmd_head
+ for arg in args:
+ cmd = cmd_head + ' ' + str(arg)
+
+ out = self.host_session.send_expect(cmd, '# ')
+
+ return out
+
+ def stop(self):
+ """
+ Stop VM.
+ """
+ self.__control_session('powerdown')
+ time.sleep(5)
+ self.virt_pool.free_all_resource(self.vm_name)
+
+
+if __name__ == "__main__":
+ import subprocess
+ import sys
+ import pdb
+ from serializer import Serializer
+ from crbs import crbs
+ from tester import Tester
+ from dut import Dut
+ import dts
+ from virt_proxy import VirtProxy
+
+ command = "ifconfig br0"
+ subp = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
+ subp.wait()
+
+ intf_info = subp.stdout.readlines()
+ for line_info in intf_info:
+ regx = re.search(r'inet (\d+\.\d+\.\d+\.\d+)', line_info)
+ if regx:
+ dutIP = regx.group(1)
+ break
+
+ print "DEBUG: dutIp: ", dutIP
+
+ # look up in crbs - to find the matching IP
+ crbInst = None
+ for crb in crbs:
+ if crb['IP'] == dutIP:
+ crbInst = crb
+ break
+
+ # only run on the dut in known crbs
+ if crbInst is None:
+ raise Exception("No available crb instance!!!")
+
+ # initialize the dut and tester
+ serializer = Serializer()
+ serializer.set_serialized_filename('../.%s.cache' % crbInst['IP'])
+ serializer.load_from_file()
+
+ read_cache = None
+ skip_setup = None
+
+ project = "dpdk"
+ dts.Package = 'dep/dpdk.tar.gz'
+ dut = dts.get_project_obj(project, Dut, crbInst, serializer)
+ tester = dts.get_project_obj(project, Tester, crbInst, serializer)
+ dut.tester = tester
+ dut.base_dir = 'dpdk'
+ dut.set_nic_type('niantic')
+ tester.dut = dut
+
+ tester.set_test_types(True, False)
+ dut.set_test_types(True, False)
+
+ tester.set_speedup_options(read_cache, skip_setup)
+ tester.tester_prerequisites()
+ dut.set_speedup_options(read_cache, skip_setup)
+ dut.dut_prerequisites()
+
+ # test that generating and destroying VF
+ port0 = dut.ports_info[0]['port']
+ dut.generate_sriov_vfs_by_port(0, 4)
+ print "port 0 sriov vfs: ", dut.ports_info[0]
+
+ dut.destroy_sriov_vfs_by_port(0)
+
+ time.sleep(2)
+
+ # test that binding and unbing the NIC
+ port0_pci = dut.ports_info[0]['pci']
+ port0.unbind_driver()
+
+ dut.logger.info("JUST TESTING!!!")
+
+ # Start VM by the qemu kvm config file
+ vm1 = QEMUKvm(dut, 'vm1', 'pmd_sriov')
+ print "VM config params:"
+ print vm1.params
+ vm1_dut = vm1.start()
+
+ try:
+ host_ip = vm1.session.send_expect("ifconfig", '# ')
+ print "Host IP:"
+ print host_ip
+
+ vm1_ip = vm1.get_vm_ip()
+ print "VM1 IP:"
+ print vm1_ip
+
+ print "VM1 PCI device:"
+ print vm_dut.session.send_expect('lspci -nn | grep -i eth', '# ')
+ except Exception as e:
+ print e
+ vm1_dut.stop()
+ port0.bind_driver()
+ # Stop VM
+ vm1.stop()
+ port0.bind_driver()
+
+ dut.host_logger.logger_exit()
+ dut.logger.logger_exit()
+ tester.logger.logger_exit()
+
+ print "Start and stop VM over!"
diff --git a/framework/virt_base.py b/framework/virt_base.py
new file mode 100644
index 0000000..625c309
--- /dev/null
+++ b/framework/virt_base.py
@@ -0,0 +1,250 @@
+# <COPYRIGHT_TAG>
+
+from random import randint
+from itertools import imap
+
+import dts
+from dut import Dut
+from config import VirtConf
+from config import VIRTCONF
+from logger import getLogger
+from settings import CONFIG_ROOT_PATH
+from virt_dut import VirtDut
+
+
+class VirtBase(object):
+
+ """
+ Basic module for customer special virtual type. This module implement functions
+ configurated and composed the VM boot command. With these function, we can get
+ and set the VM boot command, and instantiate the VM.
+ """
+
+ def __init__(self, dut, vm_name, suite_name):
+ """
+ Initialize the VirtBase.
+ dut: the instance of Dut
+ vm_name: the name of VM which you have confiured in the configure
+ suite_name: the name of test suite
+ """
+ self.host_dut = dut
+ self.vm_name = vm_name
+ self.suite = suite_name
+
+ # init the host session and logger for VM
+ self.host_dut.init_host_session()
+
+ # replace dut session
+ self.host_session = self.host_dut.host_session
+ self.host_logger = self.host_dut.logger
+
+ # init the host resouce pool for VM
+ self.virt_pool = self.host_dut.virt_pool
+
+ if not self.has_virtual_ability():
+ if not self.enable_virtual_ability():
+ raise Exception(
+ "Dut [ %s ] cannot have the virtual ability!!!")
+
+ self.virt_type = self.get_virt_type()
+ self.load_global_config()
+ self.load_local_config(suite_name)
+
+ def get_virt_type(self):
+ """
+ Get the virtual type, such as KVM, XEN or LIBVIRT.
+ """
+ NotImplemented
+
+ def has_virtual_ability(self):
+ """
+ Check if the host have the ability of virtualization.
+ """
+ NotImplemented
+
+ def enable_virtual_ability(self):
+ """
+ Enalbe the virtual ability on the DUT.
+ """
+ NotImplemented
+
+ def load_global_config(self):
+ """
+ Load global configure in the path DTS_ROOT_PAHT/conf.
+ """
+ conf = VirtConf(VIRTCONF)
+ conf.load_virt_config(self.virt_type)
+ self.params = conf.get_virt_config()
+
+ def load_local_config(self, suite_name):
+ """
+ Load local configure in the path DTS_ROOT_PATH/conf.
+ """
+ # load local configuration by suite and vm name
+ conf = VirtConf(CONFIG_ROOT_PATH + suite_name + '.cfg')
+ conf.load_virt_config(self.vm_name)
+ localparams = conf.get_virt_config()
+ # replace global configurations with local configurations
+ for param in localparams:
+ if 'mem' in param.keys():
+ self.__save_local_config('mem', param['mem'])
+ continue
+ if 'cpu' in param.keys():
+ self.__save_local_config('cpu', param['cpu'])
+ continue
+ # save local configurations
+ self.params.append(param)
+
+ def __save_local_config(self, key, value):
+ """
+ Save the local config into the global dict self.param.
+ """
+ for param in self.params:
+ if key in param.keys():
+ param[key] = value
+
+ def compose_boot_param(self):
+ """
+ Compose all boot param for starting the VM.
+ """
+ for param in self.params:
+ key = param.keys()[0]
+ value = param[key]
+ try:
+ param_func = getattr(self, 'add_vm_' + key)
+ if callable(param_func):
+ for option in value:
+ param_func(**option)
+ else:
+ print "Virt %s function not implemented!!!" % key
+ except Exception as e:
+ print "Failed: ", e
+
+ def find_option_index(self, option):
+ """
+ Find the boot option in the params which is generated from
+ the global and local configures, and this function will
+ return the index by which option can be indexed in the
+ param list.
+ """
+ index = 0
+ for param in self.params:
+ key = param.keys()[0]
+ if key.strip() == option.strip():
+ return index
+ index += 1
+
+ return None
+
+ def generate_unique_mac(self):
+ """
+ Generate a unique MAC based on the DUT.
+ """
+ mac_head = '00:00:00:'
+ mac_tail = ':'.join(
+ ['%02x' % x for x in imap(lambda x:randint(0, 255), range(3))])
+ return mac_head + mac_tail
+
+ def get_vm_ip(self):
+ """
+ Get the VM IP.
+ """
+ NotImplemented
+
+ def start(self):
+ """
+ Start VM and instantiate the VM with VirtDut.
+ """
+ self.compose_boot_param()
+ try:
+ self.start_vm()
+ except Exception as e:
+ self.host_logger.error(e)
+ return None
+ try:
+ vm_dut = self.instantiate_vm_dut()
+ except Exception as e:
+ self.host_logger.error(e)
+ self.stop()
+ return None
+ return vm_dut
+
+ def start_vm(self):
+ """
+ Start VM.
+ """
+ NotImplemented
+
+ def instantiate_vm_dut(self):
+ """
+ Instantiate the Dut class for VM.
+ """
+ crb = self.host_dut.crb.copy()
+ crb['bypass core0'] = False
+ vm_ip = self.get_vm_ip()
+ crb['IP'] = vm_ip
+ if ':' not in vm_ip:
+ remote_ip = vm_ip.strip()
+ redirect_port = ''
+ else:
+ remote_addr = vm_ip.split(':')
+ remote_ip = remote_addr[0].strip()
+ redirect_port = remote_addr[1].strip()
+ self.__remove_old_rsa_key(remote_ip, redirect_port)
+
+ serializer = self.host_dut.serializer
+
+ try:
+ vm_dut = VirtDut(
+ crb,
+ serializer,
+ self.virt_type,
+ self.vm_name,
+ self.suite)
+ except Exception as e:
+ raise Exception(e)
+ vm_dut.nic_type = 'any'
+ vm_dut.tester = self.host_dut.tester
+ vm_dut.host_dut = self.host_dut
+ vm_dut.host_session = self.host_session
+
+ read_cache = False
+ skip_setup = self.host_dut.skip_setup
+ base_dir = self.host_dut.base_dir
+ vm_dut.set_speedup_options(read_cache, skip_setup)
+ func_only = self.host_dut.want_func_tests
+ perf_only = self.host_dut.want_perf_tests
+ vm_dut.set_test_types(func_tests=func_only, perf_tests=perf_only)
+ # base_dir should be set before prerequisites
+ vm_dut.set_directory(base_dir)
+
+ # setting up dpdk in vm, must call at last
+ vm_dut.prerequisites(dts.Package, dts.Patches)
+
+ target = self.host_dut.target
+ if target:
+ vm_dut.set_target(target)
+ else:
+ raise Exception("Cannot get the HOST DUT test target!")
+
+ return vm_dut
+
+ def __remove_old_rsa_key(self, remote_ip, redirect_port):
+ """
+ Remove the old RSA key of specified remote IP.
+ """
+ rsa_key_path = "~/.ssh/known_hosts"
+ if redirect_port:
+ remove_rsa_key_cmd = "sed -i '/^\[%s\]:%d/d' %s" % \
+ (remote_ip.strip(), int(
+ redirect_port), rsa_key_path)
+ else:
+ remove_rsa_key_cmd = "sed -i '/^%s/d' %s" % \
+ (remote_ip.strip(), rsa_key_path)
+ self.host_dut.tester.send_expect(remove_rsa_key_cmd, "# ")
+
+ def stop(self):
+ """
+ Stop the VM by the name of VM.
+ """
+ NotImplemented
diff --git a/framework/virt_dut.py b/framework/virt_dut.py
new file mode 100644
index 0000000..1073253
--- /dev/null
+++ b/framework/virt_dut.py
@@ -0,0 +1,239 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2015 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.
+
+import os
+import re
+import time
+import dts
+import settings
+from config import PortConf
+from settings import NICS, LOG_NAME_SEP
+from ssh_connection import SSHConnection
+from project_dpdk import DPDKdut
+from dut import Dut
+from net_device import NetDevice
+from logger import getLogger
+
+
+class VirtDut(DPDKdut):
+
+ """
+ A connection to the CRB under test.
+ This class sends commands to the CRB and validates the responses. It is
+ implemented using either ssh for linuxapp or the terminal server for
+ baremetal.
+ All operations are in fact delegated to an instance of either CRBLinuxApp
+ or CRBBareMetal.
+ """
+
+ def __init__(self, crb, serializer, virttype, vm_name, suite):
+ super(Dut, self).__init__(crb, serializer)
+ self.vm_ip = self.get_ip_address()
+ self.NAME = 'virtdut' + LOG_NAME_SEP + '%s' % self.vm_ip
+ # load port config from suite cfg
+ self.suite = suite
+ self.logger = getLogger(self.NAME)
+ self.logger.config_execution('vmdut')
+ self.session = SSHConnection(self.vm_ip, self.NAME,
+ self.get_password())
+ self.session.init_log(self.logger)
+
+ # if redirect ssh port, there's only one session enabled
+ self.alt_session = SSHConnection(self.vm_ip, self.NAME + '_alt',
+ self.get_password())
+ self.alt_session.init_log(self.logger)
+
+ self.number_of_cores = 0
+ self.tester = None
+ self.cores = []
+ self.architecture = None
+ self.ports_info = None
+ self.ports_map = []
+ self.virttype = virttype
+ self.vmtype = ''
+ if self.virttype == 'XEN':
+ self.vmtype = 'domu'
+ self.virttype = 'host'
+
+ def set_nic_type(self, nic_type):
+ """
+ Set CRB NICS ready to validated.
+ """
+ self.nic_type = nic_type
+ # vm_dut config will load from vm configuration file
+
+ def load_portconf(self):
+ """
+ Load port config for this virtual machine
+ """
+ return
+
+ def set_target(self, target):
+ """
+ Set env variable, these have to be setup all the time. Some tests
+ need to compile example apps by themselves and will fail otherwise.
+ Set hugepage on DUT and install modules required by DPDK.
+ Configure default ixgbe PMD function.
+ """
+ self.set_toolchain(target)
+
+ # set env variable
+ # These have to be setup all the time. Some tests need to compile
+ # example apps by themselves and will fail otherwise.
+ self.send_expect("export RTE_TARGET=" + target, "#")
+ self.send_expect("export RTE_SDK=`pwd`", "#")
+
+ if not self.skip_setup:
+ self.build_install_dpdk(target)
+
+ self.setup_memory(hugepages=512)
+ self.setup_modules(target)
+
+ self.bind_interfaces_linux('igb_uio')
+
+ def prerequisites(self, pkgName, patch):
+ """
+ Prerequest function should be called before execute any test case.
+ Will call function to scan all lcore's information which on DUT.
+ Then call pci scan function to collect nic device information.
+ At last setup DUT' environment for validation.
+ """
+ self.prepare_package(pkgName, patch)
+
+ self.send_expect("cd %s" % self.base_dir, "# ")
+ self.host_session.send_expect("cd %s" % self.base_dir, "# ")
+ self.send_expect("alias ls='ls --color=none'", "#")
+
+ if self.get_os_type() == 'freebsd':
+ self.send_expect('alias make=gmake', '# ')
+ self.send_expect('alias sed=gsed', '# ')
+
+ self.init_core_list()
+ self.pci_devices_information()
+
+ # scan ports before restore interface
+ self.scan_ports()
+ # restore dut ports to kernel
+ if self.vmtype != 'domu':
+ self.restore_interfaces()
+ else:
+ self.restore_interfaces_domu()
+ # rescan ports after interface up
+ self.rescan_ports()
+
+ # no need to rescan ports for guest os just bootup
+ # load port infor from config file
+ self.load_portconf()
+
+ # enable tester port ipv6
+ self.host_dut.enable_tester_ipv6()
+ self.mount_procfs()
+ # auto detect network topology
+ self.map_available_ports()
+ # disable tester port ipv6
+ self.host_dut.disable_tester_ipv6()
+
+ # print latest ports_info
+ for port_info in self.ports_info:
+ self.logger.info(port_info)
+
+ def restore_interfaces_domu(self):
+ """
+ Restore Linux interfaces.
+ """
+ for port in self.ports_info:
+ pci_bus = port['pci']
+ pci_id = port['type']
+ driver = settings.get_nic_driver(pci_id)
+ if driver is not None:
+ addr_array = pci_bus.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+ port = NetDevice(self, bus_id, devfun_id)
+ itf = port.get_interface_name()
+ self.send_expect("ifconfig %s up" % itf, "# ")
+ time.sleep(30)
+ print self.send_expect("ip link ls %s" % itf, "# ")
+ else:
+ self.logger.info(
+ "NOT FOUND DRIVER FOR PORT (%s|%s)!!!" % (pci_bus, pci_id))
+
+ def pci_devices_information(self):
+ self.pci_devices_information_uncached()
+
+ def get_memory_channels(self):
+ """
+ Virtual machine has no memory channel concept, so always return 1
+ """
+ return 1
+
+ def check_ports_available(self, pci_bus, pci_id):
+ """
+ Check that whether auto scanned ports ready to use
+ """
+ pci_addr = "%s:%s" % (pci_bus, pci_id)
+ if pci_id == "8086:100e":
+ return False
+ return True
+ # pci_addr = "%s:%s" % (pci_bus, pci_id)
+ # if self.nic_type == 'any':
+ # load vm port conf need another function
+ # need add vitrual function device into NICS
+
+ def scan_ports(self):
+ """
+ Scan ports information, for vm will always scan
+ """
+ self.scan_ports_uncached()
+
+ def scan_ports_uncached(self):
+ """
+ Scan ports and collect port's pci id, mac adress, ipv6 address.
+ """
+ scan_ports_uncached = getattr(
+ self, 'scan_ports_uncached_%s' % self.get_os_type())
+ return scan_ports_uncached()
+
+ def map_available_ports(self):
+ """
+ Load or generate network connection mapping list.
+ """
+ self.map_available_ports_uncached()
+ self.logger.warning("DUT PORT MAP: " + str(self.ports_map))
+
+ def send_ping6(self, localPort, ipv6, mac=''):
+ """
+ Send ping6 packet from local port with destination ipv6 address.
+ """
+ if self.ports_info[localPort]['type'] == 'ixia':
+ pass
+ else:
+ return self.send_expect("ping6 -w 1 -c 1 -A -I %s %s" % (self.ports_info[localPort]['intf'], ipv6), "# ", 10)
diff --git a/framework/virt_resource.py b/framework/virt_resource.py
new file mode 100644
index 0000000..856f9dc
--- /dev/null
+++ b/framework/virt_resource.py
@@ -0,0 +1,486 @@
+#!/usr/bin/python
+# BSD LICENSE
+#
+# Copyright(c) 2010-2015 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.
+from random import randint
+
+from utils import get_obj_funcs
+
+INIT_FREE_PORT = 6060
+
+
+class VirtResource(object):
+
+ """
+ Class handle dut resource, like cpu, memory, net devices
+ """
+
+ def __init__(self, dut):
+ self.dut = dut
+
+ self.cores = [int(core['thread']) for core in dut.cores]
+ # initialized unused cores
+ self.unused_cores = self.cores[:]
+ # initialized used cores
+ self.used_cores = [-1] * len(self.unused_cores)
+
+ self.ports_info = dut.ports_info
+ # initialized unused ports
+ self.ports = [port['pci'] for port in dut.ports_info]
+ self.unused_ports = self.ports[:]
+ # initialized used ports
+ self.used_ports = ['unused'] * len(self.unused_ports)
+
+ # initialized vf ports
+ self.vfs_info = []
+ self.vfs = []
+ self.unused_vfs = []
+ self.used_vfs = []
+
+ # save allocated cores and related vm
+ self.allocated_info = {}
+
+ def __port_used(self, pci):
+ index = self.ports.index(pci)
+ self.used_ports[index] = pci
+ self.unused_ports[index] = 'used'
+
+ def __port_unused(self, pci):
+ index = self.ports.index(pci)
+ self.unused_ports[index] = pci
+ self.used_ports[index] = 'unused'
+
+ def __port_on_socket(self, pci, socket):
+ for port in self.ports_info:
+ if port['pci'] == pci:
+ if socket is -1:
+ return True
+
+ if port['numa'] == socket:
+ return True
+ else:
+ return False
+
+ return False
+
+ def __vf_used(self, pci):
+ index = self.vfs.index(pci)
+ self.used_vfs[index] = pci
+ self.unused_vfs[index] = 'used'
+
+ def __vf_unused(self, pci):
+ index = self.vfs.index(pci)
+ self.used_vfs[index] = 'unused'
+ self.unused_vfs[index] = pci
+
+ def __core_used(self, core):
+ core = int(core)
+ index = self.cores.index(core)
+ self.used_cores[index] = core
+ self.unused_cores[index] = -1
+
+ def __core_unused(self, core):
+ core = int(core)
+ index = self.cores.index(core)
+ self.unused_cores[index] = core
+ self.used_cores[index] = -1
+
+ def __core_on_socket(self, core, socket):
+ for dut_core in self.dut.cores:
+ if int(dut_core['thread']) == core:
+ if socket is -1:
+ return True
+
+ if int(dut_core['socket']) == socket:
+ return True
+ else:
+ return False
+
+ return False
+
+ def __core_isused(self, core):
+ index = self.cores.index(core)
+ if self.used_cores[index] != -1:
+ return True
+ else:
+ return False
+
+ def reserve_cpu(self, coremask=''):
+ """
+ Reserve dpdk used cpus by mask
+ """
+ val = int(coremask, base=16)
+ cpus = []
+ index = 0
+ while val != 0:
+ if val & 0x1:
+ cpus.append(index)
+
+ val = val >> 1
+ index += 1
+
+ for cpu in cpus:
+ self.__core_used(cpu)
+
+ def alloc_cpu(self, vm='', number=-1, socket=-1, corelist=None):
+ """
+ There're two options for request cpu resouce for vm.
+ If number is not -1, just allocate cpu from not used cores.
+ If list is not None, will allocate cpu after checked.
+ """
+ cores = []
+
+ if vm == '':
+ print "Alloc cpu request vitual machine name!!!"
+ return cores
+
+ if number != -1:
+ for core in self.unused_cores:
+ if core != -1 and number != 0:
+ if self.__core_on_socket(core, socket) is True:
+ self.__core_used(core)
+ cores.append(str(core))
+ number = number - 1
+ if number != 0:
+ print "Can't allocated requested cpu!!!"
+
+ if corelist is not None:
+ for core in corelist:
+ if self.__core_isused(int(core)) is True:
+ print "Core %s has been used!!!" % core
+ else:
+ if self.__core_on_socket(int(core), socket) is True:
+ self.__core_used(int(core))
+ cores.append(core)
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['cores'] = cores
+ return cores
+
+ def __vm_has_resource(self, vm, resource=''):
+ if vm == '':
+ self.dut.logger.info("VM name cannt be NULL!!!")
+ raise Exception("VM name cannt be NULL!!!")
+ if vm not in self.allocated_info:
+ self.dut.logger.info(
+ "There is no resource allocated to VM [%s]." % vm)
+ return False
+ if resource == '':
+ return True
+ if resource not in self.allocated_info[vm]:
+ self.dut.logger.info(
+ "There is no resource [%s] allocated to VM [%s] " %
+ (resource, vm))
+ return False
+ return True
+
+ def free_cpu(self, vm):
+ if self.__vm_has_resource(vm, 'cores'):
+ for core in self.allocated_info[vm]['cores']:
+ self.__core_unused(core)
+ self.allocated_info[vm].pop('cores')
+
+ def alloc_pf(self, vm='', number=-1, socket=-1, pflist=[]):
+ """
+ There're two options for request pf devices for vm.
+ If number is not -1, just allocate pf device from not used pfs.
+ If list is not None, will allocate pf devices after checked.
+ """
+ ports = []
+
+ if number != -1:
+ for pci in self.unused_ports:
+ if pci != 'unused' and number != 0:
+ if self.__port_on_socket(pci, socket) is True:
+ self.__port_used(pci)
+ ports.append(pci)
+ number = number - 1
+ if number != 0:
+ print "Can't allocated requested PF devices!!!"
+
+ if pflist is not None:
+ for pci in pflist:
+ if self.__port_isused(pci) is True:
+ print "Port %s has been used!!!" % pci
+ else:
+ if self.__port_on_socket(pci, socket) is True:
+ self.__port_used(core)
+ ports.append(core)
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['ports'] = ports
+ return ports
+
+ def free_pf(self, vm):
+ if self.__vm_has_resource(vm, 'ports'):
+ for pci in self.allocated_info[vm]['ports']:
+ self.__port_unused(pci)
+ self.allocated_info[vm].pop('ports')
+
+ def alloc_vf_from_pf(self, vm='', pf_pci='', number=-1, vflist=[]):
+ """
+ There're two options for request vf devices of pf device.
+ If number is not -1, just allocate vf device from not used vfs.
+ If list is not None, will allocate vf devices after checked.
+ """
+ vfs = []
+ if vm == '':
+ print "Alloc VF request vitual machine name!!!"
+ return vfs
+
+ if pf_pci == '':
+ print "Alloc VF request PF pci address!!!"
+ return vfs
+
+ for vf_info in self.vfs_info:
+ if vf_info['pf_pci'] == pf_pci:
+ if vf_info['pci'] in vflist:
+ vfs.append(vf_info['pci'])
+ continue
+
+ if number > 0:
+ vfs.append(vf_info['pci'])
+ number = number - 1
+
+ for vf in vfs:
+ self.__vf_used(vf)
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['vfs'] = vfs
+ return vfs
+
+ def free_vf(self, vm):
+ if self.__vm_has_resource(vm, 'vfs'):
+ for pci in self.allocated_info[vm]['vfs']:
+ self.__vf_unused(pci)
+ self.allocated_info[vm].pop('vfs')
+
+ def add_vf_on_pf(self, pf_pci='', vflist=[]):
+ """
+ Add vf devices generated by specified pf devices.
+ """
+ # add vfs into vf info list
+ vfs = []
+ for vf in vflist:
+ if vf not in self.vfs:
+ self.vfs_info.append({'pci': vf, 'pf_pci': pf_pci})
+ vfs.append(vf)
+ used_vfs = ['unused'] * len(vflist)
+ self.unused_vfs += vfs
+ self.used_vfs += used_vfs
+ self.vfs += vfs
+
+ def del_vf_on_pf(self, pf_pci='', vflist=[]):
+ """
+ Remove vf devices generated by specified pf devices.
+ """
+ vfs = []
+ for vf in vflist:
+ for vfs_info in self.vfs_info:
+ if vfs_info['pci'] == vf:
+ vfs.append(vf)
+
+ for vf in vfs:
+ try:
+ index = self.vfs.index(vf)
+ except:
+ continue
+ del self.vfs_info[index]
+ del self.unused_vfs[index]
+ del self.used_vfs[index]
+ del self.vfs[index]
+
+ def alloc_port(self, vm=''):
+ """
+ Allocate unused host port for vm
+ """
+ if vm == '':
+ print "Alloc host port request vitual machine name!!!"
+ return None
+
+ port_start = INIT_FREE_PORT + randint(1, 100)
+ port_step = randint(1, 10)
+ port = None
+ count = 20
+ while True:
+ if self.dut.check_port_occupied(port_start) is False:
+ port = port_start
+ break
+ count -= 1
+ if count < 0:
+ print 'No available port on the host!!!'
+ break
+ port_start += port_step
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['hostport'] = port
+ return port
+
+ def free_port(self, vm):
+ if self.__vm_has_resource(vm, 'hostport'):
+ self.allocated_info[vm].pop('hostport')
+
+ def alloc_vnc_num(self, vm=''):
+ """
+ Allocate unused host VNC display number for VM.
+ """
+ if vm == '':
+ print "Alloc vnc display number request vitual machine name!!!"
+ return None
+
+ max_vnc_display_num = self.dut.get_maximal_vnc_num()
+ free_vnc_display_num = max_vnc_display_num + 1
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['vnc_display_num'] = free_vnc_display_num
+
+ return free_vnc_display_num
+
+ def free_vnc_num(self, vm):
+ if self.__vm_has_resource(vm, 'vnc_display_num'):
+ self.allocated_info[vm].pop('vnc_display_num')
+
+ def free_all_resource(self, vm):
+ all_free_funcs = get_obj_funcs(self, r'free_')
+ for func in all_free_funcs:
+ if func.__name__ == 'free_all_resource':
+ continue
+ func(vm)
+ if self.__vm_has_resource(vm):
+ self.allocated_info.pop(vm)
+
+ def get_cpu_on_vm(self, vm=''):
+ """
+ Return core list on specifid VM.
+ """
+ if vm in self.allocated_info:
+ if "cores" in self.allocated_info[vm]:
+ return self.allocated_info[vm]['cores']
+
+ def get_vfs_on_vm(self, vm=''):
+ """
+ Return vf device list on specifid VM.
+ """
+ if vm in self.allocated_info:
+ if 'vfs' in self.allocated_info[vm]:
+ return self.allocated_info[vm]['vfs']
+
+ def get_pfs_on_vm(self, vm=''):
+ """
+ Return pf device list on specifid VM.
+ """
+ if vm in self.allocated_info:
+ if 'ports' in self.allocated_info[vm]:
+ return self.allocated_info[vm]['ports']
+
+
+class simple_dut(object):
+
+ def __init__(self):
+ self.ports_info = []
+ self.cores = []
+
+ def check_port_occupied(self, port):
+ return False
+
+if __name__ == "__main__":
+ dut = simple_dut()
+ dut.cores = [{'thread': '1', 'socket': '0'}, {'thread': '2', 'socket': '0'},
+ {'thread': '3', 'socket': '0'}, {'thread': '4', 'socket': '0'},
+ {'thread': '5', 'socket': '0'}, {'thread': '6', 'socket': '0'},
+ {'thread': '7', 'socket': '1'}, {'thread': '8', 'socket': '1'},
+ {'thread': '9', 'socket': '1'}, {'thread': '10', 'socket': '1'},
+ {'thread': '11', 'socket': '1'}, {'thread': '12', 'socket': '1'}]
+
+ dut.ports_info = [{'intf': 'p786p1', 'source': 'cfg', 'mac': '90:e2:ba:69:e5:e4',
+ 'pci': '08:00.0', 'numa': 0, 'ipv6': 'fe80::92e2:baff:fe69:e5e4',
+ 'peer': 'IXIA:6.5', 'type': '8086:10fb'},
+ {'intf': 'p786p2', 'source': 'cfg', 'mac': '90:e2:ba:69:e5:e5',
+ 'pci': '08:00.1', 'numa': 0, 'ipv6': 'fe80::92e2:baff:fe69:e5e5',
+ 'peer': 'IXIA:6.6', 'type': '8086:10fb'},
+ {'intf': 'p787p1', 'source': 'cfg', 'mac': '90:e2:ba:69:e5:e6',
+ 'pci': '84:00.0', 'numa': 1, 'ipv6': 'fe80::92e2:baff:fe69:e5e6',
+ 'peer': 'IXIA:6.7', 'type': '8086:10fb'},
+ {'intf': 'p787p2', 'source': 'cfg', 'mac': '90:e2:ba:69:e5:e7',
+ 'pci': '84:00.1', 'numa': 1, 'ipv6': 'fe80::92e2:baff:fe69:e5e7',
+ 'peer': 'IXIA:6.8', 'type': '8086:10fb'}]
+
+ virt_pool = VirtResource(dut)
+ print "Alloc two PF devices on socket 1 from VM"
+ print virt_pool.alloc_pf(vm='test1', number=2, socket=1)
+
+ virt_pool.add_vf_on_pf(pf_pci='08:00.0', vflist=[
+ '08:10.0', '08:10.2', '08:10.4', '08:10.6'])
+ virt_pool.add_vf_on_pf(pf_pci='08:00.1', vflist=[
+ '08:10.1', '08:10.3', '08:10.5', '08:10.7'])
+ print "Add VF devices to resource pool"
+ print virt_pool.vfs_info
+
+ print "Alloc VF device from resource pool"
+ print virt_pool.alloc_vf_from_pf(vm='test1', pf_pci='08:00.0', number=2)
+ print virt_pool.used_vfs
+ print "Alloc VF device from resource pool"
+ print virt_pool.alloc_vf_from_pf(vm='test2', pf_pci='08:00.1', vflist=['08:10.3', '08:10.5'])
+ print virt_pool.used_vfs
+
+ print "Del VF devices from resource pool"
+ virt_pool.del_vf_on_pf(pf_pci='08:00.0', vflist=['08:10.4', '08:10.2'])
+ print virt_pool.vfs_info
+
+ virt_pool.reserve_cpu('e')
+ print "Reserve three cores from resource pool"
+ print virt_pool.unused_cores
+ print "Alloc two cores on socket1 for VM-test1"
+ print virt_pool.alloc_cpu(vm="test1", number=2, socket=1)
+ print "Alloc two cores in list for VM-test2"
+ print virt_pool.alloc_cpu(vm="test2", corelist=['4', '5'])
+ print "Alloc two cores for VM-test3"
+ print virt_pool.alloc_cpu(vm="test3", number=2)
+ print "Alloc port for VM-test1"
+ print virt_pool.alloc_port(vm='test1')
+ print "Alloc information after allcated"
+ print virt_pool.allocated_info
+
+ print "Get cores on VM-test1"
+ print virt_pool.get_cpu_on_vm("test1")
+ print "Get pfs on VM-test1"
+ print virt_pool.get_pfs_on_vm("test1")
+ print "Get vfs on VM-test2"
+ print virt_pool.get_vfs_on_vm("test2")
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 5/9] Add qemu-agent-guest for QEMU VM
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
` (3 preceding siblings ...)
2015-05-18 5:07 ` [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 14:00 ` Liu, Yong
2015-05-18 5:07 ` [dts] [‘dts-v1’ 6/9] Add a global virtual configure sjiajiax
` (4 subsequent siblings)
9 siblings, 1 reply; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
dep/QMP/qemu-ga-client | 299 +++++++++++++++++++++++++++++++++++++++++++++++++
dep/QMP/qmp.py | 193 +++++++++++++++++++++++++++++++
2 files changed, 492 insertions(+)
create mode 100644 dep/QMP/qemu-ga-client
create mode 100644 dep/QMP/qmp.py
diff --git a/dep/QMP/qemu-ga-client b/dep/QMP/qemu-ga-client
new file mode 100644
index 0000000..46676c3
--- /dev/null
+++ b/dep/QMP/qemu-ga-client
@@ -0,0 +1,299 @@
+#!/usr/bin/python
+
+# QEMU Guest Agent Client
+#
+# Copyright (C) 2012 Ryota Ozaki <ozaki.ryota@gmail.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+#
+# Usage:
+#
+# Start QEMU with:
+#
+# # qemu [...] -chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
+# -device virtio-serial -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
+#
+# Run the script:
+#
+# $ qemu-ga-client --address=/tmp/qga.sock <command> [args...]
+#
+# or
+#
+# $ export QGA_CLIENT_ADDRESS=/tmp/qga.sock
+# $ qemu-ga-client <command> [args...]
+#
+# For example:
+#
+# $ qemu-ga-client cat /etc/resolv.conf
+# # Generated by NetworkManager
+# nameserver 10.0.2.3
+# $ qemu-ga-client fsfreeze status
+# thawed
+# $ qemu-ga-client fsfreeze freeze
+# 2 filesystems frozen
+#
+# See also: http://wiki.qemu.org/Features/QAPI/GuestAgent
+#
+
+import base64
+import random
+
+import qmp
+
+
+class QemuGuestAgent(qmp.QEMUMonitorProtocol):
+ def __getattr__(self, name):
+ def wrapper(**kwds):
+ return self.command('guest-' + name.replace('_', '-'), **kwds)
+ return wrapper
+
+
+class QemuGuestAgentClient:
+ error = QemuGuestAgent.error
+
+ def __init__(self, address):
+ self.qga = QemuGuestAgent(address)
+ self.qga.connect(negotiate=False)
+
+ def sync(self, timeout=3):
+ # Avoid being blocked forever
+ if not self.ping(timeout):
+ raise EnvironmentError('Agent seems not alive')
+ uid = random.randint(0, (1 << 32) - 1)
+ while True:
+ ret = self.qga.sync(id=uid)
+ if isinstance(ret, int) and int(ret) == uid:
+ break
+
+ def __file_read_all(self, handle):
+ eof = False
+ data = ''
+ while not eof:
+ ret = self.qga.file_read(handle=handle, count=1024)
+ _data = base64.b64decode(ret['buf-b64'])
+ data += _data
+ eof = ret['eof']
+ return data
+
+ def read(self, path):
+ handle = self.qga.file_open(path=path)
+ try:
+ data = self.__file_read_all(handle)
+ finally:
+ self.qga.file_close(handle=handle)
+ return data
+
+ def info(self):
+ info = self.qga.info()
+
+ msgs = []
+ msgs.append('version: ' + info['version'])
+ msgs.append('supported_commands:')
+ enabled = [c['name'] for c in info['supported_commands'] if c['enabled']]
+ msgs.append('\tenabled: ' + ', '.join(enabled))
+ disabled = [c['name'] for c in info['supported_commands'] if not c['enabled']]
+ msgs.append('\tdisabled: ' + ', '.join(disabled))
+
+ return '\n'.join(msgs)
+
+ def __gen_ipv4_netmask(self, prefixlen):
+ mask = int('1' * prefixlen + '0' * (32 - prefixlen), 2)
+ return '.'.join([str(mask >> 24),
+ str((mask >> 16) & 0xff),
+ str((mask >> 8) & 0xff),
+ str(mask & 0xff)])
+
+ def ifconfig(self):
+ nifs = self.qga.network_get_interfaces()
+
+ msgs = []
+ for nif in nifs:
+ msgs.append(nif['name'] + ':')
+ if 'ip-addresses' in nif:
+ for ipaddr in nif['ip-addresses']:
+ if ipaddr['ip-address-type'] == 'ipv4':
+ addr = ipaddr['ip-address']
+ mask = self.__gen_ipv4_netmask(int(ipaddr['prefix']))
+ msgs.append("\tinet %s netmask %s" % (addr, mask))
+ elif ipaddr['ip-address-type'] == 'ipv6':
+ addr = ipaddr['ip-address']
+ prefix = ipaddr['prefix']
+ msgs.append("\tinet6 %s prefixlen %s" % (addr, prefix))
+ if nif['hardware-address'] != '00:00:00:00:00:00':
+ msgs.append("\tether " + nif['hardware-address'])
+
+ return '\n'.join(msgs)
+
+ def ping(self, timeout):
+ self.qga.settimeout(timeout)
+ try:
+ self.qga.ping()
+ except self.qga.timeout:
+ return False
+ return True
+
+ def fsfreeze(self, cmd):
+ if cmd not in ['status', 'freeze', 'thaw']:
+ raise StandardError('Invalid command: ' + cmd)
+
+ return getattr(self.qga, 'fsfreeze' + '_' + cmd)()
+
+ def fstrim(self, minimum=0):
+ return getattr(self.qga, 'fstrim')(minimum=minimum)
+
+ def suspend(self, mode):
+ if mode not in ['disk', 'ram', 'hybrid']:
+ raise StandardError('Invalid mode: ' + mode)
+
+ try:
+ getattr(self.qga, 'suspend' + '_' + mode)()
+ # On error exception will raise
+ except self.qga.timeout:
+ # On success command will timed out
+ return
+
+ def shutdown(self, mode='powerdown'):
+ if mode not in ['powerdown', 'halt', 'reboot']:
+ raise StandardError('Invalid mode: ' + mode)
+
+ try:
+ self.qga.shutdown(mode=mode)
+ except self.qga.timeout:
+ return
+
+
+def _cmd_cat(client, args):
+ if len(args) != 1:
+ print('Invalid argument')
+ print('Usage: cat <file>')
+ sys.exit(1)
+ print(client.read(args[0]))
+
+
+def _cmd_fsfreeze(client, args):
+ usage = 'Usage: fsfreeze status|freeze|thaw'
+ if len(args) != 1:
+ print('Invalid argument')
+ print(usage)
+ sys.exit(1)
+ if args[0] not in ['status', 'freeze', 'thaw']:
+ print('Invalid command: ' + args[0])
+ print(usage)
+ sys.exit(1)
+ cmd = args[0]
+ ret = client.fsfreeze(cmd)
+ if cmd == 'status':
+ print(ret)
+ elif cmd == 'freeze':
+ print("%d filesystems frozen" % ret)
+ else:
+ print("%d filesystems thawed" % ret)
+
+
+def _cmd_fstrim(client, args):
+ if len(args) == 0:
+ minimum = 0
+ else:
+ minimum = int(args[0])
+ print(client.fstrim(minimum))
+
+
+def _cmd_ifconfig(client, args):
+ print(client.ifconfig())
+
+
+def _cmd_info(client, args):
+ print(client.info())
+
+
+def _cmd_ping(client, args):
+ if len(args) == 0:
+ timeout = 3
+ else:
+ timeout = float(args[0])
+ alive = client.ping(timeout)
+ if not alive:
+ print("Not responded in %s sec" % args[0])
+ sys.exit(1)
+
+
+def _cmd_suspend(client, args):
+ usage = 'Usage: suspend disk|ram|hybrid'
+ if len(args) != 1:
+ print('Less argument')
+ print(usage)
+ sys.exit(1)
+ if args[0] not in ['disk', 'ram', 'hybrid']:
+ print('Invalid command: ' + args[0])
+ print(usage)
+ sys.exit(1)
+ client.suspend(args[0])
+
+
+def _cmd_shutdown(client, args):
+ client.shutdown()
+_cmd_powerdown = _cmd_shutdown
+
+
+def _cmd_halt(client, args):
+ client.shutdown('halt')
+
+
+def _cmd_reboot(client, args):
+ client.shutdown('reboot')
+
+
+commands = [m.replace('_cmd_', '') for m in dir() if '_cmd_' in m]
+
+
+def main(address, cmd, args):
+ if not os.path.exists(address):
+ print('%s not found' % address)
+ sys.exit(1)
+
+ if cmd not in commands:
+ print('Invalid command: ' + cmd)
+ print('Available commands: ' + ', '.join(commands))
+ sys.exit(1)
+
+ try:
+ client = QemuGuestAgentClient(address)
+ except QemuGuestAgent.error, e:
+ import errno
+
+ print(e)
+ if e.errno == errno.ECONNREFUSED:
+ print('Hint: qemu is not running?')
+ sys.exit(1)
+
+ if cmd != 'ping':
+ client.sync()
+
+ globals()['_cmd_' + cmd](client, args)
+
+
+if __name__ == '__main__':
+ import sys
+ import os
+ import optparse
+
+ address = os.environ['QGA_CLIENT_ADDRESS'] if 'QGA_CLIENT_ADDRESS' in os.environ else None
+
+ usage = "%prog [--address=<unix_path>|<ipv4_address>] <command> [args...]\n"
+ usage += '<command>: ' + ', '.join(commands)
+ parser = optparse.OptionParser(usage=usage)
+ parser.add_option('--address', action='store', type='string',
+ default=address, help='Specify a ip:port pair or a unix socket path')
+ options, args = parser.parse_args()
+
+ address = options.address
+ if address is None:
+ parser.error('address is not specified')
+ sys.exit(1)
+
+ if len(args) == 0:
+ parser.error('Less argument')
+ sys.exit(1)
+
+ main(address, args[0], args[1:])
diff --git a/dep/QMP/qmp.py b/dep/QMP/qmp.py
new file mode 100644
index 0000000..4ade3ce
--- /dev/null
+++ b/dep/QMP/qmp.py
@@ -0,0 +1,193 @@
+# QEMU Monitor Protocol Python class
+#
+# Copyright (C) 2009, 2010 Red Hat Inc.
+#
+# Authors:
+# Luiz Capitulino <lcapitulino@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+
+import json
+import errno
+import socket
+
+class QMPError(Exception):
+ pass
+
+class QMPConnectError(QMPError):
+ pass
+
+class QMPCapabilitiesError(QMPError):
+ pass
+
+class QEMUMonitorProtocol:
+ def __init__(self, address, server=False):
+ """
+ Create a QEMUMonitorProtocol class.
+
+ @param address: QEMU address, can be either a unix socket path (string)
+ or a tuple in the form ( address, port ) for a TCP
+ connection
+ @param server: server mode listens on the socket (bool)
+ @raise socket.error on socket connection errors
+ @note No connection is established, this is done by the connect() or
+ accept() methods
+ """
+ self.__events = []
+ self.__address = address
+ self.__sock = self.__get_sock()
+ if server:
+ self.__sock.bind(self.__address)
+ self.__sock.listen(1)
+
+ def __get_sock(self):
+ if isinstance(self.__address, tuple):
+ family = socket.AF_INET
+ else:
+ family = socket.AF_UNIX
+ return socket.socket(family, socket.SOCK_STREAM)
+
+ def __negotiate_capabilities(self):
+ greeting = self.__json_read()
+ if greeting is None or not greeting.has_key('QMP'):
+ raise QMPConnectError
+ # Greeting seems ok, negotiate capabilities
+ resp = self.cmd('qmp_capabilities')
+ if "return" in resp:
+ return greeting
+ raise QMPCapabilitiesError
+
+ def __json_read(self, only_event=False):
+ while True:
+ data = self.__sockfile.readline()
+ if not data:
+ return
+ resp = json.loads(data)
+ if 'event' in resp:
+ self.__events.append(resp)
+ if not only_event:
+ continue
+ return resp
+
+ error = socket.error
+
+ def connect(self, negotiate=True):
+ """
+ Connect to the QMP Monitor and perform capabilities negotiation.
+
+ @return QMP greeting dict
+ @raise socket.error on socket connection errors
+ @raise QMPConnectError if the greeting is not received
+ @raise QMPCapabilitiesError if fails to negotiate capabilities
+ """
+ self.__sock.connect(self.__address)
+ self.__sockfile = self.__sock.makefile()
+ if negotiate:
+ return self.__negotiate_capabilities()
+
+ def accept(self):
+ """
+ Await connection from QMP Monitor and perform capabilities negotiation.
+
+ @return QMP greeting dict
+ @raise socket.error on socket connection errors
+ @raise QMPConnectError if the greeting is not received
+ @raise QMPCapabilitiesError if fails to negotiate capabilities
+ """
+ self.__sock, _ = self.__sock.accept()
+ self.__sockfile = self.__sock.makefile()
+ return self.__negotiate_capabilities()
+
+ def cmd_obj(self, qmp_cmd):
+ """
+ Send a QMP command to the QMP Monitor.
+
+ @param qmp_cmd: QMP command to be sent as a Python dict
+ @return QMP response as a Python dict or None if the connection has
+ been closed
+ """
+ try:
+ self.__sock.sendall(json.dumps(qmp_cmd))
+ except socket.error, err:
+ if err[0] == errno.EPIPE:
+ return
+ raise socket.error(err)
+ return self.__json_read()
+
+ def cmd(self, name, args=None, id=None):
+ """
+ Build a QMP command and send it to the QMP Monitor.
+
+ @param name: command name (string)
+ @param args: command arguments (dict)
+ @param id: command id (dict, list, string or int)
+ """
+ qmp_cmd = { 'execute': name }
+ if args:
+ qmp_cmd['arguments'] = args
+ if id:
+ qmp_cmd['id'] = id
+ return self.cmd_obj(qmp_cmd)
+
+ def command(self, cmd, **kwds):
+ ret = self.cmd(cmd, kwds)
+ if not ret:
+ return
+ else:
+ if ret.has_key('error'):
+ raise Exception(ret['error']['desc'])
+ return ret['return']
+
+ def pull_event(self, wait=False):
+ """
+ Get and delete the first available QMP event.
+
+ @param wait: block until an event is available (bool)
+ """
+ self.__sock.setblocking(0)
+ try:
+ self.__json_read()
+ except socket.error, err:
+ if err[0] == errno.EAGAIN:
+ # No data available
+ pass
+ self.__sock.setblocking(1)
+ if not self.__events and wait:
+ self.__json_read(only_event=True)
+ event = self.__events[0]
+ del self.__events[0]
+ return event
+
+ def get_events(self, wait=False):
+ """
+ Get a list of available QMP events.
+
+ @param wait: block until an event is available (bool)
+ """
+ self.__sock.setblocking(0)
+ try:
+ self.__json_read()
+ except socket.error, err:
+ if err[0] == errno.EAGAIN:
+ # No data available
+ pass
+ self.__sock.setblocking(1)
+ if not self.__events and wait:
+ self.__json_read(only_event=True)
+ return self.__events
+
+ def clear_events(self):
+ """
+ Clear current list of pending events.
+ """
+ self.__events = []
+
+ def close(self):
+ self.__sock.close()
+ self.__sockfile.close()
+
+ timeout = socket.timeout
+
+ def settimeout(self, timeout):
+ self.__sock.settimeout(timeout)
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 6/9] Add a global virtual configure
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
` (4 preceding siblings ...)
2015-05-18 5:07 ` [dts] [‘dts-v1’ 5/9] Add qemu-agent-guest for QEMU VM sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 6:32 ` Liu, Yong
2015-05-18 5:07 ` [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases sjiajiax
` (3 subsequent siblings)
9 siblings, 1 reply; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
conf/virt_global.cfg | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 conf/virt_global.cfg
diff --git a/conf/virt_global.cfg b/conf/virt_global.cfg
new file mode 100644
index 0000000..f26a90c
--- /dev/null
+++ b/conf/virt_global.cfg
@@ -0,0 +1,24 @@
+# virtualization global configurations
+#[LIBVIRT]
+#[KVM]
+#[XEN]
+[LIBVIRT]
+cpu =
+ number=4,cpupin=3 4 5 6;
+mem =
+ size=2048;
+net =
+ local=unused
+[KVM]
+cpu =
+ model=host,number=4,cpupin=3 4 5 6;
+mem =
+ size=2048;
+[XEN]
+cpu =
+ number=4,cpupin=3 4 5 6;
+mem =
+ size=2048;
+vif =
+ mac=random,bridge=br0
+
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
` (5 preceding siblings ...)
2015-05-18 5:07 ` [dts] [‘dts-v1’ 6/9] Add a global virtual configure sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 8:28 ` Xu, HuilongX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing sjiajiax
` (2 subsequent siblings)
9 siblings, 1 reply; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/pmd_output.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 102 insertions(+), 2 deletions(-)
diff --git a/framework/pmd_output.py b/framework/pmd_output.py
index 97274a5..642062f 100644
--- a/framework/pmd_output.py
+++ b/framework/pmd_output.py
@@ -32,6 +32,7 @@
import os
import re
import dts
+from settings import TIMEOUT
class PmdOutput():
@@ -42,6 +43,7 @@ class PmdOutput():
def __init__(self, dut):
self.dut = dut
+ self.dut.testpmd = self
self.rx_pkts_prefix = "RX-packets:"
self.rx_missed_prefix = "RX-missed:"
self.rx_bytes_prefix = "RX-bytes:"
@@ -87,10 +89,108 @@ class PmdOutput():
return self.command
def start_testpmd(self, cores, param='', eal_param='', socket=0):
+ if "--txqflags" not in param:
+ param += " --txqflags=0"
+ if socket == 0:
+ corelist = '0-3'
+ elif socket == 1:
+ corelist = '10-13'
+ else:
+ corelist = '0-3'
core_list = self.dut.get_core_list(cores, socket)
self.coremask = dts.create_mask(core_list)
- command = "./%s/app/testpmd -c %s -n %d %s -- -i %s" \
- % (self.dut.target, self.coremask, self.dut.get_memory_channels(), eal_param, param)
+ command = "taskset -c %s ./%s/app/testpmd -c %s -n %d %s -- -i %s" \
+ % (corelist, self.dut.target, self.coremask, self.dut.get_memory_channels(), eal_param, param)
out = self.dut.send_expect(command, "testpmd> ", 120)
self.command = command
return out
+
+ def execute_cmd(self, pmd_cmd, expected='testpmd> ', timeout=TIMEOUT,
+ alt_session=False, verify=False):
+ return self.dut.send_expect('%s' % pmd_cmd, expected, timeout=timeout,
+ alt_session=alt_session, verify=verify)
+
+ def get_value_from_string(self, key_str, regx_str, string):
+ """
+ Get some values from the given string by the regular expression.
+ """
+ pattern = r"(?<=%s)%s" % (key_str, regx_str)
+ s = re.compile(pattern)
+ res = s.search(string)
+ if type(res).__name__ == 'NoneType':
+ return ' '
+ else:
+ return res.group(0)
+
+ def get_detail_from_port_info(self, key_str, regx_str, port):
+ """
+ Get the detail info from the output of pmd cmd 'show port info <port num>'.
+ """
+ out = self.dut.send_expect("show port info %d" % port, "testpmd> ")
+ find_value = self.get_value_from_string(key_str, regx_str, out)
+ return find_value
+
+ def get_port_mac(self, port_id):
+ """
+ Get the specified port MAC.
+ """
+ return self.get_detail_from_port_info("MAC address: ", "([0-9A-F]{2}:){5}[0-9A-F]{2}", port_id)
+
+ def get_port_connect_socket(self, port_id):
+ """
+ Get the socket id which the specified port is connectting with.
+ """
+ return self.get_detail_from_port_info("Connect to socket: ", "\d+", port_id)
+
+ def get_port_memory_socket(self, port_id):
+ """
+ Get the socket id which the specified port memory is allocated on.
+ """
+ return self.get_detail_from_port_info("memory allocation on the socket: ", "\d+", port_id)
+
+ def get_port_link_status(self, port_id):
+ """
+ Get the specified port link status now.
+ """
+ return self.get_detail_from_port_info("Link status: ", "\d+", port_id)
+
+ def get_port_link_speed(self, port_id):
+ """
+ Get the specified port link speed now.
+ """
+ return self.get_detail_from_port_info("Link speed: ", "\d+", port_id)
+
+ def get_port_link_duplex(self, port_id):
+ """
+ Get the specified port link mode, duplex or siplex.
+ """
+ return self.get_detail_from_port_info("Link duplex: ", "\S+", port_id)
+
+ def get_port_promiscuous_mode(self, port_id):
+ """
+ Get the promiscuous mode of port.
+ """
+ return self.get_detail_from_port_info("Promiscuous mode: ", "\S+", port_id)
+
+ def get_port_allmulticast_mode(self, port_id):
+ """
+ Get the allmulticast mode of port.
+ """
+ return self.get_detail_from_port_info("Allmulticast mode: ", "\S+", port_id)
+
+ def get_port_vlan_offload(self, port_id):
+ """
+ Function: get the port vlan settting info.
+ return value:
+ 'strip':'on'
+ 'filter':'on'
+ 'qinq':'off'
+ """
+ vlan_info = {}
+ vlan_info['strip'] = self.get_detail_from_port_info(
+ "strip ", '\S+', port_id)
+ vlan_info['filter'] = self.get_detail_from_port_info(
+ 'filter', '\S+', port_id)
+ vlan_info['qinq'] = self.get_detail_from_port_info(
+ 'qinq\(extend\) ', '\S+', port_id)
+ return vlan_info
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
` (6 preceding siblings ...)
2015-05-18 5:07 ` [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 14:02 ` Liu, Yong
2015-05-18 5:07 ` [dts] [‘dts-v1’ 9/9] Add a suite to test SRIOV mirror with KVM sjiajiax
2015-05-18 6:29 ` [dts] [‘dts-v1’ 0/9] Liu, Yong
9 siblings, 1 reply; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
dep/aclpcap.tgz | Bin 0 -> 82103 bytes
dep/aclrule.tgz | Bin 0 -> 161037 bytes
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dep/aclpcap.tgz
create mode 100644 dep/aclrule.tgz
diff --git a/dep/aclpcap.tgz b/dep/aclpcap.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..d10df6f5af0e8eeb0c48d10f8fed0a293ce10864
GIT binary patch
literal 82103
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
A%m4rY
literal 0
HcmV?d00001
diff --git a/dep/aclrule.tgz b/dep/aclrule.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..cc662ce2a3f528c29c394a0839fc5384479105f8
GIT binary patch
literal 161037
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�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
literal 0
HcmV?d00001
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [dts] [‘dts-v1’ 9/9] Add a suite to test SRIOV mirror with KVM
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
` (7 preceding siblings ...)
2015-05-18 5:07 ` [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing sjiajiax
@ 2015-05-18 5:07 ` sjiajiax
2015-05-18 6:29 ` [dts] [‘dts-v1’ 0/9] Liu, Yong
9 siblings, 0 replies; 34+ messages in thread
From: sjiajiax @ 2015-05-18 5:07 UTC (permalink / raw)
To: dts
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
conf/sriov_kvm.cfg | 77 +++
test_plans/sriov_kvm_test_plan.rst | 756 +++++++++++++++++++++
tests/TestSuite_sriov_kvm.py | 1291 ++++++++++++++++++++++++++++++++++++
3 files changed, 2124 insertions(+)
create mode 100644 conf/sriov_kvm.cfg
create mode 100644 test_plans/sriov_kvm_test_plan.rst
create mode 100644 tests/TestSuite_sriov_kvm.py
diff --git a/conf/sriov_kvm.cfg b/conf/sriov_kvm.cfg
new file mode 100644
index 0000000..4be7b16
--- /dev/null
+++ b/conf/sriov_kvm.cfg
@@ -0,0 +1,77 @@
+# vm configuration for pmd sriov case
+[vm0]
+cpu =
+ model=host,number=4,cpupin=5 6 7 8;
+disk =
+ file=/home/image/vdisk01-sriov-fc20.img;
+login =
+ user=root,password=tester;
+net =
+ type=nic,opt_vlan=0;
+ type=user,opt_vlan=0;
+monitor =
+ port=;
+qga =
+ enable=yes;
+vnc =
+ displayNum=1;
+daemon =
+ enable=yes;
+
+[vm1]
+cpu =
+ model=host,number=4,cpupin=9 10 11 12;
+disk =
+ file=/home/image/vdisk02-sriov-fc20.img;
+login =
+ user=root,password=tester;
+net =
+ type=nic,opt_vlan=1;
+ type=user,opt_vlan=1;
+monitor =
+ port=;
+qga =
+ enable=yes;
+vnc =
+ displayNum=2;
+daemon =
+ enable=yes;
+
+[vm2]
+cpu =
+ model=host,number=4,cpupin=13 14 15 16;
+disk =
+ file=/home/image/vdisk03-ivshmem-fc20.img;
+login =
+ user=root,password=tester;
+net =
+ type=nic,opt_vlan=3;
+ type=tap,opt_vlan=3,opt_br=br0;
+monitor =
+ port=;
+qga =
+ enable=yes;
+vnc =
+ displayNum=3;
+daemon =
+ enable=yes;
+
+[vm3]
+cpu =
+ model=host,number=4,cpupin=17 18 19 20;
+disk =
+ file=/home/image/vdisk04-ivshmem-fc20.img;
+login =
+ user=root,password=tester;
+net =
+ type=nic,opt_vlan=4;
+ type=tap,opt_vlan=4,opt_br=br0;
+monitor =
+ port=;
+qga =
+ enable=yes;
+vnc =
+ displayNum=4;
+daemon =
+ enable=yes;
+
diff --git a/test_plans/sriov_kvm_test_plan.rst b/test_plans/sriov_kvm_test_plan.rst
new file mode 100644
index 0000000..52dd0ca
--- /dev/null
+++ b/test_plans/sriov_kvm_test_plan.rst
@@ -0,0 +1,756 @@
+.. Copyright (c) <2013>, Intel Corporation
+ 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.
+
+===============================
+SRIOV and InterVM Communication
+===============================
+
+Some applications such as pipelining of virtual appliances and traffic
+mirroring to virtual appliances require the high performance InterVM
+communications.
+
+The testpmd application is used to configure traffic mirroring, PF VM receive
+mode, PFUTA hash table and control traffic to a VF for inter-VM communication.
+
+The 82599 supports four separate mirroring rules, each associated with a
+destination pool. Each rule is programmed with one of the four mirroring types:
+
+1. Pool mirroring: reflect all the packets received to a pool from the network.
+2. Uplink port mirroring: reflect all the traffic received from the network.
+3. Downlink port mirroring: reflect all the traffic transmitted to the
+ network.
+4. VLAN mirroring: reflect all the traffic received from the network
+ in a set of given VLANs (either from the network or from local VMs).
+
+
+Prerequisites for all 2VMs cases/Mirror 2VMs cases
+==================================================
+
+Create two VF interface VF0 and VF1 from one PF interface and then attach them
+to VM0 and VM1. Suppose PF is 0000:08:00.0.Below are commands which can be
+used to generate 2VFs and make them in pci-stub modes.::
+
+ ./tools/pci_unbind.py --bind=igb_uio 0000:08:00.0
+ echo 2 > /sys/bus/pci/devices/0000\:08\:00.0/max_vfs
+ echo "8086 10ed" > /sys/bus/pci/drivers/pci-stub/new_id
+ echo 0000:08:10.0 >/sys/bus/pci/devices/0000\:08\:10.0/driver/unbind
+ echo 0000:08:10.2 >/sys/bus/pci/devices/0000\:08\:10.2/driver/unbind
+ echo 0000:08:10.0 >/sys/bus/pci/drivers/pci-stub/bind
+ echo 0000:08:10.0 >/sys/bus/pci/drivers/pci-stub/bind
+
+Start PF driver on the Host and skip the VFs.::
+
+ ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -b 0000:08:10.0 -b 0000:08:10.2 -- -i
+
+For VM0 start up command, you can refer to below command.::
+
+ qemu-system-x86_64 -name vm0 -enable-kvm -m 2048 -smp 4 -cpu host -drive file=/root/Downloads/vm0.img -net nic,macaddr=00:00:00:00:00:01 -net tap,script=/etc/qemu-ifup -device pci-assign,host=08:10.0 -vnc :1 --daemonize
+
+The /etc/qemu-ifup can be below script, need you to create first::
+
+ #!/bin/sh
+ set -x
+ switch=br0
+ if [ -n "$1" ];then
+ /usr/sbin/tunctl -u `whoami` -t $1
+ /sbin/ip link set $1 up
+ sleep 0.5s
+ /usr/sbin/brctl addif $switch $1
+ exit 0
+ else
+ echo "Error: no interface specified"
+ exit 1
+ fi
+
+Similar for VM1, please refer to below command for VM1::
+
+ qemu-system-x86_64 -name vm1 -enable-kvm -m 2048 -smp 4 -cpu host -drive file=/root/Downloads/vm1.img -net nic,macaddr=00:00:00:00:00:02 -net tap,script=/etc/qemu-ifup -device pci-assign,host=08:10.2 -vnc :4 -daemonize
+
+If you want to run all common 2VM cases, please run testpmd on VM0 and VM1 and
+start traffic forward on the VM hosts. Some specific prerequisites need to be
+set up in each case::
+
+ VF0 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF0 testpmd-> set fwd rxonly
+ VF0 testpmd-> start
+
+ VF1 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF1 testpmd-> set fwd mac
+ VF1 testpmd-> start
+
+Test Case1: InterVM communication test on 2VMs
+==============================================
+
+Set the VF0 destination mac address to VF1 mac address, packets send from VF0
+will be forwarded to VF1 and then send out::
+
+ VF1 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF1 testpmd-> show port info 0
+ VF1 testpmd-> set fwd mac
+ VF1 testpmd-> start
+
+ VF0 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- --eth-peer=0,"VF1 mac" -i
+ VF0 testpmd-> set fwd mac
+ VF0 testpmd-> start
+
+Send 10 packets with VF0 mac address and make sure the packets will be
+forwarded by VF1.
+
+Test Case2: Mirror Traffic between 2VMs with Pool mirroring
+===========================================================
+
+Set up common 2VM prerequisites.
+
+Add one mirror rule that will mirror VM0 income traffic to VM1::
+
+ PF testpmd-> set port 0 mirror-rule 0 pool-mirror 0x1 dst-pool 1 on
+
+Send 10 packets to VM0 and verify the packets has been mirrored to VM1 and
+forwarded the packet.
+
+After test need reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+
+
+Test Case3: Mirror Traffic between 2VMs with Uplink mirroring
+=============================================================
+
+Set up common 2VM prerequisites.
+
+Add one mirror rule that will mirror VM0 income traffic to VM1::
+
+ PF testpmd-> set port 0 mirror-rule 0 uplink-mirror dst-pool 1 on
+
+Send 10 packets to VM0 and verify the packets has been mirrored to VM1 and
+forwarded the packet.
+
+After test need reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+
+Test Case4: Mirror Traffic between 2VMs with Downlink mirroring
+===============================================================
+
+Run testpmd on VM0 and VM1 and start traffic forward on the VM hosts::
+
+ VF0 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF1 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+
+
+Add one mirror rule that will mirror VM0 outcome traffic to VM1::
+
+ PF testpmd-> set port 0 mirror-rule 0 downlink-mirror dst-pool 1 on
+
+Make sure VM1 in receive only mode, VM0 send 16 packets, and verify the VM0
+packets has been mirrored to VM1::
+
+ VF1 testpmd-> set fwd rxonly
+ VF1 testpmd-> start
+ VF0 testpmd-> start tx_first
+
+Note: don't let VF1 fwd packets since downlink mirror will mirror back the
+packets to received packets, which will be an infinite loop.
+
+After test need reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+
+Test Case5: Mirror Traffic between VMs with Vlan mirroring
+==========================================================
+
+Set up common 2VM prerequisites.
+
+Add rx vlan-id 0 on VF0, add one mirror rule that will mirror VM0 income
+traffic with specified vlan to VM1::
+
+ PF testpmd-> rx_vlan add 0 port 0 vf 0x1
+ PF testpmd-> set port 0 mirror-rule 0 vlan-mirror 0 dst-pool 1 on
+
+Send 10 packets with vlan-id0/vm0 MAC to VM0 and verify the packets has been
+mirrored to VM1 and forwarded the packet.
+
+After test need reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+
+Test Case6: Mirror Traffic between 2VMs with Vlan & Pool mirroring
+==================================================================
+
+Set up common 2VM prerequisites.
+
+Add rx vlan-id 3 of VF1, and 2 mirror rules, one is VM0 income traffic to VM1,
+one is VM1 vlan income traffic to VM0::
+
+ PF testpmd-> rx_vlan add 3 port 0 vf 0x2
+ PF testpmd-> set port 0 mirror-rule 0 pool-mirror 0x1 dst-pool 1 on
+ PF testpmd-> set port 0 mirror-rule 1 vlan-mirror 3 dst-pool 0 on
+
+Send 2 flows one by one, first 10 packets with VM0 mac, and the second 100
+packets with VM1 vlan and mac, and verify the first 10 packets has been
+mirrored first to VM1, second 100 packets go to VM0 and the packets have been
+forwarded.
+
+After test need reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+
+Test Case7: Mirror Traffic between 2VMs with Uplink & Downlink mirroring
+========================================================================
+
+Run testpmd on VM0 and VM1 and start traffic forward on the VM hosts::
+
+ VF0 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF1 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+
+Add 2 mirror rules that will mirror VM0 outcome and income traffic to VM1::
+
+ PF testpmd-> set port 0 mirror-rule 0 downlink-mirror dst-pool 1 on
+ PF testpmd-> set port 0 mirror-rule 0 uplink-mirror dst-pool 1 on
+
+Make sure VM1 in receive only mode, VM0 first send 16 packets, and verify the
+VM0 packets has been mirrored to VM1::
+
+ VF1 testpmd-> set fwd rxonly
+ VF1 testpmd-> start
+ VF0 testpmd-> start tx_first
+
+Note: don't let VF1 fwd packets since downlink mirror will mirror back the
+packets to received packets, which will be an infinite loop.
+
+Send 10 packets to VF0 with VF0 MAC from ixia, verify that all VF0 received
+packets and transmitted packets will mirror to VF1::
+
+ VF0 testpmd-> stop
+ VF0 testpmd-> start
+
+After test need reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+
+Test Case8: Mirror Traffic between 2VMs with Vlan & Pool & Uplink & Downlink mirroring
+======================================================================================
+
+Run testpmd on VM0 and VM1 and start traffic forward on the VM hosts::
+
+ VF0 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF1 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+
+
+Add rx vlan-id 0 on VF0 and add 4 mirror rules::
+
+ PF testpmd-> reset port 0 mirror-rule 1
+ PF testpmd-> set port 0 mirror-rule 0 downlink-mirror dst-pool 1 on
+ PF testpmd-> set port 0 mirror-rule 1 uplink-mirror dst-pool 1 on
+ PF testpmd-> rx_vlan add 0 port 0 vf 0x2
+ PF testpmd-> set port 0 mirror-rule 2 vlan-mirror 0 dst-pool 0 on
+ PF testpmd-> set port 0 mirror-rule 3 pool-mirror 0x1 dst-pool 1 on
+
+Make sure VM1 in receive only mode, VM0 first send 16 packets, and verify the
+VM0 packets has been mirrored to VM1, VF1, RX, 16packets (downlink mirror)::
+
+ VF1 testpmd-> set fwd rxonly
+ VF1 testpmd-> start
+ VF0 testpmd-> start tx_first
+
+Note: don't let VF1 fwd packets since downlink mirror will mirror back the
+packets to received packets, which will be an infinite loop.
+
+Send 1 packet to VF0 with VF0 MAC from ixia, check if VF0 RX 1 packet and TX 1
+packet, and VF1 has 2 packets mirror from VF0(uplink mirror/downlink/pool)::
+
+ VF0 testpmd-> stop
+ VF0 testpmd-> set fwd mac
+ VF0 testpmd-> start
+
+Send 1 packet with VM1 vlan id and mac, and verify that VF0 have 1 RX packet, 1
+TX packet, and VF1 have 2 packets(downlink mirror)::
+
+ VF0 testpmd-> stop
+ VF0 testpmd-> set fwd rxonly
+ VF0 testpmd-> start
+
+After test need reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+ PF testpmd-> reset port 0 mirror-rule 2
+ PF testpmd-> reset port 0 mirror-rule 3
+
+
+Test Case9: Add Multi exact MAC address on VF
+=============================================
+
+Add an exact destination mac address on VF0::
+
+ PF testpmd-> mac_addr add port 0 vf 0 00:11:22:33:44:55
+
+Send 10 packets with dst mac 00:11:22:33:44:55 to VF0 and make sure VF0 will
+receive the packets.
+
+Add another exact destination mac address on VF0::
+
+ PF testpmd-> mac_addr add port 0 vf 0 00:55:44:33:22:11
+
+Send 10 packets with dst mac 00:55:44:33:22:11 to VF0 and make sure VF0 will
+receive the packets.
+
+After test need restart PF and VF for clear exact mac addresss, first quit VF,
+then quit PF.
+
+Test Case10: Enable/Disable one uta MAC address on VF
+=====================================================
+
+Enable PF promisc mode and enable VF0 accept uta packets::
+
+ PF testpmd-> set promisc 0 on
+ PF testpmd-> set port 0 vf 0 rxmode ROPE on
+
+Add an uta destination mac address on VF0::
+
+ PF testpmd-> set port 0 uta 00:11:22:33:44:55 on
+
+Send 10 packets with dst mac 00:11:22:33:44:55 to VF0 and make sure VF0 will
+the packets.
+
+Disable PF promisc mode, repeat step3, check VF0 should not accept uta packets::
+
+ PF testpmd-> set promisc 0 off
+ PF testpmd-> set port 0 vf 0 rxmode ROPE off
+
+Test Case11: Add Multi uta MAC addresses on VF
+==============================================
+
+Add 2 uta destination mac address on VF0::
+
+ PF testpmd-> set port 0 uta 00:55:44:33:22:11 on
+ PF testpmd-> set port 0 uta 00:55:44:33:22:66 on
+
+Send 2 flows, first 10 packets with dst mac 00:55:44:33:22:11, another 100
+packets with dst mac 00:55:44:33:22:66 to VF0 and make sure VF0 will receive
+all the packets.
+
+Test Case12: Add/Remove uta MAC address on VF
+=============================================
+
+Add one uta destination mac address on VF0::
+
+ PF testpmd-> set port 0 uta 00:55:44:33:22:11 on
+
+Send 10 packets with dst mac 00:55:44:33:22:11 to VF0 and make sure VF0 will
+receive the packets.
+
+Remove the uta destination mac address on VF0::
+
+ PF testpmd-> set port 0 uta 00:55:44:33:22:11 off
+
+Send 10 packets with dst mac 00:11:22:33:44:55 to VF0 and make sure VF0 will
+not receive the packets.
+
+Add an uta destination mac address on VF0 again::
+
+ PF testpmd-> set port 0 uta 00:11:22:33:44:55 on
+
+Send packet with dst mac 00:11:22:33:44:55 to VF0 and make sure VF0 will
+receive again and forwarded the packet. This step is to make sure the on/off
+switch is working.
+
+Test Case13: Pause RX Queues
+============================
+
+Pause RX queue of VF0 then send 10 packets to VF0 and make sure VF0 will not
+receive the packets::
+
+ PF testpmd-> set port 0 vf 0 rx off
+
+Enable RX queue of VF0 then send 10 packets to VF0 and make sure VF0 will
+receive the packet::
+
+ PF testpmd-> set port 0 vf 0 rx on
+
+Repeat the off/on twice to check the switch capability, and ensure on/off can
+work stable.
+
+Test Case14: Pause TX Queues
+============================
+
+Pause TX queue of VF0 then send 10 packets to VF0 and make sure VF0 will not
+forward the packet::
+
+ PF testpmd-> set port 0 vf 0 tx off
+
+Enable RX queue of VF0 then send 10 packets to VF0 and make sure VF0 will
+forward the packet::
+
+ PF testpmd-> set port 0 vf 0 tx on
+
+Repeat the off/on twice to check the switch capability, and ensure on/off can
+work stable.
+
+Test Case15: Prevent Rx of Broadcast on VF
+==========================================
+
+Disable VF0 rx broadcast packets then send broadcast packet to VF0 and make
+sure VF0 will not receive the packet::
+
+ PF testpmd-> set port 0 vf 0 rxmode BAM off
+
+Enable VF0 rx broadcast packets then send broadcast packet to VF0 and make sure
+VF0 will receive and forward the packet::
+
+ PF testpmd-> set port 0 vf 0 rxmode BAM on
+
+Repeat the off/on twice to check the switch capability, and ensure on/off can
+work stable.
+
+Test Case16: Negative input to commands
+=======================================
+
+Input invalid commands on PF/VF to make sure the commands can't work::
+
+ 1. PF testpmd-> set port 0 vf 65 tx on
+ 2. PF testpmd-> set port 2 vf -1 tx off
+ 3. PF testpmd-> set port 0 vf 0 rx oneee
+ 4. PF testpmd-> set port 0 vf 0 rx offdd
+ 5. PF testpmd-> set port 0 vf 0 rx oneee
+ 6. PF testpmd-> set port 0 vf 64 rxmode BAM on
+ 7. PF testpmd-> set port 0 vf 64 rxmode BAM off
+ 8. PF testpmd-> set port 0 uta 00:11:22:33:44 on
+ 9. PF testpmd-> set port 7 uta 00:55:44:33:22:11 off
+ 10. PF testpmd-> set port 0 vf 34 rxmode ROPE on
+ 11. PF testpmd-> mac_addr add port 0 vf 65 00:55:44:33:22:11
+ 12. PF testpmd-> mac_addr add port 5 vf 0 00:55:44:88:22:11
+ 13. PF testpmd-> set port 0 mirror-rule 0 pool-mirror 65 dst-pool 1 on
+ 14. PF testpmd-> set port 0 mirror-rule 0xf uplink-mirror dst-pool 1 on
+ 15. PF testpmd-> set port 0 mirror-rule 2 vlan-mirror 9 dst-pool 1 on
+ 16. PF testpmd-> set port 0 mirror-rule 0 downlink-mirror 0xf dst-pool 2 off
+ 17. PF testpmd-> reset port 0 mirror-rule 4
+ 18. PF testpmd-> reset port 0xff mirror-rule 0
+
+Prerequisites for Scaling 4VFs per 1PF
+======================================
+
+Create 4VF interface VF0, VF1, VF2, VF3 from one PF interface and then attach
+them to VM0, VM1, VM2 and VM3.Start PF driver on the Host and skip the VF
+driver will has been already attached to VMs::
+
+ On PF ./tools/pci_unbind.py --bind=igb_uio 0000:08:00.0
+ echo 2 > /sys/bus/pci/devices/0000\:08\:00.0/max_vfs
+ ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -b 0000:08:10.0 -b 0000:08:10.2 -b 0000:08:10.4 -b 0000:08:10.6 -- -i
+
+If you want to run all common 4VM cases, please run testpmd on VM0, VM1, VM2
+and VM3 and start traffic forward on the VM hosts. Some specific prerequisites
+are set up in each case::
+
+ VF0 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF1 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF2 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF3 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+
+Test Case17: Scaling Pool Mirror on 4VFs
+========================================
+
+Make sure prerequisites for Scaling 4VFs per 1PF is set up.
+
+Add one mirror rules that will mirror VM0/VM1/VM2 income traffic to VM3::
+
+ PF testpmd-> set port 0 mirror-rule 0 pool-mirror 0x7 dst-pool 3 on
+ VF0 testpmd-> set fwd rxonly
+ VF0 testpmd-> start
+ VF1 testpmd-> set fwd rxonly
+ VF1 testpmd-> start
+ VF2 testpmd-> set fwd rxonly
+ VF2 testpmd-> start
+ VF3 testpmd-> set fwd rxonly
+ VF3 testpmd-> start
+
+Send 3 flows to VM0/VM1/VM2, one with VM0 mac, one with VM1 mac, one with VM2
+mac, and verify the packets has been mirrored to VM3.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+
+Set another 2 mirror rules. VM0/VM1 income traffic mirror to VM2 and VM3::
+
+ PF testpmd-> set port 0 mirror-rule 0 pool-mirror 0x3 dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 1 pool-mirror 0x3 dst-pool 3 on
+
+Send 2 flows to VM0/VM1, one with VM0 mac, one with VM1 mac and verify the
+packets has been mirrored to VM2/VM3 and VM2/VM3 have forwarded these packets.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+
+Test Case18: Scaling Uplink Mirror on 4VFs
+==========================================
+
+Make sure prerequisites for Scaling 4VFs per 1PF is set up.
+
+Add one mirror rules that will mirror all income traffic to VM2 and VM3::
+
+ PF testpmd-> set port 0 mirror-rule 0 uplink-mirror dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 1 uplink-mirror dst-pool 3 on
+ VF0 testpmd-> set fwd rxonly
+ VF0 testpmd-> start
+ VF1 testpmd-> set fwd rxonly
+ VF1 testpmd-> start
+ VF2 testpmd-> set fwd rxonly
+ VF2 testpmd-> start
+ VF3 testpmd-> set fwd rxonly
+ VF3 testpmd-> start
+
+Send 4 flows to VM0/VM1/VM2/VM3, one packet with VM0 mac, one packet with VM1
+mac, one packet with VM2 mac, and one packet with VM3 mac and verify the
+income packets has been mirrored to VM2 and VM3. Make sure VM2/VM3 will have 4
+packets.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+
+Test Case19: Scaling Downlink Mirror on 4VFs
+============================================
+
+Make sure prerequisites for scaling 4VFs per 1PF is set up.
+
+Add one mirror rules that will mirror all outcome traffic to VM2 and VM3::
+
+ PF testpmd-> set port 0 mirror-rule 0 downlink-mirror dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 1 downlink-mirror dst-pool 3 on
+ VF0 testpmd-> set fwd mac
+ VF0 testpmd-> start
+ VF1 testpmd-> set fwd mac
+ VF1 testpmd-> start
+ VF2 testpmd-> set fwd rxonly
+ VF2 testpmd-> start
+ VF3 testpmd-> set fwd rxonly
+ VF3 testpmd-> start
+
+Send 2 flows to VM0/VM1, one with VM0 mac, one with VM1 mac, and verify VM0/VM1
+will forward these packets. And verify the VM0/VM1 outcome packets have been
+mirrored to VM2 and VM3.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+
+Test Case20: Scaling Vlan Mirror on 4VFs
+========================================
+
+Make sure prerequisites for scaling 4VFs per 1PF is set up.
+
+Add 3 mirror rules that will mirror VM0/VM1/VM2 vlan income traffic to VM3::
+
+ PF testpmd-> rx_vlan add 1 port 0 vf 0x1
+ PF testpmd-> rx_vlan add 2 port 0 vf 0x2
+ PF testpmd-> rx_vlan add 3 port 0 vf 0x4
+ PF testpmd-> set port 0 mirror-rule 0 vlan-mirror 1,2,3 dst-pool 3 on
+ VF0 testpmd-> set fwd mac
+ VF0 testpmd-> start
+ VF1 testpmd-> set fwd mac
+ VF1 testpmd-> start
+ VF2 testpmd-> set fwd mac
+ VF2 testpmd-> start
+ VF3 testpmd-> set fwd mac
+ VF3 testpmd-> start
+
+Send 3 flows to VM0/VM1/VM2, one with VM0 mac/vlanid, one with VM1 mac/vlanid,
+one with VM2 mac/vlanid,and verify the packets has been mirrored to VM3 and
+VM3 has forwards these packets.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+
+Set another 2 mirror rules. VM0/VM1 income traffic mirror to VM2 and VM3::
+
+ PF testpmd-> set port 0 mirror-rule 0 vlan-mirror 1 dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 1 vlan-mirror 2 dst-pool 3 on
+
+Send 2 flows to VM0/VM1, one with VM0 mac/vlanid, one with VM1 mac/vlanid and
+verify the packets has been mirrored to VM2 and VM3, then VM2 and VM3 have
+forwarded these packets.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+
+Test Case21: Scaling Vlan Mirror & Pool Mirror on 4VFs
+======================================================
+
+Make sure prerequisites for scaling 4VFs per 1PF is set up.
+
+Add 3 mirror rules that will mirror VM0/VM1 vlan income traffic to VM2, VM0/VM1
+pool will come to VM3::
+
+ PF testpmd-> rx_vlan add 1 port 0 vf 0x1
+ PF testpmd-> rx_vlan add 2 port 0 vf 0x2
+ PF testpmd-> set port 0 mirror-rule 0 vlan-mirror 1 dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 1 vlan-mirror 2 dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 2 pool-mirror 0x3 dst-pool 3 on
+ VF0 testpmd-> set fwd mac
+ VF0 testpmd-> start
+ VF1 testpmd-> set fwd mac
+ VF1 testpmd-> start
+ VF2 testpmd-> set fwd mac
+ VF2 testpmd-> start
+ VF3 testpmd-> set fwd mac
+ VF3 testpmd-> start
+
+Send 2 flows to VM0/VM1, one with VM0 mac/vlanid, one with VM1 mac/vlanid, and
+verify the packets has been mirrored to VM2 and VM3, and VM2/VM3 have
+forwarded these packets.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+ PF testpmd-> reset port 0 mirror-rule 2
+
+Set 3 mirror rules. VM0/VM1 income traffic mirror to VM2, VM2 traffic will
+mirror to VM3::
+
+ PF testpmd-> set port 0 mirror-rule 0 vlan-mirror 1,2 dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 2 pool-mirror 0x2 dst-pool 3 on
+
+Send 2 flows to VM0/VM1, one with VM0 mac/vlanid, one with VM1 mac/vlanid and
+verify the packets has been mirrored to VM2, VM2 traffic will be mirrored to
+VM3, then VM2 and VM3 have forwarded these packets.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+ PF testpmd-> reset port 0 mirror-rule 2
+
+Test Case22: Scaling Uplink Mirror & Downlink Mirror on 4VFs
+============================================================
+
+Make sure prerequisites for scaling 4VFs per 1PF is set up.
+
+Add 2 mirror rules that will mirror all income traffic to VM2, all outcome
+traffic to VM3. Make sure VM2 and VM3 rxonly::
+
+ PF testpmd-> set port 0 mirror-rule 0 uplink-mirror dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 1 downlink-mirror dst-pool 3 on
+ VF0 testpmd-> set fwd mac
+ VF0 testpmd-> start
+ VF1 testpmd-> set fwd mac
+ VF1 testpmd-> start
+ VF2 testpmd-> set fwd rxonly
+ VF2 testpmd-> start
+ VF3 testpmd-> set fwd rxonly
+ VF3 testpmd-> start
+
+Send 2 flows to VM0/VM1, one with VM0 mac, one with VM1 mac and make sure
+VM0/VM1 will forward packets. Verify the income packets have been mirrored to
+VM2, the outcome packets has been mirrored to VM3.
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+
+Test Case23: Scaling Pool & Vlan & Uplink & Downlink Mirror on 4VFs
+===================================================================
+
+Make sure prerequisites for scaling 4VFs per 1PF is set up.
+
+Add mirror rules that VM0 vlan mirror to VM1, all income traffic mirror to VM2,
+all outcome traffic mirror to VM3, all VM1 traffic will mirror to VM0. Make
+sure VM2 and VM3 rxonly::
+
+ PF testpmd-> rx_vlan add 1 port 0 vf 0x1
+ PF testpmd-> set port 0 mirror-rule 0 vlan-mirror 1 dst-pool 1 on
+ PF testpmd-> set port 0 mirror-rule 1 pool-mirror 0x2 dst-pool 0 on
+ PF testpmd-> set port 0 mirror-rule 2 uplink-mirror dst-pool 2 on
+ PF testpmd-> set port 0 mirror-rule 3 downlink-mirror dst-pool 3 on
+ VF0 testpmd-> set fwd mac
+ VF0 testpmd-> start
+ VF1 testpmd-> set fwd mac
+ VF1 testpmd-> start
+ VF2 testpmd-> set fwd rxonly
+ VF2 testpmd-> start
+ VF3 testpmd-> set fwd rxonly
+ VF3 testpmd-> start
+
+Send 10 packets to VM0 with VM0 mac/vlanid, verify that VM1 will be mirrored
+and packets will be forwarded, VM2 will have all income traffic mirrored, VM3
+will have all outcome traffic mirrored
+
+Send 10 packets to VM1 with VM1 mac, verify that VM0 will be mirrored and
+packets will be forwarded, VM2 will have all income traffic mirrored; VM3 will
+have all outcome traffic mirrored
+
+Reset mirror rule::
+
+ PF testpmd-> reset port 0 mirror-rule 0
+ PF testpmd-> reset port 0 mirror-rule 1
+ PF testpmd-> reset port 0 mirror-rule 2
+ PF testpmd-> reset port 0 mirror-rule 3
+
+Test Case24: Scaling InterVM communication on 4VFs
+==================================================
+
+Set the VF0 destination mac address to VF1 mac address, packets send from VF0
+will be forwarded to VF1 and then send out. Similar for VF2 and VF3::
+
+ VF1 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF1 testpmd-> show port info 0
+ VF1 testpmd-> set fwd mac
+ VF1 testpmd-> start
+
+ VF0 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- --eth-peer=0,"VF1 mac" -i
+ VF0 testpmd-> set fwd mac
+ VF0 testpmd-> start
+
+ VF3 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- -i
+ VF3 testpmd-> show port info 0
+ VF3 testpmd-> set fwd mac
+ VF3 testpmd-> start
+
+ VF2 ./x86_64-default-linuxapp-gcc/app/testpmd -c f -n 4 -- --eth-peer=0,"VF3 mac" -i
+ VF2 testpmd-> set fwd mac
+ VF2 testpmd-> start
+
+Send 2 flows, one with VF0 mac address and make sure the packets will be
+forwarded by VF1, another with VF2 mac address and make sure the packets will
+be forwarded by VF3.
+
+
diff --git a/tests/TestSuite_sriov_kvm.py b/tests/TestSuite_sriov_kvm.py
new file mode 100644
index 0000000..8109840
--- /dev/null
+++ b/tests/TestSuite_sriov_kvm.py
@@ -0,0 +1,1291 @@
+# <COPYRIGHT_TAG>
+
+"""
+DPDK Test suite.
+
+
+Test userland 10Gb PMD.
+
+"""
+
+import re
+import pdb
+import time
+
+import dts
+from qemu_kvm import QEMUKvm
+from test_case import TestCase
+
+from pmd_output import PmdOutput
+
+FRAME_SIZE_64 = 64
+VM_CORES_MASK = 'all'
+
+
+class TestSriovKvm(TestCase):
+
+ def set_up_all(self):
+ # port_mirror_ref = {port_id: rule_id_list}
+ # rule_id should be integer, and should be increased based on
+ # the most rule_id when add a rule for a port successfully,
+ # case should not be operate it directly
+ # example:
+ # port_mirror_ref = {0: 1, 1: 3}
+ self.port_mirror_ref = {}
+ self.dut_ports = self.dut.get_ports(self.nic)
+ self.verify(len(self.dut_ports) >= 1, "Insufficient ports")
+
+ self.vm0 = None
+ self.vm1 = None
+ self.vm2 = None
+ self.vm3 = None
+
+ def set_up(self):
+ self.setup_2vm_2pf_env_flag = 0
+
+ self.setup_2vm_2vf_env_flag = 0
+ self.setup_2vm_prerequisite_flag = 0
+
+ self.setup_4vm_4vf_env_flag = 0
+ self.setup_4vm_prerequisite_flag = 0
+
+ def get_stats(self, dut, portid, rx_tx):
+ """
+ Get packets number from port statistic
+ """
+
+ stats = dut.testpmd.get_pmd_stats(portid)
+
+ if rx_tx == "rx":
+ stats_result = [
+ stats['RX-packets'], stats['RX-missed'], stats['RX-bytes']]
+ elif rx_tx == "tx":
+ stats_result = [
+ stats['TX-packets'], stats['TX-errors'], stats['TX-bytes']]
+ else:
+ return None
+
+ return stats_result
+
+ def parse_ether_ip(self, dut, dut_ports, dest_port, **ether_ip):
+ """
+ dut: which you want to send packet to
+ dest_port: the port num must be the index of dut.get_ports()
+ ether_ip:
+ 'ether':
+ {
+ 'dest_mac':False
+ 'src_mac':"52:00:00:00:00:00"
+ }
+ 'dot1q':
+ {
+ 'vlan':1
+ }
+ 'ip':
+ {
+ 'dest_ip':"10.239.129.88"
+ 'src_ip':"10.239.129.65"
+ }
+ 'udp':
+ {
+ 'dest_port':53
+ 'src_port':53
+ }
+ """
+ ret_ether_ip = {}
+ ether = {}
+ dot1q = {}
+ ip = {}
+ udp = {}
+
+ try:
+ dut_dest_port = dut_ports[dest_port]
+ except Exception as e:
+ print e
+
+ tester_port = dut.ports_map[dut_dest_port]
+ if not ether_ip.get('ether'):
+ ether['dest_mac'] = dut.get_mac_address(dut_dest_port)
+ ether['src_mac'] = dut.tester.get_mac(tester_port)
+ else:
+ if not ether_ip['ether'].get('dest_mac'):
+ ether['dest_mac'] = dut.get_mac_address(dut_dest_port)
+ else:
+ ether['dest_mac'] = ether_ip['ether']['dest_mac']
+ if not ether_ip['ether'].get('src_mac'):
+ ether['src_mac'] = dut.tester.get_mac(tester_port)
+ else:
+ ether['src_mac'] = ether_ip["ether"]["src_mac"]
+
+ if not ether_ip.get('dot1q'):
+ pass
+ else:
+ if not ether_ip['dot1q'].get('vlan'):
+ dot1q['vlan'] = '1'
+ else:
+ dot1q['vlan'] = ether_ip['dot1q']['vlan']
+
+ if not ether_ip.get('ip'):
+ ip['dest_ip'] = "10.239.129.88"
+ ip['src_ip'] = "10.239.129.65"
+ else:
+ if not ether_ip['ip'].get('dest_ip'):
+ ip['dest_ip'] = "10.239.129.88"
+ else:
+ ip['dest_ip'] = ether_ip['ip']['dest_ip']
+ if not ether_ip['ip'].get('src_ip'):
+ ip['src_ip'] = "10.239.129.65"
+ else:
+ ip['src_ip'] = ether_ip['ip']['src_ip']
+
+ if not ether_ip.get('udp'):
+ udp['dest_port'] = 53
+ udp['src_port'] = 53
+ else:
+ if not ether_ip['udp'].get('dest_port'):
+ udp['dest_port'] = 53
+ else:
+ udp['dest_port'] = ether_ip['udp']['dest_port']
+ if not ether_ip['udp'].get('src_port'):
+ udp['src_port'] = 53
+ else:
+ udp['src_port'] = ether_ip['udp']['src_port']
+
+ ret_ether_ip['ether'] = ether
+ ret_ether_ip['dot1q'] = dot1q
+ ret_ether_ip['ip'] = ip
+ ret_ether_ip['udp'] = udp
+
+ return ret_ether_ip
+
+ def send_packet(self,
+ dut,
+ dut_ports,
+ dest_port,
+ src_port=False,
+ frame_size=FRAME_SIZE_64,
+ count=1,
+ invert_verify=False,
+ **ether_ip):
+ """
+ Send count packet to portid
+ dut: which you want to send packet to
+ dest_port: the port num must be the index of dut.get_ports()
+ count: 1 or 2 or 3 or ... or 'MANY'
+ if count is 'MANY', then set count=1000,
+ send packets during 5 seconds.
+ ether_ip:
+ 'ether':
+ {
+ 'dest_mac':False
+ 'src_mac':"52:00:00:00:00:00"
+ }
+ 'dot1q':
+ {
+ 'vlan':1
+ }
+ 'ip':
+ {
+ 'dest_ip':"10.239.129.88"
+ 'src_ip':"10.239.129.65"
+ }
+ 'udp':
+ {
+ 'dest_port':53
+ 'src_port':53
+ }
+ """
+ during = 0
+ loop = 0
+ try:
+ count = int(count)
+ except ValueError as e:
+ if count == 'MANY':
+ during = 20
+ count = 1000 * 10
+ else:
+ raise e
+
+ gp0rx_pkts, gp0rx_err, gp0rx_bytes = [int(_)
+ for _ in self.get_stats(dut, dest_port, "rx")]
+ if not src_port:
+ itf = self.tester.get_interface(
+ dut.ports_map[dut_ports[dest_port]])
+ else:
+ itf = src_port
+
+ ret_ether_ip = self.parse_ether_ip(
+ dut,
+ dut_ports,
+ dest_port,
+ **ether_ip)
+
+ pktlen = frame_size - 18
+ padding = pktlen - 20
+
+ start = time.time()
+ while True:
+ self.tester.scapy_foreground()
+ self.tester.scapy_append(
+ 'nutmac="%s"' % ret_ether_ip['ether']['dest_mac'])
+ self.tester.scapy_append(
+ 'srcmac="%s"' % ret_ether_ip['ether']['src_mac'])
+
+ if ether_ip.get('dot1q'):
+ self.tester.scapy_append(
+ 'vlanvalue=%d' % int(ret_ether_ip['dot1q']['vlan']))
+ self.tester.scapy_append(
+ 'destip="%s"' % ret_ether_ip['ip']['dest_ip'])
+ self.tester.scapy_append(
+ 'srcip="%s"' % ret_ether_ip['ip']['src_ip'])
+ self.tester.scapy_append(
+ 'destport=%d' % ret_ether_ip['udp']['dest_port'])
+ self.tester.scapy_append(
+ 'srcport=%d' % ret_ether_ip['udp']['src_port'])
+ if not ret_ether_ip.get('dot1q'):
+ send_cmd = 'sendp([Ether(dst=nutmac, src=srcmac)/' + \
+ 'IP(dst=destip, src=srcip, len=%s)/' % pktlen + \
+ 'UDP(sport=srcport, dport=destport)/' + \
+ 'Raw(load="\x50"*%s)], ' % padding + \
+ 'iface="%s", count=%d)' % (itf, count)
+ else:
+ send_cmd = 'sendp([Ether(dst=nutmac, src=srcmac)/Dot1Q(vlan=vlanvalue)/' + \
+ 'IP(dst=destip, src=srcip, len=%s)/' % pktlen + \
+ 'UDP(sport=srcport, dport=destport)/' + \
+ 'Raw(load="\x50"*%s)], iface="%s", count=%d)' % (
+ padding, itf, count)
+ self.tester.scapy_append(send_cmd)
+
+ self.tester.scapy_execute()
+ loop += 1
+
+ now = time.time()
+ if (now - start) >= during:
+ break
+ time.sleep(.5)
+
+ p0rx_pkts, p0rx_err, p0rx_bytes = [int(_)
+ for _ in self.get_stats(dut, dest_port, "rx")]
+
+ p0rx_pkts -= gp0rx_pkts
+ p0rx_bytes -= gp0rx_bytes
+
+ if not invert_verify:
+ self.verify(p0rx_pkts >= count * loop,
+ "Data not received by port")
+ else:
+ self.verify(p0rx_pkts == 0 or
+ p0rx_pkts < count * loop,
+ "Data received by port, but should not.")
+ return count * loop
+
+ def setup_2vm_2pf_env(self):
+ p0 = self.dut_ports[0]
+ p1 = self.dut_ports[1]
+
+ self.port0 = self.dut.ports_info[p0]['port']
+ self.port0.unbind_driver()
+ self.port0_pci = self.dut.ports_info[p0]['pci']
+
+ self.port1 = self.dut.ports_info[p1]['port']
+ self.port1.unbind_driver()
+ self.port1_pci = self.dut.ports_info[p1]['pci']
+
+ vf0_prop = {'prop_host': self.port0_pci}
+ vf1_prop = {'prop_host': self.port1_pci}
+
+ # set up VM0 ENV
+ self.vm0 = QEMUKvm(self.dut, 'vm0', 'sriov_kvm')
+ self.vm0.set_vm_device(driver='pci-assign', **vf0_prop)
+ self.vm_dut_0 = self.vm0.start()
+
+ # set up VM1 ENV
+ self.vm1 = QEMUKvm(self.dut, 'vm1', 'sriov_kvm')
+ self.vm1.set_vm_device(driver='pci-assign', **vf1_prop)
+ self.vm_dut_1 = self.vm1.start()
+
+ self.setup_2vm_2vf_env_flag = 1
+
+ def destroy_2vm_2pf_env(self):
+ self.vm_dut_0.close()
+ self.vm_dut_0.logger.logger_exit()
+ self.vm0.stop()
+ self.port0.bind_driver('igb_uio')
+ self.vm0 = None
+
+ self.vm_dut_1.close()
+ self.vm_dut_1.logger.logger_exit()
+ self.vm1.stop()
+ self.port1.bind_driver('igb_uio')
+ self.vm1 = None
+
+ self.setup_2vm_2vf_env_flag = 0
+
+ def setup_2vm_2vf_env(self, driver='igb_uio'):
+ self.used_dut_port = self.dut_ports[0]
+
+ self.dut.generate_sriov_vfs_by_port(
+ self.used_dut_port, 2, driver=driver)
+ self.sriov_vfs_port = self.dut.ports_info[
+ self.used_dut_port]['vfs_port']
+
+ try:
+
+ for port in self.sriov_vfs_port:
+ port.bind_driver('pci-stub')
+
+ time.sleep(1)
+
+ vf0_prop = {'prop_host': self.sriov_vfs_port[0].pci}
+ vf1_prop = {'prop_host': self.sriov_vfs_port[1].pci}
+
+ for port_id in self.dut_ports:
+ if port_id == self.used_dut_port:
+ continue
+ port = self.dut.ports_info[port_id]['port']
+ port.bind_driver()
+
+ if driver == 'igb_uio':
+ # start testpmd with the two VFs on the host
+ self.host_testpmd = PmdOutput(self.dut)
+ eal_param = '-b %(vf0)s -b %(vf1)s' % {'vf0': self.sriov_vfs_port[0].pci,
+ 'vf1': self.sriov_vfs_port[1].pci}
+ self.host_testpmd.start_testpmd(
+ "1S/2C/2T", eal_param=eal_param)
+
+ # set up VM0 ENV
+ self.vm0 = QEMUKvm(self.dut, 'vm0', 'sriov_kvm')
+ self.vm0.set_vm_device(driver='pci-assign', **vf0_prop)
+ self.vm_dut_0 = self.vm0.start()
+ if self.vm_dut_0 is None:
+ raise Exception("Set up VM0 ENV failed!")
+
+ # set up VM1 ENV
+ self.vm1 = QEMUKvm(self.dut, 'vm1', 'sriov_kvm')
+ self.vm1.set_vm_device(driver='pci-assign', **vf1_prop)
+ self.vm_dut_1 = self.vm1.start()
+ if self.vm_dut_1 is None:
+ raise Exception("Set up VM1 ENV failed!")
+
+ self.setup_2vm_2vf_env_flag = 1
+ except Exception as e:
+ self.destroy_2vm_2vf_env()
+ raise Exception(e)
+
+ def destroy_2vm_2vf_env(self):
+ if getattr(self, 'vm_dut_0', None):
+ self.vm_dut_0.close()
+ self.vm_dut_0.logger.logger_exit()
+ if getattr(self, 'vm0', None):
+ self.vm0.stop()
+ self.vm0 = None
+
+ if getattr(self, 'vm_dut_1', None):
+ self.vm_dut_1.close()
+ self.vm_dut_1.logger.logger_exit()
+ if getattr(self, 'vm1', None):
+ self.vm1.stop()
+ self.vm1 = None
+
+ if getattr(self, 'host_testpmd', None):
+ self.host_testpmd.execute_cmd('quit', '# ')
+ self.host_testpmd = None
+
+ if getattr(self, 'used_dut_port', None):
+ self.dut.destroy_sriov_vfs_by_port(self.used_dut_port)
+ port = self.dut.ports_info[self.used_dut_port]['port']
+ port.bind_driver('igb_uio')
+ self.used_dut_port = None
+
+ for port_id in self.dut_ports:
+ port = self.dut.ports_info[port_id]['port']
+ port.bind_driver('igb_uio')
+
+ self.setup_2vm_2vf_env_flag = 0
+
+ def setup_4vm_4vf_env(self, driver='igb_uio'):
+ self.used_dut_port = self.dut_ports[0]
+
+ self.dut.generate_sriov_vfs_by_port(
+ self.used_dut_port, 4, driver=driver)
+ self.sriov_vfs_port = self.dut.ports_info[self.used_dut_port]['port']
+
+ try:
+ for port in self.sriov_vfs_port:
+ port.bind_driver('pci-stub')
+
+ time.sleep(1)
+
+ vf0_prop = {'prop_host': self.sriov_vfs_port[0].pci}
+ vf1_prop = {'prop_host': self.sriov_vfs_port[1].pci}
+ vf2_prop = {'prop_host': self.sriov_vfs_port[2].pci}
+ vf3_prop = {'prop_host': self.sriov_vfs_port[3].pci}
+
+ for port_id in self.dut_ports:
+ if port_id == self.used_dut_port:
+ continue
+ port = self.dut.ports_info[port_id]['port']
+ port.bind_driver()
+
+ if driver == 'igb_uio':
+ # start testpmd with the four VFs on the host
+ self.host_testpmd = PmdOutput(self.dut)
+ eal_param = '-b %(vf0) -b %(vf1)s -b %(vf2)s -b %(vf3)s' % \
+ {'vf0': self.sriov_vfs_pci[0],
+ 'vf1': self.sriov_vfs_pci[1],
+ 'vf2': self.sriov_vfs_pci[2],
+ 'vf3': self.sriov_vfs_pci[3]}
+ self.host_testpmd.start_testpmd(
+ "1S/2C/2T", eal_param=eal_param)
+
+ self.vm0 = QEMUKvm(self.dut, 'vm0', 'sriov_kvm')
+ self.vm0.set_vm_device(driver='pci-assign', **vf0_prop)
+ self.vm_dut_0 = self.vm0.start()
+ if self.vm_dut_0 is None:
+ raise Exception("Set up VM0 ENV failed!")
+
+ self.vm1 = QEMUKvm(self.dut, 'vm1', 'sriov_kvm')
+ self.vm1.set_vm_device(driver='pci-assign', **vf1_prop)
+ self.vm_dut_1 = self.vm1.start()
+ if self.vm_dut_1 is None:
+ raise Exception("Set up VM1 ENV failed!")
+
+ self.vm2 = QEMUKvm(self.dut, 'vm2', 'sriov_kvm')
+ self.vm2.set_vm_device(driver='pci-assign', **vf2_prop)
+ self.vm_dut_2 = self.vm1.start()
+ if self.vm_dut_2 is None:
+ raise Exception("Set up VM2 ENV failed!")
+
+ self.vm3 = QEMUKvm(self.dut, 'vm3', 'sriov_kvm')
+ self.vm3.set_vm_device(driver='pci-assign', **vf3_prop)
+ self.vm_dut_3 = self.vm3.start()
+ if self.vm_dut_3 is None:
+ raise Exception("Set up VM3 ENV failed!")
+
+ self.setup_4vm_4vf_env_flag = 1
+ except Exception as e:
+ self.destroy_4vm_4vf_env()
+ raise Exception(e)
+
+ def destroy_4vm_4vf_env(self):
+ if getattr(self, 'vm_dut_0', None):
+ self.vm_dut_0.close()
+ self.vm_dut_0.logger.logger_exit()
+ if getattr(self, 'vm0', None):
+ self.vm0.stop()
+ self.vm0 = None
+
+ if getattr(self, 'vm_dut_1', None):
+ self.vm_dut_1.close()
+ self.vm_dut_1.logger.logger_exit()
+ if getattr(self, 'vm1', None):
+ self.vm1.stop()
+ self.vm1 = None
+
+ if getattr(self, 'vm_dut_2', None):
+ self.vm_dut_2.close()
+ self.vm_dut_2.logger.logger_exit()
+ if getattr(self, 'vm2', None):
+ self.vm2.stop()
+ self.vm2 = None
+
+ if getattr(self, 'vm_dut_3', None):
+ self.vm_dut_3.close()
+ self.vm_dut_3.logger.logger_exit()
+ if getattr(slef, 'vm3', None):
+ self.vm3.stop()
+ self.vm3 = None
+
+ if getattr(self, 'host_testpmd', None):
+ self.host_testpmd.execute_cmd('stop')
+ self.host_testpmd.execute_cmd('quit', '# ')
+ self.host_testpmd = None
+
+ if getattr(self, 'used_dut_port', None):
+ self.dut.destroy_sriov_vfs_by_port(self.used_dut_port)
+ port = self.ports_info[self.used_dut_port]['port']
+ port.bind_driver('igb_uio')
+ slef.used_dut_port = None
+
+ for port_id in self.dut_ports:
+ port = self.dut.ports_info[port_id]['port']
+ port.bind_driver('igb_uio')
+
+ self.setup_4vm_4vf_env_flag = 0
+
+ def transform_integer(self, value):
+ try:
+ value = int(value)
+ except ValueError as e:
+ raise Exception("Value not integer,but is " + type(value))
+ return value
+
+ def make_port_new_ruleid(self, port):
+ port = self.transform_integer(port)
+ if port not in self.port_mirror_ref.keys():
+ max_rule_id = 0
+ else:
+ rule_ids = sorted(self.port_mirror_ref[port])
+ if rule_ids:
+ max_rule_id = rule_ids[-1] + 1
+ else:
+ max_rule_id = 0
+ return max_rule_id
+
+ def add_port_ruleid(self, port, rule_id):
+ port = self.transform_integer(port)
+ rule_id = self.transform_integer(rule_id)
+
+ if port not in self.port_mirror_ref.keys():
+ self.port_mirror_ref[port] = [rule_id]
+ else:
+ self.verify(rule_id not in self.port_mirror_ref[port],
+ "Rule id [%d] has been repeated, please check!" % rule_id)
+ self.port_mirror_ref[port].append(rule_id)
+
+ def remove_port_ruleid(self, port, rule_id):
+ port = self.transform_integer(port)
+ rule_id = self.transform_integer(rule_id)
+ if port not in self.port_mirror_ref.keys():
+ pass
+ else:
+ if rule_id not in self.port_mirror_ref[port]:
+ pass
+ else:
+ self.port_mirror_ref[port].remove(rule_id)
+ if not self.port_mirror_ref[port]:
+ self.port_mirror_ref.pop(port)
+
+ def set_port_mirror_rule(self, port, mirror_name, rule_detail):
+ """
+ Set the mirror rule for specified port.
+ """
+ port = self.transform_integer(port)
+
+ rule_id = self.make_port_new_ruleid(port)
+
+ mirror_rule_cmd = "set port %d mirror-rule %d %s %s" % \
+ (port, rule_id, mirror_name, rule_detail)
+ out = self.dut.send_expect("%s" % mirror_rule_cmd, "testpmd> ")
+ self.verify('Bad arguments' not in out, "Set port %d %s failed!" %
+ (port, mirror_name))
+
+ self.add_port_ruleid(port, rule_id)
+ return rule_id
+
+ def set_port_pool_mirror(self, port, pool_mirror_rule):
+ """
+ Set the pool mirror for specified port.
+ """
+ return self.set_port_mirror_rule(port, 'pool-mirror-up', pool_mirror_rule)
+
+ def set_port_vlan_mirror(self, port, vlan_mirror_rule):
+ """
+ Set the vlan mirror for specified port.
+ """
+ return self.set_port_mirror_rule(port, 'vlan-mirror', vlan_mirror_rule)
+
+ def set_port_uplink_mirror(self, port, uplink_mirror_rule):
+ """
+ Set the uplink mirror for specified port.
+ """
+ return self.set_port_mirror_rule(port, 'uplink-mirror', uplink_mirror_rule)
+
+ def set_port_downlink_mirror(self, port, downlink_mirror_rule):
+ """
+ Set the downlink mirror for specified port.
+ """
+ return self.set_port_mirror_rule(port, 'downlink-mirror', downlink_mirror_rule)
+
+ def reset_port_mirror_rule(self, port, rule_id):
+ """
+ Reset the pool mirror for specified port.
+ """
+ port = self.transform_integer(port)
+ rule_id = self.transform_integer(rule_id)
+
+ mirror_rule_cmd = "reset port %d mirror-rule %d" % (port, rule_id)
+ out = self.dut.send_expect("%s" % mirror_rule_cmd, "testpmd> ")
+ self.verify("Bad arguments" not in out,
+ "Reset port %d mirror rule failed!")
+
+ self.remove_port_ruleid(port, rule_id)
+
+ def reset_port_all_mirror_rule(self, port):
+ """
+ Reset all mirror rules of specified port.
+ """
+ port = self.transform_integer(port)
+
+ if port not in self.port_mirror_ref.keys():
+ pass
+ else:
+ for rule_id in self.port_mirror_ref[port]:
+ self.reset_port_mirror_rule(port, rule_id)
+
+ def setup_two_vm_common_prerequisite(self):
+ self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
+ self.vm0_testpmd = PmdOutput(self.vm_dut_0)
+ self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
+ self.vm0_testpmd.execute_cmd('set fwd rxonly')
+ self.vm0_testpmd.execute_cmd('start')
+
+ self.vm1_dut_ports = self.vm_dut_1.get_ports('any')
+ self.vm1_testpmd = PmdOutput(self.vm_dut_1)
+ self.vm1_testpmd.start_testpmd(VM_CORES_MASK)
+ self.vm1_testpmd.execute_cmd('set fwd mac')
+ self.vm1_testpmd.execute_cmd('start')
+
+ self.setup_2vm_prerequisite_flag = 1
+
+ def destroy_two_vm_common_prerequisite(self):
+ self.vm0_testpmd.execute_cmd('stop')
+ self.vm0_testpmd.execute_cmd('quit', '# ')
+ self.vm0_testpmd = None
+ self.vm0_dut_ports = None
+
+ self.vm1_testpmd.execute_cmd('stop')
+ self.vm1_testpmd.execute_cmd('quit', '# ')
+ self.vm0_testpmd = None
+ self.vm1_dut_ports = None
+
+ self.setup_2vm_prerequisite_flag = 0
+
+ def stop_test_setup_two_vm_pf_env(self):
+ self.setup_2vm_2pf_env()
+
+ out = self.vm_dut_0.send_expect("ifconfig", '# ')
+ print out
+ out = self.vm_dut_0.send_expect("lspci -nn | grep -i eth", '# ')
+ print out
+
+ out = self.vm_dut_1.send_expect("ifconfig", '# ')
+ print out
+ out = self.vm_dut_1.send_expect("lspci -nn | grep -i eth", '# ')
+ print out
+
+ self.destroy_2vm_2pf_env()
+
+ def test_two_vms_intervm_communication(self):
+ self.setup_2vm_2vf_env()
+
+ self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
+ self.vm1_dut_ports = self.vm_dut_1.get_ports('any')
+ port_id_0 = 0
+ packet_num = 10
+
+ self.vm1_testpmd = PmdOutput(self.vm_dut_1)
+ self.vm1_testpmd.start_testpmd(VM_CORES_MASK)
+ vf1_mac = self.vm1_testpmd.get_port_mac(port_id_0)
+ self.vm1_testpmd.execute_cmd('set fwd mac')
+ self.vm1_testpmd.execute_cmd('start')
+
+ self.vm0_testpmd = PmdOutput(self.vm_dut_0)
+ self.vm0_testpmd.start_testpmd(
+ VM_CORES_MASK, "--eth-peer=0,%s" % vf1_mac)
+ vf0_mac = self.vm0_testpmd.get_port_mac(port_id_0)
+ self.vm0_testpmd.execute_cmd('set fwd mac')
+ self.vm0_testpmd.execute_cmd('start')
+
+ self.setup_2vm_prerequisite_flag = 1
+ time.sleep(2)
+
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ self.send_packet(
+ self.vm_dut_0, self.vm0_dut_ports, port_id_0, count=packet_num)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ self.verify(
+ vm1_end_stats["TX-packets"] - vm1_start_stats["TX-packets"] == packet_num,
+ "VM1 transmit packets failed when sending packets to VM0")
+
+ def calculate_stats(self, start_stats, end_stats):
+ ret_stats = {}
+ for key in start_stats.keys():
+ try:
+ start_stats[key] = int(start_stats[key])
+ end_stats[key] = int(end_stats[key])
+ except TypeError:
+ ret_stats[key] = end_stats[key]
+ continue
+ ret_stats[key] = end_stats[key] - start_stats[key]
+ return ret_stats
+
+ def test_two_vms_pool_mirror(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ packet_num = 10
+
+ rule_id = self.set_port_pool_mirror(port_id_0, '0x1 dst-pool 1 on')
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ self.send_packet(
+ self.vm_dut_0, self.vm0_dut_ports, port_id_0, count=packet_num)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm1_ret_stats['RX-packets'] == packet_num and
+ vm1_ret_stats['TX-packets'] == packet_num,
+ "Pool mirror failed between VM0 and VM1!")
+
+ self.reset_port_mirror_rule(port_id_0, rule_id)
+
+ def test_two_vms_uplink_mirror(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ packet_num = 10
+
+ rule_id = self.set_port_uplink_mirror(port_id_0, 'dst-pool 1 on')
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ self.send_packet(
+ self.vm_dut_0, self.vm0_dut_ports, port_id_0, count=packet_num)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm1_ret_stats['RX-packets'] == packet_num and
+ vm1_ret_stats['TX-packets'] == packet_num,
+ "Uplink mirror failed between VM0 and VM1!")
+
+ self.reset_port_mirror_rule(port_id_0, rule_id)
+
+ def test_two_vms_downlink_mirror(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ self.vm0_testpmd.execute_cmd('stop')
+ self.vm1_testpmd.execute_cmd('stop')
+
+ port_id_0 = 0
+
+ rule_id = self.set_port_downlink_mirror(port_id_0, 'dst-pool 1 on')
+
+ self.vm1_testpmd.execute_cmd('set fwd rxonly')
+ self.vm1_testpmd.execute_cmd('start')
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ self.vm0_testpmd.execute_cmd('start tx_first')
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(vm0_start_stats, vm0_end_stats)
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm1_ret_stats['RX-packets'] == vm0_ret_stats['TX-packets'],
+ "Downlink mirror failed between VM0 and VM1!")
+
+ self.reset_port_mirror_rule(port_id_0, rule_id)
+
+ def test_two_vms_vlan_mirror(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ vlan_id = 0
+ vf_mask = '0x1'
+ packet_num = 10
+
+ self.host_testpmd.execute_cmd(
+ 'rx_vlan add %d port %d vf %s' % (vlan_id, port_id_0, vf_mask))
+ rule_id = self.set_port_vlan_mirror(port_id_0, '0 dst-pool 1 on')
+
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ ether_ip = {}
+ ether_ip['dot1q'] = {'vlan': '%d' % vlan_id}
+ self.send_packet(
+ self.vm_dut_0,
+ self.vm0_dut_ports,
+ port_id_0,
+ count=packet_num,
+ **ether_ip)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm1_ret_stats['RX-packets'] == packet_num and
+ vm1_ret_stats['TX-packets'] == packet_num,
+ "Vlan mirror failed between VM0 and VM1!")
+
+ self.reset_port_mirror_rule(port_id_0, rule_id)
+
+ def test_two_vms_vlan_and_pool_mirror(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ vlan_id = 3
+ vf_mask = '0x2'
+ packet_num = 10
+
+ self.host_testpmd.execute_cmd(
+ 'rx_vlan add %d port %d vf %s' % (vlan_id, port_id_0, vf_mask))
+ self.set_port_pool_mirror(port_id_0, '0x1 dst-pool 1 on')
+ self.set_port_vlan_mirror(port_id_0, '%d dst-pool 0 on' % vlan_id)
+
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ self.send_packet(
+ self.vm_dut_0,
+ self.vm0_dut_ports,
+ port_id_0,
+ count=packet_num)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm1_ret_stats['RX-packets'] == packet_num and
+ vm1_ret_stats['TX-packets'] == packet_num,
+ "Pool mirror failed between VM0 and VM1 when set vlan and pool mirror!")
+
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ ether_ip = {}
+ ether_ip['dot1q'] = {'vlan': '%d' % vlan_id}
+ self.send_packet(
+ self.vm_dut_1,
+ self.vm1_dut_ports,
+ port_id_0,
+ count=10 *
+ packet_num,
+ **ether_ip)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(vm0_start_stats, vm0_end_stats)
+
+ self.verify(vm0_ret_stats['RX-packets'] == 10 * packet_num,
+ "Vlan mirror failed between VM0 and VM1 when set vlan and pool mirror!")
+
+ self.reset_port_all_mirror_rule(port_id_0)
+
+ def test_two_vms_uplink_and_downlink_mirror(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ self.vm0_testpmd.execute_cmd('stop')
+ self.vm1_testpmd.execute_cmd('stop')
+
+ port_id_0 = 0
+ packet_num = 10
+
+ self.set_port_downlink_mirror(port_id_0, 'dst-pool 1 on')
+ self.set_port_uplink_mirror(port_id_0, 'dst-pool 1 on')
+
+ self.vm1_testpmd.execute_cmd('set fwd rxonly')
+ self.vm1_testpmd.execute_cmd('start')
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ self.vm0_testpmd.execute_cmd('start tx_first')
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(vm0_start_stats, vm0_end_stats)
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm1_ret_stats['RX-packets'] == vm0_ret_stats['TX-packets'],
+ "Downlink mirror failed between VM0 and VM1 " +
+ "when set uplink and downlink mirror!")
+
+ self.vm0_testpmd.execute_cmd('stop')
+ self.vm0_testpmd.execute_cmd('set fwd mac')
+ self.vm0_testpmd.execute_cmd('start')
+
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ self.send_packet(
+ self.vm_dut_0,
+ self.vm0_dut_ports,
+ port_id_0,
+ count=packet_num)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm1_ret_stats['RX-packets'] == 2 * packet_num,
+ "Uplink and down link mirror failed between VM0 and VM1 " +
+ "when set uplink and downlink mirror!")
+
+ self.reset_port_all_mirror_rule(port_id_0)
+
+ def test_two_vms_vlan_and_pool_and_uplink_and_downlink(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ self.vm0_testpmd.execute_cmd('stop')
+ self.vm1_testpmd.execute_cmd('stop')
+
+ port_id_0 = 0
+ vlan_id = 3
+ vf_mask = '0x2'
+ packet_num = 1
+
+ self.set_port_downlink_mirror(port_id_0, 'dst-pool 1 on')
+ self.set_port_uplink_mirror(port_id_0, 'dst-pool 1 on')
+ self.host_testpmd.execute_cmd("rx_vlan add %d port %d vf %s" %
+ (vlan_id, port_id_0, vf_mask))
+ self.set_port_vlan_mirror(port_id_0, '%d dst-pool 0 on' % vlan_id)
+ self.set_port_pool_mirror(port_id_0, '0x1 dst-pool 1 on')
+
+ self.vm1_testpmd.execute_cmd('set fwd rxonly')
+ self.vm1_testpmd.execute_cmd('start')
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ self.vm0_testpmd.execute_cmd('start tx_first')
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(vm0_start_stats, vm0_end_stats)
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm1_ret_stats['RX-packets'] == vm0_ret_stats['TX-packets'],
+ "Downlink mirror failed between VM0 and VM1 " +
+ "when set vlan, pool, uplink and downlink mirror!")
+
+ self.vm0_testpmd.execute_cmd('stop')
+ self.vm0_testpmd.execute_cmd('set fwd mac')
+ self.vm0_testpmd.execute_cmd('start')
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ self.send_packet(
+ self.vm_dut_0,
+ self.vm0_dut_ports,
+ port_id_0,
+ count=packet_num)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(vm0_start_stats, vm0_end_stats)
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm0_ret_stats['RX-packets'] == packet_num and
+ vm0_ret_stats['TX-packets'] == packet_num and
+ vm1_ret_stats['RX-packets'] == 2 * packet_num,
+ "Uplink and downlink mirror failed between VM0 and VM1 " +
+ "when set vlan, pool, uplink and downlink mirror!")
+
+ self.vm0_testpmd.execute_cmd('stop')
+ self.vm0_testpmd.execute_cmd('set fwd mac')
+ self.vm0_testpmd.execute_cmd('start')
+
+ ether_ip = {}
+ ether_ip['dot1q'] = {'vlan': '%d' % vlan_id}
+ vm1_start_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ self.send_packet(
+ self.vm_dut_1,
+ self.vm1_dut_ports,
+ port_id_0,
+ count=packet_num,
+ **ether_ip)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ vm1_end_stats = self.vm1_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(vm0_start_stats, vm0_end_stats)
+ vm1_ret_stats = self.calculate_stats(vm1_start_stats, vm1_end_stats)
+
+ self.verify(vm0_ret_stats['RX-packets'] == packet_num and
+ vm0_ret_stats['TX-packets'] == packet_num and
+ vm1_ret_stats['RX-packets'] == 2 * packet_num,
+ "Vlan and downlink mirror failed between VM0 and VM1 " +
+ "when set vlan, pool, uplink and downlink mirror!")
+
+ self.reset_port_all_mirror_rule(port_id_0)
+
+ def test_two_vms_add_multi_exact_mac_on_vf(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ vf_num = 0
+ packet_num = 10
+
+ for vf_mac in ["00:11:22:33:44:55", "00:55:44:33:22:11"]:
+ self.host_testpmd.execute_cmd("mac_addr add port %d vf %d %s" %
+ (port_id_0, vf_num, vf_mac))
+
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ ether_ip = {}
+ ether_ip['ether'] = {'dest_mac': '%s' % vf_mac}
+ self.send_packet(
+ self.vm_dut_0,
+ self.vm0_dut_ports,
+ port_id_0,
+ count=packet_num,
+ **ether_ip)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(
+ vm0_start_stats, vm0_end_stats)
+
+ self.verify(vm0_ret_stats['RX-packets'] == packet_num,
+ "Add exact MAC %s failed btween VF0 and VF1" % vf_mac +
+ "when add multi exact MAC address on VF!")
+
+ def test_two_vms_enalbe_or_disable_one_uta_mac_on_vf(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ vf_mac = "00:11:22:33:44:55"
+ packet_num = 10
+
+ self.host_testpmd.execute_cmd('set promisc %d on' % port_id_0)
+ self.host_testpmd.execute_cmd(
+ 'set port %d vf 0 rxmode ROPE on' % port_id_0)
+ self.host_testpmd.execute_cmd(
+ 'set port %d vf 1 rxmode ROPE off' % port_id_0)
+ self.host_testpmd.execute_cmd(
+ 'set port %d uta %s on' % (port_id_0, vf_mac))
+
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ ether_ip = {}
+ ether_ip['ether'] = {'dest_mac': '%s' % vf_mac}
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports, port_id_0,
+ count=packet_num, **ether_ip)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(vm0_start_stats, vm0_end_stats)
+
+ self.verify(vm0_ret_stats['RX-packets'] == packet_num,
+ "Enable one uta MAC failed between VM0 and VM1 " +
+ "when enable or disable one uta MAC address on VF!")
+
+ self.host_testpmd.execute_cmd('set promisc %d off' % port_id_0)
+ self.host_testpmd.execute_cmd(
+ 'set port %d vf 0 rxmode ROPE off' % port_id_0)
+
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ ether_ip = {}
+ ether_ip['ether'] = {'dest_mac': '%s' % vf_mac}
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports, port_id_0,
+ count=packet_num, invert_verify=True, **ether_ip)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(vm0_start_stats, vm0_end_stats)
+
+ self.verify(vm0_ret_stats['RX-packets'] == 0,
+ "Disable one uta MAC failed between VM0 and VM1 " +
+ "when enable or disable one uta MAC address on VF!")
+
+ def test_two_vms_add_multi_uta_mac_on_vf(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ packet_num = 10
+
+ for vf_mac in ["00:55:44:33:22:11", "00:55:44:33:22:66"]:
+ self.host_testpmd.execute_cmd("set port %d uta %s on" %
+ (port_id_0, vf_mac))
+ self.host_testpmd.execute_cmd("set port %d uta %s on" %
+ (port_id_0, vf_mac))
+
+ for vf_mac in ["00:55:44:33:22:11", "00:55:44:33:22:66"]:
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ ether_ip = {}
+ ether_ip['ether'] = {'dest_mac': '%s' % vf_mac}
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports,
+ port_id_0, count=packet_num, **ether_ip)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(
+ vm0_start_stats, vm0_end_stats)
+
+ self.verify(vm0_ret_stats['RX-packets'] == packet_num,
+ "Add MULTI uta MAC %s failed between VM0 and VM1 " % vf_mac +
+ "when add multi uta MAC address on VF!")
+
+ def test_two_vms_add_or_remove_uta_mac_on_vf(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ vf_mac = "00:55:44:33:22:11"
+ packet_num = 10
+
+ for switch in ['on', 'off', 'on']:
+ self.host_testpmd.execute_cmd("set port %d uta %s %s" %
+ (port_id_0, vf_mac, switch))
+
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ ether_ip = {}
+ ether_ip['ether'] = {'dest_mac': '%s' % vf_mac}
+ if switch == 'on':
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports,
+ port_id_0, count=packet_num, **ether_ip)
+ else:
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports, port_id_0,
+ count=packet_num, invert_verify=True, **ether_ip)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(
+ vm0_start_stats, vm0_end_stats)
+
+ if switch == 'on':
+ self.verify(vm0_ret_stats['RX-packets'] == packet_num,
+ "Add MULTI uta MAC %s failed between VM0 and VM1 " % vf_mac +
+ "when add or remove multi uta MAC address on VF!")
+ else:
+ self.verify(vm0_ret_stats['RX-packets'] == 0,
+ "Remove MULTI uta MAC %s failed between VM0 and VM1 " % vf_mac +
+ "when add or remove multi uta MAC address on VF!")
+
+ def test_two_vms_pause_rx_queues(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ packet_num = 10
+
+ for switch in ['on', 'off', 'on']:
+ self.host_testpmd.execute_cmd("set port %d vf 0 rx %s" %
+ (port_id_0, switch))
+
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ if switch == 'on':
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports,
+ port_id_0, count=packet_num)
+ else:
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports, port_id_0,
+ count=packet_num, invert_verify=True)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(
+ vm0_start_stats, vm0_end_stats)
+
+ if switch == 'on':
+ self.verify(vm0_ret_stats['RX-packets'] == packet_num,
+ "Enable RX queues failed between VM0 and VM1 " +
+ "when enable or pause RX queues on VF!")
+ else:
+ self.verify(vm0_ret_stats['RX-packets'] == 0,
+ "Pause RX queues failed between VM0 and VM1 " +
+ "when enable or pause RX queues on VF!")
+
+ def test_two_vms_pause_tx_queuse(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ self.vm0_testpmd.execute_cmd("stop")
+ self.vm0_testpmd.execute_cmd("set fwd mac")
+ self.vm0_testpmd.execute_cmd("start")
+
+ port_id_0 = 0
+ packet_num = 10
+
+ for switch in ['on', 'off', 'on']:
+ self.host_testpmd.execute_cmd("set port %d vf 0 tx %s" %
+ (port_id_0, switch))
+
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ self.send_packet(
+ self.vm_dut_0,
+ self.vm0_dut_ports,
+ port_id_0,
+ count=packet_num)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(
+ vm0_start_stats, vm0_end_stats)
+
+ if switch == 'on':
+ self.verify(vm0_ret_stats['TX-packets'] == packet_num,
+ "Enable TX queues failed between VM0 and VM1 " +
+ "when enable or pause TX queues on VF!")
+ else:
+ self.verify(vm0_ret_stats['TX-packets'] == 0,
+ "Pause TX queues failed between VM0 and VM1 " +
+ "when enable or pause TX queues on VF!")
+
+ def test_two_vms_prevent_rx_broadcast_on_vf(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ port_id_0 = 0
+ vf_mac = "FF:FF:FF:FF:FF:FF"
+ packet_num = 10
+
+ for switch in ['on', 'off', 'on']:
+ self.host_testpmd.execute_cmd("set port %d vf 0 rxmode BAM %s" %
+ (port_id_0, switch))
+
+ vm0_start_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+ ether_ip = {}
+ ether_ip['ether'] = {'dest_mac': '%s' % vf_mac}
+ if switch == 'on':
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports, port_id_0,
+ count=packet_num, **ether_ip)
+ else:
+ self.send_packet(self.vm_dut_0, self.vm0_dut_ports, port_id_0,
+ count=packet_num, invert_verify=True, **ether_ip)
+ vm0_end_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
+
+ vm0_ret_stats = self.calculate_stats(
+ vm0_start_stats, vm0_end_stats)
+
+ if switch == 'on':
+ self.verify(vm0_ret_stats['RX-packets'] == packet_num,
+ "Enable RX broadcast failed between VM0 and VM1 " +
+ "when enable or disable RX queues on VF!")
+ else:
+ self.verify(vm0_ret_stats['RX-packets'] == 0,
+ "Disable RX broadcast failed between VM0 and VM1 " +
+ "when enable or pause TX queues on VF!")
+
+ def test_two_vms_negative_input_commands(self):
+ self.setup_2vm_2vf_env()
+ self.setup_two_vm_common_prerequisite()
+
+ for command in ["set port 0 vf 65 tx on",
+ "set port 2 vf -1 tx off",
+ "set port 0 vf 0 rx oneee",
+ "set port 0 vf 0 rx offdd",
+ "set port 0 vf 64 rxmode BAM on",
+ "set port 0 vf 64 rxmode BAM off",
+ "set port 0 uta 00:11:22:33:44 on",
+ "set port 7 uta 00:55:44:33:22:11 off",
+ "set port 0 vf 34 rxmode ROPE on",
+ "mac_addr add port 0 vf 65 00:55:44:33:22:11",
+ "mac_addr add port 5 vf 0 00:55:44:88:22:11",
+ "set port 0 mirror-rule 0xf uplink-mirror dst-pool 1 on",
+ "set port 0 mirror-rule 2 vlan-mirror 9 dst-pool 1 on",
+ "set port 0 mirror-rule 0 downlink-mirror 0xf dst-pool 2 off",
+ "reset port 0 mirror-rule 4",
+ "reset port 0xff mirror-rule 0"]:
+ output = self.host_testpmd.execute_cmd(command)
+ error = False
+
+ for error_regx in [r'Bad', r'bad', r'failed', r'-[0-9]+', r'error', r'Invalid']:
+ ret_regx = re.search(error_regx, output)
+ if ret_regx and ret_regx.group():
+ error = True
+ break
+ self.verify(
+ error, "Execute command '%s' successfully, it should be failed!" % command)
+
+ def tear_down(self):
+ if self.setup_2vm_prerequisite_flag == 1:
+ self.destroy_two_vm_common_prerequisite()
+ if self.setup_2vm_2vf_env_flag == 1:
+ self.destroy_2vm_2vf_env()
+
+ if self.setup_2vm_2pf_env_flag == 1:
+ slef.destroy_2vm_2pf_env()
+
+ if self.setup_4vm_prerequisite_flag == 1:
+ self.destroy_four_vm_common_prerequisite()
+ if self.setup_4vm_4vf_env_flag == 1:
+ self.destroy_4vm_4vf_env()
+
+ def tear_down_all(self):
+ if getattr(self, 'vm0', None):
+ self.vm0.stop()
+ if getattr(self, 'vm1', None):
+ self.vm1.stop()
+ if getattr(self, 'vm2', None):
+ self.vm2.stop()
+ if getattr(self, 'vm3', None):
+ self.vm3.stop()
+
+ for port_id in self.dut_ports:
+ self.dut.destroy_sriov_vfs_by_port(port_id)
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 0/9]
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
` (8 preceding siblings ...)
2015-05-18 5:07 ` [dts] [‘dts-v1’ 9/9] Add a suite to test SRIOV mirror with KVM sjiajiax
@ 2015-05-18 6:29 ` Liu, Yong
2015-05-18 6:47 ` Jiajia, SunX
9 siblings, 1 reply; 34+ messages in thread
From: Liu, Yong @ 2015-05-18 6:29 UTC (permalink / raw)
To: Jiajia, SunX, dts
Hi Jiajia,
This is the cover letter of virtualization patch set. You should follow patch name format like below.
[PATCH V3 0/5] Support IXIA performance validation on one platform
Please add more description of architecture in cover letter. It can help us understand the design.
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 0/9]
>
> This patch set includes some virtual modules in the framework
> and a suite to test the framework
>
> sjiajiax (9):
> Abstract the NIC device as the single class NetDevice
> Optimize ssh connection
> Add some params and functions related to the virtual test
> Add VM class and the virtual DUT class and the virtual resource module
> Add qemu-agent-guest for QEMU VM
> Add a global virtual configure
> add some pmd functions for tester to code the testpmd cases
> Add two tar files for ACL testing
> Add a suite to test SRIOV mirror with KVM
>
> conf/sriov_kvm.cfg | 77 +++
> conf/virt_global.cfg | 24 +
> dep/QMP/qemu-ga-client | 299 +++++++++
> dep/QMP/qmp.py | 193 ++++++
> dep/aclpcap.tgz | Bin 0 -> 82103 bytes
> dep/aclrule.tgz | Bin 0 -> 161037 bytes
> framework/config.py | 171 ++++-
> framework/crb.py | 135 ++--
> framework/dts.py | 92 +--
> framework/dut.py | 268 +++++++-
> framework/exception.py | 27 +
> framework/logger.py | 69 +-
> framework/main.py | 7 +-
> framework/net_device.py | 600 +++++++++++++++++
> framework/pmd_output.py | 104 ++-
> framework/project_dpdk.py | 62 +-
> framework/qemu_kvm.py | 912 +++++++++++++++++++++++++
> framework/settings.py | 43 ++
> framework/ssh_connection.py | 5 +
> framework/ssh_pexpect.py | 63 +-
> framework/test_case.py | 3 +-
> framework/tester.py | 51 +-
> framework/utils.py | 77 +++
> framework/virt_base.py | 250 +++++++
> framework/virt_dut.py | 239 +++++++
> framework/virt_resource.py | 486 ++++++++++++++
> test_plans/sriov_kvm_test_plan.rst | 756 +++++++++++++++++++++
> tests/TestSuite_sriov_kvm.py | 1291
> ++++++++++++++++++++++++++++++++++++
> 28 files changed, 6062 insertions(+), 242 deletions(-)
> create mode 100644 conf/sriov_kvm.cfg
> create mode 100644 conf/virt_global.cfg
> create mode 100644 dep/QMP/qemu-ga-client
> create mode 100644 dep/QMP/qmp.py
> create mode 100644 dep/aclpcap.tgz
> create mode 100644 dep/aclrule.tgz
> mode change 100755 => 100644 framework/config.py
> create mode 100644 framework/net_device.py
> create mode 100644 framework/qemu_kvm.py
> create mode 100644 framework/utils.py
> create mode 100644 framework/virt_base.py
> create mode 100644 framework/virt_dut.py
> create mode 100644 framework/virt_resource.py
> create mode 100644 test_plans/sriov_kvm_test_plan.rst
> create mode 100644 tests/TestSuite_sriov_kvm.py
>
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 6/9] Add a global virtual configure
2015-05-18 5:07 ` [dts] [‘dts-v1’ 6/9] Add a global virtual configure sjiajiax
@ 2015-05-18 6:32 ` Liu, Yong
2015-05-18 6:48 ` Jiajia, SunX
0 siblings, 1 reply; 34+ messages in thread
From: Liu, Yong @ 2015-05-18 6:32 UTC (permalink / raw)
To: Jiajia, SunX, dts
Jiajia,
In this configuration file, need detailed introduction of the parameters. User should understand how to change these parameters.
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 6/9] Add a global virtual configure
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> conf/virt_global.cfg | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
> create mode 100644 conf/virt_global.cfg
>
> diff --git a/conf/virt_global.cfg b/conf/virt_global.cfg
> new file mode 100644
> index 0000000..f26a90c
> --- /dev/null
> +++ b/conf/virt_global.cfg
> @@ -0,0 +1,24 @@
> +# virtualization global configurations
> +#[LIBVIRT]
> +#[KVM]
> +#[XEN]
> +[LIBVIRT]
> +cpu =
> + number=4,cpupin=3 4 5 6;
> +mem =
> + size=2048;
> +net =
> + local=unused
> +[KVM]
> +cpu =
> + model=host,number=4,cpupin=3 4 5 6;
> +mem =
> + size=2048;
> +[XEN]
> +cpu =
> + number=4,cpupin=3 4 5 6;
> +mem =
> + size=2048;
> +vif =
> + mac=random,bridge=br0
> +
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 0/9]
2015-05-18 6:29 ` [dts] [‘dts-v1’ 0/9] Liu, Yong
@ 2015-05-18 6:47 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-18 6:47 UTC (permalink / raw)
To: Liu, Yong, dts
Hi Yong,
Ok, I will do it in the next version.
Thanks,
Jiajia
> -----Original Message-----
> From: Liu, Yong
> Sent: Monday, May 18, 2015 2:30 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 0/9]
>
> Hi Jiajia,
> This is the cover letter of virtualization patch set. You should follow
> patch name format like below.
>
> [PATCH V3 0/5] Support IXIA performance validation on one platform
>
> Please add more description of architecture in cover letter. It can
> help us understand the design.
>
> > -----Original Message-----
> > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > Sent: Monday, May 18, 2015 1:07 PM
> > To: dts@dpdk.org
> > Subject: [dts] [‘dts-v1’ 0/9]
> >
> > This patch set includes some virtual modules in the framework
> > and a suite to test the framework
> >
> > sjiajiax (9):
> > Abstract the NIC device as the single class NetDevice
> > Optimize ssh connection
> > Add some params and functions related to the virtual test
> > Add VM class and the virtual DUT class and the virtual resource
> module
> > Add qemu-agent-guest for QEMU VM
> > Add a global virtual configure
> > add some pmd functions for tester to code the testpmd cases
> > Add two tar files for ACL testing
> > Add a suite to test SRIOV mirror with KVM
> >
> > conf/sriov_kvm.cfg | 77 +++
> > conf/virt_global.cfg | 24 +
> > dep/QMP/qemu-ga-client | 299 +++++++++
> > dep/QMP/qmp.py | 193 ++++++
> > dep/aclpcap.tgz | Bin 0 -> 82103 bytes
> > dep/aclrule.tgz | Bin 0 -> 161037 bytes
> > framework/config.py | 171 ++++-
> > framework/crb.py | 135 ++--
> > framework/dts.py | 92 +--
> > framework/dut.py | 268 +++++++-
> > framework/exception.py | 27 +
> > framework/logger.py | 69 +-
> > framework/main.py | 7 +-
> > framework/net_device.py | 600 +++++++++++++++++
> > framework/pmd_output.py | 104 ++-
> > framework/project_dpdk.py | 62 +-
> > framework/qemu_kvm.py | 912 +++++++++++++++++++++++++
> > framework/settings.py | 43 ++
> > framework/ssh_connection.py | 5 +
> > framework/ssh_pexpect.py | 63 +-
> > framework/test_case.py | 3 +-
> > framework/tester.py | 51 +-
> > framework/utils.py | 77 +++
> > framework/virt_base.py | 250 +++++++
> > framework/virt_dut.py | 239 +++++++
> > framework/virt_resource.py | 486 ++++++++++++++
> > test_plans/sriov_kvm_test_plan.rst | 756 +++++++++++++++++++++
> > tests/TestSuite_sriov_kvm.py | 1291
> > ++++++++++++++++++++++++++++++++++++
> > 28 files changed, 6062 insertions(+), 242 deletions(-)
> > create mode 100644 conf/sriov_kvm.cfg
> > create mode 100644 conf/virt_global.cfg
> > create mode 100644 dep/QMP/qemu-ga-client
> > create mode 100644 dep/QMP/qmp.py
> > create mode 100644 dep/aclpcap.tgz
> > create mode 100644 dep/aclrule.tgz
> > mode change 100755 => 100644 framework/config.py
> > create mode 100644 framework/net_device.py
> > create mode 100644 framework/qemu_kvm.py
> > create mode 100644 framework/utils.py
> > create mode 100644 framework/virt_base.py
> > create mode 100644 framework/virt_dut.py
> > create mode 100644 framework/virt_resource.py
> > create mode 100644 test_plans/sriov_kvm_test_plan.rst
> > create mode 100644 tests/TestSuite_sriov_kvm.py
> >
> > --
> > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 6/9] Add a global virtual configure
2015-05-18 6:32 ` Liu, Yong
@ 2015-05-18 6:48 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-18 6:48 UTC (permalink / raw)
To: Liu, Yong, dts
Hi Yong,
Yes, I will add the help introduction in the next version.
Thanks,
Jiajia
> -----Original Message-----
> From: Liu, Yong
> Sent: Monday, May 18, 2015 2:32 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 6/9] Add a global virtual configure
>
> Jiajia,
> In this configuration file, need detailed introduction of the
> parameters. User should understand how to change these parameters.
>
> > -----Original Message-----
> > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > Sent: Monday, May 18, 2015 1:07 PM
> > To: dts@dpdk.org
> > Subject: [dts] [‘dts-v1’ 6/9] Add a global virtual configure
> >
> > Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> > ---
> > conf/virt_global.cfg | 24 ++++++++++++++++++++++++
> > 1 file changed, 24 insertions(+)
> > create mode 100644 conf/virt_global.cfg
> >
> > diff --git a/conf/virt_global.cfg b/conf/virt_global.cfg
> > new file mode 100644
> > index 0000000..f26a90c
> > --- /dev/null
> > +++ b/conf/virt_global.cfg
> > @@ -0,0 +1,24 @@
> > +# virtualization global configurations
> > +#[LIBVIRT]
> > +#[KVM]
> > +#[XEN]
> > +[LIBVIRT]
> > +cpu =
> > + number=4,cpupin=3 4 5 6;
> > +mem =
> > + size=2048;
> > +net =
> > + local=unused
> > +[KVM]
> > +cpu =
> > + model=host,number=4,cpupin=3 4 5 6;
> > +mem =
> > + size=2048;
> > +[XEN]
> > +cpu =
> > + number=4,cpupin=3 4 5 6;
> > +mem =
> > + size=2048;
> > +vif =
> > + mac=random,bridge=br0
> > +
> > --
> > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
2015-05-18 5:07 ` [dts] [‘dts-v1’ 2/9] Optimize ssh connection sjiajiax
@ 2015-05-18 7:06 ` Liu, Yong
2015-05-18 7:43 ` Jiajia, SunX
0 siblings, 1 reply; 34+ messages in thread
From: Liu, Yong @ 2015-05-18 7:06 UTC (permalink / raw)
To: Jiajia, SunX, dts
Jiajia,
Please see my comments below.
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
>
> Optimize configure parse
>
> Move some functions in dts to an common utils module
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> framework/config.py | 171 +++++++++++++++++++++++++++++++++++----
> -----
> framework/ssh_connection.py | 5 ++
> framework/ssh_pexpect.py | 63 +++++++++++++---
> framework/utils.py | 77 ++++++++++++++++++++
> 4 files changed, 270 insertions(+), 46 deletions(-)
> mode change 100755 => 100644 framework/config.py
> create mode 100644 framework/utils.py
>
> diff --git a/framework/config.py b/framework/config.py
> old mode 100755
> new mode 100644
> index d2548e8..927c846
> --- a/framework/config.py
> +++ b/framework/config.py
> @@ -37,45 +37,133 @@ import re
> import ConfigParser # config parse module
> import argparse # prase arguments module
>
> -portconf = "conf/ports.cfg"
> -crbconf = "conf/crbs.cfg"
> +PORTCONF = "conf/ports.cfg"
> +CRBCONF = "conf/crbs.cfg"
> +VIRTCONF = "conf/virt_global.cfg"
>
>
> class UserConf():
>
> - def __init__(self, port_conf=portconf, crb_conf=crbconf):
> - self.port_config = port_conf
> - self.crb_config = crb_conf
> + def __init__(self, config):
> + self.conf = ConfigParser.SafeConfigParser()
> + load_files = self.conf.read(config)
> + if load_files == []:
> + print "FAILED LOADING %s!!!" % config
> + self.conf = None
> + raise
> +
There's need one special exception for configuration parsed failure.
> + def get_sections(self):
> + if self.conf is None:
> + return None
> +
> + return self.conf.sections()
> +
> + def load_section(self, section):
> + if self.conf is None:
> + return None
> +
> + items = None
> + for conf_sect in self.conf.sections():
> + if conf_sect == section:
> + items = self.conf.items(section)
> +
> + return items
> +
> + def load_config(self, item):
> + confs = [conf.strip() for conf in item.split(';')]
> + if '' in confs:
> + confs.remove('')
> + return confs
> +
> + def load_param(self, conf):
> + paramDict = dict()
> +
> + for param in conf.split(','):
> + (key, _, value) = param.partition('=')
> + paramDict[key] = value
> + return paramDict
> +
> +
> +class VirtConf(UserConf):
> +
> + def __init__(self, virt_conf=VIRTCONF):
> + self.config_file = virt_conf
> + self.virt_cfg = {}
> + try:
> + self.virt_conf = UserConf(self.config_file)
> + except Exception as e:
> + print "FAILED LOADING VIRT CONFIG!!!"
> + self.virt_conf = None
> +
There's need one special exception for configuration parsed failure.
> + def load_virt_config(self, name):
> + self.virt_cfgs = []
> +
> + try:
> + virt_confs = self.virt_conf.load_section(name)
> + except:
> + print "FAILED FIND SECTION %s!!!" % name
> + return
> +
Add exception for load section failed.
> + for virt_conf in virt_confs:
> + virt_cfg = {}
> + virt_params = []
> + key, config = virt_conf
> + confs = self.virt_conf.load_config(config)
> + for config in confs:
> + virt_params.append(self.load_virt_param(config))
> + virt_cfg[key] = virt_params
> + self.virt_cfgs.append(virt_cfg)
> +
> + def get_virt_config(self):
> + return self.virt_cfgs
> +
> + def load_virt_param(self, config):
> + cfg_params = self.virt_conf.load_param(config)
> + return cfg_params
> +
> +
> +class PortConf(UserConf):
> +
> + def __init__(self, port_conf=PORTCONF):
> + self.config_file = port_conf
> self.ports_cfg = {}
> self.pci_regex = "([\da-f]{2}:[\da-f]{2}.\d{1})$"
> try:
> - self.port_conf = ConfigParser.SafeConfigParser()
> - self.port_conf.read(self.port_config)
> + self.port_conf = UserConf(self.config_file)
> except Exception as e:
> print "FAILED LOADING PORT CONFIG!!!"
> + self.port_conf = None
>
There's need one special exception for configuration parsed failure.
> def load_ports_config(self, crbIP):
> - ports = []
> - for crb in self.port_conf.sections():
> - if crb != crbIP:
> - continue
> - ports = [port.strip()
> - for port in self.port_conf.get(crb,
> 'ports').split(';')]
> + self.ports_cfg = {}
> + if self.port_conf is None:
> + return
> +
> + ports = self.port_conf.load_section(crbIP)
> + if ports is None:
> + return
> + key, config = ports[0]
> + confs = self.port_conf.load_config(config)
> +
> + for config in confs:
> + port_param = self.port_conf.load_param(config)
>
> - for port in ports:
> - port_cfg = self.__parse_port_param(port)
> # check pci BDF validity
> - if 'pci' not in port_cfg:
> + if 'pci' not in port_param:
> print "NOT FOUND CONFIG FOR NO PCI ADDRESS!!!"
> continue
> - m = re.match(self.pci_regex, port_cfg['pci'])
> + m = re.match(self.pci_regex, port_param['pci'])
> if m is None:
> print "INVALID CONFIG FOR NO PCI ADDRESS!!!"
> continue
>
> - keys = port_cfg.keys()
> + keys = port_param.keys()
> keys.remove('pci')
> - self.ports_cfg[port_cfg['pci']] = {key: port_cfg[key] for key
> in keys}
> + self.ports_cfg[port_param['pci']] = {
> + key: port_param[key] for key in keys}
> + if 'numa' in self.ports_cfg[port_param['pci']]:
> + numa_str = self.ports_cfg[port_param['pci']]['numa']
> + self.ports_cfg[port_param['pci']]['numa'] = int(numa_str)
>
> def get_ports_config(self):
> return self.ports_cfg
> @@ -86,23 +174,36 @@ class UserConf():
> else:
> return False
>
> - def __parse_port_param(self, port):
> - portDict = dict()
> -
> - for param in port.split(','):
> - (key, _, value) = param.partition('=')
> - if key == 'numa':
> - portDict[key] = int(value)
> - else:
> - portDict[key] = value
> - return portDict
> +
>
>
> if __name__ == '__main__':
> - parser = argparse.ArgumentParser(description="Load DTS configuration
> files")
> - parser.add_argument("-p", "--portconf", default=portconf)
> - parser.add_argument("-c", "--crbconf", default=crbconf)
> + parser = argparse.ArgumentParser(
> + description="Load DTS configuration files")
> + parser.add_argument("-p", "--portconf", default=PORTCONF)
> + parser.add_argument("-c", "--crbconf", default=CRBCONF)
> + parser.add_argument("-v", "--virtconf", default=VIRTCONF)
> args = parser.parse_args()
> - conf = UserConf()
> - conf.load_ports_config('192.168.1.1')
> - conf.check_port_available('0000:86:00.0')
> +
> + # not existed configuration file
> + VirtConf('/tmp/not-existed.cfg')
> +
> + # example for basic use configuration file
> + conf = UserConf(PORTCONF)
> + for section in conf.get_sections():
> + items = conf.load_section(section)
> + key, value = items[0]
> + confs = conf.load_config(value)
> + for config in confs:
> + conf.load_param(config)
> +
> + # example for port configuration file
> + portconf = PortConf(PORTCONF)
> + portconf.load_ports_config('DUT IP')
> + print portconf.get_ports_config()
> + portconf.check_port_available('86:00.0')
> +
> + # example for global virtualization configuration file
> + virtconf = VirtConf(VIRTCONF)
> + virtconf.load_virt_config('LIBVIRT')
> + print virtconf.get_virt_config()
> diff --git a/framework/ssh_connection.py b/framework/ssh_connection.py
> index 18a6517..7286b14 100644
> --- a/framework/ssh_connection.py
> +++ b/framework/ssh_connection.py
> @@ -62,6 +62,11 @@ class SSHConnection(object):
> self.logger.debug(out)
> return out
>
> + def get_session_before(self, timeout=15):
> + out = self.session.get_session_before(timeout)
> + self.logger.debug(out)
> + return out
> +
I've sent out this patch, please make sure there's no gap there.
You'd better remove those from your patch work.
> def close(self):
> self.session.close()
>
> diff --git a/framework/ssh_pexpect.py b/framework/ssh_pexpect.py
> index 735df44..4193020 100644
> --- a/framework/ssh_pexpect.py
> +++ b/framework/ssh_pexpect.py
> @@ -2,7 +2,8 @@ import time
> import pexpect
> import pxssh
> from debugger import ignore_keyintr, aware_keyintr
> -from exception import TimeoutException, SSHConnectionException
> +from exception import TimeoutException, SSHConnectionException,
> SSHSessionDeadException
> +from utils import RED, GREEN
>
> """
> Module handle ssh sessions between tester and DUT.
> @@ -14,16 +15,28 @@ Aslo support transfer files to tester or DUT.
> class SSHPexpect(object):
>
> def __init__(self, host, username, password):
> - self.magic_prompt = "[MAGIC PROMPT]"
> + self.magic_prompt = "MAGIC PROMPT"
> try:
> self.session = pxssh.pxssh()
> - self.username = username
> self.host = host
> + self.username = username
> self.password = password
> - self.session.login(self.host, self.username,
> - self.password, original_prompt='[$#>]')
> + if ':' in host:
> + self.ip = host.split(':')[0]
> + self.port = int(host.split(':')[1])
> + self.session.login(self.ip, self.username,
> + self.password, original_prompt='[$#>]',
> + port=self.port, login_timeout=20)
> + else:
> + self.session.login(self.host, self.username,
> + self.password, original_prompt='[$#>]')
> self.send_expect('stty -echo', '# ', timeout=2)
> - except Exception:
> + except Exception, e:
> + print RED(e)
> + if getattr(self, 'port', None):
> + suggestion = "\nSuggession: Check if the fireware on
> [ %s ] " % \
> + self.ip + "is stoped\n"
> + print GREEN(suggestion)
> raise SSHConnectionException(host)
>
> def init_log(self, logger, name):
> @@ -33,7 +46,7 @@ class SSHPexpect(object):
>
> def send_expect_base(self, command, expected, timeout=15):
> ignore_keyintr()
> - self.__flush() # clear buffer
> + self.__flush() # clear buffer
> self.session.PROMPT = expected
> self.__sendline(command)
> self.__prompt(command, timeout)
> @@ -45,7 +58,7 @@ class SSHPexpect(object):
> def send_expect(self, command, expected, timeout=15, verify=False):
> ret = self.send_expect_base(command, expected, timeout)
> if verify:
> - ret_status = self.send_expect_base("echo $?", expected)
> + ret_status = self.send_expect_base("echo $?", expected,
> timeout)
> if not int(ret_status):
> return ret
> else:
> @@ -54,21 +67,44 @@ class SSHPexpect(object):
> else:
> return ret
>
> - def __flush(self):
> + def get_session_before(self, timeout=15):
> + """
> + Get all output before timeout
> + """
> + ignore_keyintr()
> self.session.PROMPT = self.magic_prompt
> - self.session.prompt(0.1)
> + try:
> + self.session.prompt(timeout)
> + except Exception as e:
> + pass
> +
> + aware_keyintr()
> + before = self.get_output_before()
> + self.__flush()
> + return before
> +
> + def __flush(self):
> + """
> + Clear all session buffer
> + """
> + self.session.buffer = ""
> + self.session.before = ""
>
> def __prompt(self, command, timeout):
> if not self.session.prompt(timeout):
> raise TimeoutException(command, self.get_output_all())
>
> def __sendline(self, command):
> + if not self.isalive():
> + raise SSHSessionDeadException(self.host)
> if len(command) == 2 and command.startswith('^'):
> self.session.sendcontrol(command[1])
> else:
> self.session.sendline(command)
>
> def get_output_before(self):
> + if not self.isalive():
> + raise SSHSessionDeadException(self.host)
> self.session.flush()
> before = self.session.before.rsplit('\r\n', 1)
> if before[0] == "[PEXPECT]":
> @@ -103,7 +139,12 @@ class SSHPexpect(object):
> """
> Sends a local file to a remote place.
> """
> - command = 'scp {0} {1}@{2}:{3}'.format(src, self.username,
> self.host, dst)
> + if ':' in self.host:
> + command = 'scp -P {0} -o NoHostAuthenticationForLocalhost=yes
> {1} {2}@{3}:{4}'.format(
> + str(self.port), src, self.username, self.ip, dst)
> + else:
> + command = 'scp {0} {1}@{2}:{3}'.format(
> + src, self.username, self.host, dst)
> if password == '':
> self._spawn_scp(command, self.password)
> else:
> diff --git a/framework/utils.py b/framework/utils.py
> new file mode 100644
> index 0000000..57eb988
> --- /dev/null
> +++ b/framework/utils.py
> @@ -0,0 +1,77 @@
> +# 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.
> +
> +import json # json format
> +import re
> +
> +
> +def RED(text):
> + return "\x1B[" + "31;1m" + str(text) + "\x1B[" + "0m"
> +
> +
> +def BLUE(text):
> + return "\x1B[" + "36;1m" + str(text) + "\x1B[" + "0m"
> +
> +
> +def GREEN(text):
> + return "\x1B[" + "32;1m" + str(text) + "\x1B[" + "0m"
> +
> +
> +def pprint(some_dict):
> + """
> + Print JSON format dictionary object.
> + """
> + return json.dumps(some_dict, sort_keys=True, indent=4)
> +
> +
> +def regexp(s, to_match, allString=False):
> + """
> + Ensure that the re `to_match' only has one group in it.
> + """
> +
> + scanner = re.compile(to_match, re.DOTALL)
> + if allString:
> + return scanner.findall(s)
> + m = scanner.search(s)
> + if m is None:
> + print RED("Failed to match " + to_match + " in the string " + s)
> + return None
> + return m.group(1)
> +
> +
> +def get_obj_funcs(obj, func_name_regex):
> + """
> + Return function list which name matched regex.
> + """
> + for func_name in dir(obj):
> + func = getattr(obj, func_name)
> + if callable(func) and re.match(func_name_regex, func.__name__):
> + yield func
> --
This function now used to free resource of virtualization machine, I think it's better to call free functions directly.
Maybe there will be dependency of these free functions. What's your idea about it?
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test
2015-05-18 5:07 ` [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test sjiajiax
@ 2015-05-18 7:26 ` Liu, Yong
2015-05-18 8:08 ` Jiajia, SunX
2015-05-18 7:59 ` Xu, HuilongX
1 sibling, 1 reply; 34+ messages in thread
From: Liu, Yong @ 2015-05-18 7:26 UTC (permalink / raw)
To: Jiajia, SunX, dts
Jiajia, please see my comments below.
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 3/9] Add some params and functions related to the
> virtual test
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> framework/dts.py | 92 +++++++++++-------------------------------
> -----
> framework/exception.py | 27 ++++++++++++++
> framework/logger.py | 69 +++++++++++++++++++++++++++++------
> framework/main.py | 7 +++-
> framework/project_dpdk.py | 62 ++++++++++++++++++++++----------
> 5 files changed, 157 insertions(+), 100 deletions(-)
>
> diff --git a/framework/dts.py b/framework/dts.py
> index c9ecccb..c0df4e9 100644
> --- a/framework/dts.py
> +++ b/framework/dts.py
> @@ -49,6 +49,7 @@ from test_case import TestCase
> from test_result import Result
> from stats_reporter import StatsReporter
> from excel_reporter import ExcelReporter
> +from utils import *
> from exception import TimeoutException
> from logger import getLogger
> import logger
> @@ -57,6 +58,7 @@ import sys
> reload(sys)
> sys.setdefaultencoding('UTF8')
>
> +PROJECT_MODULE_PREFIX = 'project_'
>
> debug_mode = False
> config = None
> @@ -73,44 +75,12 @@ result = None
> excel_report = None
> stats = None
> log_handler = None
> +Package = ''
> +Patches = []
> drivername = ""
> interrupttypr = ""
>
>
> -def RED(text):
> - return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
> -
> -
> -def BLUE(text):
> - return "\x1B[" + "36;1m" + text + "\x1B[" + "0m"
> -
> -
> -def GREEN(text):
> - return "\x1B[" + "32;1m" + text + "\x1B[" + "0m"
> -
> -
> -def regexp(s, to_match, allString=False):
> - """
> - Ensure that the re `to_match' only has one group in it.
> - """
> -
> - scanner = re.compile(to_match, re.DOTALL)
> - if allString:
> - return scanner.findall(s)
> - m = scanner.search(s)
> - if m is None:
> - log_handler.warning("Failed to match " + to_match + " in the
> string " + s)
> - return None
> - return m.group(1)
> -
> -
> -def pprint(some_dict):
> - """
> - Print JSON format dictionary object.
> - """
> - return json.dumps(some_dict, sort_keys=True, indent=4)
> -
> -
> def report(text, frame=False, annex=False):
> """
> Save report text into rst file.
> @@ -132,36 +102,6 @@ def close_crb_sessions():
> log_handler.info("DTS ended")
>
>
> -def get_nic_driver(pci_id):
> - """
> - Return linux driver for specified pci device
> - """
> - driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
> - try:
> - driver = DRIVERS[driverlist[pci_id]]
> - except Exception as e:
> - driver = None
> - return driver
> -
> -
> -def accepted_nic(pci_id):
> - """
> - Return True if the pci_id is a known NIC card in the settings file
> and if
> - it is selected in the execution file, otherwise it returns False.
> - """
> - if pci_id not in NICS.values():
> - return False
> -
> - if nic is 'any':
> - return True
> -
> - else:
> - if pci_id == NICS[nic]:
> - return True
> -
> - return False
> -
> -
> def get_crb_os(crb):
> if 'OS' in crb:
> return crb['OS']
> @@ -220,9 +160,10 @@ def get_project_obj(project_name, super_class,
> crbInst, serializer):
> """
> Load project module and return crb instance.
> """
> + global PROJECT_MODULE_PREFIX
> project_obj = None
> try:
> - project_module = __import__("project_" + project_name)
> + project_module = __import__(PROJECT_MODULE_PREFIX + project_name)
>
> for project_subclassname, project_subclass in
> get_subclasses(project_module, super_class):
> project_obj = project_subclass(crbInst, serializer)
> @@ -267,19 +208,20 @@ def dts_log_execution(log_handler):
> pass
>
>
> -def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir,
> nic):
> +def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir, nic,
> virttype):
> """
> Create dts dut/tester instance and initialize them.
> """
> global dut
> global tester
> - serializer.set_serialized_filename('../.%s.cache' % crbInst['IP'])
> + serializer.set_serialized_filename('.%s.cache' % crbInst['IP'])
> serializer.load_from_file()
>
> dut = get_project_obj(project, Dut, crbInst, serializer)
> tester = get_project_obj(project, Tester, crbInst, serializer)
> dut.tester = tester
> tester.dut = dut
> + dut.set_virttype(virttype)
> dut.set_speedup_options(read_cache, skip_setup)
> dut.set_directory(base_dir)
> dut.set_nic_type(nic)
> @@ -337,7 +279,6 @@ def dts_run_target(crbInst, targets, test_suites, nic):
> if 'nic_type' not in paramDict:
> paramDict['nic_type'] = 'any'
> nic = 'any'
> - result.nic = nic
>
> dts_run_suite(crbInst, test_suites, target, nic)
>
> @@ -359,7 +300,9 @@ def dts_run_suite(crbInst, test_suites, target, nic):
> test_module = __import__('TestSuite_' + test_suite)
> for test_classname, test_class in get_subclasses(test_module,
> TestCase):
>
> - test_suite = test_class(dut, tester, target)
> + test_suite = test_class(dut, tester, target, test_suite)
> + result.nic = test_suite.nic
> +
> dts_log_testsuite(test_suite, log_handler, test_classname)
>
> log_handler.info("\nTEST SUITE : " + test_classname)
> @@ -386,7 +329,7 @@ def dts_run_suite(crbInst, test_suites, target, nic):
>
> def run_all(config_file, pkgName, git, patch, skip_setup,
> read_cache, project, suite_dir, test_cases,
> - base_dir, output_dir, verbose, debug):
> + base_dir, output_dir, verbose, virttype, debug):
> """
> Main process of DTS, it will run all test suites in the config file.
> """
> @@ -400,6 +343,12 @@ def run_all(config_file, pkgName, git, patch,
> skip_setup,
> global stats
> global log_handler
> global debug_mode
> + global Package
> + global Patches
> +
> + # save global variable
> + Package = pkgName
> + Patches = patch
>
> # prepare the output folder
> if not os.path.exists(output_dir):
> @@ -466,7 +415,8 @@ def run_all(config_file, pkgName, git, patch,
> skip_setup,
> result.dut = dutIP
>
> # init dut, tester crb
> - dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir,
> nics)
> + dts_crbs_init(
> + crbInst, skip_setup, read_cache, project, base_dir, nics,
> virttype)
>
> # Run DUT prerequisites
> if dts_run_prerequisties(pkgName, patch) is False:
> diff --git a/framework/exception.py b/framework/exception.py
> index be38c16..98dedf4 100644
> --- a/framework/exception.py
> +++ b/framework/exception.py
> @@ -46,3 +46,30 @@ class SSHConnectionException(Exception):
>
> def __str__(self):
> return 'Error trying to connect with %s' % self.host
> +
> +
> +class SSHSessionDeadException(Exception):
> +
> + """
> + SSH session is not alive.
> + It can no longer be used.
> + """
> +
> + def __init__(self, host):
> + self.host = host
> +
> + def __str__(self):
> + return 'SSH session with %s has been dead' % self.host
> +
> +
> +class StartVMFailedException(Exception):
> +
> + """
> + Start VM failed.
> + """
> +
> + def __init__(self, error):
> + self.error = error
> +
> + def __str__(self):
> + return repr(self.error)
> diff --git a/framework/logger.py b/framework/logger.py
> index 1829e18..5597e33 100644
> --- a/framework/logger.py
> +++ b/framework/logger.py
> @@ -35,6 +35,9 @@ import sys
> import inspect
> import re
>
> +from settings import LOG_NAME_SEP
> +from utils import RED
> +
> """
> DTS logger module with several log level. DTS framwork and TestSuite log
> will saved into different log files.
> @@ -58,6 +61,9 @@ logging.SUITE_TESTER_OUTPUT = logging.DEBUG + 4
> logging.DTS_IXIA_CMD = logging.INFO + 5
> logging.DTS_IXIA_OUTPUT = logging.DEBUG + 5
>
> +logging.DTS_VIRTDUT_CMD = logging.INFO + 6
> +logging.DTS_VIRTDUT_OUTPUT = logging.DEBUG + 6
> +
> logging.addLevelName(logging.DTS_DUT_CMD, 'DTS_DUT_CMD')
> logging.addLevelName(logging.DTS_DUT_OUTPUT, 'DTS_DUT_OUTPUT')
> logging.addLevelName(logging.DTS_DUT_RESULT, 'DTS_DUT_RESUTL')
> @@ -66,6 +72,12 @@ logging.addLevelName(logging.DTS_TESTER_CMD,
> 'DTS_TESTER_CMD')
> logging.addLevelName(logging.DTS_TESTER_OUTPUT, 'DTS_TESTER_OUTPUT')
> logging.addLevelName(logging.DTS_TESTER_RESULT, 'DTS_TESTER_RESULT')
>
> +logging.addLevelName(logging.DTS_IXIA_CMD, 'DTS_IXIA_CMD')
> +logging.addLevelName(logging.DTS_IXIA_OUTPUT, 'DTS_IXIA_OUTPUT')
> +
> +logging.addLevelName(logging.DTS_VIRTDUT_CMD, 'VIRTDUT_CMD')
> +logging.addLevelName(logging.DTS_VIRTDUT_OUTPUT, 'VIRTDUT_OUTPUT')
> +
> logging.addLevelName(logging.SUITE_DUT_CMD, 'SUITE_DUT_CMD')
> logging.addLevelName(logging.SUITE_DUT_OUTPUT, 'SUITE_DUT_OUTPUT')
>
> @@ -82,15 +94,18 @@ stream_fmt = '%(color)s%(levelname)20s: %(message)s' +
> RESET_COLOR
> log_dir = None
>
>
> -def RED(text):
> - return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
> -
> -
> def set_verbose():
> global verbose
> verbose = True
>
>
> +def add_salt(salt, msg):
> + if not salt:
> + return msg
> + else:
> + return '[%s] ' % salt + str(msg)
> +
> +
> class BaseLoggerAdapter(logging.LoggerAdapter):
> """
> Upper layer of original logging module.
> @@ -132,6 +147,12 @@ class BaseLoggerAdapter(logging.LoggerAdapter):
> def dts_ixia_output(self, msg, *args, **kwargs):
> self.log(logging.DTS_IXIA_OUTPUT, msg, *args, **kwargs)
>
> + def dts_virtdut_cmd(self, msg, *args, **kwargs):
> + self.log(logging.DTS_VIRTDUT_CMD, msg, *args, **kwargs)
> +
> + def dts_virtdut_output(self, msg, *args, **kwargs):
> + self.log(logging.DTS_VIRTDUT_OUTPUT, msg, *args, **kwargs)
> +
>
> class ColorHandler(logging.StreamHandler):
> """
> @@ -150,6 +171,8 @@ class ColorHandler(logging.StreamHandler):
> logging.SUITE_TESTER_CMD: '', # SYSTEM
> logging.DTS_IXIA_CMD: '', # SYSTEM
> logging.DTS_IXIA_OUTPUT: '', # SYSTEM
> + logging.DTS_VIRTDUT_CMD: '', # SYSTEM
> + logging.DTS_VIRTDUT_OUTPUT: '', # SYSTEM
> logging.WARN: '\033[01;33m', # BOLD YELLOW
> logging.DTS_DUT_RESULT: '\033[01;34m', # BOLD BLUE
> logging.DTS_TESTER_RESULT: '\033[01;34m', # BOLD BLUE
> @@ -189,6 +212,8 @@ class DTSLOG(BaseLoggerAdapter):
> self.crb = crb
> super(DTSLOG, self).__init__(self.logger, dict(crb=self.crb))
>
> + self.salt = ''
> +
> self.fh = None
> self.ch = None
>
> @@ -221,24 +246,28 @@ class DTSLOG(BaseLoggerAdapter):
> """
> DTS warnning level log function.
> """
> + message = add_salt(self.salt, message)
> self.logger.log(self.warn_lvl, message)
>
> def info(self, message):
> """
> DTS information level log function.
> """
> + message = add_salt(self.salt, message)
> self.logger.log(self.info_lvl, message)
>
> def error(self, message):
> """
> DTS error level log function.
> """
> + message = add_salt(self.salt, message)
> self.logger.log(self.error_lvl, message)
>
> def debug(self, message):
> """
> DTS debug level log function.
> """
> + message = add_salt(self.salt, message)
> self.logger.log(self.debug_lvl, message)
>
> def set_logfile_path(self, path):
> @@ -270,17 +299,34 @@ class DTSLOG(BaseLoggerAdapter):
> ch = ColorHandler()
> self.__log_hander(fh, ch)
>
> - if crb == "dut":
> + def set_salt(crb, start_flag):
> + if LOG_NAME_SEP in crb:
> + old = '%s%s' % (start_flag, LOG_NAME_SEP)
> + if not self.salt:
> + self.salt = crb.replace(old, '', 1)
> +
> + if crb.startswith('dut'):
> self.info_lvl = logging.DTS_DUT_CMD
> self.debug_lvl = logging.DTS_DUT_OUTPUT
> self.warn_lvl = logging.DTS_DUT_RESULT
> - elif crb == "tester":
> +
> + set_salt(crb, 'dut')
> + elif crb.startswith('tester'):
> self.info_lvl = logging.DTS_TESTER_CMD
> self.debug_lvl = logging.DTS_TESTER_OUTPUT
> self.warn_lvl = logging.DTS_TESTER_RESULT
> - elif crb == "ixia":
> +
> + set_salt(crb, 'tester')
> + elif crb.startswith('ixia'):
> self.info_lvl = logging.DTS_IXIA_CMD
> self.debug_lvl = logging.DTS_IXIA_OUTPUT
> +
> + set_salt(crb, 'ixia')
> + elif crb.startswith('virtdut'):
> + self.info_lvl = logging.DTS_VIRTDUT_CMD
> + self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
> +
> + set_salt(crb, 'virtdut')
> else:
> self.error_lvl = logging.ERROR
> self.warn_lvl = logging.WARNING
> @@ -296,15 +342,18 @@ class DTSLOG(BaseLoggerAdapter):
> ch = ColorHandler()
> self.__log_hander(fh, ch)
>
> - if crb == "dut":
> + if crb == 'dut':
> self.info_lvl = logging.SUITE_DUT_CMD
> self.debug_lvl = logging.SUITE_DUT_OUTPUT
> - elif crb == "tester":
> + elif crb == 'tester':
> self.info_lvl = logging.SUITE_TESTER_CMD
> self.debug_lvl = logging.SUITE_TESTER_OUTPUT
> - elif crb == "ixia":
> + elif crb == 'ixia':
> self.info_lvl = logging.DTS_IXIA_CMD
> self.debug_lvl = logging.DTS_IXIA_OUTPUT
> + elif crb == 'virtdut':
> + self.info_lvl = logging.DTS_VIRTDUT_CMD
> + self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
>
> def logger_exit(self):
> """
> diff --git a/framework/main.py b/framework/main.py
> index 3e467d0..0496b20 100755
> --- a/framework/main.py
> +++ b/framework/main.py
> @@ -117,6 +117,10 @@ parser.add_argument('-v', '--verbose',
> action='store_true',
> help='enable verbose output, all message output on
> screen')
>
> +parser.add_argument('--virttype',
> + default='kvm',
> + help='set virt type,support libvirt,xen,kvm')
> +
> parser.add_argument('--debug',
> action='store_true',
> help='enable debug mode, user can enter debug mode in
> process')
> @@ -136,4 +140,5 @@ if args.git is not None:
> dts.run_all(args.config_file, args.snapshot, args.git,
> args.patch, args.skip_setup, args.read_cache,
> args.project, args.suite_dir, args.test_cases,
> - args.dir, args.output, args.verbose, args.debug)
> + args.dir, args.output, args.verbose,args.virttype,
> + args.debug)
> diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py
> index 8963924..67bd492 100644
> --- a/framework/project_dpdk.py
> +++ b/framework/project_dpdk.py
> @@ -39,7 +39,7 @@ from crb import Crb
> from dut import Dut
> from tester import Tester
> from logger import getLogger
> -from settings import IXIA
> +from settings import IXIA, accepted_nic
>
>
> class DPDKdut(Dut):
> @@ -50,8 +50,9 @@ class DPDKdut(Dut):
> """
>
> def __init__(self, crb, serializer):
> - self.NAME = 'dut'
> +
> super(DPDKdut, self).__init__(crb, serializer)
> + self.testpmd = None
>
> def set_target(self, target):
> """
> @@ -60,6 +61,7 @@ class DPDKdut(Dut):
> Set hugepage on DUT and install modules required by DPDK.
> Configure default ixgbe PMD function.
> """
> + self.target = target
> self.set_toolchain(target)
>
> # set env variable
> @@ -99,7 +101,16 @@ class DPDKdut(Dut):
> out = self.send_expect("lsmod | grep igb_uio", "#")
> if "igb_uio" in out:
> self.send_expect("rmmod -f igb_uio", "#", 70)
> - self.send_expect("insmod ./" + target + "/kmod/igb_uio.ko",
> "#", 60)
> + if "rte_dom0_mm" in self.send_expect("lsmod |grep
> rte_dom0_mm", "#"):
> + self.send_expect("rmmod -f rte_dmo0_mm", "#", 70)
> + self.send_expect(
> + "insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
"rte_dom0_mm" module only can be built out when DOM0 enabled in DPDK configuration file.
We should not expected it existed in host. Make sure DOM0 configuration enabled and build target with modified configuration.
> + if self.virttype == 'xen':
> + self.send_expect(
> + "insmod ./" + target + "/kmod/rte_dom0_mm.ko", "#",
> 60)
> + self.send_expect(
> + r'echo 1024 > /sys/kernel/mm/dom0-mm/memsize-
> mB/memsize', "#", 70)
> +
Better to use macro replace of 1024, these settings should be defined in settings.py.
> out = self.send_expect("lsmod | grep igb_uio", "#")
> assert ("igb_uio" in out), "Failed to insmod igb_uio"
>
> @@ -110,7 +121,7 @@ class DPDKdut(Dut):
> binding_list = ''
>
> for (pci_bus, pci_id) in self.pci_devices_info:
> - if dts.accepted_nic(pci_id):
> + if accepted_nic(pci_id):
> binding_list += '%s,' % (pci_bus)
>
> self.send_expect("kldunload if_ixgbe.ko", "#")
> @@ -158,6 +169,9 @@ class DPDKdut(Dut):
> """
> # clean all
> self.send_expect("rm -rf " + target, "#")
> + if self.virttype == 'xen':
> + self.send_expect("sed -i -e
> 's/CONFIG_RTE_LIBRTE_XEN_DOM0=.*$/"
> + + "CONFIG_RTE_LIBRTE_XEN_DOM0=y/'
> config/common_linuxapp", "# ", 30)
>
> # compile
> out = self.send_expect("make -j install T=%s %s" % (target,
> extra_options), "# ", 120)
> @@ -178,9 +192,9 @@ class DPDKdut(Dut):
> self.send_expect("rm -rf " + target, "#")
>
> # compile
> - out = self.send_expect("make -j %d install T=%s CC=gcc48" %
> (self.number_of_cores,
> -
> target),
> - "#", 120)
> + out = self.send_expect(
> + "make -j %d install T=%s CC=gcc48" %
> + (self.number_of_cores, target), "#", 120)
>
> if("Error" in out or "No rule to make" in out):
> self.logger.error("ERROR - try without '-j'")
> @@ -191,10 +205,7 @@ class DPDKdut(Dut):
> assert ("Error" not in out), "Compilation error..."
> assert ("No rule to make" not in out), "No rule to make error..."
>
> - def prerequisites(self, pkgName, patch):
> - """
> - Copy DPDK package to DUT and apply patch files.
> - """
> + def prepare_package(self, pkgName, patch):
> if not self.skip_setup:
> assert (os.path.isfile(pkgName) is True), "Invalid package"
>
> @@ -202,7 +213,7 @@ class DPDKdut(Dut):
> # ToDo: make this configurable
> dst_dir = "/tmp/"
>
> - out = self.send_expect("ls %s && cd %s" % (dst_dir, p_dir),
> + out = self.send_expect("ll %s && cd %s" % (dst_dir, p_dir),
> "#", verify=True)
Command "ll" may not existed on every OS, please just use basic "ls" command.
> if out == -1:
> raise ValueError("Directiry %s or %s does not exist,"
> @@ -249,6 +260,17 @@ class DPDKdut(Dut):
> (self.base_dir, dst_dir + p),
> "# ")
> assert "****" not in out
>
> + self.session.copy_file_to("dep/aclrule.tgz", dst_dir)
> + # unpack acl rule
> + out = self.send_expect("tar zxf %saclrule.tgz -C %s" %
> (dst_dir, p_dir), "# ", 20, verify=True)
> + if out == -1:
> + raise ValueError("acl rule extract failure!!!")
> +
These files related with l3fwd acl suite, we should merged these files in following with acl suite.
Please remove these codes from your patch set.
> + def prerequisites(self, pkgName, patch):
> + """
> + Copy DPDK package to DUT and apply patch files.
> + """
> + self.prepare_package(pkgName, patch)
> self.dut_prerequisites()
>
> def bind_interfaces_linux(self, driver='igb_uio', nics_to_bind=None):
> @@ -354,16 +376,20 @@ class DPDKtester(Tester):
> total_huge_pages = self.get_total_huge_pages()
> if total_huge_pages == 0:
> self.mount_huge_pages()
> - self.set_huge_pages(4096)
> + self.set_huge_pages(1024)
>
> self.session.copy_file_to("dep/tgen.tgz")
> self.session.copy_file_to("dep/tclclient.tgz")
> + self.session.copy_file_to("dep/aclpcap.tgz")
> # unpack tgen
> out = self.send_expect("tar zxf tgen.tgz", "# ")
> assert "Error" not in out
> # unpack tclclient
> out = self.send_expect("tar zxf tclclient.tgz", "# ")
> assert "Error" not in out
These files related with l3fwd acl suite, we should merged these files in following with acl suite.
Please remove these codes from your patch set.
> + # unpacl ACL pcap files
> + out = self.send_expect("tar zxf aclpcap.tgz", "# ")
> + assert "Error" not in out
>
> self.send_expect("modprobe uio", "# ")
>
> @@ -386,10 +412,10 @@ class DPDKtester(Tester):
> """
> hugepages_size = self.send_expect("awk '/Hugepagesize/ {print
> $2}' /proc/meminfo", "# ")
>
> - if int(hugepages_size) < (1024 * 1024):
> - arch_huge_pages = hugepages if hugepages > 0 else 4096
> + if int(hugepages_size) < (2048 * 2048):
> + arch_huge_pages = hugepages if hugepages > 0 else 2048
Better to use macro replace of 2048, these settings should be defined in settings.py.
> total_huge_pages = self.get_total_huge_pages()
>
> - self.mount_huge_pages()
> - if total_huge_pages != arch_huge_pages:
> - self.set_huge_pages(arch_huge_pages)
> + self.mount_huge_pages()
> + if total_huge_pages != arch_huge_pages:
> + self.set_huge_pages(arch_huge_pages)
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
2015-05-18 7:06 ` Liu, Yong
@ 2015-05-18 7:43 ` Jiajia, SunX
2015-05-19 0:38 ` Liu, Yong
0 siblings, 1 reply; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-18 7:43 UTC (permalink / raw)
To: Liu, Yong, dts
Hi Yong,
I have replied the comments as below.
> -----Original Message-----
> From: Liu, Yong
> Sent: Monday, May 18, 2015 3:06 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
>
> Jiajia,
> Please see my comments below.
>
> > -----Original Message-----
> > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > Sent: Monday, May 18, 2015 1:07 PM
> > To: dts@dpdk.org
> > Subject: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
> >
> > Optimize configure parse
> >
> > Move some functions in dts to an common utils module
> >
> > Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> > ---
> > framework/config.py | 171
> +++++++++++++++++++++++++++++++++++----
> > -----
> > framework/ssh_connection.py | 5 ++
> > framework/ssh_pexpect.py | 63 +++++++++++++---
> > framework/utils.py | 77 ++++++++++++++++++++
> > 4 files changed, 270 insertions(+), 46 deletions(-)
> > mode change 100755 => 100644 framework/config.py
> > create mode 100644 framework/utils.py
> >
> > diff --git a/framework/config.py b/framework/config.py
> > old mode 100755
> > new mode 100644
> > index d2548e8..927c846
> > --- a/framework/config.py
> > +++ b/framework/config.py
> > @@ -37,45 +37,133 @@ import re
> > import ConfigParser # config parse module
> > import argparse # prase arguments module
> >
> > -portconf = "conf/ports.cfg"
> > -crbconf = "conf/crbs.cfg"
> > +PORTCONF = "conf/ports.cfg"
> > +CRBCONF = "conf/crbs.cfg"
> > +VIRTCONF = "conf/virt_global.cfg"
> >
> >
> > class UserConf():
> >
> > - def __init__(self, port_conf=portconf, crb_conf=crbconf):
> > - self.port_config = port_conf
> > - self.crb_config = crb_conf
> > + def __init__(self, config):
> > + self.conf = ConfigParser.SafeConfigParser()
> > + load_files = self.conf.read(config)
> > + if load_files == []:
> > + print "FAILED LOADING %s!!!" % config
> > + self.conf = None
> > + raise
> > +
>
> There's need one special exception for configuration parsed failure.
Yes, I think it is good to do that.
>
> > + def get_sections(self):
> > + if self.conf is None:
> > + return None
> > +
> > + return self.conf.sections()
> > +
> > + def load_section(self, section):
> > + if self.conf is None:
> > + return None
> > +
> > + items = None
> > + for conf_sect in self.conf.sections():
> > + if conf_sect == section:
> > + items = self.conf.items(section)
> > +
> > + return items
> > +
> > + def load_config(self, item):
> > + confs = [conf.strip() for conf in item.split(';')]
> > + if '' in confs:
> > + confs.remove('')
> > + return confs
> > +
> > + def load_param(self, conf):
> > + paramDict = dict()
> > +
> > + for param in conf.split(','):
> > + (key, _, value) = param.partition('=')
> > + paramDict[key] = value
> > + return paramDict
> > +
> > +
> > +class VirtConf(UserConf):
> > +
> > + def __init__(self, virt_conf=VIRTCONF):
> > + self.config_file = virt_conf
> > + self.virt_cfg = {}
> > + try:
> > + self.virt_conf = UserConf(self.config_file)
> > + except Exception as e:
> > + print "FAILED LOADING VIRT CONFIG!!!"
> > + self.virt_conf = None
> > +
> There's need one special exception for configuration parsed failure.
I will do it in the next version.
>
> > + def load_virt_config(self, name):
> > + self.virt_cfgs = []
> > +
> > + try:
> > + virt_confs = self.virt_conf.load_section(name)
> > + except:
> > + print "FAILED FIND SECTION %s!!!" % name
> > + return
> > +
> Add exception for load section failed.
I will do it in the next version.
>
> > + for virt_conf in virt_confs:
> > + virt_cfg = {}
> > + virt_params = []
> > + key, config = virt_conf
> > + confs = self.virt_conf.load_config(config)
> > + for config in confs:
> > + virt_params.append(self.load_virt_param(config))
> > + virt_cfg[key] = virt_params
> > + self.virt_cfgs.append(virt_cfg)
> > +
> > + def get_virt_config(self):
> > + return self.virt_cfgs
> > +
> > + def load_virt_param(self, config):
> > + cfg_params = self.virt_conf.load_param(config)
> > + return cfg_params
> > +
> > +
> > +class PortConf(UserConf):
> > +
> > + def __init__(self, port_conf=PORTCONF):
> > + self.config_file = port_conf
> > self.ports_cfg = {}
> > self.pci_regex = "([\da-f]{2}:[\da-f]{2}.\d{1})$"
> > try:
> > - self.port_conf = ConfigParser.SafeConfigParser()
> > - self.port_conf.read(self.port_config)
> > + self.port_conf = UserConf(self.config_file)
> > except Exception as e:
> > print "FAILED LOADING PORT CONFIG!!!"
> > + self.port_conf = None
> >
> There's need one special exception for configuration parsed failure.
I will do it in the next version.
>
> > def load_ports_config(self, crbIP):
> > - ports = []
> > - for crb in self.port_conf.sections():
> > - if crb != crbIP:
> > - continue
> > - ports = [port.strip()
> > - for port in self.port_conf.get(crb,
> > 'ports').split(';')]
> > + self.ports_cfg = {}
> > + if self.port_conf is None:
> > + return
> > +
> > + ports = self.port_conf.load_section(crbIP)
> > + if ports is None:
> > + return
> > + key, config = ports[0]
> > + confs = self.port_conf.load_config(config)
> > +
> > + for config in confs:
> > + port_param = self.port_conf.load_param(config)
> >
> > - for port in ports:
> > - port_cfg = self.__parse_port_param(port)
> > # check pci BDF validity
> > - if 'pci' not in port_cfg:
> > + if 'pci' not in port_param:
> > print "NOT FOUND CONFIG FOR NO PCI ADDRESS!!!"
> > continue
> > - m = re.match(self.pci_regex, port_cfg['pci'])
> > + m = re.match(self.pci_regex, port_param['pci'])
> > if m is None:
> > print "INVALID CONFIG FOR NO PCI ADDRESS!!!"
> > continue
> >
> > - keys = port_cfg.keys()
> > + keys = port_param.keys()
> > keys.remove('pci')
> > - self.ports_cfg[port_cfg['pci']] = {key: port_cfg[key]
> for key
> > in keys}
> > + self.ports_cfg[port_param['pci']] = {
> > + key: port_param[key] for key in keys}
> > + if 'numa' in self.ports_cfg[port_param['pci']]:
> > + numa_str = self.ports_cfg[port_param['pci']]['numa']
> > + self.ports_cfg[port_param['pci']]['numa'] =
> int(numa_str)
> >
> > def get_ports_config(self):
> > return self.ports_cfg
> > @@ -86,23 +174,36 @@ class UserConf():
> > else:
> > return False
> >
> > - def __parse_port_param(self, port):
> > - portDict = dict()
> > -
> > - for param in port.split(','):
> > - (key, _, value) = param.partition('=')
> > - if key == 'numa':
> > - portDict[key] = int(value)
> > - else:
> > - portDict[key] = value
> > - return portDict
> > +
> >
> >
> > if __name__ == '__main__':
> > - parser = argparse.ArgumentParser(description="Load DTS
> configuration
> > files")
> > - parser.add_argument("-p", "--portconf", default=portconf)
> > - parser.add_argument("-c", "--crbconf", default=crbconf)
> > + parser = argparse.ArgumentParser(
> > + description="Load DTS configuration files")
> > + parser.add_argument("-p", "--portconf", default=PORTCONF)
> > + parser.add_argument("-c", "--crbconf", default=CRBCONF)
> > + parser.add_argument("-v", "--virtconf", default=VIRTCONF)
> > args = parser.parse_args()
> > - conf = UserConf()
> > - conf.load_ports_config('192.168.1.1')
> > - conf.check_port_available('0000:86:00.0')
> > +
> > + # not existed configuration file
> > + VirtConf('/tmp/not-existed.cfg')
> > +
> > + # example for basic use configuration file
> > + conf = UserConf(PORTCONF)
> > + for section in conf.get_sections():
> > + items = conf.load_section(section)
> > + key, value = items[0]
> > + confs = conf.load_config(value)
> > + for config in confs:
> > + conf.load_param(config)
> > +
> > + # example for port configuration file
> > + portconf = PortConf(PORTCONF)
> > + portconf.load_ports_config('DUT IP')
> > + print portconf.get_ports_config()
> > + portconf.check_port_available('86:00.0')
> > +
> > + # example for global virtualization configuration file
> > + virtconf = VirtConf(VIRTCONF)
> > + virtconf.load_virt_config('LIBVIRT')
> > + print virtconf.get_virt_config()
> > diff --git a/framework/ssh_connection.py
> b/framework/ssh_connection.py
> > index 18a6517..7286b14 100644
> > --- a/framework/ssh_connection.py
> > +++ b/framework/ssh_connection.py
> > @@ -62,6 +62,11 @@ class SSHConnection(object):
> > self.logger.debug(out)
> > return out
> >
> > + def get_session_before(self, timeout=15):
> > + out = self.session.get_session_before(timeout)
> > + self.logger.debug(out)
> > + return out
> > +
>
> I've sent out this patch, please make sure there's no gap there.
> You'd better remove those from your patch work.
>
About this, I have checked it, yes, you have sent it, I will remove it
from my patch work.
> > def close(self):
> > self.session.close()
> >
> > diff --git a/framework/ssh_pexpect.py b/framework/ssh_pexpect.py
> > index 735df44..4193020 100644
> > --- a/framework/ssh_pexpect.py
> > +++ b/framework/ssh_pexpect.py
> > @@ -2,7 +2,8 @@ import time
> > import pexpect
> > import pxssh
> > from debugger import ignore_keyintr, aware_keyintr
> > -from exception import TimeoutException, SSHConnectionException
> > +from exception import TimeoutException, SSHConnectionException,
> > SSHSessionDeadException
> > +from utils import RED, GREEN
> >
> > """
> > Module handle ssh sessions between tester and DUT.
> > @@ -14,16 +15,28 @@ Aslo support transfer files to tester or DUT.
> > class SSHPexpect(object):
> >
> > def __init__(self, host, username, password):
> > - self.magic_prompt = "[MAGIC PROMPT]"
> > + self.magic_prompt = "MAGIC PROMPT"
> > try:
> > self.session = pxssh.pxssh()
> > - self.username = username
> > self.host = host
> > + self.username = username
> > self.password = password
> > - self.session.login(self.host, self.username,
> > - self.password,
> original_prompt='[$#>]')
> > + if ':' in host:
> > + self.ip = host.split(':')[0]
> > + self.port = int(host.split(':')[1])
> > + self.session.login(self.ip, self.username,
> > + self.password,
> original_prompt='[$#>]',
> > + port=self.port, login_timeout=20)
> > + else:
> > + self.session.login(self.host, self.username,
> > + self.password,
> original_prompt='[$#>]')
> > self.send_expect('stty -echo', '# ', timeout=2)
> > - except Exception:
> > + except Exception, e:
> > + print RED(e)
> > + if getattr(self, 'port', None):
> > + suggestion = "\nSuggession: Check if the fireware on
> > [ %s ] " % \
> > + self.ip + "is stoped\n"
> > + print GREEN(suggestion)
> > raise SSHConnectionException(host)
> >
> > def init_log(self, logger, name):
> > @@ -33,7 +46,7 @@ class SSHPexpect(object):
> >
> > def send_expect_base(self, command, expected, timeout=15):
> > ignore_keyintr()
> > - self.__flush() # clear buffer
> > + self.__flush() # clear buffer
> > self.session.PROMPT = expected
> > self.__sendline(command)
> > self.__prompt(command, timeout)
> > @@ -45,7 +58,7 @@ class SSHPexpect(object):
> > def send_expect(self, command, expected, timeout=15,
> verify=False):
> > ret = self.send_expect_base(command, expected, timeout)
> > if verify:
> > - ret_status = self.send_expect_base("echo $?", expected)
> > + ret_status = self.send_expect_base("echo $?", expected,
> > timeout)
> > if not int(ret_status):
> > return ret
> > else:
> > @@ -54,21 +67,44 @@ class SSHPexpect(object):
> > else:
> > return ret
> >
> > - def __flush(self):
> > + def get_session_before(self, timeout=15):
> > + """
> > + Get all output before timeout
> > + """
> > + ignore_keyintr()
> > self.session.PROMPT = self.magic_prompt
> > - self.session.prompt(0.1)
> > + try:
> > + self.session.prompt(timeout)
> > + except Exception as e:
> > + pass
> > +
> > + aware_keyintr()
> > + before = self.get_output_before()
> > + self.__flush()
> > + return before
> > +
> > + def __flush(self):
> > + """
> > + Clear all session buffer
> > + """
> > + self.session.buffer = ""
> > + self.session.before = ""
> >
> > def __prompt(self, command, timeout):
> > if not self.session.prompt(timeout):
> > raise TimeoutException(command, self.get_output_all())
> >
> > def __sendline(self, command):
> > + if not self.isalive():
> > + raise SSHSessionDeadException(self.host)
> > if len(command) == 2 and command.startswith('^'):
> > self.session.sendcontrol(command[1])
> > else:
> > self.session.sendline(command)
> >
> > def get_output_before(self):
> > + if not self.isalive():
> > + raise SSHSessionDeadException(self.host)
> > self.session.flush()
> > before = self.session.before.rsplit('\r\n', 1)
> > if before[0] == "[PEXPECT]":
> > @@ -103,7 +139,12 @@ class SSHPexpect(object):
> > """
> > Sends a local file to a remote place.
> > """
> > - command = 'scp {0} {1}@{2}:{3}'.format(src, self.username,
> > self.host, dst)
> > + if ':' in self.host:
> > + command = 'scp -P {0} -o
> NoHostAuthenticationForLocalhost=yes
> > {1} {2}@{3}:{4}'.format(
> > + str(self.port), src, self.username, self.ip, dst)
> > + else:
> > + command = 'scp {0} {1}@{2}:{3}'.format(
> > + src, self.username, self.host, dst)
> > if password == '':
> > self._spawn_scp(command, self.password)
> > else:
> > diff --git a/framework/utils.py b/framework/utils.py
> > new file mode 100644
> > index 0000000..57eb988
> > --- /dev/null
> > +++ b/framework/utils.py
> > @@ -0,0 +1,77 @@
> > +# 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.
> > +
> > +import json # json format
> > +import re
> > +
> > +
> > +def RED(text):
> > + return "\x1B[" + "31;1m" + str(text) + "\x1B[" + "0m"
> > +
> > +
> > +def BLUE(text):
> > + return "\x1B[" + "36;1m" + str(text) + "\x1B[" + "0m"
> > +
> > +
> > +def GREEN(text):
> > + return "\x1B[" + "32;1m" + str(text) + "\x1B[" + "0m"
> > +
> > +
> > +def pprint(some_dict):
> > + """
> > + Print JSON format dictionary object.
> > + """
> > + return json.dumps(some_dict, sort_keys=True, indent=4)
> > +
> > +
> > +def regexp(s, to_match, allString=False):
> > + """
> > + Ensure that the re `to_match' only has one group in it.
> > + """
> > +
> > + scanner = re.compile(to_match, re.DOTALL)
> > + if allString:
> > + return scanner.findall(s)
> > + m = scanner.search(s)
> > + if m is None:
> > + print RED("Failed to match " + to_match + " in the string "
> + s)
> > + return None
> > + return m.group(1)
> > +
> > +
> > +def get_obj_funcs(obj, func_name_regex):
> > + """
> > + Return function list which name matched regex.
> > + """
> > + for func_name in dir(obj):
> > + func = getattr(obj, func_name)
> > + if callable(func) and re.match(func_name_regex,
> func.__name__):
> > + yield func
> > --
> This function now used to free resource of virtualization machine, I
> think it's better to call free functions directly.
> Maybe there will be dependency of these free functions. What's your
> idea about it?
No, now it is just used on the module of virtual resource.
But I think this is common function, it can be used in other module if there
is a demand.
>
> > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice
2015-05-18 5:07 ` [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice sjiajiax
@ 2015-05-18 7:46 ` Xu, HuilongX
2015-05-18 8:58 ` Jiajia, SunX
0 siblings, 1 reply; 34+ messages in thread
From: Xu, HuilongX @ 2015-05-18 7:46 UTC (permalink / raw)
To: Jiajia, SunX, dts
Hi Jiajia,
I have two comments in this patch,
Would you check the comments in function "def destroy_sriov_vfs_by_port(self, port_id):" and "def set_toolchain(self, target):"
Thanks a lot
-----Original Message-----
From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
Sent: Monday, May 18, 2015 1:07 PM
To: dts@dpdk.org
Subject: [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/crb.py | 135 +++++++----
framework/dut.py | 268 ++++++++++++++++++---
framework/net_device.py | 600 ++++++++++++++++++++++++++++++++++++++++++++++++
framework/settings.py | 43 ++++
framework/test_case.py | 3 +-
framework/tester.py | 51 +++-
6 files changed, 1006 insertions(+), 94 deletions(-)
create mode 100644 framework/net_device.py
diff --git a/framework/crb.py b/framework/crb.py
index a699bfc..2eb2033 100644
--- a/framework/crb.py
+++ b/framework/crb.py
@@ -69,6 +69,12 @@ class Crb(object):
return self.session.send_expect(cmds, expected, timeout, verify)
+ def get_session_output(self, timeout=TIMEOUT):
+ """
+ Get session output message before timeout
+ """
+ return self.session.get_session_before(timeout)
+
def set_test_types(self, func_tests, perf_tests):
"""
Enable or disable function/performance test.
@@ -80,7 +86,9 @@ class Crb(object):
"""
Get the huge page number of CRB.
"""
- huge_pages = self.send_expect("awk '/HugePages_Total/ { print $2 }' /proc/meminfo", "# ")
+ huge_pages = self.send_expect(
+ "awk '/HugePages_Total/ { print $2 }' /proc/meminfo",
+ "# ", alt_session=True)
if huge_pages != "":
return int(huge_pages)
return 0
@@ -115,6 +123,9 @@ class Crb(object):
"""
self.base_dir = base_dir
+ def set_virttype(self, virttype):
+ self.virttype = virttype
+
def admin_ports(self, port, status):
"""
Force set port's interface status.
@@ -127,13 +138,15 @@ class Crb(object):
Force set remote interface link status in FreeBSD.
"""
eth = self.ports_info[port]['intf']
- self.send_expect("ifconfig %s %s" % (eth, status), "# ")
+ self.send_expect("ifconfig %s %s" %
+ (eth, status), "# ", alt_session=True)
def admin_ports_linux(self, eth, status):
"""
Force set remote interface link status in Linux.
"""
- self.send_expect("ip link set %s %s" % (eth, status), "# ")
+ self.send_expect("ip link set %s %s" %
+ (eth, status), "# ", alt_session=True)
def pci_devices_information(self):
"""
@@ -157,8 +170,9 @@ class Crb(object):
"""
Look for the NIC's information (PCI Id and card type).
"""
- out = self.send_expect("lspci -nn | grep -i eth", "# ")
- rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) Ethernet .*?([\da-f]{4}:[\da-f]{4})"
+ out = self.send_expect(
+ "lspci -nn | grep -i eth", "# ", alt_session=True)
+ rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) .*Eth.*?ernet .*?([\da-f]{4}:[\da-f]{4})"
pattern = re.compile(rexp)
match = pattern.findall(out)
self.pci_devices_info = []
@@ -169,7 +183,7 @@ class Crb(object):
"""
Look for the NIC's information (PCI Id and card type).
"""
- out = self.send_expect("pciconf -l", "# ")
+ out = self.send_expect("pciconf -l", "# ", alt_session=True)
rexp = r"pci0:([\da-f]{1,3}:[\da-f]{1,2}:\d{1}):\s*class=0x020000.*chip=0x([\da-f]{4})8086"
pattern = re.compile(rexp)
match = pattern.findall(out)
@@ -179,66 +193,69 @@ class Crb(object):
card_type = "8086:%s" % match[i][1]
self.pci_devices_info.append((match[i][0], card_type))
- def get_interface_name(self, bus_id, devfun_id=''):
- """
- Get interface name of specified pci device.
- """
- get_interface_name = getattr(self, 'get_interface_name_%s' % self.get_os_type())
- return get_interface_name(bus_id, devfun_id)
-
- def get_interface_name_linux(self, bus_id, devfun_id):
+ def get_pci_dev_driver(self, bus_id, devfun_id):
"""
- Get interface name of specified pci device on linux.
+ Get the driver of specified pci device.
"""
- command = 'ls --color=never /sys/bus/pci/devices/0000:%s:%s/net' % (bus_id, devfun_id)
- out = self.send_expect(command, '# ', verify=True)
- if out == -1:
- name = ""
- else:
- name = out.split()[0]
- return name
+ get_pci_dev_driver = getattr(
+ self, 'get_pci_dev_driver_%s' % self.get_os_type())
+ return get_pci_dev_driver(bus_id, devfun_id)
- def get_interface_name_freebsd(self, bus_id, devfun_id):
+ def get_pci_dev_driver_linux(self, bus_id, devfun_id):
"""
- Get interface name of specified pci device on Freebsd.
+ Get the driver of specified pci device on linux.
"""
- out = self.send_expect("pciconf -l", "# ")
- rexp = r"(\w*)@pci0:%s" % bus_id
+ out = self.send_expect("cat /sys/bus/pci/devices/0000\:%s\:%s/uevent" %
+ (bus_id, devfun_id), "# ", alt_session=True)
+ rexp = r"DRIVER=(.+?)\r"
pattern = re.compile(rexp)
- match = pattern.findall(out)
- return match[0]
+ match = pattern.search(out)
+ if not match:
+ return None
+ return match.group(1)
- def get_mac_addr(self, intf, bus_id='', devfun_id=''):
+ def get_pci_dev_driver_freebsd(self, bus_id, devfun_id):
"""
- Get mac address of specified pci device.
+ Get the driver of specified pci device.
"""
- get_mac_addr = getattr(self, 'get_mac_addr_%s' % self.get_os_type())
- return get_mac_addr(intf, bus_id, devfun_id)
+ return True
- def get_mac_addr_linux(self, intf, bus_id, devfun_id):
+ def get_pci_dev_id(self, bus_id, devfun_id):
"""
- Get mac address of specified pci device on linux.
+ Get the pci id of specified pci device.
"""
- command = ('cat /sys/bus/pci/devices/0000:%s:%s/net/%s/address' %
- (bus_id, devfun_id, intf))
- return self.send_expect(command, '# ')
+ get_pci_dev_id = getattr(
+ self, 'get_pci_dev_id_%s' % self.get_os_type())
+ return get_pci_dev_id(bus_id, devfun_id)
- def get_mac_addr_freebsd(self, intf, bus_id, devfun_id):
+ def get_pci_dev_id_linux(self, bus_id, devfun_id):
"""
- Get mac address of specified pci device on Freebsd.
+ Get the pci id of specified pci device on linux.
"""
- out = self.send_expect('ifconfig %s' % intf, '# ')
- rexp = r"ether ([\da-f:]*)"
+ out = self.send_expect("cat /sys/bus/pci/devices/0000\:%s\:%s/uevent" %
+ (bus_id, devfun_id), "# ", alt_session=True)
+ rexp = r"PCI_ID=(.+)"
pattern = re.compile(rexp)
- match = pattern.findall(out)
- return match[0]
+ match = re.search(out)
+ if not match:
+ return None
+ return match.group(1)
def get_device_numa(self, bus_id, devfun_id):
"""
- Get numa id of specified pci device
+ Get numa number of specified pci device.
+ """
+ get_device_numa = getattr(
+ self, "get_device_numa_%s" % self.get_os_type())
+ return get_device_numa(bus_id, devfun_id)
+
+ def get_device_numa_linux(self, bus_id, devfun_id):
+ """
+ Get numa number of specified pci device on Linux.
"""
- numa = self.send_expect("cat /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
- (bus_id, devfun_id), "# ")
+ numa = self.send_expect(
+ "cat /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
+ (bus_id, devfun_id), "# ", alt_session=True)
try:
numa = int(numa)
@@ -259,14 +276,14 @@ class Crb(object):
Get ipv6 address of specified pci device on linux.
"""
out = self.send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
- % intf, "# ")
+ % intf, "# ", alt_session=True)
return out.split('/')[0]
def get_ipv6_addr_freebsd(self, intf):
"""
Get ipv6 address of specified pci device on Freebsd.
"""
- out = self.send_expect('ifconfig %s' % intf, '# ')
+ out = self.send_expect('ifconfig %s' % intf, '# ', alt_session=True)
rexp = r"inet6 ([\da-f:]*)%"
pattern = re.compile(rexp)
match = pattern.findall(out)
@@ -275,6 +292,22 @@ class Crb(object):
return match[0]
+ def disable_ipv6(self, intf):
+ """
+ Disable ipv6 of of specified interface
+ """
+ if intf != 'N/A':
+ self.send_expect("sysctl net.ipv6.conf.%s.disable_ipv6=1" %
+ intf, "# ", alt_session=True)
+
+ def enable_ipv6(self, intf):
+ """
+ Enable ipv6 of of specified interface
+ """
+ if intf != 'N/A':
+ self.send_expect("sysctl net.ipv6.conf.%s.disable_ipv6=0" %
+ intf, "# ", alt_session=True)
+
def create_file(self, contents, fileName):
"""
Create file with contents and copy it to CRB.
@@ -318,7 +351,7 @@ class Crb(object):
if isinstance(self, Dut) and self.get_os_type() == 'freebsd':
expected = 'FreeBSD.*#'
- self.send_expect('uname', expected, 2)
+ self.send_expect('uname', expected, 2, alt_session=True)
def init_core_list(self):
"""
@@ -378,7 +411,9 @@ class Crb(object):
self.cores = []
cpuinfo = \
- self.send_expect("grep \"processor\\|physical id\\|core id\\|^$\" /proc/cpuinfo", "#")
+ self.send_expect(
+ "grep --color=never \"processor\\|physical id\\|core id\\|^$\" /proc/cpuinfo",
+ "#", alt_session=True)
cpuinfo = cpuinfo.split('\r\n\r\n')
for line in cpuinfo:
m = re.search("processor\t: (\d+)\r\n" +
diff --git a/framework/dut.py b/framework/dut.py
index 5b7aba2..247b01c 100644
--- a/framework/dut.py
+++ b/framework/dut.py
@@ -33,11 +33,17 @@ import os
import re
import time
import dts
-from config import UserConf
-from settings import NICS
+import settings
+from config import PortConf
+from settings import NICS, LOG_NAME_SEP
from ssh_connection import SSHConnection
from crb import Crb
+from net_device import NetDevice
from logger import getLogger
+from virt_resource import VirtResource
+from utils import RED
+
+
class Dut(Crb):
@@ -60,20 +66,36 @@ class Dut(Crb):
def __init__(self, crb, serializer):
super(Dut, self).__init__(crb, serializer)
self.NAME = 'dut'
+
+ self.host_init_flag = 0
self.logger = getLogger(self.NAME)
self.session = SSHConnection(self.get_ip_address(), self.NAME,
self.get_password())
self.session.init_log(self.logger)
- self.alt_session = SSHConnection(self.get_ip_address(), self.NAME + '_alt',
- self.get_password())
+ self.alt_session = SSHConnection(
+ self.get_ip_address(),
+ self.NAME + '_alt',
+ self.get_password())
self.alt_session.init_log(self.logger)
self.number_of_cores = 0
self.tester = None
self.cores = []
self.architecture = None
self.ports_info = None
- self.conf = UserConf()
+ self.conf = PortConf()
self.ports_map = []
+ self.virt_pool = None
+
+ def init_host_session(self):
+ if self.host_init_flag:
+ pass
+ else:
+ self.host_session = SSHConnection(
+ self.get_ip_address(),
+ self.NAME + '_host',
+ self.get_password())
+ self.host_session.init_log(self.logger)
+ self.host_init_flag = 1
def change_config_option(self, target, parameter, value):
"""
@@ -82,12 +104,12 @@ class Dut(Crb):
self.send_expect("sed -i 's/%s=.*$/%s=%s/' config/defconfig_%s" %
(parameter, parameter, value, target), "# ")
- def set_nic_type(self, nic):
+ def set_nic_type(self, nic_type):
"""
Set CRB NICS ready to validated.
"""
- self.nic = nic
- if 'cfg' in nic:
+ self.nic_type = nic_type
+ if 'cfg' in nic_type:
self.conf.load_ports_config(self.get_ip_address())
def set_toolchain(self, target):
@@ -167,11 +189,17 @@ class Dut(Crb):
self.mount_procfs()
# auto detect network topology
self.map_available_ports()
+ # disable tester port ipv6
+ self.disable_tester_ipv6()
# print latest ports_info
- self.logger.info(dts.pprint(self.ports_info))
+ for port_info in self.ports_info:
+ self.logger.info(port_info)
when virt dut init not have any port, but we will add port by hot plug or build vport by dpdk app testpmd(eg, xen virtio test)
The test will can't continued
if self.ports_map is None or len(self.ports_map) == 0:
raise ValueError("ports_map should not be empty, please check all links")
+ # initialize virtualization resource pool
+ self.virt_pool = VirtResource(self)
+
def restore_interfaces(self):
"""
Restore all ports's interfaces.
@@ -195,20 +223,22 @@ class Dut(Crb):
pci_bus = port['pci']
pci_id = port['type']
# get device driver
- driver = dts.get_nic_driver(pci_id)
+ driver = settings.get_nic_driver(pci_id)
if driver is not None:
# unbind device driver
addr_array = pci_bus.split(':')
bus_id = addr_array[0]
devfun_id = addr_array[1]
+ port = NetDevice(self, bus_id, devfun_id)
+
self.send_expect('echo 0000:%s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind'
% (pci_bus, bus_id, devfun_id), '# ')
# bind to linux kernel driver
self.send_expect('modprobe %s' % driver, '# ')
self.send_expect('echo 0000:%s > /sys/bus/pci/drivers/%s/bind'
% (pci_bus, driver), '# ')
- itf = self.get_interface_name(addr_array[0], addr_array[1])
+ itf = port.get_interface_name()
self.send_expect("ifconfig %s up" % itf, "# ")
else:
self.logger.info("NOT FOUND DRIVER FOR PORT (%s|%s)!!!" % (pci_bus, pci_id))
@@ -228,7 +258,10 @@ class Dut(Crb):
"""
Setup Linux hugepages.
"""
- hugepages_size = self.send_expect("awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
+ if self.virttype == 'xen':
+ return
+ hugepages_size = self.send_expect(
+ "awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
if int(hugepages_size) < (1024 * 1024):
if self.architecture == "x86_64":
@@ -265,6 +298,20 @@ class Dut(Crb):
return 'taskset %s ' % core
+ def is_ssh_session_port(self, pci_bus):
+ """
+ Check if the pci device is the dut SSH session port.
+ """
+ port = None
+ for port_info in self.ports_info:
+ if pci_bus == port_info['pci']:
+ port = port_info['port']
+ break
+ if port and port.get_ipv4_addr() == crbs['IP'].strip():
+ return True
+ else:
+ return False
+
def bind_interfaces_linux(self, driver='igb_uio', nics_to_bind=None):
"""
Bind the interfaces to the selected driver. nics_to_bind can be None
@@ -275,12 +322,17 @@ class Dut(Crb):
current_nic = 0
for (pci_bus, pci_id) in self.pci_devices_info:
- if dts.accepted_nic(pci_id):
+ if settings.accepted_nic(pci_id):
+ if self.is_ssh_session_port(pci_bus):
+ continue
if nics_to_bind is None or current_nic in nics_to_bind:
binding_list += '%s ' % (pci_bus)
current_nic += 1
+ if current_nic == 0:
+ self.logger.info("Not nic need bind driver: %s" % driver)
+ return
self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ')
@@ -293,13 +345,19 @@ class Dut(Crb):
current_nic = 0
for (pci_bus, pci_id) in self.pci_devices_info:
- if dts.accepted_nic(pci_id):
+ if settings.accepted_nic(pci_id):
+ if self.is_ssh_session_port(pci_bus):
+ continue
if nics_to_bind is None or current_nic in nics_to_bind:
binding_list += '%s ' % (pci_bus)
current_nic += 1
+ if current_nic == 0:
+ self.logger.info("Not nic need unbind driver")
+ return
+
self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ', 30)
def get_ports(self, nic_type='any', perf=None, socket=None):
@@ -314,14 +372,17 @@ class Dut(Crb):
perf = self.want_perf_tests
nictypes = []
- if nic_type == 'any':
+ if self.nic_type == 'any':
for portid in range(len(self.ports_info)):
ports.append(portid)
return ports
- elif nic_type == 'cfg':
+ elif self.nic_type == 'cfg':
for portid in range(len(self.ports_info)):
if self.ports_info[portid]['source'] == 'cfg':
- ports.append(portid)
+ if (socket is None or
+ self.ports_info[portid]['numa'] == -1 or
+ socket == self.ports_info[portid]['numa']):
+ ports.append(portid)
return ports
else:
for portid in range(len(self.ports_info)):
@@ -440,36 +501,38 @@ class Dut(Crb):
Check that whether auto scanned ports ready to use
"""
pci_addr = "%s:%s" % (pci_bus, pci_id)
- if self.nic == 'any':
+ if self.nic_type == 'any':
return True
- elif self.nic == 'cfg':
+ elif self.nic_type == 'cfg':
if self.conf.check_port_available(pci_bus) is True:
return True
- elif self.nic not in NICS.keys():
- self.logger.warning("NOT SUPPORTED NIC TYPE: %s" % self.nic)
+ elif self.nic_type not in NICS.keys():
+ self.logger.warning("NOT SUPPORTED NIC TYPE: %s" % self.nic_type)
else:
- codename = NICS[self.nic]
+ codename = NICS[self.nic_type]
if pci_id == codename:
return True
return False
def rescan_ports(self):
- unknow_interface = dts.RED('Skipped: unknow_interface')
+ unknow_interface = RED('Skipped: unknow_interface')
for port_info in self.ports_info:
pci_bus = port_info['pci']
addr_array = pci_bus.split(':')
bus_id = addr_array[0]
devfun_id = addr_array[1]
- intf = self.get_interface_name(bus_id, devfun_id)
+
+ port = NetDevice(self, bus_id, devfun_id)
+ intf = port.get_interface_name()
if "No such file" in intf:
self.logger.info("DUT: [0000:%s] %s" % (pci_bus, unknow_interface))
out = self.send_expect("ip link show %s" % intf, "# ")
if "DOWN" in out:
self.send_expect("ip link set %s up" % intf, "# ")
time.sleep(5)
- macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
+ macaddr = port.get_mac_addr()
out = self.send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
% intf, "# ")
ipv6 = out.split('/')[0]
@@ -481,16 +544,32 @@ class Dut(Crb):
port_info['intf'] = intf
port_info['ipv6'] = ipv6
+ def load_serializer_ports(self):
+ self.ports_info = []
+ cached_ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
+ if cached_ports_info is None:
+ return
+ for port in cached_ports_info:
+ self.ports_info.append({'pci': port['pci'], 'type': port['type'],
+ 'numa': port['numa']})
+
+ def save_serializer_ports(self):
+ cached_ports_info = []
+ for port in self.ports_info:
+ cached_ports_info.append({'pci': port['pci'], 'type': port['type'],
+ 'numa': port['numa']})
+ self.serializer.save(self.PORT_INFO_CACHE_KEY, cached_ports_info)
+
def scan_ports(self):
"""
Scan ports information or just read it from cache file.
"""
if self.read_cache:
- self.ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
+ self.load_serializer_ports()
if not self.read_cache or self.ports_info is None:
self.scan_ports_uncached()
- self.serializer.save(self.PORT_INFO_CACHE_KEY, self.ports_info)
+ self.save_serializer_ports()
def scan_ports_uncached(self):
"""
@@ -505,8 +584,8 @@ class Dut(Crb):
"""
self.ports_info = []
- skipped = dts.RED('Skipped: Unknown/not selected')
- unknow_interface = dts.RED('Skipped: unknow_interface')
+ skipped = RED('Skipped: Unknown/not selected')
+ unknow_interface = RED('Skipped: unknow_interface')
for (pci_bus, pci_id) in self.pci_devices_info:
if self.check_ports_available(pci_bus, pci_id) is False:
@@ -518,9 +597,11 @@ class Dut(Crb):
bus_id = addr_array[0]
devfun_id = addr_array[1]
+ port = NetDevice(self, bus_id, devfun_id)
numa = self.get_device_numa(bus_id, devfun_id)
# store the port info to port mapping
- self.ports_info.append({'pci': pci_bus, 'type': pci_id, 'numa': numa})
+ self.ports_info.append(
+ {'port': port, 'pci': pci_bus, 'type': pci_id, 'numa': numa})
def scan_ports_uncached_freebsd(self):
"""
@@ -528,16 +609,17 @@ class Dut(Crb):
"""
self.ports_info = []
- skipped = dts.RED('Skipped: Unknown/not selected')
+ skipped = RED('Skipped: Unknown/not selected')
for (pci_bus, pci_id) in self.pci_devices_info:
- if not dts.accepted_nic(pci_id):
+ if not setttings.accepted_nic(pci_id):
self.logger.info("DUT: [%s %s] %s" % (pci_bus, pci_id,
skipped))
continue
- intf = self.get_interface_name(pci_bus)
+ port = NetDevice(self, pci_bus, '')
+ intf = port.get_interface_name(pci_bus)
macaddr = self.get_mac_addr(intf)
ipv6 = self.get_ipv6_addr(intf)
@@ -560,9 +642,93 @@ class Dut(Crb):
pci_str = "%s:%s.%s" % (pci_bus_id, pci_dev_str, pci_split[2])
# store the port info to port mapping
- self.ports_info.append({'pci': pci_str, 'type': pci_id, 'intf':
+ self.ports_info.append({'port': port, 'pci': pci_str, 'type': pci_id, 'intf':
intf, 'mac': macaddr, 'ipv6': ipv6, 'numa': -1})
+ def generate_sriov_vfs_by_port(self, port_id, vf_num, driver='default'):
+ """
+ Generate SRIOV VFs with default driver it is bound now or specifid driver.
+ """
+ port = self.ports_info[port_id]['port']
+ port_driver = port.get_nic_driver()
+
+ if driver == 'default':
+ if not port_driver:
+ self.logger.info(
+ "No driver on specified port, can not generate SRIOV VF.")
+ return None
+ else:
+ if port_driver != driver:
+ port.bind_driver(driver)
+ port.generate_sriov_vfs(vf_num)
+
+ # append the VF PCIs into the ports_info
+ sriov_vfs_pci = port.get_sriov_vfs_pci()
+ self.ports_info[port_id]['sriov_vfs_pci'] = sriov_vfs_pci
+
+ # instantiate the VF with NetDevice
+ vfs_port = []
+ for vf_pci in sriov_vfs_pci:
+ addr_array = vf_pci.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+ vf_port = NetDevice(self, bus_id, devfun_id)
+ vfs_port.append(vf_port)
+ self.ports_info[port_id]['vfs_port'] = vfs_port
+
+ pci = self.ports_info[port_id]['pci']
+ self.virt_pool.add_vf_on_pf(pf_pci=pci, vflist=sriov_vfs_pci)
+
+ def destroy_sriov_vfs_by_port(self, port_id):
+ port = self.ports_info[port_id]['port']
+ vflist = []
+ port_driver = port.get_nic_driver()
+ if 'sriov_vfs_pci' in self.ports_info[port_id] and \
+ self.ports_info[port_id]['sriov_vfs_pci']:
+ vflist = self.ports_info[port_id]['sriov_vfs_pci']
+ else:
+ if not port.get_sriov_vfs_pci():
+ return
+
+ if not port_driver:
+ self.logger.info(
+ "No driver on specified port, skip destroy SRIOV VF.")
+ else:
Why we need "sriov_vfs_pci"? would we check destroy sriov vfs succeed or failed before we reset ports_info?
+ sriov_vfs_pci = port.destroy_sriov_vfs()
+ self.ports_info[port_id]['sriov_vfs_pci'] = []
+ self.ports_info[port_id]['vfs_port'] = []
+
+ pci = self.ports_info[port_id]['pci']
+ self.virt_pool.del_vf_on_pf(pf_pci=pci, vflist=vflist)
+
+ def get_vm_core_list(self):
+ return VMCORELIST[self.crb['VM CoreList']]
+
+ def create_blacklist_string(self, target, nic):
+ create_blacklist_string = getattr(
+ self, 'create_blacklist_string_%s' % self.get_os_type())
+ return create_blacklist_string(target, nic)
+
+ def create_blacklist_string_linux(self, target, nic):
+ blacklist = ''
+ dutPorts = self.get_ports(nic)
+ self.restore_interfaces()
+ if dts.drivername == "igb_uio":
+ self.send_expect('insmod ./%s/kmod/igb_uio.ko ' % target, '# ')
+ elif dts.drivername == "vfio-pci":
+ self.send_expect("modprobe vfio", '# ')
+ self.send_expect("modprobe vfio-pci", '# ')
+ self.bind_interfaces_linux(dts.drivername)
+ for port in range(0, len(self.ports_info)):
+ if(port not in dutPorts):
+ blacklist += '-b 0000:%s ' % self.ports_info[port]['pci']
+ return blacklist
+
+ def create_blacklist_string_freebsd(self, target, nic):
+ blacklist = ''
+ # No blacklist option in FreeBSD
+ return blacklist
+
def load_portconf(self):
"""
Load port configurations for ports_info. If manually configured infor
@@ -637,7 +803,11 @@ class Dut(Crb):
if ipv6 == "Not connected":
continue
- out = self.tester.send_ping6(remotePort, ipv6, self.get_mac_address(dutPort))
+ if getattr(self, 'send_ping6', None):
+ self.send_ping6(
+ dutPort, self.tester.ports_info[remotePort]['ipv6'])
+ out = self.tester.send_ping6(
+ remotePort, ipv6, self.get_mac_address(dutPort))
if ('64 bytes from' in out):
self.logger.info("PORT MAP: [dut %d: tester %d]" % (dutPort, remotePort))
@@ -656,3 +826,31 @@ class Dut(Crb):
for port in remove:
self.ports_info.remove(port)
+
+ def disable_tester_ipv6(self):
+ for tester_port in self.ports_map:
+ intf = self.tester.get_interface(tester_port)
+ self.tester.disable_ipv6(intf)
+
+ def enable_tester_ipv6(self):
+ for tester_port in self.ports_map:
+ intf = self.tester.get_interface(tester_port)
+ self.tester.enable_ipv6(intf)
+
+ def check_port_occupied(self, port):
+ out = self.alt_session.send_expect('lsof -i:%d' % port, '# ')
+ if out == '':
+ return False
+ else:
+ return True
+
+ def get_maximal_vnc_num(self):
+ out = self.send_expect("ps aux | grep '\-vnc' | grep -v grep", '# ')
+ if out:
+ ports = re.findall(r'-vnc .*?:(\d+)', out)
+ for num in range(len(ports)):
+ ports[num] = int(ports[num])
+ ports.sort()
+ else:
+ ports = [0, ]
+ return ports[-1]
diff --git a/framework/net_device.py b/framework/net_device.py
new file mode 100644
index 0000000..c04d442
--- /dev/null
+++ b/framework/net_device.py
@@ -0,0 +1,600 @@
+import os
+import re
+from functools import wraps
+import time
+import pdb
+
+import settings
+from crb import Crb
+from settings import TIMEOUT
+
+
+class NetDevice(object):
+
+ """
+ Abstract the device which is PF or VF.
+ """
+
+ def __init__(self, crb, bus_id, devfun_id):
+ if not isinstance(crb, Crb):
+ raise Exception(" Please input the instance of Crb!!!")
+ self.crb = crb
+ self.bus_id = bus_id
+ self.devfun_id = devfun_id
+ self.pci = bus_id + ':' + devfun_id
+ self.pci_id = self.get_pci_id(bus_id, devfun_id)
+ self.default_driver = settings.get_nic_driver(self.pci_id)
+ # bind to default driver
+ current_driver = self.get_nic_driver()
+ if self.default_driver != current_driver:
+ self.bind_driver()
+ if self.nic_is_pf():
+ self.default_vf_driver = ''
+ self.intf_name = self.get_interface_name()
+
+ def __send_expect(self, cmds, expected, timeout=TIMEOUT, alt_session=True):
+ """
+ Wrap the crb`s session as private session for sending expect.
+ """
+ return self.crb.send_expect(cmds, expected, timeout=timeout, alt_session=alt_session)
+
+ def __get_os_type(self):
+ """
+ Get OS type.
+ """
+ return self.crb.get_os_type()
+
+ def nic_is_pf(self):
+ """
+ It is the method that you can check if the nic is PF.
+ """
+ return True
+
+ def nic_has_driver(func):
+ """
+ Check if the NIC has a driver.
+ """
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ nic_instance = args[0]
+ nic_instance.current_driver = nic_instance.get_nic_driver()
+ if not nic_instance.current_driver:
+ return ''
+ return func(*args, **kwargs)
+ return wrapper
+
+ def get_nic_driver(self):
+ """
+ Get the NIC driver.
+ """
+ return self.crb.get_pci_dev_driver(self.bus_id, self.devfun_id)
+
+ @nic_has_driver
+ def get_interface_name(self):
+ """
+ Get interface name of specified pci device.
+ """
+ get_interface_name = getattr(
+ self, 'get_interface_name_%s' %
+ self.__get_os_type())
+ return get_interface_name(self.bus_id, self.devfun_id, self.current_driver)
+
+ def get_interface_name_linux(self, bus_id, devfun_id, driver):
+ """
+ Get interface name of specified pci device on linux.
+ """
+ try:
+ get_interface_name_linux = getattr(
+ self,
+ 'get_interface_name_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_interface_name_linux = getattr(self,
+ 'get_interface_name_linux_%s' % generic_driver)
+
+ return get_interface_name_linux(bus_id, devfun_id)
+
+ def get_interface_name_linux_generic(self, bus_id, devfun_id):
+ """
+ Get the interface name by the default way on linux.
+ """
+ command = 'ls --color=never /sys/bus/pci/devices/0000\:%s\:%s/net' % (
+ bus_id, devfun_id)
+ return self.__send_expect(command, '# ')
+
+ def get_interface_name_freebsd(self, bus_id, devfun_id, driver):
+ """
+ Get interface name of specified pci device on Freebsd.
+ """
+ try:
+ get_interface_name_linux = getattr(self,
+ 'get_interface_name_freebsd_%s' % driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_interface_name_linux = getattr(self,
+ 'get_interface_name_freebsd_%s' % generic_driver)
+
+ return get_interface_name_freebsd(bus_id, devfun_id)
+
+ def get_interface_name_freebsd_generic(self, bus_id, devfun_id):
+ """
+ Get the interface name by the default way on freebsd.
+ """
+ out = self.__send_expect("pciconf -l", "# ")
+ rexp = r"(\w*)@pci0:%s" % bus_id
+ pattern = re.compile(rexp)
+ match = pattern.findall(out)
+ return match[0]
+
+ @nic_has_driver
+ def get_mac_addr(self):
+ """
+ Get mac address of specified pci device.
+ """
+ get_mac_addr = getattr(self, 'get_mac_addr_%s' % self.__get_os_type())
+ return get_mac_addr(self.intf_name, self.bus_id, self.devfun_id, self.current_driver)
+
+ def get_mac_addr_linux(self, intf, bus_id, devfun_id, driver):
+ """
+ Get mac address of specified pci device on linux.
+ """
+ try:
+ get_mac_addr_linux = getattr(
+ self,
+ 'get_mac_addr_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_mac_addr_linux = getattr(
+ self,
+ 'get_mac_addr_linux_%s' %
+ generic_driver)
+
+ return get_mac_addr_linux(intf, bus_id, devfun_id, driver)
+
+ def get_pci_id(self, bus_id, devfun_id):
+ command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/vendor' %
+ (bus_id, devfun_id))
+ out = self.__send_expect(command, '# ')
+ vender = out[2:]
+ command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/device' %
+ (bus_id, devfun_id))
+ out = self.__send_expect(command, '# ')
+ device = out[2:]
+ return "%s:%s" % (vender, device)
+
+ def get_mac_addr_linux_generic(self, intf, bus_id, devfun_id, driver):
+ """
+ Get MAC by the default way on linux.
+ """
+ command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/net/%s/address' %
+ (bus_id, devfun_id, intf))
+ return self.__send_expect(command, '# ')
+
+ def get_mac_addr_freebsd(self, intf, bus_id, devfun_id, driver):
+ """
+ Get mac address of specified pci device on Freebsd.
+ """
+ try:
+ get_mac_addr_freebsd = getattr(
+ self,
+ 'get_mac_addr_freebsd_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_mac_addr_freebsd = getattr(
+ self,
+ 'get_mac_addr_freebsd_%s' %
+ generic_driver)
+
+ return get_mac_addr_freebsd(intf, bus_id, devfun_id, driver)
+
+ def get_mac_addr_freebsd_generic(self, intf, bus_id, devfun_id):
+ """
+ Get the MAC by the default way on Freebsd.
+ """
+ out = self.__send_expect('ifconfig %s' % intf, '# ')
+ rexp = r"ether ([\da-f:]*)"
+ pattern = re.compile(rexp)
+ match = pattern.findall(out)
+ return match[0]
+
+ @nic_has_driver
+ def get_ipv4_addr(self):
+ """
+ Get ipv4 address of specified pci device.
+ """
+ get_ipv4_addr = getaddr(
+ self, 'get_ipv4_addr_%s' % self.__get_os_type())
+ return get_ipv4_addr(self.intf_name, self.currenct_driver)
+
+ def get_ipv4_addr_linux(self, intf, driver):
+ """
+ Get ipv4 address of specified pci device on linux.
+ """
+ try:
+ get_ipv4_addr_linux = getattr(self, 'get_ipv4_linux_%s' % driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_ipv4_addr_linux = getattr(
+ self, 'get_ipv4_linux_%s' %
+ generic_driver)
+
+ return get_ipv4_addr_linux(intf, bus_id, devfun_id, driver)
+
+ def get_ipv4_addr_linux_generic(self, intf):
+ """
+ Get IPv4 address by the default way on linux.
+ """
+ out = self.__send_expect("ip -family inet address show dev %s | awk '/inet/ { print $2 }'"
+ % intf, "# ")
+ return out.split('/')[0]
+
+ def get_ipv4_addr_freebsd(self, intf, driver):
+ """
+ Get ipv4 address of specified pci device on Freebsd.
+ """
+ try:
+ get_ipv4_addr_freebsd = getattr(
+ self,
+ 'get_ipv4_addr_freebsd_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_ipv4_addr_freebsd = getattr(
+ self,
+ 'get_ipv4_addr_freebsd_%s' %
+ generic_driver)
+
+ return get_ipv4_addr_freebsd(intf, bus_id, devfun_id)
+
+ def get_ipv4_addr_freebsd_generic(self, intf):
+ """
+ Get the IPv4 address by the default way on Freebsd.
+ """
+ out = self.__send_expect('ifconfig %s' % intf, '# ')
+ rexp = r"inet ([\d:]*)%"
+ pattern = re.compile(rexp)
+ match = pattern.findall(out)
+ if len(match) == 0:
+ return None
+
+ return match[0]
+
+ @nic_has_driver
+ def get_ipv6_addr(self):
+ """
+ Get ipv6 address of specified pci device.
+ """
+ get_ipv6_addr = getattr(
+ self, 'get_ipv6_addr_%s' % self.__get_os_type())
+ return get_ipv6_addr(self.intf_name, self.current_driver)
+
+ def get_ipv6_addr_linux(self, intf, driver):
+ """
+ Get ipv6 address of specified pci device on linux.
+ """
+ try:
+ get_ipv6_addr_linux = getattr(
+ self,
+ 'get_ipv6_addr_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_ipv6_addr_linux = getattr(
+ self,
+ 'get_ipv6_addr_linux_%s' %
+ generic_driver)
+
+ return get_ipv6_addr_linux(intf)
+
+ def get_ipv6_addr_linux_generic(self, intf):
+ """
+ Get the IPv6 address by the default way on linux.
+ """
+ out = self.__send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
+ % intf, "# ")
+ return out.split('/')[0]
+
+ def get_ipv6_addr_freebsd(self, intf, driver):
+ """
+ Get ipv6 address of specified pci device on Freebsd.
+ """
+ try:
+ get_ipv6_addr_freebsd = getattr(
+ self,
+ 'get_ipv6_addr_freebsd_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_ipv6_addr_freebsd = getattr(
+ self,
+ 'get_ipv6_addr_freebsd_%s' %
+ generic_driver)
+
+ return get_ipv6_addr_freebsd(intf)
+
+ def get_ipv6_addr_freebsd_generic(self, intf):
+ """
+ Get the IPv6 address by the default way on Freebsd.
+ """
+ out = self.__send_expect('ifconfig %s' % intf, '# ')
+ rexp = r"inet6 ([\da-f:]*)%"
+ pattern = re.compile(rexp)
+ match = pattern.findall(out)
+ if len(match) == 0:
+ return None
+
+ return match[0]
+
+ def get_nic_numa(self):
+ """
+ Get numa number of specified pci device.
+ """
+ self.crb.get_nic_numa(self.bus_id, self.devfun_id)
+
+ def get_card_type(self):
+ """
+ Get card type of specified pci device.
+ """
+ return self.crb.get_pci_dev_id(self.bus_id, self.devfun_id)
+
+ @nic_has_driver
+ def get_sriov_vfs_pci(self):
+ """
+ Get all SRIOV VF pci bus of specified pci device.
+ """
+ get_sriov_vfs_pci = getattr(
+ self, 'get_sriov_vfs_pci_%s' % self.__get_os_type())
+ return get_sriov_vfs_pci(self.bus_id, self.devfun_id, self.current_driver)
+
+ def get_sriov_vfs_pci_linux(self, bus_id, devfun_id, driver):
+ """
+ Get all SRIOV VF pci bus of specified pci device on linux.
+ """
+ try:
+ get_sriov_vfs_pci_linux = getattr(
+ self,
+ 'get_sriov_vfs_pci_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ get_sriov_vfs_pci_linux = getattr(
+ self,
+ 'get_sriov_vfs_pci_linux_%s' %
+ generic_driver)
+
+ return get_sriov_vfs_pci_linux(bus_id, devfun_id)
+
+ def get_sriov_vfs_pci_linux_generic(self, bus_id, devfun_id):
+ """
+ Get all the VF PCIs of specified PF by the default way on linux.
+ """
+ sriov_numvfs = self.__send_expect(
+ "cat /sys/bus/pci/devices/0000\:%s\:%s/sriov_numvfs" %
+ (bus_id, devfun_id), "# ")
+ sriov_vfs_pci = []
+ if int(sriov_numvfs) == 0:
+ pass
+ else:
+ try:
+ virtfns = self.__send_expect(
+ "ls -d /sys/bus/pci/devices/0000\:%s\:%s/virtfn*" %
+ (bus_id, devfun_id), "# ")
+ for virtfn in virtfns.split():
+ vf_uevent = self.__send_expect(
+ "cat %s" %
+ os.path.join(virtfn, "uevent"), "# ")
+ vf_pci = re.search(
+ r"PCI_SLOT_NAME=0000:([0-9a-f]+:[0-9a-f]+\.[0-9a-f]+)",
+ vf_uevent).group(1)
+ sriov_vfs_pci.append(vf_pci)
+ except Exception as e:
+ print "Scan linux port [0000:%s.%s] sriov vf failed: %s" % (bus_id, devfun_id, e)
+
+ return sriov_vfs_pci
+
+ @nic_has_driver
+ def generate_sriov_vfs(self, vf_num):
+ """
+ Generate some numbers of SRIOV VF.
+ """
+ if vf_num == 0:
+ self.bind_vf_driver()
+ generate_sriov_vfs = getattr(
+ self, 'generate_sriov_vfs_%s' %
+ self.__get_os_type())
+ generate_sriov_vfs(
+ self.bus_id,
+ self.devfun_id,
+ vf_num,
+ self.current_driver)
+ if vf_num != 0:
+ self.sriov_vfs_pci = self.get_sriov_vfs_pci()
+
+ vf_pci = self.sriov_vfs_pci[0]
+ addr_array = vf_pci.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+
+ self.default_vf_driver = self.crb.get_pci_dev_driver(
+ bus_id, devfun_id)
+ else:
+ self.sriov_vfs_pci = []
+ time.sleep(1)
+
+ def generate_sriov_vfs_linux(self, bus_id, devfun_id, vf_num, driver):
+ """
+ Generate some numbers of SRIOV VF.
+ """
+ try:
+ generate_sriov_vfs_linux = getattr(
+ self,
+ 'generate_sriov_vfs_linux_%s' %
+ driver)
+ except Exception as e:
+ generic_driver = 'generic'
+ generate_sriov_vfs_linux = getattr(
+ self,
+ 'generate_sriov_vfs_linux_%s' %
+ generic_driver)
+
+ return generate_sriov_vfs_linux(bus_id, devfun_id, vf_num)
+
+ def generate_sriov_vfs_linux_generic(self, bus_id, devfun_id, vf_num):
+ """
+ Generate SRIOV VFs by the default way on linux.
+ """
+ nic_driver = self.get_nic_driver()
+
+ if not nic_driver:
+ return None
+
+ vf_reg_file = "sriov_numvfs"
+ vf_reg_path = os.path.join("/sys/bus/pci/devices/0000:%s:%s" %
+ (bus_id, devfun_id), vf_reg_file)
+ self.__send_expect("echo %d > %s" %
+ (int(vf_num), vf_reg_path), "# ")
+
+ def generate_sriov_vfs_linux_igb_uio(self, bus_id, devfun_id, vf_num):
+ """
+ Generate SRIOV VFs by the special way of igb_uio driver on linux.
+ """
+ nic_driver = self.get_nic_driver()
+
+ if not nic_driver:
+ return None
+
+ vf_reg_file = "max_vfs"
+ vf_reg_path = os.path.join("/sys/bus/pci/devices/0000:%s:%s" %
+ (bus_id, devfun_id), vf_reg_file)
+ self.__send_expect("echo %d > %s" %
+ (int(vf_num), vf_reg_path), "# ")
+
+ def destroy_sriov_vfs(self):
+ """
+ Destroy the SRIOV VFs.
+ """
+ self.generate_sriov_vfs(0)
+
+ def bind_vf_driver(self, pci='', driver=''):
+ """
+ Bind the specified driver to VF.
+ """
+ bind_vf_driver = getattr(self, 'bind_driver_%s' % self.__get_os_type())
+ if not driver:
+ if not self.default_vf_driver:
+ print "Must specify a driver because default VF driver is NULL!"
+ return
+ driver = self.default_vf_driver
+
+ if not pci:
+ if not self.sriov_vfs_pci:
+ print "No VFs on the nic [%s]!" % self.pci
+ return
+ for vf_pci in self.sriov_vfs_pci:
+ addr_array = vf_pci.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+
+ bind_vf_driver(bus_id, devfun_id, driver)
+ else:
+ addr_array = pci.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+
+ bind_vf_driver(bus_id, devfun_id, driver)
+
+ def bind_driver(self, driver=''):
+ """
+ Bind specified driver to PF.
+ """
+ bind_driver = getattr(self, 'bind_driver_%s' % self.__get_os_type())
+ if not driver:
+ if not self.default_driver:
+ print "Must specify a driver because default driver is NULL!"
+ return
+ driver = self.default_driver
+ ret = bind_driver(self.bus_id, self.devfun_id, driver)
+ time.sleep(1)
+ return ret
+
+ def bind_driver_linux(self, bus_id, devfun_id, driver):
+ """
+ Bind NIC port to specified driver on linux.
+ """
+ driver_alias = driver.replace('-', '_')
+ try:
+ bind_driver_linux = getattr(
+ self,
+ 'bind_driver_linux_%s' %
+ driver_alias)
+ return bind_driver_linux(bus_id, devfun_id)
+ except Exception as e:
+ driver_alias = 'generic'
+ bind_driver_linux = getattr(
+ self,
+ 'bind_driver_linux_%s' %
+ driver_alias)
+ return bind_driver_linux(bus_id, devfun_id, driver)
+
+ def bind_driver_linux_generic(self, bus_id, devfun_id, driver):
+ """
+ Bind NIC port to specified driver by the default way on linux.
+ """
+ nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind" %
+ (nic_pci_num, bus_id, devfun_id), "# ")
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/drivers/%s/bind" %
+ (nic_pci_num, driver), "# ")
+
+ def bind_driver_linux_pci_stub(self, bus_id, devfun_id):
+ """
+ Bind NIC port to the pci-stub driver on linux.
+ """
+ nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
+ pci_id = self.get_card_type()
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/drivers/pci-stub/new_id" %
+ nic_pci_num, "# ")
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind" %
+ (nic_pci_num, bus_id, devfun_id), "# ")
+ self.__send_expect(
+ "echo %s > /sys/bus/pci/drivers/pci-stub/bind" %
+ nic_pci_num, "# ")
+
+ @nic_has_driver
+ def unbind_driver(self, driver=''):
+ """
+ Unbind driver.
+ """
+ unbind_driver = getattr(
+ self, 'unbind_driver_%s' %
+ self.__get_os_type())
+ if not driver:
+ driver = 'generic'
+ ret = unbind_driver(self.bus_id, self.devfun_id, driver)
+ time.sleep(1)
+ return ret
+
+ def unbind_driver_linux(self, bus_id, devfun_id, driver):
+ """
+ Unbind driver on linux.
+ """
+ driver_alias = driver.replace('-', '_')
+
+ unbind_driver_linux = getattr(
+ self, 'unbind_driver_linux_%s' % driver_alias)
+ return unbind_driver_linux(bus_id, devfun_id)
+
+ def unbind_driver_linux_generic(self, bus_id, devfun_id):
+ """
+ Unbind driver by the default way on linux.
+ """
+ nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
+ cmd = "echo %s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind"
+ self.send_expect(cmd % (nic_pci_num, bus_id, devfun_id), "# ")
diff --git a/framework/settings.py b/framework/settings.py
index feb6fa5..2eccc64 100644
--- a/framework/settings.py
+++ b/framework/settings.py
@@ -48,6 +48,7 @@ NICS = {
'powerville': '8086:1521',
'ophir': '8086:105e',
'niantic': '8086:10fb',
+ 'niantic_vf': '8086:10ed',
'ironpond': '8086:151c',
'twinpond': '8086:1528',
'twinville': '8086:1512',
@@ -77,6 +78,7 @@ DRIVERS = {
'powerville': 'igb',
'ophir': 'igb',
'niantic': 'ixgbe',
+ 'niantic_vf': 'ixgbevf',
'ironpond': 'ixgbe',
'twinpond': 'ixgbe',
'twinville': 'ixgbe',
@@ -137,6 +139,17 @@ Global macro for dts.
"""
IXIA = "ixia"
+"""
+The root path of framework configs.
+"""
+CONFIG_ROOT_PATH = "./conf/"
+
+"""
+The log name seperater.
+"""
+LOG_NAME_SEP = '.'
+
+
def nic_name_from_type(type):
"""
strip nic code name by nic type
@@ -145,3 +158,33 @@ def nic_name_from_type(type):
if nic_type == type:
return name
return 'Unknown'
+
+
+def get_nic_driver(pci_id):
+ """
+ Return linux driver for specified pci device
+ """
+ driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
+ try:
+ driver = DRIVERS[driverlist[pci_id]]
+ except Exception as e:
+ driver = None
+ return driver
+
+
+def accepted_nic(pci_id):
+ """
+ Return True if the pci_id is a known NIC card in the settings file and if
+ it is selected in the execution file, otherwise it returns False.
+ """
+ if pci_id not in NICS.values():
+ return False
+
+ if nic is 'any':
+ return True
+
+ else:
+ if pci_id == NICS[nic]:
+ return True
+
+ return False
diff --git a/framework/test_case.py b/framework/test_case.py
index 3d2e2dc..a519691 100644
--- a/framework/test_case.py
+++ b/framework/test_case.py
@@ -40,10 +40,11 @@ from settings import DRIVERS, NICS, nic_name_from_type
class TestCase(object):
- def __init__(self, dut, tester, target):
+ def __init__(self, dut, tester, target, suite):
self.dut = dut
self.tester = tester
self.target = target
+ self.suite = suite
self.nics = []
for portid in range(len(self.dut.ports_info)):
nic_type = self.dut.ports_info[portid]['type']
diff --git a/framework/tester.py b/framework/tester.py
index aba0356..ce136e4 100644
--- a/framework/tester.py
+++ b/framework/tester.py
@@ -38,6 +38,7 @@ from time import sleep
from settings import NICS
from ssh_connection import SSHConnection
from crb import Crb
+from net_device import NetDevice
from etgen import IxiaPacketGenerator, SoftwarePacketGenerator
from logger import getLogger
from settings import IXIA
@@ -152,6 +153,7 @@ class Tester(Crb):
index += 1
if pci == port['pci']:
return index
+ return -1
def get_pci(self, localPort):
"""
@@ -163,6 +165,9 @@ class Tester(Crb):
"""
Return tester local port interface name.
"""
+ if 'intf' not in self.ports_info[localPort]:
+ return 'N/A'
+
return self.ports_info[localPort]['intf']
def get_mac(self, localPort):
@@ -202,26 +207,51 @@ class Tester(Crb):
try:
for (pci_bus, pci_id) in self.pci_devices_info:
addr_array = pci_bus.split(':')
- itf = self.get_interface_name(addr_array[0], addr_array[1])
+ port = NetDevice(self, addr_array[0], addr_array[1])
+ itf = port.get_interface_name()
+ self.enable_ipv6(itf)
self.send_expect("ifconfig %s up" % itf, "# ")
except Exception as e:
self.logger.error(" !!! Restore ITF: " + e.message)
+ sleep(2)
+
+ def load_serializer_ports(self):
+ self.ports_info = []
+ cached_ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
+ if cached_ports_info is None:
+ return
+
+ # now not save netdev object, will implemented later
+ self.ports_info = cached_ports_info
+
+ def save_serializer_ports(self):
+ cached_ports_info = []
+ for port in self.ports_info:
+ port_info = {}
+ for key in port.keys():
+ if type(port[key]) is str:
+ port_info[key] = port[key]
+ # need save netdev objects
+ cached_ports_info.append(port_info)
+ self.serializer.save(self.PORT_INFO_CACHE_KEY, cached_ports_info)
+
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)
+ self.load_serializer_ports()
if not self.read_cache or self.ports_info is None:
self.scan_ports_uncached()
if self.it_uses_external_generator():
self.ports_info.extend(self.ixia_packet_gen.get_ports())
- self.serializer.save(self.PORT_INFO_CACHE_KEY, self.ports_info)
+ self.save_serializer_ports()
- self.logger.info(self.ports_info)
+ for port_info in self.ports_info:
+ self.logger.info(port_info)
def scan_ports_uncached(self):
"""
@@ -240,7 +270,8 @@ class Tester(Crb):
bus_id = addr_array[0]
devfun_id = addr_array[1]
- intf = self.get_interface_name(bus_id, devfun_id)
+ port = NetDevice(self, bus_id, devfun_id)
+ intf = port.get_interface_name()
if "No such file" in intf:
self.logger.info("Tester: [000:%s %s] %s" % (pci_bus, pci_id,
@@ -248,13 +279,17 @@ class Tester(Crb):
continue
self.logger.info("Tester: [000:%s %s] %s" % (pci_bus, pci_id, intf))
- macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
+ macaddr = port.get_mac_addr()
+
+ ipv6 = port.get_ipv6_addr()
# store the port info to port mapping
- self.ports_info.append({'pci': pci_bus,
+ self.ports_info.append({'port': port,
+ 'pci': pci_bus,
'type': pci_id,
'intf': intf,
- 'mac': macaddr})
+ 'mac': macaddr,
+ 'ipv6': ipv6})
def send_ping6(self, localPort, ipv6, mac):
"""
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test
2015-05-18 5:07 ` [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test sjiajiax
2015-05-18 7:26 ` Liu, Yong
@ 2015-05-18 7:59 ` Xu, HuilongX
2015-05-18 9:08 ` Jiajia, SunX
1 sibling, 1 reply; 34+ messages in thread
From: Xu, HuilongX @ 2015-05-18 7:59 UTC (permalink / raw)
To: Jiajia, SunX, dts
Hi Jiajia,
I have one comments at "@@ -202,7 +213,7 @@ class DPDKdut(Dut):"
Would you check it, thanks a lot
-----Original Message-----
From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
Sent: Monday, May 18, 2015 1:07 PM
To: dts@dpdk.org
Subject: [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/dts.py | 92 +++++++++++------------------------------------
framework/exception.py | 27 ++++++++++++++
framework/logger.py | 69 +++++++++++++++++++++++++++++------
framework/main.py | 7 +++-
framework/project_dpdk.py | 62 ++++++++++++++++++++++----------
5 files changed, 157 insertions(+), 100 deletions(-)
diff --git a/framework/dts.py b/framework/dts.py
index c9ecccb..c0df4e9 100644
--- a/framework/dts.py
+++ b/framework/dts.py
@@ -49,6 +49,7 @@ from test_case import TestCase
from test_result import Result
from stats_reporter import StatsReporter
from excel_reporter import ExcelReporter
+from utils import *
from exception import TimeoutException
from logger import getLogger
import logger
@@ -57,6 +58,7 @@ import sys
reload(sys)
sys.setdefaultencoding('UTF8')
+PROJECT_MODULE_PREFIX = 'project_'
debug_mode = False
config = None
@@ -73,44 +75,12 @@ result = None
excel_report = None
stats = None
log_handler = None
+Package = ''
+Patches = []
drivername = ""
interrupttypr = ""
-def RED(text):
- return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
-
-
-def BLUE(text):
- return "\x1B[" + "36;1m" + text + "\x1B[" + "0m"
-
-
-def GREEN(text):
- return "\x1B[" + "32;1m" + text + "\x1B[" + "0m"
-
-
-def regexp(s, to_match, allString=False):
- """
- Ensure that the re `to_match' only has one group in it.
- """
-
- scanner = re.compile(to_match, re.DOTALL)
- if allString:
- return scanner.findall(s)
- m = scanner.search(s)
- if m is None:
- log_handler.warning("Failed to match " + to_match + " in the string " + s)
- return None
- return m.group(1)
-
-
-def pprint(some_dict):
- """
- Print JSON format dictionary object.
- """
- return json.dumps(some_dict, sort_keys=True, indent=4)
-
-
def report(text, frame=False, annex=False):
"""
Save report text into rst file.
@@ -132,36 +102,6 @@ def close_crb_sessions():
log_handler.info("DTS ended")
-def get_nic_driver(pci_id):
- """
- Return linux driver for specified pci device
- """
- driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
- try:
- driver = DRIVERS[driverlist[pci_id]]
- except Exception as e:
- driver = None
- return driver
-
-
-def accepted_nic(pci_id):
- """
- Return True if the pci_id is a known NIC card in the settings file and if
- it is selected in the execution file, otherwise it returns False.
- """
- if pci_id not in NICS.values():
- return False
-
- if nic is 'any':
- return True
-
- else:
- if pci_id == NICS[nic]:
- return True
-
- return False
-
-
def get_crb_os(crb):
if 'OS' in crb:
return crb['OS']
@@ -220,9 +160,10 @@ def get_project_obj(project_name, super_class, crbInst, serializer):
"""
Load project module and return crb instance.
"""
+ global PROJECT_MODULE_PREFIX
project_obj = None
try:
- project_module = __import__("project_" + project_name)
+ project_module = __import__(PROJECT_MODULE_PREFIX + project_name)
for project_subclassname, project_subclass in get_subclasses(project_module, super_class):
project_obj = project_subclass(crbInst, serializer)
@@ -267,19 +208,20 @@ def dts_log_execution(log_handler):
pass
-def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir, nic):
+def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir, nic, virttype):
"""
Create dts dut/tester instance and initialize them.
"""
global dut
global tester
- serializer.set_serialized_filename('../.%s.cache' % crbInst['IP'])
+ serializer.set_serialized_filename('.%s.cache' % crbInst['IP'])
serializer.load_from_file()
dut = get_project_obj(project, Dut, crbInst, serializer)
tester = get_project_obj(project, Tester, crbInst, serializer)
dut.tester = tester
tester.dut = dut
+ dut.set_virttype(virttype)
dut.set_speedup_options(read_cache, skip_setup)
dut.set_directory(base_dir)
dut.set_nic_type(nic)
@@ -337,7 +279,6 @@ def dts_run_target(crbInst, targets, test_suites, nic):
if 'nic_type' not in paramDict:
paramDict['nic_type'] = 'any'
nic = 'any'
- result.nic = nic
dts_run_suite(crbInst, test_suites, target, nic)
@@ -359,7 +300,9 @@ def dts_run_suite(crbInst, test_suites, target, nic):
test_module = __import__('TestSuite_' + test_suite)
for test_classname, test_class in get_subclasses(test_module, TestCase):
- test_suite = test_class(dut, tester, target)
+ test_suite = test_class(dut, tester, target, test_suite)
+ result.nic = test_suite.nic
+
dts_log_testsuite(test_suite, log_handler, test_classname)
log_handler.info("\nTEST SUITE : " + test_classname)
@@ -386,7 +329,7 @@ def dts_run_suite(crbInst, test_suites, target, nic):
def run_all(config_file, pkgName, git, patch, skip_setup,
read_cache, project, suite_dir, test_cases,
- base_dir, output_dir, verbose, debug):
+ base_dir, output_dir, verbose, virttype, debug):
"""
Main process of DTS, it will run all test suites in the config file.
"""
@@ -400,6 +343,12 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
global stats
global log_handler
global debug_mode
+ global Package
+ global Patches
+
+ # save global variable
+ Package = pkgName
+ Patches = patch
# prepare the output folder
if not os.path.exists(output_dir):
@@ -466,7 +415,8 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
result.dut = dutIP
# init dut, tester crb
- dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir, nics)
+ dts_crbs_init(
+ crbInst, skip_setup, read_cache, project, base_dir, nics, virttype)
# Run DUT prerequisites
if dts_run_prerequisties(pkgName, patch) is False:
diff --git a/framework/exception.py b/framework/exception.py
index be38c16..98dedf4 100644
--- a/framework/exception.py
+++ b/framework/exception.py
@@ -46,3 +46,30 @@ class SSHConnectionException(Exception):
def __str__(self):
return 'Error trying to connect with %s' % self.host
+
+
+class SSHSessionDeadException(Exception):
+
+ """
+ SSH session is not alive.
+ It can no longer be used.
+ """
+
+ def __init__(self, host):
+ self.host = host
+
+ def __str__(self):
+ return 'SSH session with %s has been dead' % self.host
+
+
+class StartVMFailedException(Exception):
+
+ """
+ Start VM failed.
+ """
+
+ def __init__(self, error):
+ self.error = error
+
+ def __str__(self):
+ return repr(self.error)
diff --git a/framework/logger.py b/framework/logger.py
index 1829e18..5597e33 100644
--- a/framework/logger.py
+++ b/framework/logger.py
@@ -35,6 +35,9 @@ import sys
import inspect
import re
+from settings import LOG_NAME_SEP
+from utils import RED
+
"""
DTS logger module with several log level. DTS framwork and TestSuite log
will saved into different log files.
@@ -58,6 +61,9 @@ logging.SUITE_TESTER_OUTPUT = logging.DEBUG + 4
logging.DTS_IXIA_CMD = logging.INFO + 5
logging.DTS_IXIA_OUTPUT = logging.DEBUG + 5
+logging.DTS_VIRTDUT_CMD = logging.INFO + 6
+logging.DTS_VIRTDUT_OUTPUT = logging.DEBUG + 6
+
logging.addLevelName(logging.DTS_DUT_CMD, 'DTS_DUT_CMD')
logging.addLevelName(logging.DTS_DUT_OUTPUT, 'DTS_DUT_OUTPUT')
logging.addLevelName(logging.DTS_DUT_RESULT, 'DTS_DUT_RESUTL')
@@ -66,6 +72,12 @@ logging.addLevelName(logging.DTS_TESTER_CMD, 'DTS_TESTER_CMD')
logging.addLevelName(logging.DTS_TESTER_OUTPUT, 'DTS_TESTER_OUTPUT')
logging.addLevelName(logging.DTS_TESTER_RESULT, 'DTS_TESTER_RESULT')
+logging.addLevelName(logging.DTS_IXIA_CMD, 'DTS_IXIA_CMD')
+logging.addLevelName(logging.DTS_IXIA_OUTPUT, 'DTS_IXIA_OUTPUT')
+
+logging.addLevelName(logging.DTS_VIRTDUT_CMD, 'VIRTDUT_CMD')
+logging.addLevelName(logging.DTS_VIRTDUT_OUTPUT, 'VIRTDUT_OUTPUT')
+
logging.addLevelName(logging.SUITE_DUT_CMD, 'SUITE_DUT_CMD')
logging.addLevelName(logging.SUITE_DUT_OUTPUT, 'SUITE_DUT_OUTPUT')
@@ -82,15 +94,18 @@ stream_fmt = '%(color)s%(levelname)20s: %(message)s' + RESET_COLOR
log_dir = None
-def RED(text):
- return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
-
-
def set_verbose():
global verbose
verbose = True
+def add_salt(salt, msg):
+ if not salt:
+ return msg
+ else:
+ return '[%s] ' % salt + str(msg)
+
+
class BaseLoggerAdapter(logging.LoggerAdapter):
"""
Upper layer of original logging module.
@@ -132,6 +147,12 @@ class BaseLoggerAdapter(logging.LoggerAdapter):
def dts_ixia_output(self, msg, *args, **kwargs):
self.log(logging.DTS_IXIA_OUTPUT, msg, *args, **kwargs)
+ def dts_virtdut_cmd(self, msg, *args, **kwargs):
+ self.log(logging.DTS_VIRTDUT_CMD, msg, *args, **kwargs)
+
+ def dts_virtdut_output(self, msg, *args, **kwargs):
+ self.log(logging.DTS_VIRTDUT_OUTPUT, msg, *args, **kwargs)
+
class ColorHandler(logging.StreamHandler):
"""
@@ -150,6 +171,8 @@ class ColorHandler(logging.StreamHandler):
logging.SUITE_TESTER_CMD: '', # SYSTEM
logging.DTS_IXIA_CMD: '', # SYSTEM
logging.DTS_IXIA_OUTPUT: '', # SYSTEM
+ logging.DTS_VIRTDUT_CMD: '', # SYSTEM
+ logging.DTS_VIRTDUT_OUTPUT: '', # SYSTEM
logging.WARN: '\033[01;33m', # BOLD YELLOW
logging.DTS_DUT_RESULT: '\033[01;34m', # BOLD BLUE
logging.DTS_TESTER_RESULT: '\033[01;34m', # BOLD BLUE
@@ -189,6 +212,8 @@ class DTSLOG(BaseLoggerAdapter):
self.crb = crb
super(DTSLOG, self).__init__(self.logger, dict(crb=self.crb))
+ self.salt = ''
+
self.fh = None
self.ch = None
@@ -221,24 +246,28 @@ class DTSLOG(BaseLoggerAdapter):
"""
DTS warnning level log function.
"""
+ message = add_salt(self.salt, message)
self.logger.log(self.warn_lvl, message)
def info(self, message):
"""
DTS information level log function.
"""
+ message = add_salt(self.salt, message)
self.logger.log(self.info_lvl, message)
def error(self, message):
"""
DTS error level log function.
"""
+ message = add_salt(self.salt, message)
self.logger.log(self.error_lvl, message)
def debug(self, message):
"""
DTS debug level log function.
"""
+ message = add_salt(self.salt, message)
self.logger.log(self.debug_lvl, message)
def set_logfile_path(self, path):
@@ -270,17 +299,34 @@ class DTSLOG(BaseLoggerAdapter):
ch = ColorHandler()
self.__log_hander(fh, ch)
- if crb == "dut":
+ def set_salt(crb, start_flag):
+ if LOG_NAME_SEP in crb:
+ old = '%s%s' % (start_flag, LOG_NAME_SEP)
+ if not self.salt:
+ self.salt = crb.replace(old, '', 1)
+
+ if crb.startswith('dut'):
self.info_lvl = logging.DTS_DUT_CMD
self.debug_lvl = logging.DTS_DUT_OUTPUT
self.warn_lvl = logging.DTS_DUT_RESULT
- elif crb == "tester":
+
+ set_salt(crb, 'dut')
+ elif crb.startswith('tester'):
self.info_lvl = logging.DTS_TESTER_CMD
self.debug_lvl = logging.DTS_TESTER_OUTPUT
self.warn_lvl = logging.DTS_TESTER_RESULT
- elif crb == "ixia":
+
+ set_salt(crb, 'tester')
+ elif crb.startswith('ixia'):
self.info_lvl = logging.DTS_IXIA_CMD
self.debug_lvl = logging.DTS_IXIA_OUTPUT
+
+ set_salt(crb, 'ixia')
+ elif crb.startswith('virtdut'):
+ self.info_lvl = logging.DTS_VIRTDUT_CMD
+ self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
+
+ set_salt(crb, 'virtdut')
else:
self.error_lvl = logging.ERROR
self.warn_lvl = logging.WARNING
@@ -296,15 +342,18 @@ class DTSLOG(BaseLoggerAdapter):
ch = ColorHandler()
self.__log_hander(fh, ch)
- if crb == "dut":
+ if crb == 'dut':
self.info_lvl = logging.SUITE_DUT_CMD
self.debug_lvl = logging.SUITE_DUT_OUTPUT
- elif crb == "tester":
+ elif crb == 'tester':
self.info_lvl = logging.SUITE_TESTER_CMD
self.debug_lvl = logging.SUITE_TESTER_OUTPUT
- elif crb == "ixia":
+ elif crb == 'ixia':
self.info_lvl = logging.DTS_IXIA_CMD
self.debug_lvl = logging.DTS_IXIA_OUTPUT
+ elif crb == 'virtdut':
+ self.info_lvl = logging.DTS_VIRTDUT_CMD
+ self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
def logger_exit(self):
"""
diff --git a/framework/main.py b/framework/main.py
index 3e467d0..0496b20 100755
--- a/framework/main.py
+++ b/framework/main.py
@@ -117,6 +117,10 @@ parser.add_argument('-v', '--verbose',
action='store_true',
help='enable verbose output, all message output on screen')
+parser.add_argument('--virttype',
+ default='kvm',
+ help='set virt type,support libvirt,xen,kvm')
+
parser.add_argument('--debug',
action='store_true',
help='enable debug mode, user can enter debug mode in process')
@@ -136,4 +140,5 @@ if args.git is not None:
dts.run_all(args.config_file, args.snapshot, args.git,
args.patch, args.skip_setup, args.read_cache,
args.project, args.suite_dir, args.test_cases,
- args.dir, args.output, args.verbose, args.debug)
+ args.dir, args.output, args.verbose,args.virttype,
+ args.debug)
diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py
index 8963924..67bd492 100644
--- a/framework/project_dpdk.py
+++ b/framework/project_dpdk.py
@@ -39,7 +39,7 @@ from crb import Crb
from dut import Dut
from tester import Tester
from logger import getLogger
-from settings import IXIA
+from settings import IXIA, accepted_nic
class DPDKdut(Dut):
@@ -50,8 +50,9 @@ class DPDKdut(Dut):
"""
def __init__(self, crb, serializer):
- self.NAME = 'dut'
+
super(DPDKdut, self).__init__(crb, serializer)
+ self.testpmd = None
def set_target(self, target):
"""
@@ -60,6 +61,7 @@ class DPDKdut(Dut):
Set hugepage on DUT and install modules required by DPDK.
Configure default ixgbe PMD function.
"""
+ self.target = target
self.set_toolchain(target)
# set env variable
@@ -99,7 +101,16 @@ class DPDKdut(Dut):
out = self.send_expect("lsmod | grep igb_uio", "#")
if "igb_uio" in out:
self.send_expect("rmmod -f igb_uio", "#", 70)
- self.send_expect("insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
+ if "rte_dom0_mm" in self.send_expect("lsmod |grep rte_dom0_mm", "#"):
+ self.send_expect("rmmod -f rte_dmo0_mm", "#", 70)
+ self.send_expect(
+ "insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
+ if self.virttype == 'xen':
+ self.send_expect(
+ "insmod ./" + target + "/kmod/rte_dom0_mm.ko", "#", 60)
+ self.send_expect(
+ r'echo 1024 > /sys/kernel/mm/dom0-mm/memsize-mB/memsize', "#", 70)
+
out = self.send_expect("lsmod | grep igb_uio", "#")
assert ("igb_uio" in out), "Failed to insmod igb_uio"
@@ -110,7 +121,7 @@ class DPDKdut(Dut):
binding_list = ''
for (pci_bus, pci_id) in self.pci_devices_info:
- if dts.accepted_nic(pci_id):
+ if accepted_nic(pci_id):
binding_list += '%s,' % (pci_bus)
self.send_expect("kldunload if_ixgbe.ko", "#")
@@ -158,6 +169,9 @@ class DPDKdut(Dut):
"""
# clean all
self.send_expect("rm -rf " + target, "#")
+ if self.virttype == 'xen':
+ self.send_expect("sed -i -e 's/CONFIG_RTE_LIBRTE_XEN_DOM0=.*$/"
+ + "CONFIG_RTE_LIBRTE_XEN_DOM0=y/' config/common_linuxapp", "# ", 30)
# compile
out = self.send_expect("make -j install T=%s %s" % (target, extra_options), "# ", 120)
@@ -178,9 +192,9 @@ class DPDKdut(Dut):
self.send_expect("rm -rf " + target, "#")
# compile
- out = self.send_expect("make -j %d install T=%s CC=gcc48" % (self.number_of_cores,
- target),
- "#", 120)
+ out = self.send_expect(
+ "make -j %d install T=%s CC=gcc48" %
+ (self.number_of_cores, target), "#", 120)
if("Error" in out or "No rule to make" in out):
self.logger.error("ERROR - try without '-j'")
@@ -191,10 +205,7 @@ class DPDKdut(Dut):
assert ("Error" not in out), "Compilation error..."
assert ("No rule to make" not in out), "No rule to make error..."
- def prerequisites(self, pkgName, patch):
- """
- Copy DPDK package to DUT and apply patch files.
- """
+ def prepare_package(self, pkgName, patch):
if not self.skip_setup:
assert (os.path.isfile(pkgName) is True), "Invalid package"
@@ -202,7 +213,7 @@ class DPDKdut(Dut):
# ToDo: make this configurable
dst_dir = "/tmp/"
ll isn’t linux kernel default cmdline, some linux not have this cmd, would used ls to replace.
- out = self.send_expect("ls %s && cd %s" % (dst_dir, p_dir),
+ out = self.send_expect("ll %s && cd %s" % (dst_dir, p_dir),
"#", verify=True)
if out == -1:
raise ValueError("Directiry %s or %s does not exist,"
@@ -249,6 +260,17 @@ class DPDKdut(Dut):
(self.base_dir, dst_dir + p), "# ")
assert "****" not in out
+ self.session.copy_file_to("dep/aclrule.tgz", dst_dir)
+ # unpack acl rule
+ out = self.send_expect("tar zxf %saclrule.tgz -C %s" % (dst_dir, p_dir), "# ", 20, verify=True)
+ if out == -1:
+ raise ValueError("acl rule extract failure!!!")
+
+ def prerequisites(self, pkgName, patch):
+ """
+ Copy DPDK package to DUT and apply patch files.
+ """
+ self.prepare_package(pkgName, patch)
self.dut_prerequisites()
def bind_interfaces_linux(self, driver='igb_uio', nics_to_bind=None):
@@ -354,16 +376,20 @@ class DPDKtester(Tester):
total_huge_pages = self.get_total_huge_pages()
if total_huge_pages == 0:
self.mount_huge_pages()
- self.set_huge_pages(4096)
+ self.set_huge_pages(1024)
self.session.copy_file_to("dep/tgen.tgz")
self.session.copy_file_to("dep/tclclient.tgz")
+ self.session.copy_file_to("dep/aclpcap.tgz")
# unpack tgen
out = self.send_expect("tar zxf tgen.tgz", "# ")
assert "Error" not in out
# unpack tclclient
out = self.send_expect("tar zxf tclclient.tgz", "# ")
assert "Error" not in out
+ # unpacl ACL pcap files
+ out = self.send_expect("tar zxf aclpcap.tgz", "# ")
+ assert "Error" not in out
self.send_expect("modprobe uio", "# ")
@@ -386,10 +412,10 @@ class DPDKtester(Tester):
"""
hugepages_size = self.send_expect("awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
- if int(hugepages_size) < (1024 * 1024):
- arch_huge_pages = hugepages if hugepages > 0 else 4096
+ if int(hugepages_size) < (2048 * 2048):
+ arch_huge_pages = hugepages if hugepages > 0 else 2048
total_huge_pages = self.get_total_huge_pages()
- self.mount_huge_pages()
- if total_huge_pages != arch_huge_pages:
- self.set_huge_pages(arch_huge_pages)
+ self.mount_huge_pages()
+ if total_huge_pages != arch_huge_pages:
+ self.set_huge_pages(arch_huge_pages)
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test
2015-05-18 7:26 ` Liu, Yong
@ 2015-05-18 8:08 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-18 8:08 UTC (permalink / raw)
To: Liu, Yong, dts
> -----Original Message-----
> From: Liu, Yong
> Sent: Monday, May 18, 2015 3:26 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 3/9] Add some params and functions related
> to the virtual test
>
> Jiajia, please see my comments below.
>
> > -----Original Message-----
> > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > Sent: Monday, May 18, 2015 1:07 PM
> > To: dts@dpdk.org
> > Subject: [dts] [‘dts-v1’ 3/9] Add some params and functions related
> to the
> > virtual test
> >
> > Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> > ---
> > framework/dts.py | 92 +++++++++++--------------------------
> -----
> > -----
> > framework/exception.py | 27 ++++++++++++++
> > framework/logger.py | 69 +++++++++++++++++++++++++++++------
> > framework/main.py | 7 +++-
> > framework/project_dpdk.py | 62 ++++++++++++++++++++++----------
> > 5 files changed, 157 insertions(+), 100 deletions(-)
> >
> > diff --git a/framework/dts.py b/framework/dts.py
> > index c9ecccb..c0df4e9 100644
> > --- a/framework/dts.py
> > +++ b/framework/dts.py
> > @@ -49,6 +49,7 @@ from test_case import TestCase
> > from test_result import Result
> > from stats_reporter import StatsReporter
> > from excel_reporter import ExcelReporter
> > +from utils import *
> > from exception import TimeoutException
> > from logger import getLogger
> > import logger
> > @@ -57,6 +58,7 @@ import sys
> > reload(sys)
> > sys.setdefaultencoding('UTF8')
> >
> > +PROJECT_MODULE_PREFIX = 'project_'
> >
> > debug_mode = False
> > config = None
> > @@ -73,44 +75,12 @@ result = None
> > excel_report = None
> > stats = None
> > log_handler = None
> > +Package = ''
> > +Patches = []
> > drivername = ""
> > interrupttypr = ""
> >
> >
> > -def RED(text):
> > - return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
> > -
> > -
> > -def BLUE(text):
> > - return "\x1B[" + "36;1m" + text + "\x1B[" + "0m"
> > -
> > -
> > -def GREEN(text):
> > - return "\x1B[" + "32;1m" + text + "\x1B[" + "0m"
> > -
> > -
> > -def regexp(s, to_match, allString=False):
> > - """
> > - Ensure that the re `to_match' only has one group in it.
> > - """
> > -
> > - scanner = re.compile(to_match, re.DOTALL)
> > - if allString:
> > - return scanner.findall(s)
> > - m = scanner.search(s)
> > - if m is None:
> > - log_handler.warning("Failed to match " + to_match + " in the
> > string " + s)
> > - return None
> > - return m.group(1)
> > -
> > -
> > -def pprint(some_dict):
> > - """
> > - Print JSON format dictionary object.
> > - """
> > - return json.dumps(some_dict, sort_keys=True, indent=4)
> > -
> > -
> > def report(text, frame=False, annex=False):
> > """
> > Save report text into rst file.
> > @@ -132,36 +102,6 @@ def close_crb_sessions():
> > log_handler.info("DTS ended")
> >
> >
> > -def get_nic_driver(pci_id):
> > - """
> > - Return linux driver for specified pci device
> > - """
> > - driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
> > - try:
> > - driver = DRIVERS[driverlist[pci_id]]
> > - except Exception as e:
> > - driver = None
> > - return driver
> > -
> > -
> > -def accepted_nic(pci_id):
> > - """
> > - Return True if the pci_id is a known NIC card in the settings
> file
> > and if
> > - it is selected in the execution file, otherwise it returns False.
> > - """
> > - if pci_id not in NICS.values():
> > - return False
> > -
> > - if nic is 'any':
> > - return True
> > -
> > - else:
> > - if pci_id == NICS[nic]:
> > - return True
> > -
> > - return False
> > -
> > -
> > def get_crb_os(crb):
> > if 'OS' in crb:
> > return crb['OS']
> > @@ -220,9 +160,10 @@ def get_project_obj(project_name, super_class,
> > crbInst, serializer):
> > """
> > Load project module and return crb instance.
> > """
> > + global PROJECT_MODULE_PREFIX
> > project_obj = None
> > try:
> > - project_module = __import__("project_" + project_name)
> > + project_module = __import__(PROJECT_MODULE_PREFIX +
> project_name)
> >
> > for project_subclassname, project_subclass in
> > get_subclasses(project_module, super_class):
> > project_obj = project_subclass(crbInst, serializer)
> > @@ -267,19 +208,20 @@ def dts_log_execution(log_handler):
> > pass
> >
> >
> > -def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir,
> > nic):
> > +def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir,
> nic,
> > virttype):
> > """
> > Create dts dut/tester instance and initialize them.
> > """
> > global dut
> > global tester
> > - serializer.set_serialized_filename('../.%s.cache' %
> crbInst['IP'])
> > + serializer.set_serialized_filename('.%s.cache' % crbInst['IP'])
> > serializer.load_from_file()
> >
> > dut = get_project_obj(project, Dut, crbInst, serializer)
> > tester = get_project_obj(project, Tester, crbInst, serializer)
> > dut.tester = tester
> > tester.dut = dut
> > + dut.set_virttype(virttype)
> > dut.set_speedup_options(read_cache, skip_setup)
> > dut.set_directory(base_dir)
> > dut.set_nic_type(nic)
> > @@ -337,7 +279,6 @@ def dts_run_target(crbInst, targets, test_suites,
> nic):
> > if 'nic_type' not in paramDict:
> > paramDict['nic_type'] = 'any'
> > nic = 'any'
> > - result.nic = nic
> >
> > dts_run_suite(crbInst, test_suites, target, nic)
> >
> > @@ -359,7 +300,9 @@ def dts_run_suite(crbInst, test_suites, target,
> nic):
> > test_module = __import__('TestSuite_' + test_suite)
> > for test_classname, test_class in
> get_subclasses(test_module,
> > TestCase):
> >
> > - test_suite = test_class(dut, tester, target)
> > + test_suite = test_class(dut, tester, target,
> test_suite)
> > + result.nic = test_suite.nic
> > +
> > dts_log_testsuite(test_suite, log_handler,
> test_classname)
> >
> > log_handler.info("\nTEST SUITE : " + test_classname)
> > @@ -386,7 +329,7 @@ def dts_run_suite(crbInst, test_suites, target,
> nic):
> >
> > def run_all(config_file, pkgName, git, patch, skip_setup,
> > read_cache, project, suite_dir, test_cases,
> > - base_dir, output_dir, verbose, debug):
> > + base_dir, output_dir, verbose, virttype, debug):
> > """
> > Main process of DTS, it will run all test suites in the config
> file.
> > """
> > @@ -400,6 +343,12 @@ def run_all(config_file, pkgName, git, patch,
> > skip_setup,
> > global stats
> > global log_handler
> > global debug_mode
> > + global Package
> > + global Patches
> > +
> > + # save global variable
> > + Package = pkgName
> > + Patches = patch
> >
> > # prepare the output folder
> > if not os.path.exists(output_dir):
> > @@ -466,7 +415,8 @@ def run_all(config_file, pkgName, git, patch,
> > skip_setup,
> > result.dut = dutIP
> >
> > # init dut, tester crb
> > - dts_crbs_init(crbInst, skip_setup, read_cache, project,
> base_dir,
> > nics)
> > + dts_crbs_init(
> > + crbInst, skip_setup, read_cache, project, base_dir, nics,
> > virttype)
> >
> > # Run DUT prerequisites
> > if dts_run_prerequisties(pkgName, patch) is False:
> > diff --git a/framework/exception.py b/framework/exception.py
> > index be38c16..98dedf4 100644
> > --- a/framework/exception.py
> > +++ b/framework/exception.py
> > @@ -46,3 +46,30 @@ class SSHConnectionException(Exception):
> >
> > def __str__(self):
> > return 'Error trying to connect with %s' % self.host
> > +
> > +
> > +class SSHSessionDeadException(Exception):
> > +
> > + """
> > + SSH session is not alive.
> > + It can no longer be used.
> > + """
> > +
> > + def __init__(self, host):
> > + self.host = host
> > +
> > + def __str__(self):
> > + return 'SSH session with %s has been dead' % self.host
> > +
> > +
> > +class StartVMFailedException(Exception):
> > +
> > + """
> > + Start VM failed.
> > + """
> > +
> > + def __init__(self, error):
> > + self.error = error
> > +
> > + def __str__(self):
> > + return repr(self.error)
> > diff --git a/framework/logger.py b/framework/logger.py
> > index 1829e18..5597e33 100644
> > --- a/framework/logger.py
> > +++ b/framework/logger.py
> > @@ -35,6 +35,9 @@ import sys
> > import inspect
> > import re
> >
> > +from settings import LOG_NAME_SEP
> > +from utils import RED
> > +
> > """
> > DTS logger module with several log level. DTS framwork and TestSuite
> log
> > will saved into different log files.
> > @@ -58,6 +61,9 @@ logging.SUITE_TESTER_OUTPUT = logging.DEBUG + 4
> > logging.DTS_IXIA_CMD = logging.INFO + 5
> > logging.DTS_IXIA_OUTPUT = logging.DEBUG + 5
> >
> > +logging.DTS_VIRTDUT_CMD = logging.INFO + 6
> > +logging.DTS_VIRTDUT_OUTPUT = logging.DEBUG + 6
> > +
> > logging.addLevelName(logging.DTS_DUT_CMD, 'DTS_DUT_CMD')
> > logging.addLevelName(logging.DTS_DUT_OUTPUT, 'DTS_DUT_OUTPUT')
> > logging.addLevelName(logging.DTS_DUT_RESULT, 'DTS_DUT_RESUTL')
> > @@ -66,6 +72,12 @@ logging.addLevelName(logging.DTS_TESTER_CMD,
> > 'DTS_TESTER_CMD')
> > logging.addLevelName(logging.DTS_TESTER_OUTPUT, 'DTS_TESTER_OUTPUT')
> > logging.addLevelName(logging.DTS_TESTER_RESULT, 'DTS_TESTER_RESULT')
> >
> > +logging.addLevelName(logging.DTS_IXIA_CMD, 'DTS_IXIA_CMD')
> > +logging.addLevelName(logging.DTS_IXIA_OUTPUT, 'DTS_IXIA_OUTPUT')
> > +
> > +logging.addLevelName(logging.DTS_VIRTDUT_CMD, 'VIRTDUT_CMD')
> > +logging.addLevelName(logging.DTS_VIRTDUT_OUTPUT, 'VIRTDUT_OUTPUT')
> > +
> > logging.addLevelName(logging.SUITE_DUT_CMD, 'SUITE_DUT_CMD')
> > logging.addLevelName(logging.SUITE_DUT_OUTPUT, 'SUITE_DUT_OUTPUT')
> >
> > @@ -82,15 +94,18 @@ stream_fmt =
> '%(color)s%(levelname)20s: %(message)s' +
> > RESET_COLOR
> > log_dir = None
> >
> >
> > -def RED(text):
> > - return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
> > -
> > -
> > def set_verbose():
> > global verbose
> > verbose = True
> >
> >
> > +def add_salt(salt, msg):
> > + if not salt:
> > + return msg
> > + else:
> > + return '[%s] ' % salt + str(msg)
> > +
> > +
> > class BaseLoggerAdapter(logging.LoggerAdapter):
> > """
> > Upper layer of original logging module.
> > @@ -132,6 +147,12 @@ class BaseLoggerAdapter(logging.LoggerAdapter):
> > def dts_ixia_output(self, msg, *args, **kwargs):
> > self.log(logging.DTS_IXIA_OUTPUT, msg, *args, **kwargs)
> >
> > + def dts_virtdut_cmd(self, msg, *args, **kwargs):
> > + self.log(logging.DTS_VIRTDUT_CMD, msg, *args, **kwargs)
> > +
> > + def dts_virtdut_output(self, msg, *args, **kwargs):
> > + self.log(logging.DTS_VIRTDUT_OUTPUT, msg, *args, **kwargs)
> > +
> >
> > class ColorHandler(logging.StreamHandler):
> > """
> > @@ -150,6 +171,8 @@ class ColorHandler(logging.StreamHandler):
> > logging.SUITE_TESTER_CMD: '', # SYSTEM
> > logging.DTS_IXIA_CMD: '', # SYSTEM
> > logging.DTS_IXIA_OUTPUT: '', # SYSTEM
> > + logging.DTS_VIRTDUT_CMD: '', # SYSTEM
> > + logging.DTS_VIRTDUT_OUTPUT: '', # SYSTEM
> > logging.WARN: '\033[01;33m', # BOLD YELLOW
> > logging.DTS_DUT_RESULT: '\033[01;34m', # BOLD BLUE
> > logging.DTS_TESTER_RESULT: '\033[01;34m', # BOLD BLUE
> > @@ -189,6 +212,8 @@ class DTSLOG(BaseLoggerAdapter):
> > self.crb = crb
> > super(DTSLOG, self).__init__(self.logger, dict(crb=self.crb))
> >
> > + self.salt = ''
> > +
> > self.fh = None
> > self.ch = None
> >
> > @@ -221,24 +246,28 @@ class DTSLOG(BaseLoggerAdapter):
> > """
> > DTS warnning level log function.
> > """
> > + message = add_salt(self.salt, message)
> > self.logger.log(self.warn_lvl, message)
> >
> > def info(self, message):
> > """
> > DTS information level log function.
> > """
> > + message = add_salt(self.salt, message)
> > self.logger.log(self.info_lvl, message)
> >
> > def error(self, message):
> > """
> > DTS error level log function.
> > """
> > + message = add_salt(self.salt, message)
> > self.logger.log(self.error_lvl, message)
> >
> > def debug(self, message):
> > """
> > DTS debug level log function.
> > """
> > + message = add_salt(self.salt, message)
> > self.logger.log(self.debug_lvl, message)
> >
> > def set_logfile_path(self, path):
> > @@ -270,17 +299,34 @@ class DTSLOG(BaseLoggerAdapter):
> > ch = ColorHandler()
> > self.__log_hander(fh, ch)
> >
> > - if crb == "dut":
> > + def set_salt(crb, start_flag):
> > + if LOG_NAME_SEP in crb:
> > + old = '%s%s' % (start_flag, LOG_NAME_SEP)
> > + if not self.salt:
> > + self.salt = crb.replace(old, '', 1)
> > +
> > + if crb.startswith('dut'):
> > self.info_lvl = logging.DTS_DUT_CMD
> > self.debug_lvl = logging.DTS_DUT_OUTPUT
> > self.warn_lvl = logging.DTS_DUT_RESULT
> > - elif crb == "tester":
> > +
> > + set_salt(crb, 'dut')
> > + elif crb.startswith('tester'):
> > self.info_lvl = logging.DTS_TESTER_CMD
> > self.debug_lvl = logging.DTS_TESTER_OUTPUT
> > self.warn_lvl = logging.DTS_TESTER_RESULT
> > - elif crb == "ixia":
> > +
> > + set_salt(crb, 'tester')
> > + elif crb.startswith('ixia'):
> > self.info_lvl = logging.DTS_IXIA_CMD
> > self.debug_lvl = logging.DTS_IXIA_OUTPUT
> > +
> > + set_salt(crb, 'ixia')
> > + elif crb.startswith('virtdut'):
> > + self.info_lvl = logging.DTS_VIRTDUT_CMD
> > + self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
> > +
> > + set_salt(crb, 'virtdut')
> > else:
> > self.error_lvl = logging.ERROR
> > self.warn_lvl = logging.WARNING
> > @@ -296,15 +342,18 @@ class DTSLOG(BaseLoggerAdapter):
> > ch = ColorHandler()
> > self.__log_hander(fh, ch)
> >
> > - if crb == "dut":
> > + if crb == 'dut':
> > self.info_lvl = logging.SUITE_DUT_CMD
> > self.debug_lvl = logging.SUITE_DUT_OUTPUT
> > - elif crb == "tester":
> > + elif crb == 'tester':
> > self.info_lvl = logging.SUITE_TESTER_CMD
> > self.debug_lvl = logging.SUITE_TESTER_OUTPUT
> > - elif crb == "ixia":
> > + elif crb == 'ixia':
> > self.info_lvl = logging.DTS_IXIA_CMD
> > self.debug_lvl = logging.DTS_IXIA_OUTPUT
> > + elif crb == 'virtdut':
> > + self.info_lvl = logging.DTS_VIRTDUT_CMD
> > + self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
> >
> > def logger_exit(self):
> > """
> > diff --git a/framework/main.py b/framework/main.py
> > index 3e467d0..0496b20 100755
> > --- a/framework/main.py
> > +++ b/framework/main.py
> > @@ -117,6 +117,10 @@ parser.add_argument('-v', '--verbose',
> > action='store_true',
> > help='enable verbose output, all message output
> on
> > screen')
> >
> > +parser.add_argument('--virttype',
> > + default='kvm',
> > + help='set virt type,support libvirt,xen,kvm')
> > +
> > parser.add_argument('--debug',
> > action='store_true',
> > help='enable debug mode, user can enter debug
> mode in
> > process')
> > @@ -136,4 +140,5 @@ if args.git is not None:
> > dts.run_all(args.config_file, args.snapshot, args.git,
> > args.patch, args.skip_setup, args.read_cache,
> > args.project, args.suite_dir, args.test_cases,
> > - args.dir, args.output, args.verbose, args.debug)
> > + args.dir, args.output, args.verbose,args.virttype,
> > + args.debug)
> > diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py
> > index 8963924..67bd492 100644
> > --- a/framework/project_dpdk.py
> > +++ b/framework/project_dpdk.py
> > @@ -39,7 +39,7 @@ from crb import Crb
> > from dut import Dut
> > from tester import Tester
> > from logger import getLogger
> > -from settings import IXIA
> > +from settings import IXIA, accepted_nic
> >
> >
> > class DPDKdut(Dut):
> > @@ -50,8 +50,9 @@ class DPDKdut(Dut):
> > """
> >
> > def __init__(self, crb, serializer):
> > - self.NAME = 'dut'
> > +
> > super(DPDKdut, self).__init__(crb, serializer)
> > + self.testpmd = None
> >
> > def set_target(self, target):
> > """
> > @@ -60,6 +61,7 @@ class DPDKdut(Dut):
> > Set hugepage on DUT and install modules required by DPDK.
> > Configure default ixgbe PMD function.
> > """
> > + self.target = target
> > self.set_toolchain(target)
> >
> > # set env variable
> > @@ -99,7 +101,16 @@ class DPDKdut(Dut):
> > out = self.send_expect("lsmod | grep igb_uio", "#")
> > if "igb_uio" in out:
> > self.send_expect("rmmod -f igb_uio", "#", 70)
> > - self.send_expect("insmod ./" + target +
> "/kmod/igb_uio.ko",
> > "#", 60)
> > + if "rte_dom0_mm" in self.send_expect("lsmod |grep
> > rte_dom0_mm", "#"):
> > + self.send_expect("rmmod -f rte_dmo0_mm", "#", 70)
> > + self.send_expect(
> > + "insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
>
> "rte_dom0_mm" module only can be built out when DOM0 enabled in DPDK
> configuration file.
> We should not expected it existed in host. Make sure DOM0 configuration
> enabled and build target with modified configuration.
>
This will be checked if the 'virttype' is set to be 'xen'.
>
> > + if self.virttype == 'xen':
> > + self.send_expect(
> > + "insmod ./" + target + "/kmod/rte_dom0_mm.ko",
> "#",
> > 60)
> > + self.send_expect(
> > + r'echo 1024 > /sys/kernel/mm/dom0-mm/memsize-
> > mB/memsize', "#", 70)
> > +
> Better to use macro replace of 1024, these settings should be defined
> in settings.py.
Ok, I will define it in the setting.py.
>
> > out = self.send_expect("lsmod | grep igb_uio", "#")
> > assert ("igb_uio" in out), "Failed to insmod igb_uio"
> >
> > @@ -110,7 +121,7 @@ class DPDKdut(Dut):
> > binding_list = ''
> >
> > for (pci_bus, pci_id) in self.pci_devices_info:
> > - if dts.accepted_nic(pci_id):
> > + if accepted_nic(pci_id):
> > binding_list += '%s,' % (pci_bus)
> >
> > self.send_expect("kldunload if_ixgbe.ko", "#")
> > @@ -158,6 +169,9 @@ class DPDKdut(Dut):
> > """
> > # clean all
> > self.send_expect("rm -rf " + target, "#")
> > + if self.virttype == 'xen':
> > + self.send_expect("sed -i -e
> > 's/CONFIG_RTE_LIBRTE_XEN_DOM0=.*$/"
> > + + "CONFIG_RTE_LIBRTE_XEN_DOM0=y/'
> > config/common_linuxapp", "# ", 30)
> >
> > # compile
> > out = self.send_expect("make -j install T=%s %s" % (target,
> > extra_options), "# ", 120)
> > @@ -178,9 +192,9 @@ class DPDKdut(Dut):
> > self.send_expect("rm -rf " + target, "#")
> >
> > # compile
> > - out = self.send_expect("make -j %d install T=%s CC=gcc48" %
> > (self.number_of_cores,
> > -
> > target),
> > - "#", 120)
> > + out = self.send_expect(
> > + "make -j %d install T=%s CC=gcc48" %
> > + (self.number_of_cores, target), "#", 120)
> >
> > if("Error" in out or "No rule to make" in out):
> > self.logger.error("ERROR - try without '-j'")
> > @@ -191,10 +205,7 @@ class DPDKdut(Dut):
> > assert ("Error" not in out), "Compilation error..."
> > assert ("No rule to make" not in out), "No rule to make
> error..."
> >
> > - def prerequisites(self, pkgName, patch):
> > - """
> > - Copy DPDK package to DUT and apply patch files.
> > - """
> > + def prepare_package(self, pkgName, patch):
> > if not self.skip_setup:
> > assert (os.path.isfile(pkgName) is True), "Invalid
> package"
> >
> > @@ -202,7 +213,7 @@ class DPDKdut(Dut):
> > # ToDo: make this configurable
> > dst_dir = "/tmp/"
> >
> > - out = self.send_expect("ls %s && cd %s" % (dst_dir,
> p_dir),
> > + out = self.send_expect("ll %s && cd %s" % (dst_dir,
> p_dir),
> > "#", verify=True)
> Command "ll" may not existed on every OS, please just use basic "ls"
> command.
>
Ok, I will change it in the next version.
> > if out == -1:
> > raise ValueError("Directiry %s or %s does not
> exist,"
> > @@ -249,6 +260,17 @@ class DPDKdut(Dut):
> > (self.base_dir, dst_dir +
> p),
> > "# ")
> > assert "****" not in out
> >
> > + self.session.copy_file_to("dep/aclrule.tgz", dst_dir)
> > + # unpack acl rule
> > + out = self.send_expect("tar zxf %saclrule.tgz -C %s" %
> > (dst_dir, p_dir), "# ", 20, verify=True)
> > + if out == -1:
> > + raise ValueError("acl rule extract failure!!!")
> > +
>
> These files related with l3fwd acl suite, we should merged these files
> in following with acl suite.
> Please remove these codes from your patch set.
Ok, I will remove it in the next version.
>
> > + def prerequisites(self, pkgName, patch):
> > + """
> > + Copy DPDK package to DUT and apply patch files.
> > + """
> > + self.prepare_package(pkgName, patch)
> > self.dut_prerequisites()
> >
> > def bind_interfaces_linux(self, driver='igb_uio',
> nics_to_bind=None):
> > @@ -354,16 +376,20 @@ class DPDKtester(Tester):
> > total_huge_pages = self.get_total_huge_pages()
> > if total_huge_pages == 0:
> > self.mount_huge_pages()
> > - self.set_huge_pages(4096)
> > + self.set_huge_pages(1024)
> >
> > self.session.copy_file_to("dep/tgen.tgz")
> > self.session.copy_file_to("dep/tclclient.tgz")
> > + self.session.copy_file_to("dep/aclpcap.tgz")
> > # unpack tgen
> > out = self.send_expect("tar zxf tgen.tgz", "# ")
> > assert "Error" not in out
> > # unpack tclclient
> > out = self.send_expect("tar zxf tclclient.tgz", "# ")
> > assert "Error" not in out
>
>
> These files related with l3fwd acl suite, we should merged these files
> in following with acl suite.
> Please remove these codes from your patch set.
Ok, I will remove it in the next version.
>
> > + # unpacl ACL pcap files
> > + out = self.send_expect("tar zxf aclpcap.tgz", "# ")
> > + assert "Error" not in out
> >
> > self.send_expect("modprobe uio", "# ")
> >
> > @@ -386,10 +412,10 @@ class DPDKtester(Tester):
> > """
> > hugepages_size = self.send_expect("awk '/Hugepagesize/
> {print
> > $2}' /proc/meminfo", "# ")
> >
> > - if int(hugepages_size) < (1024 * 1024):
> > - arch_huge_pages = hugepages if hugepages > 0 else 4096
> > + if int(hugepages_size) < (2048 * 2048):
> > + arch_huge_pages = hugepages if hugepages > 0 else 2048
>
> Better to use macro replace of 2048, these settings should be defined
> in settings.py.
Ok, I will change it in the next version.
>
> > total_huge_pages = self.get_total_huge_pages()
> >
> > - self.mount_huge_pages()
> > - if total_huge_pages != arch_huge_pages:
> > - self.set_huge_pages(arch_huge_pages)
> > + self.mount_huge_pages()
> > + if total_huge_pages != arch_huge_pages:
> > + self.set_huge_pages(arch_huge_pages)
> > --
> > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module
2015-05-18 5:07 ` [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module sjiajiax
@ 2015-05-18 8:23 ` Xu, HuilongX
2015-05-18 13:57 ` Liu, Yong
1 sibling, 0 replies; 34+ messages in thread
From: Xu, HuilongX @ 2015-05-18 8:23 UTC (permalink / raw)
To: Jiajia, SunX, dts
Hi Jiajia,
I have a comment at "@@ -202,7 +213,7 @@ class DPDKdut(Dut):"
Would you check it, thanks a lot.
-----Original Message-----
From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
Sent: Monday, May 18, 2015 1:07 PM
To: dts@dpdk.org
Subject: [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/qemu_kvm.py | 912 +++++++++++++++++++++++++++++++++++++++++++++
framework/virt_base.py | 250 +++++++++++++
framework/virt_dut.py | 239 ++++++++++++
framework/virt_resource.py | 486 ++++++++++++++++++++++++
4 files changed, 1887 insertions(+)
create mode 100644 framework/qemu_kvm.py
create mode 100644 framework/virt_base.py
create mode 100644 framework/virt_dut.py
create mode 100644 framework/virt_resource.py
diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py
new file mode 100644
index 0000000..5f5f665
--- /dev/null
+++ b/framework/qemu_kvm.py
@@ -0,0 +1,912 @@
+# <COPYRIGHT_TAG>
+
+import time
+import re
+import os
+
+from virt_base import VirtBase
+from exception import StartVMFailedException
+
+# This name is derictly defined in the qemu guest serivce
+# So you can not change it except it is changed by the service
+QGA_DEV_NAME = 'org.qemu.guest_agent.0'
+# This path defines an socket path on the host connected with
+# a specified VM
+QGA_SOCK_PATH_TEMPLATE = '/tmp/%(vm_name)s_qga0.sock'
+
+
+class QEMUKvm(VirtBase):
+
+ DEFAULT_BRIDGE = 'br0'
+ QEMU_IFUP = """#!/bin/sh
+
+set -x
+
+switch=%(switch)s
+
+if [ -n "$1" ];then
+ tunctl -t $1
+ ip link set $1 up
+ sleep 0.5s
+ brctl addif $switch $1
+ exit 0
+else
+ echo "Error: no interface specified"
+ exit 1
+fi
+"""
+ QEMU_IFUP_PATH = '/etc/qemu-ifup'
+
+ def __init__(self, dut, vm_name, suite_name):
+ super(QEMUKvm, self).__init__(dut, vm_name, suite_name)
+ self.set_vm_name(self.vm_name)
+ self.set_vm_enable_kvm()
+ self.set_vm_qga()
+ self.set_vm_daemon()
+
+ # initialize qemu emulator, example: qemu-system-x86_64
+ self.qemu_emulator = self.get_qemu_emulator()
+
+ # initialize qemu boot command line
+ # example: qemu-system-x86_64 -name vm1 -m 2048 -vnc :1 -daemonize
+ self.whole_qemu_kvm_boot_line = ''
+
+ self.init_vm_request_resource()
+
+ QGA_CLI_PATH = '-r dep/QMP/'
+ self.host_session.copy_file_to(QGA_CLI_PATH)
+
+ def init_vm_request_resource(self):
+ """
+ initialize vcpus what will be pinned to the VM.
+ If specify this param, the specified vcpus will
+ be pinned to VM by the command 'taskset' when
+ starting the VM.
+ example:
+ vcpus_pinned_to_vm = '1 2 3 4'
+ taskset -c 1,2,3,4 qemu-boot-command-line
+ """
+ self.vcpus_pinned_to_vm = ''
+
+ # initialize assigned PCI
+ self.assigned_pcis = []
+
+ def get_virt_type(self):
+ """
+ Get the virtual type.
+ """
+ return 'KVM'
+
+ def get_qemu_emulator(self):
+ """
+ Get the qemu emulator based on the crb.
+ """
+ arch = self.host_session.send_expect('uname -m', '# ')
+ return 'qemu-system-' + arch
+
+ def set_qemu_emulator(self, qemu_emulator):
+ """
+ Set the qemu emulator explicitly.
+ """
+ out = self.host_session.send_expect(
+ 'whereis %s' % str(qemu_emulator), '[.*')
+ command_paths = out.split(':')[1:]
+ if command_paths[0].lstrip():
+ print "No emulator [ %s ] on the DUT [ %s ]" % \
+ (qemu_emulator, self.host_dut.get_ip_address())
+ return None
+ self.qemu_emulator = qemu_emulator
+
+ def has_virtual_ability(self):
+ """
+ Check if host has the virtual ability.
+ """
+ out = self.host_session.send_expect('lsmod | grep kvm', '# ')
+ if 'kvm' in out and 'kvm_intel' in out:
+ return True
+ else:
+ return False
+
+ def enable_virtual_ability(self):
+ """
+ Load the virutal module of kernel to enable the virutal ability.
+ """
+ self.host_session.send_expect('modprobe kvm', '# ')
+ self.host_session.send_expect('modprobe kvm_intel', '# ')
We need check modprobe kvm and kvm_intel module success befor return.
Because when bios disable VT-D or linux kernel not support virtualization,
if we exec modprobe kvm_intel by session, the session exec success.
+ return True
+
+ def disk_image_is_ok(self, image):
+ """
+ Check if the image is OK and no error.
+ """
+ pass
+
+ def image_is_used(self, image_path):
+ """
+ Check if the image has been used on the host.
+ """
+ qemu_cmd_lines = self.host_session.send_expect(
+ "ps aux | grep qemu | grep -v grep", "# ")
+
+ image_name_flag = '/' + image_path.strip().split('/')[-1] + ' '
+ if image_path in qemu_cmd_lines or \
+ image_name_flag in qemu_cmd_lines:
+ return True
+ return False
+
+ def __add_boot_line(self, option_boot_line):
+ """
+ Add boot option into the boot line.
+ """
+ separator = ' '
+ self.whole_qemu_kvm_boot_line += separator + option_boot_line
+
+ def set_vm_enable_kvm(self, enable='yes'):
+ """
+ Set VM boot option to enable the option 'enable-kvm'.
+ """
+ self.params.append({'enable_kvm': [{'enable': '%s' % enable}]})
+
+ def add_vm_enable_kvm(self, **options):
+ """
+ 'enable': 'yes'
+ """
+ if 'enable' in options.keys() and \
+ options['enable'] == 'yes':
+ enable_kvm_boot_line = '-enable-kvm'
+ self.__add_boot_line(enable_kvm_boot_line)
+
+ def set_vm_name(self, vm_name):
+ """
+ Set VM name.
+ """
+ self.params.append({'name': [{'name': '%s' % vm_name}]})
+
+ def add_vm_name(self, **options):
+ """
+ name: vm1
+ """
+ if 'name' in options.keys() and \
+ options['name']:
+ name_boot_line = '-name %s' % options['name']
+ self.__add_boot_line(name_boot_line)
+
+ def add_vm_cpu(self, **options):
+ """
+ model: [host | core2duo | ...]
+ usage:
+ choose model value from the command
+ qemu-system-x86_64 -cpu help
+ number: '4' #number of vcpus
+ cpupin: '3 4 5 6' # host cpu list
+ """
+ if 'model' in options.keys() and \
+ options['model']:
+ cpu_boot_line = '-cpu %s' % options['model']
+ self.__add_boot_line(cpu_boot_line)
+ if 'number' in options.keys() and \
+ options['number']:
+ smp_cmd_line = '-smp %d' % int(options['number'])
+ self.__add_boot_line(smp_cmd_line)
+ if 'cpupin' in options.keys() and \
+ options['cpupin']:
+ self.vcpus_pinned_to_vm = str(options['cpupin'])
+
+ def add_vm_mem(self, **options):
+ """
+ size: 1024
+ """
+ if 'size' in options.keys():
+ mem_boot_line = '-m %s' % options['size']
+ self.__add_boot_line(mem_boot_line)
+
+ def add_vm_disk(self, **options):
+ """
+ file: /home/image/test.img
+ """
+ if 'file' in options.keys():
+ disk_boot_line = '-drive file=%s' % options['file']
+ self.__add_boot_line(disk_boot_line)
+
+ def add_vm_net(self, **options):
+ """
+ Add VM net device.
+ type: [nic | user | tap | bridge | ...]
+ opt_[vlan | fd | br | mac | ...]
+ note:the sub-option will be decided according to the net type.
+ """
+ if 'type' in options.keys():
+ if 'opt_vlan' not in options.keys():
+ options['opt_vlan'] = '0'
+ if options['type'] == 'nic':
+ self.__add_vm_net_nic(**options)
+ if options['type'] == 'user':
+ self.__add_vm_net_user(**options)
+ if options['type'] == 'tap':
+ self.__add_vm_net_tap(**options)
+
+ if options['type'] == 'user':
+ self.net_type = 'hostfwd'
+ elif options['type'] in ['tap', 'bridge']:
+ self.net_type = 'bridge'
+
+ def __add_vm_net_nic(self, **options):
+ """
+ type: nic
+ opt_vlan: 0
+ note: Default is 0.
+ opt_macaddr: 00:00:00:00:01:01
+ note: if creating a nic, it`s better to specify a MAC,
+ else it will get a random number.
+ opt_model:["e1000" | "virtio" | "i82551" | ...]
+ note: Default is e1000.
+ opt_name: 'nic1'
+ opt_addr: ''
+ note: PCI cards only.
+ opt_vectors:
+ note: This option currently only affects virtio cards.
+ """
+ net_boot_line = '-net nic'
+ separator = ','
+ if 'opt_vlan' in options.keys() and \
+ options['opt_vlan']:
+ net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
+
+ # add MAC info
+ if 'opt_macaddr' in options.keys() and \
+ options['opt_macaddr']:
+ mac = options['opt_macaddr']
+ else:
+ mac = self.generate_unique_mac()
+ net_boot_line += separator + 'macaddr=%s' % mac
+
+ if 'opt_model' in options.keys() and \
+ options['opt_model']:
+ net_boot_line += separator + 'model=%s' % options['opt_model']
+ if 'opt_name' in options.keys() and \
+ options['opt_name']:
+ net_boot_line += separator + 'name=%s' % options['opt_name']
+ if 'opt_addr' in options.keys() and \
+ options['opt_addr']:
+ net_boot_line += separator + 'addr=%s' % options['opt_addr']
+ if 'opt_vectors' in options.keys() and \
+ options['opt_vectors']:
+ net_boot_line += separator + 'vectors=%s' % options['opt_vectors']
+
+ if self.__string_has_multi_fields(net_boot_line, separator):
+ self.__add_boot_line(net_boot_line)
+
+ def __add_vm_net_user(self, **options):
+ """
+ type: user
+ opt_vlan: 0
+ note: default is 0.
+ opt_hostfwd: [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport
+ """
+ net_boot_line = '-net user'
+ separator = ','
+ if 'opt_vlan' in options.keys() and \
+ options['opt_vlan']:
+ net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
+ if 'opt_hostfwd' in options.keys() and \
+ options['opt_hostfwd']:
+ self.__check_net_user_opt_hostfwd(options['opt_hostfwd'])
+ opt_hostfwd = options['opt_hostfwd']
+ else:
+ opt_hostfwd = '::-:'
+ hostfwd_line = self.__parse_net_user_opt_hostfwd(opt_hostfwd)
+ net_boot_line += separator + 'hostfwd=%s' % hostfwd_line
+
+ if self.__string_has_multi_fields(net_boot_line, separator):
+ self.__add_boot_line(net_boot_line)
+
+ def __check_net_user_opt_hostfwd(self, opt_hostfwd):
+ """
+ Use regular expression to check if hostfwd value format is correct.
+ """
+ regx_ip = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
+ regx_hostfwd = r'["tcp" | "udp"]?:%s?:\d+-%s?:\d+' % (regx_ip, regx_ip)
+ if not re.match(regx_hostfwd, opt_hostfwd):
+ raise Exception("Option opt_hostfwd format is not correct,\n" +
+ "it is %s,\n " % opt_hostfwd +
+ "it should be [tcp|udp]:[hostaddr]:hostport-" +
+ "[guestaddr]:guestport.\n")
+
+ def __parse_net_user_opt_hostfwd(self, opt_hostfwd):
+ """
+ Parse the boot option 'hostfwd'.
+ """
+ separator = ':'
+ field = lambda option, index, separator=':': \
+ option.split(separator)[index]
+
+ # get the forword type
+ fwd_type = field(opt_hostfwd, 0)
+ if not fwd_type:
+ fwd_type = 'tcp'
+
+ # get the host addr
+ host_addr = field(opt_hostfwd, 1)
+ if not host_addr:
+ host_addr = str(self.host_dut.get_ip_address())
+
+ # get the host port in the option
+ host_port = field(opt_hostfwd, 2).split('-')[0]
+ if not host_port:
+ host_port = str(self.virt_pool.alloc_port(self.vm_name))
+ self.redir_port = host_port
+
+ # get the guest addr
+ try:
+ guest_addr = str(field(opt_hostfwd, 2).split('-')[1])
+ except IndexError as e:
+ guest_addr = ''
+
+ # get the guest port in the option
+ guest_port = str(field(opt_hostfwd, 3))
+ if not guest_port:
+ guest_port = '22'
+
+ hostfwd_line = fwd_type + separator + \
+ host_addr + separator + \
+ host_port + \
+ '-' + \
+ guest_addr + separator + \
+ guest_port
+
+ # init the redirect incoming TCP or UDP connections
+ # just combine host address and host port, it is enough
+ # for using ssh to connect with VM
+ self.hostfwd_addr = host_addr + separator + host_port
+
+ return hostfwd_line
+
+ def __add_vm_net_tap(self, **options):
+ """
+ type: tap
+ opt_vlan: 0
+ note: default is 0.
+ opt_br: br0
+ note: if choosing tap, need to specify bridge name,
+ else it will be br0.
+ opt_script: QEMU_IFUP_PATH
+ note: if not specified, default is self.QEMU_IFUP_PATH.
+ opt_downscript: QEMU_IFDOWN_PATH
+ note: if not specified, default is self.QEMU_IFDOWN_PATH.
+ """
+ net_boot_line = '-net tap'
+ separator = ','
+
+ # add bridge info
+ if 'opt_br' in options.keys() and \
+ options['opt_br']:
+ bridge = options['opt_br']
+ else:
+ bridge = self.DEFAULT_BRIDGE
+ self.__generate_net_config_script(str(bridge))
+
+ if 'opt_vlan' in options.keys() and \
+ options['opt_vlan']:
+ net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
+
+ # add network configure script path
+ if 'opt_script' in options.keys() and \
+ options['opt_script']:
+ script_path = options['opt_script']
+ else:
+ script_path = self.QEMU_IFUP_PATH
+ net_boot_line += separator + 'script=%s' % script_path
+
+ # add network configure downscript path
+ if 'opt_downscript' in options.keys() and \
+ options['opt_downscript']:
+ net_boot_line += separator + \
+ 'downscript=%s' % options['opt_downscript']
+
+ if self.__string_has_multi_fields(net_boot_line, separator):
+ self.__add_boot_line(net_boot_line)
+
+ def __generate_net_config_script(self, switch=DEFAULT_BRIDGE):
+ """
+ Generate a script for qemu emulator to build a tap device
+ between host and guest.
+ """
+ qemu_ifup = self.QEMU_IFUP % {'switch': switch}
+ file_name = os.path.basename(self.QEMU_IFUP_PATH)
+ tmp_file_path = '/tmp/%s' % file_name
+ self.host_dut.create_file(qemu_ifup, tmp_file_path)
+ self.host_session.send_expect('mv -f ~/%s %s' % (file_name,
+ self.QEMU_IFUP_PATH), '# ')
+ self.host_session.send_expect(
+ 'chmod +x %s' % self.QEMU_IFUP_PATH, '# ')
+
+ def set_vm_device(self, driver='pci-assign', **props):
+ """
+ Set VM device with specified driver.
+ """
+ props['driver'] = driver
+ index = self.find_option_index('device')
+ if index:
+ self.params[index]['device'].append(props)
+ else:
+ self.params.append({'device': [props]})
+
+ def add_vm_device(self, **options):
+ """
+ driver: [pci-assign | virtio-net-pci | ...]
+ prop_[host | addr | ...]: value
+ note:the sub-property will be decided according to the driver.
+ """
+ if 'driver' in options.keys() and \
+ options['driver']:
+ if options['driver'] == 'pci-assign':
+ self.__add_vm_pci_assign(**options)
+ elif options['driver'] == 'virtio-net-pci':
+ self.__add_vm_virtio_net_pci(**options)
+
+ def __add_vm_pci_assign(self, **options):
+ """
+ driver: pci-assign
+ prop_host: 08:00.0
+ prop_addr: 00:00:00:00:01:02
+ """
+ dev_boot_line = '-device pci-assign'
+ separator = ','
+ if 'prop_host' in options.keys() and \
+ options['prop_host']:
+ dev_boot_line += separator + 'host=%s' % options['prop_host']
+ if 'prop_addr' in options.keys() and \
+ options['prop_addr']:
+ dev_boot_line += separator + 'addr=%s' % options['prop_addr']
+ self.assigned_pcis.append(options['prop_addr'])
+
+ if self.__string_has_multi_fields(dev_boot_line, separator):
+ self.__add_boot_line(dev_boot_line)
+
+ def __add_vm_virtio_net_pci(self, **options):
+ """
+ driver: virtio-net-pci
+ prop_netdev: mynet1
+ prop_id: net1
+ prop_mac: 00:00:00:00:01:03
+ prop_bus: pci.0
+ prop_addr: 0x3
+ """
+ dev_boot_line = '-device virtio-net-pci'
+ separator = ','
+ if 'prop_netdev' in options.keys() and \
+ options['prop_netdev']:
+ dev_boot_line += separator + 'netdev=%s' % options['prop_netdev']
+ if 'prop_id' in options.keys() and \
+ options['prop_id']:
+ dev_boot_line += separator + 'id=%s' % options['prop_id']
+ if 'prop_mac' in options.keys() and \
+ options['prop_mac']:
+ dev_boot_line += separator + 'mac=%s' % options['prop_mac']
+ if 'prop_bus' in options.keys() and \
+ options['prop_bus']:
+ dev_boot_line += separator + 'bus=%s' % options['prop_bus']
+ if 'prop_addr' in options.keys() and \
+ options['prop_addr']:
+ dev_boot_line += separator + 'addr=%s' % options['prop_addr']
+
+ if self.__string_has_multi_fields(self, string, separator):
+ self.__add_boot_line(dev_boot_line)
+
+ def __string_has_multi_fields(self, string, separator, field_num=2):
+ """
+ Check if string has multiple fields which is splited with
+ specified separator.
+ """
+ fields = string.split(separator)
+ number = 0
+ for field in fields:
+ if field:
+ number += 1
+ if number >= field_num:
+ return True
+ else:
+ return False
+
+ def add_vm_monitor(self, **options):
+ """
+ port: 6061 # if adding monitor to vm, need to specicy
+ this port, else it will get a free port
+ on the host machine.
+ """
+ if 'port' in options.keys():
+ if options['port']:
+ port = options['port']
+ else:
+ port = self.virt_pool.alloc_port(self.vm_name)
+
+ monitor_boot_line = '-monitor tcp::%d,server,nowait' % int(port)
+ self.__add_boot_line(monitor_boot_line)
+
+ def set_vm_qga(self, enable='yes'):
+ """
+ Set VM qemu-guest-agent.
+ """
+ index = self.find_option_index('qga')
+ if index:
+ self.params[index] = {'qga': [{'enable': '%s' % enable}]}
+ else:
+ self.params.append({'qga': [{'enable': '%s' % enable}]})
+ QGA_SOCK_PATH = QGA_SOCK_PATH_TEMPLATE % {'vm_name': self.vm_name}
+ self.qga_sock_path = QGA_SOCK_PATH
+
+ def add_vm_qga(self, **options):
+ """
+ enable: 'yes'
+ """
+ QGA_DEV_ID = '%(vm_name)s_qga0' % {'vm_name': self.vm_name}
+ QGA_SOCK_PATH = QGA_SOCK_PATH_TEMPLATE % {'vm_name': self.vm_name}
+
+ separator = ' '
+
+ if 'enable' in options.keys():
+ if options['enable'] == 'yes':
+ qga_boot_block = '-chardev socket,path=%(SOCK_PATH)s,server,nowait,id=%(ID)s' + \
+ separator + '-device virtio-serial' + separator + \
+ '-device virtserialport,chardev=%(ID)s,name=%(DEV_NAME)s'
+ qga_boot_line = qga_boot_block % {'SOCK_PATH': QGA_SOCK_PATH,
+ 'DEV_NAME': QGA_DEV_NAME,
+ 'ID': QGA_DEV_ID}
+ self.__add_boot_line(qga_boot_line)
+ self.qga_sock_path = QGA_SOCK_PATH
+ else:
+ self.qga_sock_path = ''
+
+ def add_vm_serial_port(self, **options):
+ """
+ enable: 'yes'
+ """
+ SERAIL_SOCK_PATH = "/tmp/%s_serial.sock" % self.vm_name
+ if 'enable' in options.keys():
+ if options['enable'] == 'yes':
+ serial_boot_line = '-serial unix:%s,server,nowait' % SERIAL_SOCK_PATH
+ self.__add_boot_line(serial_boot_line)
+ else:
+ pass
+
+ def add_vm_vnc(self, **options):
+ """
+ displayNum: 1
+ """
+ if 'displayNum' in options.keys() and \
+ options['displayNum']:
+ display_num = options['displayNum']
+ else:
+ display_num = self.virt_pool.alloc_vnc_num(self.vm_name)
+
+ vnc_boot_line = '-vnc :%d' % int(display_num)
+ self.__add_boot_line(vnc_boot_line)
+
+ def set_vm_daemon(self, enable='yes'):
+ """
+ Set VM daemon option.
+ """
+ index = self.find_option_index('daemon')
+ if index:
+ self.params[index] = {'daemon': [{'enable': '%s' % enable}]}
+ else:
+ self.params.append({'daemon': [{'enable': '%s' % enable}]})
+
+ def add_vm_daemon(self, **options):
+ """
+ enable: 'yes'
+ note:
+ By default VM will start with the daemonize status.
+ Not support starting it on the stdin now.
+ """
+ if 'daemon' in options.keys() and \
+ options['enable'] == 'no':
+ pass
+ else:
+ daemon_boot_line = '-daemonize'
+ self.__add_boot_line(daemon_boot_line)
+
+ def start_vm(self):
+ """
+ Start VM.
+ """
+ qemu_emulator = self.qemu_emulator
+
+ self.__alloc_assigned_pcis()
+
+ if self.vcpus_pinned_to_vm.strip():
+ vcpus = self.__alloc_vcpus()
+
+ if vcpus.strip():
+ whole_qemu_kvm_boot_line = 'taskset -c %s ' % vcpus + \
+ qemu_emulator + ' ' + \
+ self.whole_qemu_kvm_boot_line
+ else:
+ whole_qemu_kvm_boot_line = qemu_emulator + ' ' + \
+ self.whole_qemu_kvm_boot_line
+
+ # Start VM using the qemu command
+ out = self.host_session.send_expect(whole_qemu_kvm_boot_line, '# ')
+ time.sleep(30)
+ if out:
+ raise StartVMFailedException(out)
+
+ def __alloc_vcpus(self):
+ """
+ Allocate virtual CPUs for VM.
+ """
+ req_cpus = self.vcpus_pinned_to_vm.split()
+ cpus = self.virt_pool.alloc_cpu(vm=self.vm_name, corelist=req_cpus)
+
+ vcpus_pinned_to_vm = ''
+ for cpu in cpus:
+ vcpus_pinned_to_vm += ',' + cpu
+ vcpus_pinned_to_vm = vcpus_pinned_to_vm.lstrip(',')
+
+ if len(req_cpus) != len(cpus):
+ print "WARNING: Just pin vcpus [ %s ] to VM!" % vcpus_pinned_to_vm
+
+ return vcpus_pinned_to_vm
+
+ def __alloc_assigned_pcis(self):
+ """
+ Record the PCI device info
+ Struct: {dev pci: {'is_vf': [True | False],
+ 'pf_pci': pci}}
+ example:
+ {'08:10.0':{'is_vf':True, 'pf_pci': 08:00.0}}
+ """
+ assigned_pcis_info = {}
+ for pci in self.assigned_pcis:
+ assigned_pcis_info[pci] = {}
+ if self.__is_vf_pci(pci):
+ assigned_pcis_info[pci]['is_vf'] = True
+ pf_pci = self.__map_vf_to_pf(pci)
+ assgined_pcis_info[pci]['pf_pci'] = pf_pci
+ if self.virt_pool.alloc_vf_from_pf(vm=self.vm_name,
+ pf_pci=pf_pci,
+ *[pci]):
+ port = self.__get_vf_port(pci)
+ port.unbind_driver()
+ port.bind_driver('pci-stub')
+ else:
+ # check that if any VF of specified PF has been
+ # used, raise exception
+ vf_pci = self.__vf_has_been_assinged(pci, **assinged_pcis_info)
+ if vf_pci:
+ raise Exception(
+ "Error: A VF [%s] generated by PF [%s] has " %
+ (vf_pci, pci) +
+ "been assigned to VM, so this PF can not be " +
+ "assigned to VM again!")
+ # get the port instance of PF
+ port = self.__get_net_device_by_pci(pci)
+
+ if self.virt_pool.alloc_pf(vm=self.vm_name,
+ *[pci]):
+ port.unbind_driver()
+
+ def __is_vf_pci(self, dev_pci):
+ """
+ Check if the specified PCI dev is a VF.
+ """
+ for port_info in self.host_dut.ports_info:
+ if 'sriov_vfs_pci' in port_info.keys():
+ if dev_pci in port_info['sriov_vfs_pci']:
+ return True
+ return False
+
+ def __map_vf_to_pf(self, dev_pci):
+ """
+ Map the specified VF to PF.
+ """
+ for port_info in self.host_dut.ports_info:
+ if 'sriov_vfs_pci' in port_info.keys():
+ if dev_pci in port_info['sriov_vfs_pci']:
+ return port_info['pci']
+ return None
+
+ def __get_vf_port(self, dev_pci):
+ """
+ Get the NetDevice instance of specified VF.
+ """
+ for port_info in self.host_dut.ports_info:
+ if 'vfs_port' in port_info.keys():
+ for port in port_info['vfs_port']:
+ if dev_pci == port.pci:
+ return port
+ return None
+
+ def __vf_has_been_assigned(self, pf_pci, **assigned_pcis_info):
+ """
+ Check if the specified VF has been used.
+ """
+ for pci in assigned_pcis_info.keys():
+ if assigned_pcis_info[pci]['is_vf'] and \
+ assigned_pcis_info[pci]['pf_pci'] == pf_pci:
+ return pci
+ return False
+
+ def __get_net_device_by_pci(self, net_device_pci):
+ """
+ Get NetDevice instance by the specified PCI bus number.
+ """
+ port_info = self.host_dut.get_port_info(net_device_pci)
+ return port_info['port']
+
+ def get_vm_ip(self):
+ """
+ Get VM IP.
+ """
+ get_vm_ip = getattr(self, "get_vm_ip_%s" % self.net_type)
+ return get_vm_ip()
+
+ def get_vm_ip_hostfwd(self):
+ """
+ Get IP which VM is connected by hostfwd.
+ """
+ return self.hostfwd_addr
+
+ def get_vm_ip_bridge(self):
+ """
+ Get IP which VM is connected by bridge.
+ """
+ out = self.__control_session('ping', '60')
+ if not out:
+ time.sleep(10)
+ out = self.__control_session('ifconfig')
+ ips = re.findall(r'inet (\d+\.\d+\.\d+\.\d+)', out)
+
+ if '127.0.0.1' in ips:
+ ips.remove('127.0.0.1')
+
+ num = 3
+ for ip in ips:
+ out = self.host_session.send_expect(
+ 'ping -c %d %s' % (num, ip), '# ')
+ if '0% packet loss' in out:
+ return ip
+ return ''
+
+ def __control_session(self, command, *args):
+ """
+ Use the qemu guest agent service to control VM.
+ Note:
+ :command: there are these commands as below:
+ cat, fsfreeze, fstrim, halt, ifconfig, info,\
+ ping, powerdown, reboot, shutdown, suspend
+ :args: give different args by the different commands.
+ """
+ if not self.qga_sock_path:
+ self.host_logger.info(
+ "No QGA service between host [ %s ] and guest [ %s ]" %
+ (self.host_dut.Name, self.vm_name))
+ return None
+
+ cmd_head = '~/QMP/' + \
+ "qemu-ga-client " + \
+ "--address=%s %s" % \
+ (self.qga_sock_path, command)
+
+ cmd = cmd_head
+ for arg in args:
+ cmd = cmd_head + ' ' + str(arg)
+
+ out = self.host_session.send_expect(cmd, '# ')
+
+ return out
+
+ def stop(self):
+ """
+ Stop VM.
+ """
+ self.__control_session('powerdown')
+ time.sleep(5)
+ self.virt_pool.free_all_resource(self.vm_name)
+
+
+if __name__ == "__main__":
+ import subprocess
+ import sys
+ import pdb
+ from serializer import Serializer
+ from crbs import crbs
+ from tester import Tester
+ from dut import Dut
+ import dts
+ from virt_proxy import VirtProxy
+
+ command = "ifconfig br0"
+ subp = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
+ subp.wait()
+
+ intf_info = subp.stdout.readlines()
+ for line_info in intf_info:
+ regx = re.search(r'inet (\d+\.\d+\.\d+\.\d+)', line_info)
+ if regx:
+ dutIP = regx.group(1)
+ break
+
+ print "DEBUG: dutIp: ", dutIP
+
+ # look up in crbs - to find the matching IP
+ crbInst = None
+ for crb in crbs:
+ if crb['IP'] == dutIP:
+ crbInst = crb
+ break
+
+ # only run on the dut in known crbs
+ if crbInst is None:
+ raise Exception("No available crb instance!!!")
+
+ # initialize the dut and tester
+ serializer = Serializer()
+ serializer.set_serialized_filename('../.%s.cache' % crbInst['IP'])
+ serializer.load_from_file()
+
+ read_cache = None
+ skip_setup = None
+
+ project = "dpdk"
+ dts.Package = 'dep/dpdk.tar.gz'
+ dut = dts.get_project_obj(project, Dut, crbInst, serializer)
+ tester = dts.get_project_obj(project, Tester, crbInst, serializer)
+ dut.tester = tester
+ dut.base_dir = 'dpdk'
+ dut.set_nic_type('niantic')
+ tester.dut = dut
+
+ tester.set_test_types(True, False)
+ dut.set_test_types(True, False)
+
+ tester.set_speedup_options(read_cache, skip_setup)
+ tester.tester_prerequisites()
+ dut.set_speedup_options(read_cache, skip_setup)
+ dut.dut_prerequisites()
+
+ # test that generating and destroying VF
+ port0 = dut.ports_info[0]['port']
+ dut.generate_sriov_vfs_by_port(0, 4)
+ print "port 0 sriov vfs: ", dut.ports_info[0]
+
+ dut.destroy_sriov_vfs_by_port(0)
+
+ time.sleep(2)
+
+ # test that binding and unbing the NIC
+ port0_pci = dut.ports_info[0]['pci']
+ port0.unbind_driver()
+
+ dut.logger.info("JUST TESTING!!!")
+
+ # Start VM by the qemu kvm config file
+ vm1 = QEMUKvm(dut, 'vm1', 'pmd_sriov')
+ print "VM config params:"
+ print vm1.params
+ vm1_dut = vm1.start()
+
+ try:
+ host_ip = vm1.session.send_expect("ifconfig", '# ')
+ print "Host IP:"
+ print host_ip
+
+ vm1_ip = vm1.get_vm_ip()
+ print "VM1 IP:"
+ print vm1_ip
+
+ print "VM1 PCI device:"
+ print vm_dut.session.send_expect('lspci -nn | grep -i eth', '# ')
+ except Exception as e:
+ print e
+ vm1_dut.stop()
+ port0.bind_driver()
+ # Stop VM
+ vm1.stop()
+ port0.bind_driver()
+
+ dut.host_logger.logger_exit()
+ dut.logger.logger_exit()
+ tester.logger.logger_exit()
+
+ print "Start and stop VM over!"
diff --git a/framework/virt_base.py b/framework/virt_base.py
new file mode 100644
index 0000000..625c309
--- /dev/null
+++ b/framework/virt_base.py
@@ -0,0 +1,250 @@
+# <COPYRIGHT_TAG>
+
+from random import randint
+from itertools import imap
+
+import dts
+from dut import Dut
+from config import VirtConf
+from config import VIRTCONF
+from logger import getLogger
+from settings import CONFIG_ROOT_PATH
+from virt_dut import VirtDut
+
+
+class VirtBase(object):
+
+ """
+ Basic module for customer special virtual type. This module implement functions
+ configurated and composed the VM boot command. With these function, we can get
+ and set the VM boot command, and instantiate the VM.
+ """
+
+ def __init__(self, dut, vm_name, suite_name):
+ """
+ Initialize the VirtBase.
+ dut: the instance of Dut
+ vm_name: the name of VM which you have confiured in the configure
+ suite_name: the name of test suite
+ """
+ self.host_dut = dut
+ self.vm_name = vm_name
+ self.suite = suite_name
+
+ # init the host session and logger for VM
+ self.host_dut.init_host_session()
+
+ # replace dut session
+ self.host_session = self.host_dut.host_session
+ self.host_logger = self.host_dut.logger
+
+ # init the host resouce pool for VM
+ self.virt_pool = self.host_dut.virt_pool
+
+ if not self.has_virtual_ability():
+ if not self.enable_virtual_ability():
+ raise Exception(
+ "Dut [ %s ] cannot have the virtual ability!!!")
+
+ self.virt_type = self.get_virt_type()
+ self.load_global_config()
+ self.load_local_config(suite_name)
+
+ def get_virt_type(self):
+ """
+ Get the virtual type, such as KVM, XEN or LIBVIRT.
+ """
+ NotImplemented
+
+ def has_virtual_ability(self):
+ """
+ Check if the host have the ability of virtualization.
+ """
+ NotImplemented
+
+ def enable_virtual_ability(self):
+ """
+ Enalbe the virtual ability on the DUT.
+ """
+ NotImplemented
+
+ def load_global_config(self):
+ """
+ Load global configure in the path DTS_ROOT_PAHT/conf.
+ """
+ conf = VirtConf(VIRTCONF)
+ conf.load_virt_config(self.virt_type)
+ self.params = conf.get_virt_config()
+
+ def load_local_config(self, suite_name):
+ """
+ Load local configure in the path DTS_ROOT_PATH/conf.
+ """
+ # load local configuration by suite and vm name
+ conf = VirtConf(CONFIG_ROOT_PATH + suite_name + '.cfg')
+ conf.load_virt_config(self.vm_name)
+ localparams = conf.get_virt_config()
+ # replace global configurations with local configurations
+ for param in localparams:
+ if 'mem' in param.keys():
+ self.__save_local_config('mem', param['mem'])
+ continue
+ if 'cpu' in param.keys():
+ self.__save_local_config('cpu', param['cpu'])
+ continue
+ # save local configurations
+ self.params.append(param)
+
+ def __save_local_config(self, key, value):
+ """
+ Save the local config into the global dict self.param.
+ """
+ for param in self.params:
+ if key in param.keys():
+ param[key] = value
+
+ def compose_boot_param(self):
+ """
+ Compose all boot param for starting the VM.
+ """
+ for param in self.params:
+ key = param.keys()[0]
+ value = param[key]
+ try:
+ param_func = getattr(self, 'add_vm_' + key)
+ if callable(param_func):
+ for option in value:
+ param_func(**option)
+ else:
+ print "Virt %s function not implemented!!!" % key
+ except Exception as e:
+ print "Failed: ", e
+
+ def find_option_index(self, option):
+ """
+ Find the boot option in the params which is generated from
+ the global and local configures, and this function will
+ return the index by which option can be indexed in the
+ param list.
+ """
+ index = 0
+ for param in self.params:
+ key = param.keys()[0]
+ if key.strip() == option.strip():
+ return index
+ index += 1
+
+ return None
+
+ def generate_unique_mac(self):
+ """
+ Generate a unique MAC based on the DUT.
+ """
+ mac_head = '00:00:00:'
+ mac_tail = ':'.join(
+ ['%02x' % x for x in imap(lambda x:randint(0, 255), range(3))])
+ return mac_head + mac_tail
+
+ def get_vm_ip(self):
+ """
+ Get the VM IP.
+ """
+ NotImplemented
+
+ def start(self):
+ """
+ Start VM and instantiate the VM with VirtDut.
+ """
+ self.compose_boot_param()
+ try:
+ self.start_vm()
+ except Exception as e:
+ self.host_logger.error(e)
+ return None
+ try:
+ vm_dut = self.instantiate_vm_dut()
+ except Exception as e:
+ self.host_logger.error(e)
+ self.stop()
+ return None
+ return vm_dut
+
+ def start_vm(self):
+ """
+ Start VM.
+ """
+ NotImplemented
+
+ def instantiate_vm_dut(self):
+ """
+ Instantiate the Dut class for VM.
+ """
+ crb = self.host_dut.crb.copy()
+ crb['bypass core0'] = False
+ vm_ip = self.get_vm_ip()
+ crb['IP'] = vm_ip
+ if ':' not in vm_ip:
+ remote_ip = vm_ip.strip()
+ redirect_port = ''
+ else:
+ remote_addr = vm_ip.split(':')
+ remote_ip = remote_addr[0].strip()
+ redirect_port = remote_addr[1].strip()
+ self.__remove_old_rsa_key(remote_ip, redirect_port)
+
+ serializer = self.host_dut.serializer
+
+ try:
+ vm_dut = VirtDut(
+ crb,
+ serializer,
+ self.virt_type,
+ self.vm_name,
+ self.suite)
+ except Exception as e:
+ raise Exception(e)
+ vm_dut.nic_type = 'any'
+ vm_dut.tester = self.host_dut.tester
+ vm_dut.host_dut = self.host_dut
+ vm_dut.host_session = self.host_session
+
+ read_cache = False
+ skip_setup = self.host_dut.skip_setup
+ base_dir = self.host_dut.base_dir
+ vm_dut.set_speedup_options(read_cache, skip_setup)
+ func_only = self.host_dut.want_func_tests
+ perf_only = self.host_dut.want_perf_tests
+ vm_dut.set_test_types(func_tests=func_only, perf_tests=perf_only)
+ # base_dir should be set before prerequisites
+ vm_dut.set_directory(base_dir)
+
+ # setting up dpdk in vm, must call at last
+ vm_dut.prerequisites(dts.Package, dts.Patches)
+
+ target = self.host_dut.target
+ if target:
+ vm_dut.set_target(target)
+ else:
+ raise Exception("Cannot get the HOST DUT test target!")
+
+ return vm_dut
+
+ def __remove_old_rsa_key(self, remote_ip, redirect_port):
+ """
+ Remove the old RSA key of specified remote IP.
+ """
+ rsa_key_path = "~/.ssh/known_hosts"
+ if redirect_port:
+ remove_rsa_key_cmd = "sed -i '/^\[%s\]:%d/d' %s" % \
+ (remote_ip.strip(), int(
+ redirect_port), rsa_key_path)
+ else:
+ remove_rsa_key_cmd = "sed -i '/^%s/d' %s" % \
+ (remote_ip.strip(), rsa_key_path)
+ self.host_dut.tester.send_expect(remove_rsa_key_cmd, "# ")
+
+ def stop(self):
+ """
+ Stop the VM by the name of VM.
+ """
+ NotImplemented
diff --git a/framework/virt_dut.py b/framework/virt_dut.py
new file mode 100644
index 0000000..1073253
--- /dev/null
+++ b/framework/virt_dut.py
@@ -0,0 +1,239 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2015 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.
+
+import os
+import re
+import time
+import dts
+import settings
+from config import PortConf
+from settings import NICS, LOG_NAME_SEP
+from ssh_connection import SSHConnection
+from project_dpdk import DPDKdut
+from dut import Dut
+from net_device import NetDevice
+from logger import getLogger
+
+
+class VirtDut(DPDKdut):
+
+ """
+ A connection to the CRB under test.
+ This class sends commands to the CRB and validates the responses. It is
+ implemented using either ssh for linuxapp or the terminal server for
+ baremetal.
+ All operations are in fact delegated to an instance of either CRBLinuxApp
+ or CRBBareMetal.
+ """
+
+ def __init__(self, crb, serializer, virttype, vm_name, suite):
+ super(Dut, self).__init__(crb, serializer)
+ self.vm_ip = self.get_ip_address()
+ self.NAME = 'virtdut' + LOG_NAME_SEP + '%s' % self.vm_ip
+ # load port config from suite cfg
+ self.suite = suite
+ self.logger = getLogger(self.NAME)
+ self.logger.config_execution('vmdut')
+ self.session = SSHConnection(self.vm_ip, self.NAME,
+ self.get_password())
+ self.session.init_log(self.logger)
+
+ # if redirect ssh port, there's only one session enabled
+ self.alt_session = SSHConnection(self.vm_ip, self.NAME + '_alt',
+ self.get_password())
+ self.alt_session.init_log(self.logger)
+
+ self.number_of_cores = 0
+ self.tester = None
+ self.cores = []
+ self.architecture = None
+ self.ports_info = None
+ self.ports_map = []
+ self.virttype = virttype
+ self.vmtype = ''
+ if self.virttype == 'XEN':
+ self.vmtype = 'domu'
+ self.virttype = 'host'
+
+ def set_nic_type(self, nic_type):
+ """
+ Set CRB NICS ready to validated.
+ """
+ self.nic_type = nic_type
+ # vm_dut config will load from vm configuration file
+
+ def load_portconf(self):
+ """
+ Load port config for this virtual machine
+ """
+ return
+
+ def set_target(self, target):
+ """
+ Set env variable, these have to be setup all the time. Some tests
+ need to compile example apps by themselves and will fail otherwise.
+ Set hugepage on DUT and install modules required by DPDK.
+ Configure default ixgbe PMD function.
+ """
+ self.set_toolchain(target)
+
+ # set env variable
+ # These have to be setup all the time. Some tests need to compile
+ # example apps by themselves and will fail otherwise.
+ self.send_expect("export RTE_TARGET=" + target, "#")
+ self.send_expect("export RTE_SDK=`pwd`", "#")
+
+ if not self.skip_setup:
+ self.build_install_dpdk(target)
+
+ self.setup_memory(hugepages=512)
+ self.setup_modules(target)
+
+ self.bind_interfaces_linux('igb_uio')
+
+ def prerequisites(self, pkgName, patch):
+ """
+ Prerequest function should be called before execute any test case.
+ Will call function to scan all lcore's information which on DUT.
+ Then call pci scan function to collect nic device information.
+ At last setup DUT' environment for validation.
+ """
+ self.prepare_package(pkgName, patch)
+
+ self.send_expect("cd %s" % self.base_dir, "# ")
+ self.host_session.send_expect("cd %s" % self.base_dir, "# ")
+ self.send_expect("alias ls='ls --color=none'", "#")
+
+ if self.get_os_type() == 'freebsd':
+ self.send_expect('alias make=gmake', '# ')
+ self.send_expect('alias sed=gsed', '# ')
+
+ self.init_core_list()
+ self.pci_devices_information()
+
+ # scan ports before restore interface
+ self.scan_ports()
+ # restore dut ports to kernel
+ if self.vmtype != 'domu':
+ self.restore_interfaces()
+ else:
+ self.restore_interfaces_domu()
+ # rescan ports after interface up
+ self.rescan_ports()
+
+ # no need to rescan ports for guest os just bootup
+ # load port infor from config file
+ self.load_portconf()
+
+ # enable tester port ipv6
+ self.host_dut.enable_tester_ipv6()
+ self.mount_procfs()
+ # auto detect network topology
+ self.map_available_ports()
+ # disable tester port ipv6
+ self.host_dut.disable_tester_ipv6()
+
+ # print latest ports_info
+ for port_info in self.ports_info:
+ self.logger.info(port_info)
+
+ def restore_interfaces_domu(self):
+ """
+ Restore Linux interfaces.
+ """
+ for port in self.ports_info:
+ pci_bus = port['pci']
+ pci_id = port['type']
+ driver = settings.get_nic_driver(pci_id)
+ if driver is not None:
+ addr_array = pci_bus.split(':')
+ bus_id = addr_array[0]
+ devfun_id = addr_array[1]
+ port = NetDevice(self, bus_id, devfun_id)
+ itf = port.get_interface_name()
+ self.send_expect("ifconfig %s up" % itf, "# ")
+ time.sleep(30)
+ print self.send_expect("ip link ls %s" % itf, "# ")
+ else:
+ self.logger.info(
+ "NOT FOUND DRIVER FOR PORT (%s|%s)!!!" % (pci_bus, pci_id))
+
+ def pci_devices_information(self):
+ self.pci_devices_information_uncached()
+
+ def get_memory_channels(self):
+ """
+ Virtual machine has no memory channel concept, so always return 1
+ """
+ return 1
+
+ def check_ports_available(self, pci_bus, pci_id):
+ """
+ Check that whether auto scanned ports ready to use
+ """
+ pci_addr = "%s:%s" % (pci_bus, pci_id)
+ if pci_id == "8086:100e":
+ return False
+ return True
+ # pci_addr = "%s:%s" % (pci_bus, pci_id)
+ # if self.nic_type == 'any':
+ # load vm port conf need another function
+ # need add vitrual function device into NICS
+
+ def scan_ports(self):
+ """
+ Scan ports information, for vm will always scan
+ """
+ self.scan_ports_uncached()
+
+ def scan_ports_uncached(self):
+ """
+ Scan ports and collect port's pci id, mac adress, ipv6 address.
+ """
+ scan_ports_uncached = getattr(
+ self, 'scan_ports_uncached_%s' % self.get_os_type())
+ return scan_ports_uncached()
+
+ def map_available_ports(self):
+ """
+ Load or generate network connection mapping list.
+ """
+ self.map_available_ports_uncached()
+ self.logger.warning("DUT PORT MAP: " + str(self.ports_map))
+
+ def send_ping6(self, localPort, ipv6, mac=''):
+ """
+ Send ping6 packet from local port with destination ipv6 address.
+ """
+ if self.ports_info[localPort]['type'] == 'ixia':
+ pass
+ else:
+ return self.send_expect("ping6 -w 1 -c 1 -A -I %s %s" % (self.ports_info[localPort]['intf'], ipv6), "# ", 10)
diff --git a/framework/virt_resource.py b/framework/virt_resource.py
new file mode 100644
index 0000000..856f9dc
--- /dev/null
+++ b/framework/virt_resource.py
@@ -0,0 +1,486 @@
+#!/usr/bin/python
+# BSD LICENSE
+#
+# Copyright(c) 2010-2015 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.
+from random import randint
+
+from utils import get_obj_funcs
+
+INIT_FREE_PORT = 6060
+
+
+class VirtResource(object):
+
+ """
+ Class handle dut resource, like cpu, memory, net devices
+ """
+
+ def __init__(self, dut):
+ self.dut = dut
+
+ self.cores = [int(core['thread']) for core in dut.cores]
+ # initialized unused cores
+ self.unused_cores = self.cores[:]
+ # initialized used cores
+ self.used_cores = [-1] * len(self.unused_cores)
+
+ self.ports_info = dut.ports_info
+ # initialized unused ports
+ self.ports = [port['pci'] for port in dut.ports_info]
+ self.unused_ports = self.ports[:]
+ # initialized used ports
+ self.used_ports = ['unused'] * len(self.unused_ports)
+
+ # initialized vf ports
+ self.vfs_info = []
+ self.vfs = []
+ self.unused_vfs = []
+ self.used_vfs = []
+
+ # save allocated cores and related vm
+ self.allocated_info = {}
+
+ def __port_used(self, pci):
+ index = self.ports.index(pci)
+ self.used_ports[index] = pci
+ self.unused_ports[index] = 'used'
+
+ def __port_unused(self, pci):
+ index = self.ports.index(pci)
+ self.unused_ports[index] = pci
+ self.used_ports[index] = 'unused'
+
+ def __port_on_socket(self, pci, socket):
+ for port in self.ports_info:
+ if port['pci'] == pci:
+ if socket is -1:
+ return True
+
+ if port['numa'] == socket:
+ return True
+ else:
+ return False
+
+ return False
+
+ def __vf_used(self, pci):
+ index = self.vfs.index(pci)
+ self.used_vfs[index] = pci
+ self.unused_vfs[index] = 'used'
+
+ def __vf_unused(self, pci):
+ index = self.vfs.index(pci)
+ self.used_vfs[index] = 'unused'
+ self.unused_vfs[index] = pci
+
+ def __core_used(self, core):
+ core = int(core)
+ index = self.cores.index(core)
+ self.used_cores[index] = core
+ self.unused_cores[index] = -1
+
+ def __core_unused(self, core):
+ core = int(core)
+ index = self.cores.index(core)
+ self.unused_cores[index] = core
+ self.used_cores[index] = -1
+
+ def __core_on_socket(self, core, socket):
+ for dut_core in self.dut.cores:
+ if int(dut_core['thread']) == core:
+ if socket is -1:
+ return True
+
+ if int(dut_core['socket']) == socket:
+ return True
+ else:
+ return False
+
+ return False
+
+ def __core_isused(self, core):
+ index = self.cores.index(core)
+ if self.used_cores[index] != -1:
+ return True
+ else:
+ return False
+
+ def reserve_cpu(self, coremask=''):
+ """
+ Reserve dpdk used cpus by mask
+ """
+ val = int(coremask, base=16)
+ cpus = []
+ index = 0
+ while val != 0:
+ if val & 0x1:
+ cpus.append(index)
+
+ val = val >> 1
+ index += 1
+
+ for cpu in cpus:
+ self.__core_used(cpu)
+
+ def alloc_cpu(self, vm='', number=-1, socket=-1, corelist=None):
+ """
+ There're two options for request cpu resouce for vm.
+ If number is not -1, just allocate cpu from not used cores.
+ If list is not None, will allocate cpu after checked.
+ """
+ cores = []
+
+ if vm == '':
+ print "Alloc cpu request vitual machine name!!!"
+ return cores
+
+ if number != -1:
+ for core in self.unused_cores:
+ if core != -1 and number != 0:
+ if self.__core_on_socket(core, socket) is True:
+ self.__core_used(core)
+ cores.append(str(core))
+ number = number - 1
+ if number != 0:
+ print "Can't allocated requested cpu!!!"
+
+ if corelist is not None:
+ for core in corelist:
+ if self.__core_isused(int(core)) is True:
+ print "Core %s has been used!!!" % core
+ else:
+ if self.__core_on_socket(int(core), socket) is True:
+ self.__core_used(int(core))
+ cores.append(core)
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['cores'] = cores
+ return cores
+
+ def __vm_has_resource(self, vm, resource=''):
+ if vm == '':
+ self.dut.logger.info("VM name cannt be NULL!!!")
+ raise Exception("VM name cannt be NULL!!!")
+ if vm not in self.allocated_info:
+ self.dut.logger.info(
+ "There is no resource allocated to VM [%s]." % vm)
+ return False
+ if resource == '':
+ return True
+ if resource not in self.allocated_info[vm]:
+ self.dut.logger.info(
+ "There is no resource [%s] allocated to VM [%s] " %
+ (resource, vm))
+ return False
+ return True
+
+ def free_cpu(self, vm):
+ if self.__vm_has_resource(vm, 'cores'):
+ for core in self.allocated_info[vm]['cores']:
+ self.__core_unused(core)
+ self.allocated_info[vm].pop('cores')
+
+ def alloc_pf(self, vm='', number=-1, socket=-1, pflist=[]):
+ """
+ There're two options for request pf devices for vm.
+ If number is not -1, just allocate pf device from not used pfs.
+ If list is not None, will allocate pf devices after checked.
+ """
+ ports = []
+
+ if number != -1:
+ for pci in self.unused_ports:
+ if pci != 'unused' and number != 0:
+ if self.__port_on_socket(pci, socket) is True:
+ self.__port_used(pci)
+ ports.append(pci)
+ number = number - 1
+ if number != 0:
+ print "Can't allocated requested PF devices!!!"
+
+ if pflist is not None:
+ for pci in pflist:
+ if self.__port_isused(pci) is True:
+ print "Port %s has been used!!!" % pci
+ else:
+ if self.__port_on_socket(pci, socket) is True:
+ self.__port_used(core)
+ ports.append(core)
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['ports'] = ports
+ return ports
+
+ def free_pf(self, vm):
+ if self.__vm_has_resource(vm, 'ports'):
+ for pci in self.allocated_info[vm]['ports']:
+ self.__port_unused(pci)
+ self.allocated_info[vm].pop('ports')
+
+ def alloc_vf_from_pf(self, vm='', pf_pci='', number=-1, vflist=[]):
+ """
+ There're two options for request vf devices of pf device.
+ If number is not -1, just allocate vf device from not used vfs.
+ If list is not None, will allocate vf devices after checked.
+ """
+ vfs = []
+ if vm == '':
+ print "Alloc VF request vitual machine name!!!"
+ return vfs
+
+ if pf_pci == '':
+ print "Alloc VF request PF pci address!!!"
+ return vfs
+
+ for vf_info in self.vfs_info:
+ if vf_info['pf_pci'] == pf_pci:
+ if vf_info['pci'] in vflist:
+ vfs.append(vf_info['pci'])
+ continue
+
+ if number > 0:
+ vfs.append(vf_info['pci'])
+ number = number - 1
+
+ for vf in vfs:
+ self.__vf_used(vf)
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['vfs'] = vfs
+ return vfs
+
+ def free_vf(self, vm):
+ if self.__vm_has_resource(vm, 'vfs'):
+ for pci in self.allocated_info[vm]['vfs']:
+ self.__vf_unused(pci)
+ self.allocated_info[vm].pop('vfs')
+
+ def add_vf_on_pf(self, pf_pci='', vflist=[]):
+ """
+ Add vf devices generated by specified pf devices.
+ """
+ # add vfs into vf info list
+ vfs = []
+ for vf in vflist:
+ if vf not in self.vfs:
+ self.vfs_info.append({'pci': vf, 'pf_pci': pf_pci})
+ vfs.append(vf)
+ used_vfs = ['unused'] * len(vflist)
+ self.unused_vfs += vfs
+ self.used_vfs += used_vfs
+ self.vfs += vfs
+
+ def del_vf_on_pf(self, pf_pci='', vflist=[]):
+ """
+ Remove vf devices generated by specified pf devices.
+ """
+ vfs = []
+ for vf in vflist:
+ for vfs_info in self.vfs_info:
+ if vfs_info['pci'] == vf:
+ vfs.append(vf)
+
+ for vf in vfs:
+ try:
+ index = self.vfs.index(vf)
+ except:
+ continue
+ del self.vfs_info[index]
+ del self.unused_vfs[index]
+ del self.used_vfs[index]
+ del self.vfs[index]
+
+ def alloc_port(self, vm=''):
+ """
+ Allocate unused host port for vm
+ """
+ if vm == '':
+ print "Alloc host port request vitual machine name!!!"
+ return None
+
+ port_start = INIT_FREE_PORT + randint(1, 100)
+ port_step = randint(1, 10)
+ port = None
+ count = 20
+ while True:
+ if self.dut.check_port_occupied(port_start) is False:
+ port = port_start
+ break
+ count -= 1
+ if count < 0:
+ print 'No available port on the host!!!'
+ break
+ port_start += port_step
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['hostport'] = port
+ return port
+
+ def free_port(self, vm):
+ if self.__vm_has_resource(vm, 'hostport'):
+ self.allocated_info[vm].pop('hostport')
+
+ def alloc_vnc_num(self, vm=''):
+ """
+ Allocate unused host VNC display number for VM.
+ """
+ if vm == '':
+ print "Alloc vnc display number request vitual machine name!!!"
+ return None
+
+ max_vnc_display_num = self.dut.get_maximal_vnc_num()
+ free_vnc_display_num = max_vnc_display_num + 1
+
+ if vm not in self.allocated_info:
+ self.allocated_info[vm] = {}
+
+ self.allocated_info[vm]['vnc_display_num'] = free_vnc_display_num
+
+ return free_vnc_display_num
+
+ def free_vnc_num(self, vm):
+ if self.__vm_has_resource(vm, 'vnc_display_num'):
+ self.allocated_info[vm].pop('vnc_display_num')
+
+ def free_all_resource(self, vm):
+ all_free_funcs = get_obj_funcs(self, r'free_')
+ for func in all_free_funcs:
+ if func.__name__ == 'free_all_resource':
+ continue
+ func(vm)
+ if self.__vm_has_resource(vm):
+ self.allocated_info.pop(vm)
+
+ def get_cpu_on_vm(self, vm=''):
+ """
+ Return core list on specifid VM.
+ """
+ if vm in self.allocated_info:
+ if "cores" in self.allocated_info[vm]:
+ return self.allocated_info[vm]['cores']
+
+ def get_vfs_on_vm(self, vm=''):
+ """
+ Return vf device list on specifid VM.
+ """
+ if vm in self.allocated_info:
+ if 'vfs' in self.allocated_info[vm]:
+ return self.allocated_info[vm]['vfs']
+
+ def get_pfs_on_vm(self, vm=''):
+ """
+ Return pf device list on specifid VM.
+ """
+ if vm in self.allocated_info:
+ if 'ports' in self.allocated_info[vm]:
+ return self.allocated_info[vm]['ports']
+
+
+class simple_dut(object):
+
+ def __init__(self):
+ self.ports_info = []
+ self.cores = []
+
+ def check_port_occupied(self, port):
+ return False
+
+if __name__ == "__main__":
+ dut = simple_dut()
+ dut.cores = [{'thread': '1', 'socket': '0'}, {'thread': '2', 'socket': '0'},
+ {'thread': '3', 'socket': '0'}, {'thread': '4', 'socket': '0'},
+ {'thread': '5', 'socket': '0'}, {'thread': '6', 'socket': '0'},
+ {'thread': '7', 'socket': '1'}, {'thread': '8', 'socket': '1'},
+ {'thread': '9', 'socket': '1'}, {'thread': '10', 'socket': '1'},
+ {'thread': '11', 'socket': '1'}, {'thread': '12', 'socket': '1'}]
+
+ dut.ports_info = [{'intf': 'p786p1', 'source': 'cfg', 'mac': '90:e2:ba:69:e5:e4',
+ 'pci': '08:00.0', 'numa': 0, 'ipv6': 'fe80::92e2:baff:fe69:e5e4',
+ 'peer': 'IXIA:6.5', 'type': '8086:10fb'},
+ {'intf': 'p786p2', 'source': 'cfg', 'mac': '90:e2:ba:69:e5:e5',
+ 'pci': '08:00.1', 'numa': 0, 'ipv6': 'fe80::92e2:baff:fe69:e5e5',
+ 'peer': 'IXIA:6.6', 'type': '8086:10fb'},
+ {'intf': 'p787p1', 'source': 'cfg', 'mac': '90:e2:ba:69:e5:e6',
+ 'pci': '84:00.0', 'numa': 1, 'ipv6': 'fe80::92e2:baff:fe69:e5e6',
+ 'peer': 'IXIA:6.7', 'type': '8086:10fb'},
+ {'intf': 'p787p2', 'source': 'cfg', 'mac': '90:e2:ba:69:e5:e7',
+ 'pci': '84:00.1', 'numa': 1, 'ipv6': 'fe80::92e2:baff:fe69:e5e7',
+ 'peer': 'IXIA:6.8', 'type': '8086:10fb'}]
+
+ virt_pool = VirtResource(dut)
+ print "Alloc two PF devices on socket 1 from VM"
+ print virt_pool.alloc_pf(vm='test1', number=2, socket=1)
+
+ virt_pool.add_vf_on_pf(pf_pci='08:00.0', vflist=[
+ '08:10.0', '08:10.2', '08:10.4', '08:10.6'])
+ virt_pool.add_vf_on_pf(pf_pci='08:00.1', vflist=[
+ '08:10.1', '08:10.3', '08:10.5', '08:10.7'])
+ print "Add VF devices to resource pool"
+ print virt_pool.vfs_info
+
+ print "Alloc VF device from resource pool"
+ print virt_pool.alloc_vf_from_pf(vm='test1', pf_pci='08:00.0', number=2)
+ print virt_pool.used_vfs
+ print "Alloc VF device from resource pool"
+ print virt_pool.alloc_vf_from_pf(vm='test2', pf_pci='08:00.1', vflist=['08:10.3', '08:10.5'])
+ print virt_pool.used_vfs
+
+ print "Del VF devices from resource pool"
+ virt_pool.del_vf_on_pf(pf_pci='08:00.0', vflist=['08:10.4', '08:10.2'])
+ print virt_pool.vfs_info
+
+ virt_pool.reserve_cpu('e')
+ print "Reserve three cores from resource pool"
+ print virt_pool.unused_cores
+ print "Alloc two cores on socket1 for VM-test1"
+ print virt_pool.alloc_cpu(vm="test1", number=2, socket=1)
+ print "Alloc two cores in list for VM-test2"
+ print virt_pool.alloc_cpu(vm="test2", corelist=['4', '5'])
+ print "Alloc two cores for VM-test3"
+ print virt_pool.alloc_cpu(vm="test3", number=2)
+ print "Alloc port for VM-test1"
+ print virt_pool.alloc_port(vm='test1')
+ print "Alloc information after allcated"
+ print virt_pool.allocated_info
+
+ print "Get cores on VM-test1"
+ print virt_pool.get_cpu_on_vm("test1")
+ print "Get pfs on VM-test1"
+ print virt_pool.get_pfs_on_vm("test1")
+ print "Get vfs on VM-test2"
+ print virt_pool.get_vfs_on_vm("test2")
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases
2015-05-18 5:07 ` [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases sjiajiax
@ 2015-05-18 8:28 ` Xu, HuilongX
2015-05-18 8:45 ` Liu, Yong
2015-05-18 9:20 ` Jiajia, SunX
0 siblings, 2 replies; 34+ messages in thread
From: Xu, HuilongX @ 2015-05-18 8:28 UTC (permalink / raw)
To: Jiajia, SunX, dts
Hi Jiajia,
I have a comments at " def execute_cmd(self, pmd_cmd, expected='testpmd> ', timeout=TIMEOUT "
Would you check it, thanks a lot
-----Original Message-----
From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
Sent: Monday, May 18, 2015 1:07 PM
To: dts@dpdk.org
Subject: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases
Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
---
framework/pmd_output.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 102 insertions(+), 2 deletions(-)
diff --git a/framework/pmd_output.py b/framework/pmd_output.py
index 97274a5..642062f 100644
--- a/framework/pmd_output.py
+++ b/framework/pmd_output.py
@@ -32,6 +32,7 @@
import os
import re
import dts
+from settings import TIMEOUT
class PmdOutput():
@@ -42,6 +43,7 @@ class PmdOutput():
def __init__(self, dut):
self.dut = dut
+ self.dut.testpmd = self
self.rx_pkts_prefix = "RX-packets:"
self.rx_missed_prefix = "RX-missed:"
self.rx_bytes_prefix = "RX-bytes:"
@@ -87,10 +89,108 @@ class PmdOutput():
return self.command
def start_testpmd(self, cores, param='', eal_param='', socket=0):
+ if "--txqflags" not in param:
+ param += " --txqflags=0"
+ if socket == 0:
+ corelist = '0-3'
+ elif socket == 1:
+ corelist = '10-13'
+ else:
+ corelist = '0-3'
core_list = self.dut.get_core_list(cores, socket)
self.coremask = dts.create_mask(core_list)
- command = "./%s/app/testpmd -c %s -n %d %s -- -i %s" \
- % (self.dut.target, self.coremask, self.dut.get_memory_channels(), eal_param, param)
+ command = "taskset -c %s ./%s/app/testpmd -c %s -n %d %s -- -i %s" \
+ % (corelist, self.dut.target, self.coremask, self.dut.get_memory_channels(), eal_param, param)
out = self.dut.send_expect(command, "testpmd> ", 120)
self.command = command
return out
maybe we need delete parameter "verify=False" in function execute_cmd,
when we used execute_cmd for exec testpmd cmdline, the parameter only False.
+
+ def execute_cmd(self, pmd_cmd, expected='testpmd> ', timeout=TIMEOUT,
+ alt_session=False, verify=False):
+ return self.dut.send_expect('%s' % pmd_cmd, expected, timeout=timeout,
+ alt_session=alt_session, verify=verify)
+
+ def get_value_from_string(self, key_str, regx_str, string):
+ """
+ Get some values from the given string by the regular expression.
+ """
+ pattern = r"(?<=%s)%s" % (key_str, regx_str)
+ s = re.compile(pattern)
+ res = s.search(string)
+ if type(res).__name__ == 'NoneType':
+ return ' '
+ else:
+ return res.group(0)
+
+ def get_detail_from_port_info(self, key_str, regx_str, port):
+ """
+ Get the detail info from the output of pmd cmd 'show port info <port num>'.
+ """
+ out = self.dut.send_expect("show port info %d" % port, "testpmd> ")
+ find_value = self.get_value_from_string(key_str, regx_str, out)
+ return find_value
+
+ def get_port_mac(self, port_id):
+ """
+ Get the specified port MAC.
+ """
+ return self.get_detail_from_port_info("MAC address: ", "([0-9A-F]{2}:){5}[0-9A-F]{2}", port_id)
+
+ def get_port_connect_socket(self, port_id):
+ """
+ Get the socket id which the specified port is connectting with.
+ """
+ return self.get_detail_from_port_info("Connect to socket: ", "\d+", port_id)
+
+ def get_port_memory_socket(self, port_id):
+ """
+ Get the socket id which the specified port memory is allocated on.
+ """
+ return self.get_detail_from_port_info("memory allocation on the socket: ", "\d+", port_id)
+
+ def get_port_link_status(self, port_id):
+ """
+ Get the specified port link status now.
+ """
+ return self.get_detail_from_port_info("Link status: ", "\d+", port_id)
+
+ def get_port_link_speed(self, port_id):
+ """
+ Get the specified port link speed now.
+ """
+ return self.get_detail_from_port_info("Link speed: ", "\d+", port_id)
+
+ def get_port_link_duplex(self, port_id):
+ """
+ Get the specified port link mode, duplex or siplex.
+ """
+ return self.get_detail_from_port_info("Link duplex: ", "\S+", port_id)
+
+ def get_port_promiscuous_mode(self, port_id):
+ """
+ Get the promiscuous mode of port.
+ """
+ return self.get_detail_from_port_info("Promiscuous mode: ", "\S+", port_id)
+
+ def get_port_allmulticast_mode(self, port_id):
+ """
+ Get the allmulticast mode of port.
+ """
+ return self.get_detail_from_port_info("Allmulticast mode: ", "\S+", port_id)
+
+ def get_port_vlan_offload(self, port_id):
+ """
+ Function: get the port vlan settting info.
+ return value:
+ 'strip':'on'
+ 'filter':'on'
+ 'qinq':'off'
+ """
+ vlan_info = {}
+ vlan_info['strip'] = self.get_detail_from_port_info(
+ "strip ", '\S+', port_id)
+ vlan_info['filter'] = self.get_detail_from_port_info(
+ 'filter', '\S+', port_id)
+ vlan_info['qinq'] = self.get_detail_from_port_info(
+ 'qinq\(extend\) ', '\S+', port_id)
+ return vlan_info
--
1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases
2015-05-18 8:28 ` Xu, HuilongX
@ 2015-05-18 8:45 ` Liu, Yong
2015-05-18 9:05 ` Jiajia, SunX
2015-05-18 9:20 ` Jiajia, SunX
1 sibling, 1 reply; 34+ messages in thread
From: Liu, Yong @ 2015-05-18 8:45 UTC (permalink / raw)
To: Xu, HuilongX, Jiajia, SunX, dts
Some additional comments.
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of Xu, HuilongX
> Sent: Monday, May 18, 2015 4:29 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: Re: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to
> code the testpmd cases
>
> Hi Jiajia,
> I have a comments at " def execute_cmd(self, pmd_cmd, expected='testpmd> ',
> timeout=TIMEOUT "
> Would you check it, thanks a lot
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code
> the testpmd cases
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> framework/pmd_output.py | 104
> +++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 102 insertions(+), 2 deletions(-)
>
> diff --git a/framework/pmd_output.py b/framework/pmd_output.py
> index 97274a5..642062f 100644
> --- a/framework/pmd_output.py
> +++ b/framework/pmd_output.py
> @@ -32,6 +32,7 @@
> import os
> import re
> import dts
> +from settings import TIMEOUT
>
>
> class PmdOutput():
> @@ -42,6 +43,7 @@ class PmdOutput():
>
> def __init__(self, dut):
> self.dut = dut
> + self.dut.testpmd = self
> self.rx_pkts_prefix = "RX-packets:"
> self.rx_missed_prefix = "RX-missed:"
> self.rx_bytes_prefix = "RX-bytes:"
> @@ -87,10 +89,108 @@ class PmdOutput():
> return self.command
>
> def start_testpmd(self, cores, param='', eal_param='', socket=0):
> + if "--txqflags" not in param:
> + param += " --txqflags=0"
> + if socket == 0:
> + corelist = '0-3'
> + elif socket == 1:
> + corelist = '10-13'
> + else:
> + corelist = '0-3'
Should not hard code here, cpu may change between platforms.
> core_list = self.dut.get_core_list(cores, socket)
> self.coremask = dts.create_mask(core_list)
> - command = "./%s/app/testpmd -c %s -n %d %s -- -i %s" \
> - % (self.dut.target, self.coremask,
> self.dut.get_memory_channels(), eal_param, param)
> + command = "taskset -c %s ./%s/app/testpmd -c %s -n %d %s -- -
> i %s" \
> + % (corelist, self.dut.target, self.coremask,
> self.dut.get_memory_channels(), eal_param, param)
> out = self.dut.send_expect(command, "testpmd> ", 120)
> self.command = command
> return out
>
> maybe we need delete parameter "verify=False" in function execute_cmd,
> when we used execute_cmd for exec testpmd cmdline, the parameter only
> False.
> +
> + def execute_cmd(self, pmd_cmd, expected='testpmd> ', timeout=TIMEOUT,
> + alt_session=False, verify=False):
> + return self.dut.send_expect('%s' % pmd_cmd, expected,
> timeout=timeout,
> + alt_session=alt_session,
> verify=verify)
> +
> + def get_value_from_string(self, key_str, regx_str, string):
> + """
> + Get some values from the given string by the regular expression.
> + """
> + pattern = r"(?<=%s)%s" % (key_str, regx_str)
> + s = re.compile(pattern)
> + res = s.search(string)
> + if type(res).__name__ == 'NoneType':
> + return ' '
> + else:
> + return res.group(0)
> +
> + def get_detail_from_port_info(self, key_str, regx_str, port):
> + """
> + Get the detail info from the output of pmd cmd 'show port info
> <port num>'.
> + """
> + out = self.dut.send_expect("show port info %d" % port, "testpmd>
> ")
> + find_value = self.get_value_from_string(key_str, regx_str, out)
> + return find_value
> +
> + def get_port_mac(self, port_id):
> + """
> + Get the specified port MAC.
> + """
> + return self.get_detail_from_port_info("MAC address: ", "([0-9A-
> F]{2}:){5}[0-9A-F]{2}", port_id)
> +
> + def get_port_connect_socket(self, port_id):
> + """
> + Get the socket id which the specified port is connectting with.
> + """
> + return self.get_detail_from_port_info("Connect to socket: ",
> "\d+", port_id)
> +
> + def get_port_memory_socket(self, port_id):
> + """
> + Get the socket id which the specified port memory is allocated on.
> + """
> + return self.get_detail_from_port_info("memory allocation on the
> socket: ", "\d+", port_id)
> +
> + def get_port_link_status(self, port_id):
> + """
> + Get the specified port link status now.
> + """
> + return self.get_detail_from_port_info("Link status: ", "\d+",
> port_id)
> +
> + def get_port_link_speed(self, port_id):
> + """
> + Get the specified port link speed now.
> + """
> + return self.get_detail_from_port_info("Link speed: ", "\d+",
> port_id)
> +
> + def get_port_link_duplex(self, port_id):
> + """
> + Get the specified port link mode, duplex or siplex.
> + """
> + return self.get_detail_from_port_info("Link duplex: ", "\S+",
> port_id)
> +
> + def get_port_promiscuous_mode(self, port_id):
> + """
> + Get the promiscuous mode of port.
> + """
> + return self.get_detail_from_port_info("Promiscuous mode: ", "\S+",
> port_id)
> +
> + def get_port_allmulticast_mode(self, port_id):
> + """
> + Get the allmulticast mode of port.
> + """
> + return self.get_detail_from_port_info("Allmulticast mode: ",
> "\S+", port_id)
> +
> + def get_port_vlan_offload(self, port_id):
> + """
> + Function: get the port vlan settting info.
> + return value:
> + 'strip':'on'
> + 'filter':'on'
> + 'qinq':'off'
> + """
> + vlan_info = {}
> + vlan_info['strip'] = self.get_detail_from_port_info(
> + "strip ", '\S+', port_id)
> + vlan_info['filter'] = self.get_detail_from_port_info(
> + 'filter', '\S+', port_id)
> + vlan_info['qinq'] = self.get_detail_from_port_info(
> + 'qinq\(extend\) ', '\S+', port_id)
> + return vlan_info
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice
2015-05-18 7:46 ` Xu, HuilongX
@ 2015-05-18 8:58 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-18 8:58 UTC (permalink / raw)
To: Xu, HuilongX, dts
Hi Huilong,
Please see my comments as below.
> -----Original Message-----
> From: Xu, HuilongX
> Sent: Monday, May 18, 2015 3:47 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single
> class NetDevice
>
> Hi Jiajia,
> I have two comments in this patch,
> Would you check the comments in function "def
> destroy_sriov_vfs_by_port(self, port_id):" and "def set_toolchain(self,
> target):"
> Thanks a lot
>
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single
> class NetDevice
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> framework/crb.py | 135 +++++++----
> framework/dut.py | 268 ++++++++++++++++++---
> framework/net_device.py | 600
> ++++++++++++++++++++++++++++++++++++++++++++++++
> framework/settings.py | 43 ++++
> framework/test_case.py | 3 +-
> framework/tester.py | 51 +++-
> 6 files changed, 1006 insertions(+), 94 deletions(-)
> create mode 100644 framework/net_device.py
>
> diff --git a/framework/crb.py b/framework/crb.py
> index a699bfc..2eb2033 100644
> --- a/framework/crb.py
> +++ b/framework/crb.py
> @@ -69,6 +69,12 @@ class Crb(object):
>
> return self.session.send_expect(cmds, expected, timeout,
> verify)
>
> + def get_session_output(self, timeout=TIMEOUT):
> + """
> + Get session output message before timeout
> + """
> + return self.session.get_session_before(timeout)
> +
> def set_test_types(self, func_tests, perf_tests):
> """
> Enable or disable function/performance test.
> @@ -80,7 +86,9 @@ class Crb(object):
> """
> Get the huge page number of CRB.
> """
> - huge_pages = self.send_expect("awk '/HugePages_Total/ { print
> $2 }' /proc/meminfo", "# ")
> + huge_pages = self.send_expect(
> + "awk '/HugePages_Total/ { print $2 }' /proc/meminfo",
> + "# ", alt_session=True)
> if huge_pages != "":
> return int(huge_pages)
> return 0
> @@ -115,6 +123,9 @@ class Crb(object):
> """
> self.base_dir = base_dir
>
> + def set_virttype(self, virttype):
> + self.virttype = virttype
> +
> def admin_ports(self, port, status):
> """
> Force set port's interface status.
> @@ -127,13 +138,15 @@ class Crb(object):
> Force set remote interface link status in FreeBSD.
> """
> eth = self.ports_info[port]['intf']
> - self.send_expect("ifconfig %s %s" % (eth, status), "# ")
> + self.send_expect("ifconfig %s %s" %
> + (eth, status), "# ", alt_session=True)
>
> def admin_ports_linux(self, eth, status):
> """
> Force set remote interface link status in Linux.
> """
> - self.send_expect("ip link set %s %s" % (eth, status), "# ")
> + self.send_expect("ip link set %s %s" %
> + (eth, status), "# ", alt_session=True)
>
> def pci_devices_information(self):
> """
> @@ -157,8 +170,9 @@ class Crb(object):
> """
> Look for the NIC's information (PCI Id and card type).
> """
> - out = self.send_expect("lspci -nn | grep -i eth", "# ")
> - rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) Ethernet .*?([\da-
> f]{4}:[\da-f]{4})"
> + out = self.send_expect(
> + "lspci -nn | grep -i eth", "# ", alt_session=True)
> + rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) .*Eth.*?ernet .*?([\da-
> f]{4}:[\da-f]{4})"
> pattern = re.compile(rexp)
> match = pattern.findall(out)
> self.pci_devices_info = []
> @@ -169,7 +183,7 @@ class Crb(object):
> """
> Look for the NIC's information (PCI Id and card type).
> """
> - out = self.send_expect("pciconf -l", "# ")
> + out = self.send_expect("pciconf -l", "# ", alt_session=True)
> rexp = r"pci0:([\da-f]{1,3}:[\da-
> f]{1,2}:\d{1}):\s*class=0x020000.*chip=0x([\da-f]{4})8086"
> pattern = re.compile(rexp)
> match = pattern.findall(out)
> @@ -179,66 +193,69 @@ class Crb(object):
> card_type = "8086:%s" % match[i][1]
> self.pci_devices_info.append((match[i][0], card_type))
>
> - def get_interface_name(self, bus_id, devfun_id=''):
> - """
> - Get interface name of specified pci device.
> - """
> - get_interface_name = getattr(self, 'get_interface_name_%s' %
> self.get_os_type())
> - return get_interface_name(bus_id, devfun_id)
> -
> - def get_interface_name_linux(self, bus_id, devfun_id):
> + def get_pci_dev_driver(self, bus_id, devfun_id):
> """
> - Get interface name of specified pci device on linux.
> + Get the driver of specified pci device.
> """
> - command = 'ls --color=never
> /sys/bus/pci/devices/0000:%s:%s/net' % (bus_id, devfun_id)
> - out = self.send_expect(command, '# ', verify=True)
> - if out == -1:
> - name = ""
> - else:
> - name = out.split()[0]
> - return name
> + get_pci_dev_driver = getattr(
> + self, 'get_pci_dev_driver_%s' % self.get_os_type())
> + return get_pci_dev_driver(bus_id, devfun_id)
>
> - def get_interface_name_freebsd(self, bus_id, devfun_id):
> + def get_pci_dev_driver_linux(self, bus_id, devfun_id):
> """
> - Get interface name of specified pci device on Freebsd.
> + Get the driver of specified pci device on linux.
> """
> - out = self.send_expect("pciconf -l", "# ")
> - rexp = r"(\w*)@pci0:%s" % bus_id
> + out = self.send_expect("cat
> /sys/bus/pci/devices/0000\:%s\:%s/uevent" %
> + (bus_id, devfun_id), "# ",
> alt_session=True)
> + rexp = r"DRIVER=(.+?)\r"
> pattern = re.compile(rexp)
> - match = pattern.findall(out)
> - return match[0]
> + match = pattern.search(out)
> + if not match:
> + return None
> + return match.group(1)
>
> - def get_mac_addr(self, intf, bus_id='', devfun_id=''):
> + def get_pci_dev_driver_freebsd(self, bus_id, devfun_id):
> """
> - Get mac address of specified pci device.
> + Get the driver of specified pci device.
> """
> - get_mac_addr = getattr(self, 'get_mac_addr_%s' %
> self.get_os_type())
> - return get_mac_addr(intf, bus_id, devfun_id)
> + return True
>
> - def get_mac_addr_linux(self, intf, bus_id, devfun_id):
> + def get_pci_dev_id(self, bus_id, devfun_id):
> """
> - Get mac address of specified pci device on linux.
> + Get the pci id of specified pci device.
> """
> - command = ('cat
> /sys/bus/pci/devices/0000:%s:%s/net/%s/address' %
> - (bus_id, devfun_id, intf))
> - return self.send_expect(command, '# ')
> + get_pci_dev_id = getattr(
> + self, 'get_pci_dev_id_%s' % self.get_os_type())
> + return get_pci_dev_id(bus_id, devfun_id)
>
> - def get_mac_addr_freebsd(self, intf, bus_id, devfun_id):
> + def get_pci_dev_id_linux(self, bus_id, devfun_id):
> """
> - Get mac address of specified pci device on Freebsd.
> + Get the pci id of specified pci device on linux.
> """
> - out = self.send_expect('ifconfig %s' % intf, '# ')
> - rexp = r"ether ([\da-f:]*)"
> + out = self.send_expect("cat
> /sys/bus/pci/devices/0000\:%s\:%s/uevent" %
> + (bus_id, devfun_id), "# ",
> alt_session=True)
> + rexp = r"PCI_ID=(.+)"
> pattern = re.compile(rexp)
> - match = pattern.findall(out)
> - return match[0]
> + match = re.search(out)
> + if not match:
> + return None
> + return match.group(1)
>
> def get_device_numa(self, bus_id, devfun_id):
> """
> - Get numa id of specified pci device
> + Get numa number of specified pci device.
> + """
> + get_device_numa = getattr(
> + self, "get_device_numa_%s" % self.get_os_type())
> + return get_device_numa(bus_id, devfun_id)
> +
> + def get_device_numa_linux(self, bus_id, devfun_id):
> + """
> + Get numa number of specified pci device on Linux.
> """
> - numa = self.send_expect("cat
> /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
> - (bus_id, devfun_id), "# ")
> + numa = self.send_expect(
> + "cat /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
> + (bus_id, devfun_id), "# ", alt_session=True)
>
> try:
> numa = int(numa)
> @@ -259,14 +276,14 @@ class Crb(object):
> Get ipv6 address of specified pci device on linux.
> """
> out = self.send_expect("ip -family inet6 address show dev %s |
> awk '/inet6/ { print $2 }'"
> - % intf, "# ")
> + % intf, "# ", alt_session=True)
> return out.split('/')[0]
>
> def get_ipv6_addr_freebsd(self, intf):
> """
> Get ipv6 address of specified pci device on Freebsd.
> """
> - out = self.send_expect('ifconfig %s' % intf, '# ')
> + out = self.send_expect('ifconfig %s' % intf, '# ',
> alt_session=True)
> rexp = r"inet6 ([\da-f:]*)%"
> pattern = re.compile(rexp)
> match = pattern.findall(out)
> @@ -275,6 +292,22 @@ class Crb(object):
>
> return match[0]
>
> + def disable_ipv6(self, intf):
> + """
> + Disable ipv6 of of specified interface
> + """
> + if intf != 'N/A':
> + self.send_expect("sysctl net.ipv6.conf.%s.disable_ipv6=1" %
> + intf, "# ", alt_session=True)
> +
> + def enable_ipv6(self, intf):
> + """
> + Enable ipv6 of of specified interface
> + """
> + if intf != 'N/A':
> + self.send_expect("sysctl net.ipv6.conf.%s.disable_ipv6=0" %
> + intf, "# ", alt_session=True)
> +
> def create_file(self, contents, fileName):
> """
> Create file with contents and copy it to CRB.
> @@ -318,7 +351,7 @@ class Crb(object):
> if isinstance(self, Dut) and self.get_os_type() == 'freebsd':
> expected = 'FreeBSD.*#'
>
> - self.send_expect('uname', expected, 2)
> + self.send_expect('uname', expected, 2, alt_session=True)
>
> def init_core_list(self):
> """
> @@ -378,7 +411,9 @@ class Crb(object):
> self.cores = []
>
> cpuinfo = \
> - self.send_expect("grep \"processor\\|physical id\\|core
> id\\|^$\" /proc/cpuinfo", "#")
> + self.send_expect(
> + "grep --color=never \"processor\\|physical id\\|core
> id\\|^$\" /proc/cpuinfo",
> + "#", alt_session=True)
> cpuinfo = cpuinfo.split('\r\n\r\n')
> for line in cpuinfo:
> m = re.search("processor\t: (\d+)\r\n" +
> diff --git a/framework/dut.py b/framework/dut.py
> index 5b7aba2..247b01c 100644
> --- a/framework/dut.py
> +++ b/framework/dut.py
> @@ -33,11 +33,17 @@ import os
> import re
> import time
> import dts
> -from config import UserConf
> -from settings import NICS
> +import settings
> +from config import PortConf
> +from settings import NICS, LOG_NAME_SEP
> from ssh_connection import SSHConnection
> from crb import Crb
> +from net_device import NetDevice
> from logger import getLogger
> +from virt_resource import VirtResource
> +from utils import RED
> +
> +
>
>
> class Dut(Crb):
> @@ -60,20 +66,36 @@ class Dut(Crb):
> def __init__(self, crb, serializer):
> super(Dut, self).__init__(crb, serializer)
> self.NAME = 'dut'
> +
> + self.host_init_flag = 0
> self.logger = getLogger(self.NAME)
> self.session = SSHConnection(self.get_ip_address(), self.NAME,
> self.get_password())
> self.session.init_log(self.logger)
> - self.alt_session = SSHConnection(self.get_ip_address(),
> self.NAME + '_alt',
> - self.get_password())
> + self.alt_session = SSHConnection(
> + self.get_ip_address(),
> + self.NAME + '_alt',
> + self.get_password())
> self.alt_session.init_log(self.logger)
> self.number_of_cores = 0
> self.tester = None
> self.cores = []
> self.architecture = None
> self.ports_info = None
> - self.conf = UserConf()
> + self.conf = PortConf()
> self.ports_map = []
> + self.virt_pool = None
> +
> + def init_host_session(self):
> + if self.host_init_flag:
> + pass
> + else:
> + self.host_session = SSHConnection(
> + self.get_ip_address(),
> + self.NAME + '_host',
> + self.get_password())
> + self.host_session.init_log(self.logger)
> + self.host_init_flag = 1
>
> def change_config_option(self, target, parameter, value):
> """
> @@ -82,12 +104,12 @@ class Dut(Crb):
> self.send_expect("sed -i 's/%s=.*$/%s=%s/'
> config/defconfig_%s" %
> (parameter, parameter, value, target), "# ")
>
> - def set_nic_type(self, nic):
> + def set_nic_type(self, nic_type):
> """
> Set CRB NICS ready to validated.
> """
> - self.nic = nic
> - if 'cfg' in nic:
> + self.nic_type = nic_type
> + if 'cfg' in nic_type:
> self.conf.load_ports_config(self.get_ip_address())
>
> def set_toolchain(self, target):
> @@ -167,11 +189,17 @@ class Dut(Crb):
> self.mount_procfs()
> # auto detect network topology
> self.map_available_ports()
> + # disable tester port ipv6
> + self.disable_tester_ipv6()
> # print latest ports_info
> - self.logger.info(dts.pprint(self.ports_info))
> + for port_info in self.ports_info:
> + self.logger.info(port_info)
> when virt dut init not have any port, but we will add port by
> hot plug or build vport by dpdk app testpmd(eg, xen virtio test)
> The test will can't continued
Yes, maybe it is good to have a warning message.
> if self.ports_map is None or len(self.ports_map) == 0:
> raise ValueError("ports_map should not be empty, please
> check all links")
>
> + # initialize virtualization resource pool
> + self.virt_pool = VirtResource(self)
> +
> def restore_interfaces(self):
> """
> Restore all ports's interfaces.
> @@ -195,20 +223,22 @@ class Dut(Crb):
> pci_bus = port['pci']
> pci_id = port['type']
> # get device driver
> - driver = dts.get_nic_driver(pci_id)
> + driver = settings.get_nic_driver(pci_id)
> if driver is not None:
> # unbind device driver
> addr_array = pci_bus.split(':')
> bus_id = addr_array[0]
> devfun_id = addr_array[1]
>
> + port = NetDevice(self, bus_id, devfun_id)
> +
> self.send_expect('echo 0000:%s >
> /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind'
> % (pci_bus, bus_id, devfun_id), '# ')
> # bind to linux kernel driver
> self.send_expect('modprobe %s' % driver, '# ')
> self.send_expect('echo 0000:%s >
> /sys/bus/pci/drivers/%s/bind'
> % (pci_bus, driver), '# ')
> - itf = self.get_interface_name(addr_array[0],
> addr_array[1])
> + itf = port.get_interface_name()
> self.send_expect("ifconfig %s up" % itf, "# ")
> else:
> self.logger.info("NOT FOUND DRIVER FOR PORT
> (%s|%s)!!!" % (pci_bus, pci_id))
> @@ -228,7 +258,10 @@ class Dut(Crb):
> """
> Setup Linux hugepages.
> """
> - hugepages_size = self.send_expect("awk '/Hugepagesize/ {print
> $2}' /proc/meminfo", "# ")
> + if self.virttype == 'xen':
> + return
> + hugepages_size = self.send_expect(
> + "awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
>
> if int(hugepages_size) < (1024 * 1024):
> if self.architecture == "x86_64":
> @@ -265,6 +298,20 @@ class Dut(Crb):
>
> return 'taskset %s ' % core
>
> + def is_ssh_session_port(self, pci_bus):
> + """
> + Check if the pci device is the dut SSH session port.
> + """
> + port = None
> + for port_info in self.ports_info:
> + if pci_bus == port_info['pci']:
> + port = port_info['port']
> + break
> + if port and port.get_ipv4_addr() == crbs['IP'].strip():
> + return True
> + else:
> + return False
> +
> def bind_interfaces_linux(self, driver='igb_uio',
> nics_to_bind=None):
> """
> Bind the interfaces to the selected driver. nics_to_bind can
> be None
> @@ -275,12 +322,17 @@ class Dut(Crb):
>
> current_nic = 0
> for (pci_bus, pci_id) in self.pci_devices_info:
> - if dts.accepted_nic(pci_id):
> + if settings.accepted_nic(pci_id):
> + if self.is_ssh_session_port(pci_bus):
> + continue
>
> if nics_to_bind is None or current_nic in nics_to_bind:
> binding_list += '%s ' % (pci_bus)
>
> current_nic += 1
> + if current_nic == 0:
> + self.logger.info("Not nic need bind driver: %s" % driver)
> + return
>
> self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list,
> '# ')
>
> @@ -293,13 +345,19 @@ class Dut(Crb):
>
> current_nic = 0
> for (pci_bus, pci_id) in self.pci_devices_info:
> - if dts.accepted_nic(pci_id):
> + if settings.accepted_nic(pci_id):
> + if self.is_ssh_session_port(pci_bus):
> + continue
>
> if nics_to_bind is None or current_nic in nics_to_bind:
> binding_list += '%s ' % (pci_bus)
>
> current_nic += 1
>
> + if current_nic == 0:
> + self.logger.info("Not nic need unbind driver")
> + return
> +
> self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list,
> '# ', 30)
>
> def get_ports(self, nic_type='any', perf=None, socket=None):
> @@ -314,14 +372,17 @@ class Dut(Crb):
> perf = self.want_perf_tests
>
> nictypes = []
> - if nic_type == 'any':
> + if self.nic_type == 'any':
> for portid in range(len(self.ports_info)):
> ports.append(portid)
> return ports
> - elif nic_type == 'cfg':
> + elif self.nic_type == 'cfg':
> for portid in range(len(self.ports_info)):
> if self.ports_info[portid]['source'] == 'cfg':
> - ports.append(portid)
> + if (socket is None or
> + self.ports_info[portid]['numa'] == -1 or
> + socket == self.ports_info[portid]['numa']):
> + ports.append(portid)
> return ports
> else:
> for portid in range(len(self.ports_info)):
> @@ -440,36 +501,38 @@ class Dut(Crb):
> Check that whether auto scanned ports ready to use
> """
> pci_addr = "%s:%s" % (pci_bus, pci_id)
> - if self.nic == 'any':
> + if self.nic_type == 'any':
> return True
> - elif self.nic == 'cfg':
> + elif self.nic_type == 'cfg':
> if self.conf.check_port_available(pci_bus) is True:
> return True
> - elif self.nic not in NICS.keys():
> - self.logger.warning("NOT SUPPORTED NIC TYPE: %s" %
> self.nic)
> + elif self.nic_type not in NICS.keys():
> + self.logger.warning("NOT SUPPORTED NIC TYPE: %s" %
> self.nic_type)
> else:
> - codename = NICS[self.nic]
> + codename = NICS[self.nic_type]
> if pci_id == codename:
> return True
>
> return False
>
> def rescan_ports(self):
> - unknow_interface = dts.RED('Skipped: unknow_interface')
> + unknow_interface = RED('Skipped: unknow_interface')
>
> for port_info in self.ports_info:
> pci_bus = port_info['pci']
> addr_array = pci_bus.split(':')
> bus_id = addr_array[0]
> devfun_id = addr_array[1]
> - intf = self.get_interface_name(bus_id, devfun_id)
> +
> + port = NetDevice(self, bus_id, devfun_id)
> + intf = port.get_interface_name()
> if "No such file" in intf:
> self.logger.info("DUT: [0000:%s] %s" % (pci_bus,
> unknow_interface))
> out = self.send_expect("ip link show %s" % intf, "# ")
> if "DOWN" in out:
> self.send_expect("ip link set %s up" % intf, "# ")
> time.sleep(5)
> - macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
> + macaddr = port.get_mac_addr()
> out = self.send_expect("ip -family inet6 address show
> dev %s | awk '/inet6/ { print $2 }'"
> % intf, "# ")
> ipv6 = out.split('/')[0]
> @@ -481,16 +544,32 @@ class Dut(Crb):
> port_info['intf'] = intf
> port_info['ipv6'] = ipv6
>
> + def load_serializer_ports(self):
> + self.ports_info = []
> + cached_ports_info =
> self.serializer.load(self.PORT_INFO_CACHE_KEY)
> + if cached_ports_info is None:
> + return
> + for port in cached_ports_info:
> + self.ports_info.append({'pci': port['pci'], 'type':
> port['type'],
> + 'numa': port['numa']})
> +
> + def save_serializer_ports(self):
> + cached_ports_info = []
> + for port in self.ports_info:
> + cached_ports_info.append({'pci': port['pci'], 'type':
> port['type'],
> + 'numa': port['numa']})
> + self.serializer.save(self.PORT_INFO_CACHE_KEY,
> cached_ports_info)
> +
> def scan_ports(self):
> """
> Scan ports information or just read it from cache file.
> """
> if self.read_cache:
> - self.ports_info =
> self.serializer.load(self.PORT_INFO_CACHE_KEY)
> + self.load_serializer_ports()
>
> if not self.read_cache or self.ports_info is None:
> self.scan_ports_uncached()
> - self.serializer.save(self.PORT_INFO_CACHE_KEY,
> self.ports_info)
> + self.save_serializer_ports()
>
> def scan_ports_uncached(self):
> """
> @@ -505,8 +584,8 @@ class Dut(Crb):
> """
> self.ports_info = []
>
> - skipped = dts.RED('Skipped: Unknown/not selected')
> - unknow_interface = dts.RED('Skipped: unknow_interface')
> + skipped = RED('Skipped: Unknown/not selected')
> + unknow_interface = RED('Skipped: unknow_interface')
>
> for (pci_bus, pci_id) in self.pci_devices_info:
> if self.check_ports_available(pci_bus, pci_id) is False:
> @@ -518,9 +597,11 @@ class Dut(Crb):
> bus_id = addr_array[0]
> devfun_id = addr_array[1]
>
> + port = NetDevice(self, bus_id, devfun_id)
> numa = self.get_device_numa(bus_id, devfun_id)
> # store the port info to port mapping
> - self.ports_info.append({'pci': pci_bus, 'type': pci_id,
> 'numa': numa})
> + self.ports_info.append(
> + {'port': port, 'pci': pci_bus, 'type': pci_id, 'numa':
> numa})
>
> def scan_ports_uncached_freebsd(self):
> """
> @@ -528,16 +609,17 @@ class Dut(Crb):
> """
> self.ports_info = []
>
> - skipped = dts.RED('Skipped: Unknown/not selected')
> + skipped = RED('Skipped: Unknown/not selected')
>
> for (pci_bus, pci_id) in self.pci_devices_info:
>
> - if not dts.accepted_nic(pci_id):
> + if not setttings.accepted_nic(pci_id):
> self.logger.info("DUT: [%s %s] %s" % (pci_bus, pci_id,
> skipped))
> continue
>
> - intf = self.get_interface_name(pci_bus)
> + port = NetDevice(self, pci_bus, '')
> + intf = port.get_interface_name(pci_bus)
>
> macaddr = self.get_mac_addr(intf)
> ipv6 = self.get_ipv6_addr(intf)
> @@ -560,9 +642,93 @@ class Dut(Crb):
> pci_str = "%s:%s.%s" % (pci_bus_id, pci_dev_str,
> pci_split[2])
>
> # store the port info to port mapping
> - self.ports_info.append({'pci': pci_str, 'type': pci_id,
> 'intf':
> + self.ports_info.append({'port': port, 'pci': pci_str,
> 'type': pci_id, 'intf':
> intf, 'mac': macaddr, 'ipv6': ipv6,
> 'numa': -1})
>
> + def generate_sriov_vfs_by_port(self, port_id, vf_num,
> driver='default'):
> + """
> + Generate SRIOV VFs with default driver it is bound now or
> specifid driver.
> + """
> + port = self.ports_info[port_id]['port']
> + port_driver = port.get_nic_driver()
> +
> + if driver == 'default':
> + if not port_driver:
> + self.logger.info(
> + "No driver on specified port, can not generate
> SRIOV VF.")
> + return None
> + else:
> + if port_driver != driver:
> + port.bind_driver(driver)
> + port.generate_sriov_vfs(vf_num)
> +
> + # append the VF PCIs into the ports_info
> + sriov_vfs_pci = port.get_sriov_vfs_pci()
> + self.ports_info[port_id]['sriov_vfs_pci'] = sriov_vfs_pci
> +
> + # instantiate the VF with NetDevice
> + vfs_port = []
> + for vf_pci in sriov_vfs_pci:
> + addr_array = vf_pci.split(':')
> + bus_id = addr_array[0]
> + devfun_id = addr_array[1]
> + vf_port = NetDevice(self, bus_id, devfun_id)
> + vfs_port.append(vf_port)
> + self.ports_info[port_id]['vfs_port'] = vfs_port
> +
> + pci = self.ports_info[port_id]['pci']
> + self.virt_pool.add_vf_on_pf(pf_pci=pci, vflist=sriov_vfs_pci)
> +
> + def destroy_sriov_vfs_by_port(self, port_id):
> + port = self.ports_info[port_id]['port']
> + vflist = []
> + port_driver = port.get_nic_driver()
> + if 'sriov_vfs_pci' in self.ports_info[port_id] and \
> + self.ports_info[port_id]['sriov_vfs_pci']:
> + vflist = self.ports_info[port_id]['sriov_vfs_pci']
> + else:
> + if not port.get_sriov_vfs_pci():
> + return
> +
> + if not port_driver:
> + self.logger.info(
> + "No driver on specified port, skip destroy SRIOV VF.")
> + else:
> Why we need "sriov_vfs_pci"? would we check destroy sriov
> vfs succeed or failed before we reset ports_info?
Yes, I think it is better to check the sriov_vfs_pci to confirm if the VFs
have been destroyed.
> + sriov_vfs_pci = port.destroy_sriov_vfs()
> + self.ports_info[port_id]['sriov_vfs_pci'] = []
> + self.ports_info[port_id]['vfs_port'] = []
> +
> + pci = self.ports_info[port_id]['pci']
> + self.virt_pool.del_vf_on_pf(pf_pci=pci, vflist=vflist)
> +
> + def get_vm_core_list(self):
> + return VMCORELIST[self.crb['VM CoreList']]
> +
> + def create_blacklist_string(self, target, nic):
> + create_blacklist_string = getattr(
> + self, 'create_blacklist_string_%s' % self.get_os_type())
> + return create_blacklist_string(target, nic)
> +
> + def create_blacklist_string_linux(self, target, nic):
> + blacklist = ''
> + dutPorts = self.get_ports(nic)
> + self.restore_interfaces()
> + if dts.drivername == "igb_uio":
> + self.send_expect('insmod ./%s/kmod/igb_uio.ko ' % target,
> '# ')
> + elif dts.drivername == "vfio-pci":
> + self.send_expect("modprobe vfio", '# ')
> + self.send_expect("modprobe vfio-pci", '# ')
> + self.bind_interfaces_linux(dts.drivername)
> + for port in range(0, len(self.ports_info)):
> + if(port not in dutPorts):
> + blacklist += '-b 0000:%s ' %
> self.ports_info[port]['pci']
> + return blacklist
> +
> + def create_blacklist_string_freebsd(self, target, nic):
> + blacklist = ''
> + # No blacklist option in FreeBSD
> + return blacklist
> +
> def load_portconf(self):
> """
> Load port configurations for ports_info. If manually
> configured infor
> @@ -637,7 +803,11 @@ class Dut(Crb):
> if ipv6 == "Not connected":
> continue
>
> - out = self.tester.send_ping6(remotePort, ipv6,
> self.get_mac_address(dutPort))
> + if getattr(self, 'send_ping6', None):
> + self.send_ping6(
> + dutPort,
> self.tester.ports_info[remotePort]['ipv6'])
> + out = self.tester.send_ping6(
> + remotePort, ipv6, self.get_mac_address(dutPort))
>
> if ('64 bytes from' in out):
> self.logger.info("PORT MAP: [dut %d: tester %d]" %
> (dutPort, remotePort))
> @@ -656,3 +826,31 @@ class Dut(Crb):
>
> for port in remove:
> self.ports_info.remove(port)
> +
> + def disable_tester_ipv6(self):
> + for tester_port in self.ports_map:
> + intf = self.tester.get_interface(tester_port)
> + self.tester.disable_ipv6(intf)
> +
> + def enable_tester_ipv6(self):
> + for tester_port in self.ports_map:
> + intf = self.tester.get_interface(tester_port)
> + self.tester.enable_ipv6(intf)
> +
> + def check_port_occupied(self, port):
> + out = self.alt_session.send_expect('lsof -i:%d' % port, '# ')
> + if out == '':
> + return False
> + else:
> + return True
> +
> + def get_maximal_vnc_num(self):
> + out = self.send_expect("ps aux | grep '\-vnc' | grep -v grep",
> '# ')
> + if out:
> + ports = re.findall(r'-vnc .*?:(\d+)', out)
> + for num in range(len(ports)):
> + ports[num] = int(ports[num])
> + ports.sort()
> + else:
> + ports = [0, ]
> + return ports[-1]
> diff --git a/framework/net_device.py b/framework/net_device.py
> new file mode 100644
> index 0000000..c04d442
> --- /dev/null
> +++ b/framework/net_device.py
> @@ -0,0 +1,600 @@
> +import os
> +import re
> +from functools import wraps
> +import time
> +import pdb
> +
> +import settings
> +from crb import Crb
> +from settings import TIMEOUT
> +
> +
> +class NetDevice(object):
> +
> + """
> + Abstract the device which is PF or VF.
> + """
> +
> + def __init__(self, crb, bus_id, devfun_id):
> + if not isinstance(crb, Crb):
> + raise Exception(" Please input the instance of Crb!!!")
> + self.crb = crb
> + self.bus_id = bus_id
> + self.devfun_id = devfun_id
> + self.pci = bus_id + ':' + devfun_id
> + self.pci_id = self.get_pci_id(bus_id, devfun_id)
> + self.default_driver = settings.get_nic_driver(self.pci_id)
> + # bind to default driver
> + current_driver = self.get_nic_driver()
> + if self.default_driver != current_driver:
> + self.bind_driver()
> + if self.nic_is_pf():
> + self.default_vf_driver = ''
> + self.intf_name = self.get_interface_name()
> +
> + def __send_expect(self, cmds, expected, timeout=TIMEOUT,
> alt_session=True):
> + """
> + Wrap the crb`s session as private session for sending expect.
> + """
> + return self.crb.send_expect(cmds, expected, timeout=timeout,
> alt_session=alt_session)
> +
> + def __get_os_type(self):
> + """
> + Get OS type.
> + """
> + return self.crb.get_os_type()
> +
> + def nic_is_pf(self):
> + """
> + It is the method that you can check if the nic is PF.
> + """
> + return True
> +
> + def nic_has_driver(func):
> + """
> + Check if the NIC has a driver.
> + """
> + @wraps(func)
> + def wrapper(*args, **kwargs):
> + nic_instance = args[0]
> + nic_instance.current_driver = nic_instance.get_nic_driver()
> + if not nic_instance.current_driver:
> + return ''
> + return func(*args, **kwargs)
> + return wrapper
> +
> + def get_nic_driver(self):
> + """
> + Get the NIC driver.
> + """
> + return self.crb.get_pci_dev_driver(self.bus_id, self.devfun_id)
> +
> + @nic_has_driver
> + def get_interface_name(self):
> + """
> + Get interface name of specified pci device.
> + """
> + get_interface_name = getattr(
> + self, 'get_interface_name_%s' %
> + self.__get_os_type())
> + return get_interface_name(self.bus_id, self.devfun_id,
> self.current_driver)
> +
> + def get_interface_name_linux(self, bus_id, devfun_id, driver):
> + """
> + Get interface name of specified pci device on linux.
> + """
> + try:
> + get_interface_name_linux = getattr(
> + self,
> + 'get_interface_name_linux_%s' %
> + driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_interface_name_linux = getattr(self,
> +
> 'get_interface_name_linux_%s' % generic_driver)
> +
> + return get_interface_name_linux(bus_id, devfun_id)
> +
> + def get_interface_name_linux_generic(self, bus_id, devfun_id):
> + """
> + Get the interface name by the default way on linux.
> + """
> + command = 'ls --color=never
> /sys/bus/pci/devices/0000\:%s\:%s/net' % (
> + bus_id, devfun_id)
> + return self.__send_expect(command, '# ')
> +
> + def get_interface_name_freebsd(self, bus_id, devfun_id, driver):
> + """
> + Get interface name of specified pci device on Freebsd.
> + """
> + try:
> + get_interface_name_linux = getattr(self,
> +
> 'get_interface_name_freebsd_%s' % driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_interface_name_linux = getattr(self,
> +
> 'get_interface_name_freebsd_%s' % generic_driver)
> +
> + return get_interface_name_freebsd(bus_id, devfun_id)
> +
> + def get_interface_name_freebsd_generic(self, bus_id, devfun_id):
> + """
> + Get the interface name by the default way on freebsd.
> + """
> + out = self.__send_expect("pciconf -l", "# ")
> + rexp = r"(\w*)@pci0:%s" % bus_id
> + pattern = re.compile(rexp)
> + match = pattern.findall(out)
> + return match[0]
> +
> + @nic_has_driver
> + def get_mac_addr(self):
> + """
> + Get mac address of specified pci device.
> + """
> + get_mac_addr = getattr(self, 'get_mac_addr_%s' %
> self.__get_os_type())
> + return get_mac_addr(self.intf_name, self.bus_id,
> self.devfun_id, self.current_driver)
> +
> + def get_mac_addr_linux(self, intf, bus_id, devfun_id, driver):
> + """
> + Get mac address of specified pci device on linux.
> + """
> + try:
> + get_mac_addr_linux = getattr(
> + self,
> + 'get_mac_addr_linux_%s' %
> + driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_mac_addr_linux = getattr(
> + self,
> + 'get_mac_addr_linux_%s' %
> + generic_driver)
> +
> + return get_mac_addr_linux(intf, bus_id, devfun_id, driver)
> +
> + def get_pci_id(self, bus_id, devfun_id):
> + command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/vendor' %
> + (bus_id, devfun_id))
> + out = self.__send_expect(command, '# ')
> + vender = out[2:]
> + command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/device' %
> + (bus_id, devfun_id))
> + out = self.__send_expect(command, '# ')
> + device = out[2:]
> + return "%s:%s" % (vender, device)
> +
> + def get_mac_addr_linux_generic(self, intf, bus_id, devfun_id,
> driver):
> + """
> + Get MAC by the default way on linux.
> + """
> + command = ('cat
> /sys/bus/pci/devices/0000\:%s\:%s/net/%s/address' %
> + (bus_id, devfun_id, intf))
> + return self.__send_expect(command, '# ')
> +
> + def get_mac_addr_freebsd(self, intf, bus_id, devfun_id, driver):
> + """
> + Get mac address of specified pci device on Freebsd.
> + """
> + try:
> + get_mac_addr_freebsd = getattr(
> + self,
> + 'get_mac_addr_freebsd_%s' %
> + driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_mac_addr_freebsd = getattr(
> + self,
> + 'get_mac_addr_freebsd_%s' %
> + generic_driver)
> +
> + return get_mac_addr_freebsd(intf, bus_id, devfun_id, driver)
> +
> + def get_mac_addr_freebsd_generic(self, intf, bus_id, devfun_id):
> + """
> + Get the MAC by the default way on Freebsd.
> + """
> + out = self.__send_expect('ifconfig %s' % intf, '# ')
> + rexp = r"ether ([\da-f:]*)"
> + pattern = re.compile(rexp)
> + match = pattern.findall(out)
> + return match[0]
> +
> + @nic_has_driver
> + def get_ipv4_addr(self):
> + """
> + Get ipv4 address of specified pci device.
> + """
> + get_ipv4_addr = getaddr(
> + self, 'get_ipv4_addr_%s' % self.__get_os_type())
> + return get_ipv4_addr(self.intf_name, self.currenct_driver)
> +
> + def get_ipv4_addr_linux(self, intf, driver):
> + """
> + Get ipv4 address of specified pci device on linux.
> + """
> + try:
> + get_ipv4_addr_linux = getattr(self, 'get_ipv4_linux_%s' %
> driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_ipv4_addr_linux = getattr(
> + self, 'get_ipv4_linux_%s' %
> + generic_driver)
> +
> + return get_ipv4_addr_linux(intf, bus_id, devfun_id, driver)
> +
> + def get_ipv4_addr_linux_generic(self, intf):
> + """
> + Get IPv4 address by the default way on linux.
> + """
> + out = self.__send_expect("ip -family inet address show dev %s
> | awk '/inet/ { print $2 }'"
> + % intf, "# ")
> + return out.split('/')[0]
> +
> + def get_ipv4_addr_freebsd(self, intf, driver):
> + """
> + Get ipv4 address of specified pci device on Freebsd.
> + """
> + try:
> + get_ipv4_addr_freebsd = getattr(
> + self,
> + 'get_ipv4_addr_freebsd_%s' %
> + driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_ipv4_addr_freebsd = getattr(
> + self,
> + 'get_ipv4_addr_freebsd_%s' %
> + generic_driver)
> +
> + return get_ipv4_addr_freebsd(intf, bus_id, devfun_id)
> +
> + def get_ipv4_addr_freebsd_generic(self, intf):
> + """
> + Get the IPv4 address by the default way on Freebsd.
> + """
> + out = self.__send_expect('ifconfig %s' % intf, '# ')
> + rexp = r"inet ([\d:]*)%"
> + pattern = re.compile(rexp)
> + match = pattern.findall(out)
> + if len(match) == 0:
> + return None
> +
> + return match[0]
> +
> + @nic_has_driver
> + def get_ipv6_addr(self):
> + """
> + Get ipv6 address of specified pci device.
> + """
> + get_ipv6_addr = getattr(
> + self, 'get_ipv6_addr_%s' % self.__get_os_type())
> + return get_ipv6_addr(self.intf_name, self.current_driver)
> +
> + def get_ipv6_addr_linux(self, intf, driver):
> + """
> + Get ipv6 address of specified pci device on linux.
> + """
> + try:
> + get_ipv6_addr_linux = getattr(
> + self,
> + 'get_ipv6_addr_linux_%s' %
> + driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_ipv6_addr_linux = getattr(
> + self,
> + 'get_ipv6_addr_linux_%s' %
> + generic_driver)
> +
> + return get_ipv6_addr_linux(intf)
> +
> + def get_ipv6_addr_linux_generic(self, intf):
> + """
> + Get the IPv6 address by the default way on linux.
> + """
> + out = self.__send_expect("ip -family inet6 address show dev %s
> | awk '/inet6/ { print $2 }'"
> + % intf, "# ")
> + return out.split('/')[0]
> +
> + def get_ipv6_addr_freebsd(self, intf, driver):
> + """
> + Get ipv6 address of specified pci device on Freebsd.
> + """
> + try:
> + get_ipv6_addr_freebsd = getattr(
> + self,
> + 'get_ipv6_addr_freebsd_%s' %
> + driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_ipv6_addr_freebsd = getattr(
> + self,
> + 'get_ipv6_addr_freebsd_%s' %
> + generic_driver)
> +
> + return get_ipv6_addr_freebsd(intf)
> +
> + def get_ipv6_addr_freebsd_generic(self, intf):
> + """
> + Get the IPv6 address by the default way on Freebsd.
> + """
> + out = self.__send_expect('ifconfig %s' % intf, '# ')
> + rexp = r"inet6 ([\da-f:]*)%"
> + pattern = re.compile(rexp)
> + match = pattern.findall(out)
> + if len(match) == 0:
> + return None
> +
> + return match[0]
> +
> + def get_nic_numa(self):
> + """
> + Get numa number of specified pci device.
> + """
> + self.crb.get_nic_numa(self.bus_id, self.devfun_id)
> +
> + def get_card_type(self):
> + """
> + Get card type of specified pci device.
> + """
> + return self.crb.get_pci_dev_id(self.bus_id, self.devfun_id)
> +
> + @nic_has_driver
> + def get_sriov_vfs_pci(self):
> + """
> + Get all SRIOV VF pci bus of specified pci device.
> + """
> + get_sriov_vfs_pci = getattr(
> + self, 'get_sriov_vfs_pci_%s' % self.__get_os_type())
> + return get_sriov_vfs_pci(self.bus_id, self.devfun_id,
> self.current_driver)
> +
> + def get_sriov_vfs_pci_linux(self, bus_id, devfun_id, driver):
> + """
> + Get all SRIOV VF pci bus of specified pci device on linux.
> + """
> + try:
> + get_sriov_vfs_pci_linux = getattr(
> + self,
> + 'get_sriov_vfs_pci_linux_%s' %
> + driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + get_sriov_vfs_pci_linux = getattr(
> + self,
> + 'get_sriov_vfs_pci_linux_%s' %
> + generic_driver)
> +
> + return get_sriov_vfs_pci_linux(bus_id, devfun_id)
> +
> + def get_sriov_vfs_pci_linux_generic(self, bus_id, devfun_id):
> + """
> + Get all the VF PCIs of specified PF by the default way on
> linux.
> + """
> + sriov_numvfs = self.__send_expect(
> + "cat /sys/bus/pci/devices/0000\:%s\:%s/sriov_numvfs" %
> + (bus_id, devfun_id), "# ")
> + sriov_vfs_pci = []
> + if int(sriov_numvfs) == 0:
> + pass
> + else:
> + try:
> + virtfns = self.__send_expect(
> + "ls -d /sys/bus/pci/devices/0000\:%s\:%s/virtfn*" %
> + (bus_id, devfun_id), "# ")
> + for virtfn in virtfns.split():
> + vf_uevent = self.__send_expect(
> + "cat %s" %
> + os.path.join(virtfn, "uevent"), "# ")
> + vf_pci = re.search(
> + r"PCI_SLOT_NAME=0000:([0-9a-f]+:[0-9a-f]+\.[0-
> 9a-f]+)",
> + vf_uevent).group(1)
> + sriov_vfs_pci.append(vf_pci)
> + except Exception as e:
> + print "Scan linux port [0000:%s.%s] sriov vf
> failed: %s" % (bus_id, devfun_id, e)
> +
> + return sriov_vfs_pci
> +
> + @nic_has_driver
> + def generate_sriov_vfs(self, vf_num):
> + """
> + Generate some numbers of SRIOV VF.
> + """
> + if vf_num == 0:
> + self.bind_vf_driver()
> + generate_sriov_vfs = getattr(
> + self, 'generate_sriov_vfs_%s' %
> + self.__get_os_type())
> + generate_sriov_vfs(
> + self.bus_id,
> + self.devfun_id,
> + vf_num,
> + self.current_driver)
> + if vf_num != 0:
> + self.sriov_vfs_pci = self.get_sriov_vfs_pci()
> +
> + vf_pci = self.sriov_vfs_pci[0]
> + addr_array = vf_pci.split(':')
> + bus_id = addr_array[0]
> + devfun_id = addr_array[1]
> +
> + self.default_vf_driver = self.crb.get_pci_dev_driver(
> + bus_id, devfun_id)
> + else:
> + self.sriov_vfs_pci = []
> + time.sleep(1)
> +
> + def generate_sriov_vfs_linux(self, bus_id, devfun_id, vf_num,
> driver):
> + """
> + Generate some numbers of SRIOV VF.
> + """
> + try:
> + generate_sriov_vfs_linux = getattr(
> + self,
> + 'generate_sriov_vfs_linux_%s' %
> + driver)
> + except Exception as e:
> + generic_driver = 'generic'
> + generate_sriov_vfs_linux = getattr(
> + self,
> + 'generate_sriov_vfs_linux_%s' %
> + generic_driver)
> +
> + return generate_sriov_vfs_linux(bus_id, devfun_id, vf_num)
> +
> + def generate_sriov_vfs_linux_generic(self, bus_id, devfun_id,
> vf_num):
> + """
> + Generate SRIOV VFs by the default way on linux.
> + """
> + nic_driver = self.get_nic_driver()
> +
> + if not nic_driver:
> + return None
> +
> + vf_reg_file = "sriov_numvfs"
> + vf_reg_path = os.path.join("/sys/bus/pci/devices/0000:%s:%s" %
> + (bus_id, devfun_id), vf_reg_file)
> + self.__send_expect("echo %d > %s" %
> + (int(vf_num), vf_reg_path), "# ")
> +
> + def generate_sriov_vfs_linux_igb_uio(self, bus_id, devfun_id,
> vf_num):
> + """
> + Generate SRIOV VFs by the special way of igb_uio driver on
> linux.
> + """
> + nic_driver = self.get_nic_driver()
> +
> + if not nic_driver:
> + return None
> +
> + vf_reg_file = "max_vfs"
> + vf_reg_path = os.path.join("/sys/bus/pci/devices/0000:%s:%s" %
> + (bus_id, devfun_id), vf_reg_file)
> + self.__send_expect("echo %d > %s" %
> + (int(vf_num), vf_reg_path), "# ")
> +
> + def destroy_sriov_vfs(self):
> + """
> + Destroy the SRIOV VFs.
> + """
> + self.generate_sriov_vfs(0)
> +
> + def bind_vf_driver(self, pci='', driver=''):
> + """
> + Bind the specified driver to VF.
> + """
> + bind_vf_driver = getattr(self, 'bind_driver_%s' %
> self.__get_os_type())
> + if not driver:
> + if not self.default_vf_driver:
> + print "Must specify a driver because default VF driver
> is NULL!"
> + return
> + driver = self.default_vf_driver
> +
> + if not pci:
> + if not self.sriov_vfs_pci:
> + print "No VFs on the nic [%s]!" % self.pci
> + return
> + for vf_pci in self.sriov_vfs_pci:
> + addr_array = vf_pci.split(':')
> + bus_id = addr_array[0]
> + devfun_id = addr_array[1]
> +
> + bind_vf_driver(bus_id, devfun_id, driver)
> + else:
> + addr_array = pci.split(':')
> + bus_id = addr_array[0]
> + devfun_id = addr_array[1]
> +
> + bind_vf_driver(bus_id, devfun_id, driver)
> +
> + def bind_driver(self, driver=''):
> + """
> + Bind specified driver to PF.
> + """
> + bind_driver = getattr(self, 'bind_driver_%s' %
> self.__get_os_type())
> + if not driver:
> + if not self.default_driver:
> + print "Must specify a driver because default driver is
> NULL!"
> + return
> + driver = self.default_driver
> + ret = bind_driver(self.bus_id, self.devfun_id, driver)
> + time.sleep(1)
> + return ret
> +
> + def bind_driver_linux(self, bus_id, devfun_id, driver):
> + """
> + Bind NIC port to specified driver on linux.
> + """
> + driver_alias = driver.replace('-', '_')
> + try:
> + bind_driver_linux = getattr(
> + self,
> + 'bind_driver_linux_%s' %
> + driver_alias)
> + return bind_driver_linux(bus_id, devfun_id)
> + except Exception as e:
> + driver_alias = 'generic'
> + bind_driver_linux = getattr(
> + self,
> + 'bind_driver_linux_%s' %
> + driver_alias)
> + return bind_driver_linux(bus_id, devfun_id, driver)
> +
> + def bind_driver_linux_generic(self, bus_id, devfun_id, driver):
> + """
> + Bind NIC port to specified driver by the default way on linux.
> + """
> + nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
> + self.__send_expect(
> + "echo %s >
> /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind" %
> + (nic_pci_num, bus_id, devfun_id), "# ")
> + self.__send_expect(
> + "echo %s > /sys/bus/pci/drivers/%s/bind" %
> + (nic_pci_num, driver), "# ")
> +
> + def bind_driver_linux_pci_stub(self, bus_id, devfun_id):
> + """
> + Bind NIC port to the pci-stub driver on linux.
> + """
> + nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
> + pci_id = self.get_card_type()
> + self.__send_expect(
> + "echo %s > /sys/bus/pci/drivers/pci-stub/new_id" %
> + nic_pci_num, "# ")
> + self.__send_expect(
> + "echo %s >
> /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind" %
> + (nic_pci_num, bus_id, devfun_id), "# ")
> + self.__send_expect(
> + "echo %s > /sys/bus/pci/drivers/pci-stub/bind" %
> + nic_pci_num, "# ")
> +
> + @nic_has_driver
> + def unbind_driver(self, driver=''):
> + """
> + Unbind driver.
> + """
> + unbind_driver = getattr(
> + self, 'unbind_driver_%s' %
> + self.__get_os_type())
> + if not driver:
> + driver = 'generic'
> + ret = unbind_driver(self.bus_id, self.devfun_id, driver)
> + time.sleep(1)
> + return ret
> +
> + def unbind_driver_linux(self, bus_id, devfun_id, driver):
> + """
> + Unbind driver on linux.
> + """
> + driver_alias = driver.replace('-', '_')
> +
> + unbind_driver_linux = getattr(
> + self, 'unbind_driver_linux_%s' % driver_alias)
> + return unbind_driver_linux(bus_id, devfun_id)
> +
> + def unbind_driver_linux_generic(self, bus_id, devfun_id):
> + """
> + Unbind driver by the default way on linux.
> + """
> + nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
> + cmd = "echo %s >
> /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind"
> + self.send_expect(cmd % (nic_pci_num, bus_id, devfun_id), "# ")
> diff --git a/framework/settings.py b/framework/settings.py
> index feb6fa5..2eccc64 100644
> --- a/framework/settings.py
> +++ b/framework/settings.py
> @@ -48,6 +48,7 @@ NICS = {
> 'powerville': '8086:1521',
> 'ophir': '8086:105e',
> 'niantic': '8086:10fb',
> + 'niantic_vf': '8086:10ed',
> 'ironpond': '8086:151c',
> 'twinpond': '8086:1528',
> 'twinville': '8086:1512',
> @@ -77,6 +78,7 @@ DRIVERS = {
> 'powerville': 'igb',
> 'ophir': 'igb',
> 'niantic': 'ixgbe',
> + 'niantic_vf': 'ixgbevf',
> 'ironpond': 'ixgbe',
> 'twinpond': 'ixgbe',
> 'twinville': 'ixgbe',
> @@ -137,6 +139,17 @@ Global macro for dts.
> """
> IXIA = "ixia"
>
> +"""
> +The root path of framework configs.
> +"""
> +CONFIG_ROOT_PATH = "./conf/"
> +
> +"""
> +The log name seperater.
> +"""
> +LOG_NAME_SEP = '.'
> +
> +
> def nic_name_from_type(type):
> """
> strip nic code name by nic type
> @@ -145,3 +158,33 @@ def nic_name_from_type(type):
> if nic_type == type:
> return name
> return 'Unknown'
> +
> +
> +def get_nic_driver(pci_id):
> + """
> + Return linux driver for specified pci device
> + """
> + driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
> + try:
> + driver = DRIVERS[driverlist[pci_id]]
> + except Exception as e:
> + driver = None
> + return driver
> +
> +
> +def accepted_nic(pci_id):
> + """
> + Return True if the pci_id is a known NIC card in the settings file
> and if
> + it is selected in the execution file, otherwise it returns False.
> + """
> + if pci_id not in NICS.values():
> + return False
> +
> + if nic is 'any':
> + return True
> +
> + else:
> + if pci_id == NICS[nic]:
> + return True
> +
> + return False
> diff --git a/framework/test_case.py b/framework/test_case.py
> index 3d2e2dc..a519691 100644
> --- a/framework/test_case.py
> +++ b/framework/test_case.py
> @@ -40,10 +40,11 @@ from settings import DRIVERS, NICS,
> nic_name_from_type
>
> class TestCase(object):
>
> - def __init__(self, dut, tester, target):
> + def __init__(self, dut, tester, target, suite):
> self.dut = dut
> self.tester = tester
> self.target = target
> + self.suite = suite
> self.nics = []
> for portid in range(len(self.dut.ports_info)):
> nic_type = self.dut.ports_info[portid]['type']
> diff --git a/framework/tester.py b/framework/tester.py
> index aba0356..ce136e4 100644
> --- a/framework/tester.py
> +++ b/framework/tester.py
> @@ -38,6 +38,7 @@ from time import sleep
> from settings import NICS
> from ssh_connection import SSHConnection
> from crb import Crb
> +from net_device import NetDevice
> from etgen import IxiaPacketGenerator, SoftwarePacketGenerator
> from logger import getLogger
> from settings import IXIA
> @@ -152,6 +153,7 @@ class Tester(Crb):
> index += 1
> if pci == port['pci']:
> return index
> + return -1
>
> def get_pci(self, localPort):
> """
> @@ -163,6 +165,9 @@ class Tester(Crb):
> """
> Return tester local port interface name.
> """
> + if 'intf' not in self.ports_info[localPort]:
> + return 'N/A'
> +
> return self.ports_info[localPort]['intf']
>
> def get_mac(self, localPort):
> @@ -202,26 +207,51 @@ class Tester(Crb):
> try:
> for (pci_bus, pci_id) in self.pci_devices_info:
> addr_array = pci_bus.split(':')
> - itf = self.get_interface_name(addr_array[0],
> addr_array[1])
> + port = NetDevice(self, addr_array[0], addr_array[1])
> + itf = port.get_interface_name()
> + self.enable_ipv6(itf)
> self.send_expect("ifconfig %s up" % itf, "# ")
>
> except Exception as e:
> self.logger.error(" !!! Restore ITF: " + e.message)
>
> + sleep(2)
> +
> + def load_serializer_ports(self):
> + self.ports_info = []
> + cached_ports_info =
> self.serializer.load(self.PORT_INFO_CACHE_KEY)
> + if cached_ports_info is None:
> + return
> +
> + # now not save netdev object, will implemented later
> + self.ports_info = cached_ports_info
> +
> + def save_serializer_ports(self):
> + cached_ports_info = []
> + for port in self.ports_info:
> + port_info = {}
> + for key in port.keys():
> + if type(port[key]) is str:
> + port_info[key] = port[key]
> + # need save netdev objects
> + cached_ports_info.append(port_info)
> + self.serializer.save(self.PORT_INFO_CACHE_KEY,
> cached_ports_info)
> +
> 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)
> + self.load_serializer_ports()
>
> if not self.read_cache or self.ports_info is None:
> self.scan_ports_uncached()
> if self.it_uses_external_generator():
>
> self.ports_info.extend(self.ixia_packet_gen.get_ports())
> - self.serializer.save(self.PORT_INFO_CACHE_KEY,
> self.ports_info)
> + self.save_serializer_ports()
>
> - self.logger.info(self.ports_info)
> + for port_info in self.ports_info:
> + self.logger.info(port_info)
>
> def scan_ports_uncached(self):
> """
> @@ -240,7 +270,8 @@ class Tester(Crb):
> bus_id = addr_array[0]
> devfun_id = addr_array[1]
>
> - intf = self.get_interface_name(bus_id, devfun_id)
> + port = NetDevice(self, bus_id, devfun_id)
> + intf = port.get_interface_name()
>
> if "No such file" in intf:
> self.logger.info("Tester: [000:%s %s] %s" % (pci_bus,
> pci_id,
> @@ -248,13 +279,17 @@ class Tester(Crb):
> continue
>
> self.logger.info("Tester: [000:%s %s] %s" % (pci_bus,
> pci_id, intf))
> - macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
> + macaddr = port.get_mac_addr()
> +
> + ipv6 = port.get_ipv6_addr()
>
> # store the port info to port mapping
> - self.ports_info.append({'pci': pci_bus,
> + self.ports_info.append({'port': port,
> + 'pci': pci_bus,
> 'type': pci_id,
> 'intf': intf,
> - 'mac': macaddr})
> + 'mac': macaddr,
> + 'ipv6': ipv6})
>
> def send_ping6(self, localPort, ipv6, mac):
> """
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases
2015-05-18 8:45 ` Liu, Yong
@ 2015-05-18 9:05 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-18 9:05 UTC (permalink / raw)
To: Liu, Yong, Xu, HuilongX, dts
> -----Original Message-----
> From: Liu, Yong
> Sent: Monday, May 18, 2015 4:46 PM
> To: Xu, HuilongX; Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to
> code the testpmd cases
>
> Some additional comments.
>
> > -----Original Message-----
> > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of Xu, HuilongX
> > Sent: Monday, May 18, 2015 4:29 PM
> > To: Jiajia, SunX; dts@dpdk.org
> > Subject: Re: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester
> to
> > code the testpmd cases
> >
> > Hi Jiajia,
> > I have a comments at " def execute_cmd(self, pmd_cmd,
> expected='testpmd> ',
> > timeout=TIMEOUT "
> > Would you check it, thanks a lot
> > -----Original Message-----
> > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > Sent: Monday, May 18, 2015 1:07 PM
> > To: dts@dpdk.org
> > Subject: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to
> code
> > the testpmd cases
> >
> > Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> > ---
> > framework/pmd_output.py | 104
> > +++++++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 102 insertions(+), 2 deletions(-)
> >
> > diff --git a/framework/pmd_output.py b/framework/pmd_output.py
> > index 97274a5..642062f 100644
> > --- a/framework/pmd_output.py
> > +++ b/framework/pmd_output.py
> > @@ -32,6 +32,7 @@
> > import os
> > import re
> > import dts
> > +from settings import TIMEOUT
> >
> >
> > class PmdOutput():
> > @@ -42,6 +43,7 @@ class PmdOutput():
> >
> > def __init__(self, dut):
> > self.dut = dut
> > + self.dut.testpmd = self
> > self.rx_pkts_prefix = "RX-packets:"
> > self.rx_missed_prefix = "RX-missed:"
> > self.rx_bytes_prefix = "RX-bytes:"
> > @@ -87,10 +89,108 @@ class PmdOutput():
> > return self.command
> >
> > def start_testpmd(self, cores, param='', eal_param='', socket=0):
> > + if "--txqflags" not in param:
> > + param += " --txqflags=0"
> > + if socket == 0:
> > + corelist = '0-3'
> > + elif socket == 1:
> > + corelist = '10-13'
> > + else:
> > + corelist = '0-3'
>
> Should not hard code here, cpu may change between platforms.
Yes, I will try to change it in the next version.
>
>
> > core_list = self.dut.get_core_list(cores, socket)
> > self.coremask = dts.create_mask(core_list)
> > - command = "./%s/app/testpmd -c %s -n %d %s -- -i %s" \
> > - % (self.dut.target, self.coremask,
> > self.dut.get_memory_channels(), eal_param, param)
> > + command = "taskset -c %s ./%s/app/testpmd -c %s -n %d %s --
> -
> > i %s" \
> > + % (corelist, self.dut.target, self.coremask,
> > self.dut.get_memory_channels(), eal_param, param)
> > out = self.dut.send_expect(command, "testpmd> ", 120)
> > self.command = command
> > return out
> >
> > maybe we need delete parameter "verify=False" in function
> execute_cmd,
> > when we used execute_cmd for exec testpmd cmdline, the parameter
> only
> > False.
Yes, I agree it.
> > +
> > + def execute_cmd(self, pmd_cmd, expected='testpmd> ',
> timeout=TIMEOUT,
> > + alt_session=False, verify=False):
> > + return self.dut.send_expect('%s' % pmd_cmd, expected,
> > timeout=timeout,
> > + alt_session=alt_session,
> > verify=verify)
> > +
> > + def get_value_from_string(self, key_str, regx_str, string):
> > + """
> > + Get some values from the given string by the regular
> expression.
> > + """
> > + pattern = r"(?<=%s)%s" % (key_str, regx_str)
> > + s = re.compile(pattern)
> > + res = s.search(string)
> > + if type(res).__name__ == 'NoneType':
> > + return ' '
> > + else:
> > + return res.group(0)
> > +
> > + def get_detail_from_port_info(self, key_str, regx_str, port):
> > + """
> > + Get the detail info from the output of pmd cmd 'show port
> info
> > <port num>'.
> > + """
> > + out = self.dut.send_expect("show port info %d" % port,
> "testpmd>
> > ")
> > + find_value = self.get_value_from_string(key_str, regx_str,
> out)
> > + return find_value
> > +
> > + def get_port_mac(self, port_id):
> > + """
> > + Get the specified port MAC.
> > + """
> > + return self.get_detail_from_port_info("MAC address: ", "([0-
> 9A-
> > F]{2}:){5}[0-9A-F]{2}", port_id)
> > +
> > + def get_port_connect_socket(self, port_id):
> > + """
> > + Get the socket id which the specified port is connectting
> with.
> > + """
> > + return self.get_detail_from_port_info("Connect to socket: ",
> > "\d+", port_id)
> > +
> > + def get_port_memory_socket(self, port_id):
> > + """
> > + Get the socket id which the specified port memory is
> allocated on.
> > + """
> > + return self.get_detail_from_port_info("memory allocation on
> the
> > socket: ", "\d+", port_id)
> > +
> > + def get_port_link_status(self, port_id):
> > + """
> > + Get the specified port link status now.
> > + """
> > + return self.get_detail_from_port_info("Link status: ", "\d+",
> > port_id)
> > +
> > + def get_port_link_speed(self, port_id):
> > + """
> > + Get the specified port link speed now.
> > + """
> > + return self.get_detail_from_port_info("Link speed: ", "\d+",
> > port_id)
> > +
> > + def get_port_link_duplex(self, port_id):
> > + """
> > + Get the specified port link mode, duplex or siplex.
> > + """
> > + return self.get_detail_from_port_info("Link duplex: ", "\S+",
> > port_id)
> > +
> > + def get_port_promiscuous_mode(self, port_id):
> > + """
> > + Get the promiscuous mode of port.
> > + """
> > + return self.get_detail_from_port_info("Promiscuous mode: ",
> "\S+",
> > port_id)
> > +
> > + def get_port_allmulticast_mode(self, port_id):
> > + """
> > + Get the allmulticast mode of port.
> > + """
> > + return self.get_detail_from_port_info("Allmulticast mode: ",
> > "\S+", port_id)
> > +
> > + def get_port_vlan_offload(self, port_id):
> > + """
> > + Function: get the port vlan settting info.
> > + return value:
> > + 'strip':'on'
> > + 'filter':'on'
> > + 'qinq':'off'
> > + """
> > + vlan_info = {}
> > + vlan_info['strip'] = self.get_detail_from_port_info(
> > + "strip ", '\S+', port_id)
> > + vlan_info['filter'] = self.get_detail_from_port_info(
> > + 'filter', '\S+', port_id)
> > + vlan_info['qinq'] = self.get_detail_from_port_info(
> > + 'qinq\(extend\) ', '\S+', port_id)
> > + return vlan_info
> > --
> > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test
2015-05-18 7:59 ` Xu, HuilongX
@ 2015-05-18 9:08 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-18 9:08 UTC (permalink / raw)
To: Xu, HuilongX, dts
> -----Original Message-----
> From: Xu, HuilongX
> Sent: Monday, May 18, 2015 4:00 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 3/9] Add some params and functions related
> to the virtual test
>
>
> Hi Jiajia,
> I have one comments at "@@ -202,7 +213,7 @@ class DPDKdut(Dut):"
> Would you check it, thanks a lot
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 3/9] Add some params and functions related to
> the virtual test
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> framework/dts.py | 92 +++++++++++----------------------------
> --------
> framework/exception.py | 27 ++++++++++++++
> framework/logger.py | 69 +++++++++++++++++++++++++++++------
> framework/main.py | 7 +++-
> framework/project_dpdk.py | 62 ++++++++++++++++++++++----------
> 5 files changed, 157 insertions(+), 100 deletions(-)
>
> diff --git a/framework/dts.py b/framework/dts.py
> index c9ecccb..c0df4e9 100644
> --- a/framework/dts.py
> +++ b/framework/dts.py
> @@ -49,6 +49,7 @@ from test_case import TestCase
> from test_result import Result
> from stats_reporter import StatsReporter
> from excel_reporter import ExcelReporter
> +from utils import *
> from exception import TimeoutException
> from logger import getLogger
> import logger
> @@ -57,6 +58,7 @@ import sys
> reload(sys)
> sys.setdefaultencoding('UTF8')
>
> +PROJECT_MODULE_PREFIX = 'project_'
>
> debug_mode = False
> config = None
> @@ -73,44 +75,12 @@ result = None
> excel_report = None
> stats = None
> log_handler = None
> +Package = ''
> +Patches = []
> drivername = ""
> interrupttypr = ""
>
>
> -def RED(text):
> - return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
> -
> -
> -def BLUE(text):
> - return "\x1B[" + "36;1m" + text + "\x1B[" + "0m"
> -
> -
> -def GREEN(text):
> - return "\x1B[" + "32;1m" + text + "\x1B[" + "0m"
> -
> -
> -def regexp(s, to_match, allString=False):
> - """
> - Ensure that the re `to_match' only has one group in it.
> - """
> -
> - scanner = re.compile(to_match, re.DOTALL)
> - if allString:
> - return scanner.findall(s)
> - m = scanner.search(s)
> - if m is None:
> - log_handler.warning("Failed to match " + to_match + " in the
> string " + s)
> - return None
> - return m.group(1)
> -
> -
> -def pprint(some_dict):
> - """
> - Print JSON format dictionary object.
> - """
> - return json.dumps(some_dict, sort_keys=True, indent=4)
> -
> -
> def report(text, frame=False, annex=False):
> """
> Save report text into rst file.
> @@ -132,36 +102,6 @@ def close_crb_sessions():
> log_handler.info("DTS ended")
>
>
> -def get_nic_driver(pci_id):
> - """
> - Return linux driver for specified pci device
> - """
> - driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
> - try:
> - driver = DRIVERS[driverlist[pci_id]]
> - except Exception as e:
> - driver = None
> - return driver
> -
> -
> -def accepted_nic(pci_id):
> - """
> - Return True if the pci_id is a known NIC card in the settings file
> and if
> - it is selected in the execution file, otherwise it returns False.
> - """
> - if pci_id not in NICS.values():
> - return False
> -
> - if nic is 'any':
> - return True
> -
> - else:
> - if pci_id == NICS[nic]:
> - return True
> -
> - return False
> -
> -
> def get_crb_os(crb):
> if 'OS' in crb:
> return crb['OS']
> @@ -220,9 +160,10 @@ def get_project_obj(project_name, super_class,
> crbInst, serializer):
> """
> Load project module and return crb instance.
> """
> + global PROJECT_MODULE_PREFIX
> project_obj = None
> try:
> - project_module = __import__("project_" + project_name)
> + project_module = __import__(PROJECT_MODULE_PREFIX +
> project_name)
>
> for project_subclassname, project_subclass in
> get_subclasses(project_module, super_class):
> project_obj = project_subclass(crbInst, serializer)
> @@ -267,19 +208,20 @@ def dts_log_execution(log_handler):
> pass
>
>
> -def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir,
> nic):
> +def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir,
> nic, virttype):
> """
> Create dts dut/tester instance and initialize them.
> """
> global dut
> global tester
> - serializer.set_serialized_filename('../.%s.cache' % crbInst['IP'])
> + serializer.set_serialized_filename('.%s.cache' % crbInst['IP'])
> serializer.load_from_file()
>
> dut = get_project_obj(project, Dut, crbInst, serializer)
> tester = get_project_obj(project, Tester, crbInst, serializer)
> dut.tester = tester
> tester.dut = dut
> + dut.set_virttype(virttype)
> dut.set_speedup_options(read_cache, skip_setup)
> dut.set_directory(base_dir)
> dut.set_nic_type(nic)
> @@ -337,7 +279,6 @@ def dts_run_target(crbInst, targets, test_suites,
> nic):
> if 'nic_type' not in paramDict:
> paramDict['nic_type'] = 'any'
> nic = 'any'
> - result.nic = nic
>
> dts_run_suite(crbInst, test_suites, target, nic)
>
> @@ -359,7 +300,9 @@ def dts_run_suite(crbInst, test_suites, target,
> nic):
> test_module = __import__('TestSuite_' + test_suite)
> for test_classname, test_class in
> get_subclasses(test_module, TestCase):
>
> - test_suite = test_class(dut, tester, target)
> + test_suite = test_class(dut, tester, target,
> test_suite)
> + result.nic = test_suite.nic
> +
> dts_log_testsuite(test_suite, log_handler,
> test_classname)
>
> log_handler.info("\nTEST SUITE : " + test_classname)
> @@ -386,7 +329,7 @@ def dts_run_suite(crbInst, test_suites, target,
> nic):
>
> def run_all(config_file, pkgName, git, patch, skip_setup,
> read_cache, project, suite_dir, test_cases,
> - base_dir, output_dir, verbose, debug):
> + base_dir, output_dir, verbose, virttype, debug):
> """
> Main process of DTS, it will run all test suites in the config
> file.
> """
> @@ -400,6 +343,12 @@ def run_all(config_file, pkgName, git, patch,
> skip_setup,
> global stats
> global log_handler
> global debug_mode
> + global Package
> + global Patches
> +
> + # save global variable
> + Package = pkgName
> + Patches = patch
>
> # prepare the output folder
> if not os.path.exists(output_dir):
> @@ -466,7 +415,8 @@ def run_all(config_file, pkgName, git, patch,
> skip_setup,
> result.dut = dutIP
>
> # init dut, tester crb
> - dts_crbs_init(crbInst, skip_setup, read_cache, project,
> base_dir, nics)
> + dts_crbs_init(
> + crbInst, skip_setup, read_cache, project, base_dir, nics,
> virttype)
>
> # Run DUT prerequisites
> if dts_run_prerequisties(pkgName, patch) is False:
> diff --git a/framework/exception.py b/framework/exception.py
> index be38c16..98dedf4 100644
> --- a/framework/exception.py
> +++ b/framework/exception.py
> @@ -46,3 +46,30 @@ class SSHConnectionException(Exception):
>
> def __str__(self):
> return 'Error trying to connect with %s' % self.host
> +
> +
> +class SSHSessionDeadException(Exception):
> +
> + """
> + SSH session is not alive.
> + It can no longer be used.
> + """
> +
> + def __init__(self, host):
> + self.host = host
> +
> + def __str__(self):
> + return 'SSH session with %s has been dead' % self.host
> +
> +
> +class StartVMFailedException(Exception):
> +
> + """
> + Start VM failed.
> + """
> +
> + def __init__(self, error):
> + self.error = error
> +
> + def __str__(self):
> + return repr(self.error)
> diff --git a/framework/logger.py b/framework/logger.py
> index 1829e18..5597e33 100644
> --- a/framework/logger.py
> +++ b/framework/logger.py
> @@ -35,6 +35,9 @@ import sys
> import inspect
> import re
>
> +from settings import LOG_NAME_SEP
> +from utils import RED
> +
> """
> DTS logger module with several log level. DTS framwork and TestSuite
> log
> will saved into different log files.
> @@ -58,6 +61,9 @@ logging.SUITE_TESTER_OUTPUT = logging.DEBUG + 4
> logging.DTS_IXIA_CMD = logging.INFO + 5
> logging.DTS_IXIA_OUTPUT = logging.DEBUG + 5
>
> +logging.DTS_VIRTDUT_CMD = logging.INFO + 6
> +logging.DTS_VIRTDUT_OUTPUT = logging.DEBUG + 6
> +
> logging.addLevelName(logging.DTS_DUT_CMD, 'DTS_DUT_CMD')
> logging.addLevelName(logging.DTS_DUT_OUTPUT, 'DTS_DUT_OUTPUT')
> logging.addLevelName(logging.DTS_DUT_RESULT, 'DTS_DUT_RESUTL')
> @@ -66,6 +72,12 @@ logging.addLevelName(logging.DTS_TESTER_CMD,
> 'DTS_TESTER_CMD')
> logging.addLevelName(logging.DTS_TESTER_OUTPUT, 'DTS_TESTER_OUTPUT')
> logging.addLevelName(logging.DTS_TESTER_RESULT, 'DTS_TESTER_RESULT')
>
> +logging.addLevelName(logging.DTS_IXIA_CMD, 'DTS_IXIA_CMD')
> +logging.addLevelName(logging.DTS_IXIA_OUTPUT, 'DTS_IXIA_OUTPUT')
> +
> +logging.addLevelName(logging.DTS_VIRTDUT_CMD, 'VIRTDUT_CMD')
> +logging.addLevelName(logging.DTS_VIRTDUT_OUTPUT, 'VIRTDUT_OUTPUT')
> +
> logging.addLevelName(logging.SUITE_DUT_CMD, 'SUITE_DUT_CMD')
> logging.addLevelName(logging.SUITE_DUT_OUTPUT, 'SUITE_DUT_OUTPUT')
>
> @@ -82,15 +94,18 @@ stream_fmt =
> '%(color)s%(levelname)20s: %(message)s' + RESET_COLOR
> log_dir = None
>
>
> -def RED(text):
> - return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
> -
> -
> def set_verbose():
> global verbose
> verbose = True
>
>
> +def add_salt(salt, msg):
> + if not salt:
> + return msg
> + else:
> + return '[%s] ' % salt + str(msg)
> +
> +
> class BaseLoggerAdapter(logging.LoggerAdapter):
> """
> Upper layer of original logging module.
> @@ -132,6 +147,12 @@ class BaseLoggerAdapter(logging.LoggerAdapter):
> def dts_ixia_output(self, msg, *args, **kwargs):
> self.log(logging.DTS_IXIA_OUTPUT, msg, *args, **kwargs)
>
> + def dts_virtdut_cmd(self, msg, *args, **kwargs):
> + self.log(logging.DTS_VIRTDUT_CMD, msg, *args, **kwargs)
> +
> + def dts_virtdut_output(self, msg, *args, **kwargs):
> + self.log(logging.DTS_VIRTDUT_OUTPUT, msg, *args, **kwargs)
> +
>
> class ColorHandler(logging.StreamHandler):
> """
> @@ -150,6 +171,8 @@ class ColorHandler(logging.StreamHandler):
> logging.SUITE_TESTER_CMD: '', # SYSTEM
> logging.DTS_IXIA_CMD: '', # SYSTEM
> logging.DTS_IXIA_OUTPUT: '', # SYSTEM
> + logging.DTS_VIRTDUT_CMD: '', # SYSTEM
> + logging.DTS_VIRTDUT_OUTPUT: '', # SYSTEM
> logging.WARN: '\033[01;33m', # BOLD YELLOW
> logging.DTS_DUT_RESULT: '\033[01;34m', # BOLD BLUE
> logging.DTS_TESTER_RESULT: '\033[01;34m', # BOLD BLUE
> @@ -189,6 +212,8 @@ class DTSLOG(BaseLoggerAdapter):
> self.crb = crb
> super(DTSLOG, self).__init__(self.logger, dict(crb=self.crb))
>
> + self.salt = ''
> +
> self.fh = None
> self.ch = None
>
> @@ -221,24 +246,28 @@ class DTSLOG(BaseLoggerAdapter):
> """
> DTS warnning level log function.
> """
> + message = add_salt(self.salt, message)
> self.logger.log(self.warn_lvl, message)
>
> def info(self, message):
> """
> DTS information level log function.
> """
> + message = add_salt(self.salt, message)
> self.logger.log(self.info_lvl, message)
>
> def error(self, message):
> """
> DTS error level log function.
> """
> + message = add_salt(self.salt, message)
> self.logger.log(self.error_lvl, message)
>
> def debug(self, message):
> """
> DTS debug level log function.
> """
> + message = add_salt(self.salt, message)
> self.logger.log(self.debug_lvl, message)
>
> def set_logfile_path(self, path):
> @@ -270,17 +299,34 @@ class DTSLOG(BaseLoggerAdapter):
> ch = ColorHandler()
> self.__log_hander(fh, ch)
>
> - if crb == "dut":
> + def set_salt(crb, start_flag):
> + if LOG_NAME_SEP in crb:
> + old = '%s%s' % (start_flag, LOG_NAME_SEP)
> + if not self.salt:
> + self.salt = crb.replace(old, '', 1)
> +
> + if crb.startswith('dut'):
> self.info_lvl = logging.DTS_DUT_CMD
> self.debug_lvl = logging.DTS_DUT_OUTPUT
> self.warn_lvl = logging.DTS_DUT_RESULT
> - elif crb == "tester":
> +
> + set_salt(crb, 'dut')
> + elif crb.startswith('tester'):
> self.info_lvl = logging.DTS_TESTER_CMD
> self.debug_lvl = logging.DTS_TESTER_OUTPUT
> self.warn_lvl = logging.DTS_TESTER_RESULT
> - elif crb == "ixia":
> +
> + set_salt(crb, 'tester')
> + elif crb.startswith('ixia'):
> self.info_lvl = logging.DTS_IXIA_CMD
> self.debug_lvl = logging.DTS_IXIA_OUTPUT
> +
> + set_salt(crb, 'ixia')
> + elif crb.startswith('virtdut'):
> + self.info_lvl = logging.DTS_VIRTDUT_CMD
> + self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
> +
> + set_salt(crb, 'virtdut')
> else:
> self.error_lvl = logging.ERROR
> self.warn_lvl = logging.WARNING
> @@ -296,15 +342,18 @@ class DTSLOG(BaseLoggerAdapter):
> ch = ColorHandler()
> self.__log_hander(fh, ch)
>
> - if crb == "dut":
> + if crb == 'dut':
> self.info_lvl = logging.SUITE_DUT_CMD
> self.debug_lvl = logging.SUITE_DUT_OUTPUT
> - elif crb == "tester":
> + elif crb == 'tester':
> self.info_lvl = logging.SUITE_TESTER_CMD
> self.debug_lvl = logging.SUITE_TESTER_OUTPUT
> - elif crb == "ixia":
> + elif crb == 'ixia':
> self.info_lvl = logging.DTS_IXIA_CMD
> self.debug_lvl = logging.DTS_IXIA_OUTPUT
> + elif crb == 'virtdut':
> + self.info_lvl = logging.DTS_VIRTDUT_CMD
> + self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT
>
> def logger_exit(self):
> """
> diff --git a/framework/main.py b/framework/main.py
> index 3e467d0..0496b20 100755
> --- a/framework/main.py
> +++ b/framework/main.py
> @@ -117,6 +117,10 @@ parser.add_argument('-v', '--verbose',
> action='store_true',
> help='enable verbose output, all message output on
> screen')
>
> +parser.add_argument('--virttype',
> + default='kvm',
> + help='set virt type,support libvirt,xen,kvm')
> +
> parser.add_argument('--debug',
> action='store_true',
> help='enable debug mode, user can enter debug mode
> in process')
> @@ -136,4 +140,5 @@ if args.git is not None:
> dts.run_all(args.config_file, args.snapshot, args.git,
> args.patch, args.skip_setup, args.read_cache,
> args.project, args.suite_dir, args.test_cases,
> - args.dir, args.output, args.verbose, args.debug)
> + args.dir, args.output, args.verbose,args.virttype,
> + args.debug)
> diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py
> index 8963924..67bd492 100644
> --- a/framework/project_dpdk.py
> +++ b/framework/project_dpdk.py
> @@ -39,7 +39,7 @@ from crb import Crb
> from dut import Dut
> from tester import Tester
> from logger import getLogger
> -from settings import IXIA
> +from settings import IXIA, accepted_nic
>
>
> class DPDKdut(Dut):
> @@ -50,8 +50,9 @@ class DPDKdut(Dut):
> """
>
> def __init__(self, crb, serializer):
> - self.NAME = 'dut'
> +
> super(DPDKdut, self).__init__(crb, serializer)
> + self.testpmd = None
>
> def set_target(self, target):
> """
> @@ -60,6 +61,7 @@ class DPDKdut(Dut):
> Set hugepage on DUT and install modules required by DPDK.
> Configure default ixgbe PMD function.
> """
> + self.target = target
> self.set_toolchain(target)
>
> # set env variable
> @@ -99,7 +101,16 @@ class DPDKdut(Dut):
> out = self.send_expect("lsmod | grep igb_uio", "#")
> if "igb_uio" in out:
> self.send_expect("rmmod -f igb_uio", "#", 70)
> - self.send_expect("insmod ./" + target + "/kmod/igb_uio.ko",
> "#", 60)
> + if "rte_dom0_mm" in self.send_expect("lsmod |grep
> rte_dom0_mm", "#"):
> + self.send_expect("rmmod -f rte_dmo0_mm", "#", 70)
> + self.send_expect(
> + "insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
> + if self.virttype == 'xen':
> + self.send_expect(
> + "insmod ./" + target + "/kmod/rte_dom0_mm.ko", "#",
> 60)
> + self.send_expect(
> + r'echo 1024 > /sys/kernel/mm/dom0-mm/memsize-
> mB/memsize', "#", 70)
> +
> out = self.send_expect("lsmod | grep igb_uio", "#")
> assert ("igb_uio" in out), "Failed to insmod igb_uio"
>
> @@ -110,7 +121,7 @@ class DPDKdut(Dut):
> binding_list = ''
>
> for (pci_bus, pci_id) in self.pci_devices_info:
> - if dts.accepted_nic(pci_id):
> + if accepted_nic(pci_id):
> binding_list += '%s,' % (pci_bus)
>
> self.send_expect("kldunload if_ixgbe.ko", "#")
> @@ -158,6 +169,9 @@ class DPDKdut(Dut):
> """
> # clean all
> self.send_expect("rm -rf " + target, "#")
> + if self.virttype == 'xen':
> + self.send_expect("sed -i -e
> 's/CONFIG_RTE_LIBRTE_XEN_DOM0=.*$/"
> + + "CONFIG_RTE_LIBRTE_XEN_DOM0=y/'
> config/common_linuxapp", "# ", 30)
>
> # compile
> out = self.send_expect("make -j install T=%s %s" % (target,
> extra_options), "# ", 120)
> @@ -178,9 +192,9 @@ class DPDKdut(Dut):
> self.send_expect("rm -rf " + target, "#")
>
> # compile
> - out = self.send_expect("make -j %d install T=%s CC=gcc48" %
> (self.number_of_cores,
> -
> target),
> - "#", 120)
> + out = self.send_expect(
> + "make -j %d install T=%s CC=gcc48" %
> + (self.number_of_cores, target), "#", 120)
>
> if("Error" in out or "No rule to make" in out):
> self.logger.error("ERROR - try without '-j'")
> @@ -191,10 +205,7 @@ class DPDKdut(Dut):
> assert ("Error" not in out), "Compilation error..."
> assert ("No rule to make" not in out), "No rule to make
> error..."
>
> - def prerequisites(self, pkgName, patch):
> - """
> - Copy DPDK package to DUT and apply patch files.
> - """
> + def prepare_package(self, pkgName, patch):
> if not self.skip_setup:
> assert (os.path.isfile(pkgName) is True), "Invalid
> package"
>
> @@ -202,7 +213,7 @@ class DPDKdut(Dut):
> # ToDo: make this configurable
> dst_dir = "/tmp/"
> ll isn’t linux kernel default cmdline, some linux not have
> this cmd, would used ls to replace.
Yes, I will change it in the next version.
> - out = self.send_expect("ls %s && cd %s" % (dst_dir, p_dir),
> + out = self.send_expect("ll %s && cd %s" % (dst_dir, p_dir),
> "#", verify=True)
> if out == -1:
> raise ValueError("Directiry %s or %s does not exist,"
> @@ -249,6 +260,17 @@ class DPDKdut(Dut):
> (self.base_dir, dst_dir +
> p), "# ")
> assert "****" not in out
>
> + self.session.copy_file_to("dep/aclrule.tgz", dst_dir)
> + # unpack acl rule
> + out = self.send_expect("tar zxf %saclrule.tgz -C %s" %
> (dst_dir, p_dir), "# ", 20, verify=True)
> + if out == -1:
> + raise ValueError("acl rule extract failure!!!")
> +
> + def prerequisites(self, pkgName, patch):
> + """
> + Copy DPDK package to DUT and apply patch files.
> + """
> + self.prepare_package(pkgName, patch)
> self.dut_prerequisites()
>
> def bind_interfaces_linux(self, driver='igb_uio',
> nics_to_bind=None):
> @@ -354,16 +376,20 @@ class DPDKtester(Tester):
> total_huge_pages = self.get_total_huge_pages()
> if total_huge_pages == 0:
> self.mount_huge_pages()
> - self.set_huge_pages(4096)
> + self.set_huge_pages(1024)
>
> self.session.copy_file_to("dep/tgen.tgz")
> self.session.copy_file_to("dep/tclclient.tgz")
> + self.session.copy_file_to("dep/aclpcap.tgz")
> # unpack tgen
> out = self.send_expect("tar zxf tgen.tgz", "# ")
> assert "Error" not in out
> # unpack tclclient
> out = self.send_expect("tar zxf tclclient.tgz", "# ")
> assert "Error" not in out
> + # unpacl ACL pcap files
> + out = self.send_expect("tar zxf aclpcap.tgz", "# ")
> + assert "Error" not in out
>
> self.send_expect("modprobe uio", "# ")
>
> @@ -386,10 +412,10 @@ class DPDKtester(Tester):
> """
> hugepages_size = self.send_expect("awk '/Hugepagesize/ {print
> $2}' /proc/meminfo", "# ")
>
> - if int(hugepages_size) < (1024 * 1024):
> - arch_huge_pages = hugepages if hugepages > 0 else 4096
> + if int(hugepages_size) < (2048 * 2048):
> + arch_huge_pages = hugepages if hugepages > 0 else 2048
> total_huge_pages = self.get_total_huge_pages()
>
> - self.mount_huge_pages()
> - if total_huge_pages != arch_huge_pages:
> - self.set_huge_pages(arch_huge_pages)
> + self.mount_huge_pages()
> + if total_huge_pages != arch_huge_pages:
> + self.set_huge_pages(arch_huge_pages)
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases
2015-05-18 8:28 ` Xu, HuilongX
2015-05-18 8:45 ` Liu, Yong
@ 2015-05-18 9:20 ` Jiajia, SunX
1 sibling, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-18 9:20 UTC (permalink / raw)
To: Xu, HuilongX, dts
> -----Original Message-----
> From: Xu, HuilongX
> Sent: Monday, May 18, 2015 4:29 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to
> code the testpmd cases
>
> Hi Jiajia,
> I have a comments at " def execute_cmd(self, pmd_cmd, expected='testpmd>
> ', timeout=TIMEOUT "
> Would you check it, thanks a lot
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code
> the testpmd cases
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> framework/pmd_output.py | 104
> +++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 102 insertions(+), 2 deletions(-)
>
> diff --git a/framework/pmd_output.py b/framework/pmd_output.py
> index 97274a5..642062f 100644
> --- a/framework/pmd_output.py
> +++ b/framework/pmd_output.py
> @@ -32,6 +32,7 @@
> import os
> import re
> import dts
> +from settings import TIMEOUT
>
>
> class PmdOutput():
> @@ -42,6 +43,7 @@ class PmdOutput():
>
> def __init__(self, dut):
> self.dut = dut
> + self.dut.testpmd = self
> self.rx_pkts_prefix = "RX-packets:"
> self.rx_missed_prefix = "RX-missed:"
> self.rx_bytes_prefix = "RX-bytes:"
> @@ -87,10 +89,108 @@ class PmdOutput():
> return self.command
>
> def start_testpmd(self, cores, param='', eal_param='', socket=0):
> + if "--txqflags" not in param:
> + param += " --txqflags=0"
> + if socket == 0:
> + corelist = '0-3'
> + elif socket == 1:
> + corelist = '10-13'
> + else:
> + corelist = '0-3'
> core_list = self.dut.get_core_list(cores, socket)
> self.coremask = dts.create_mask(core_list)
> - command = "./%s/app/testpmd -c %s -n %d %s -- -i %s" \
> - % (self.dut.target, self.coremask,
> self.dut.get_memory_channels(), eal_param, param)
> + command = "taskset -c %s ./%s/app/testpmd -c %s -n %d %s -- -
> i %s" \
> + % (corelist, self.dut.target, self.coremask,
> self.dut.get_memory_channels(), eal_param, param)
> out = self.dut.send_expect(command, "testpmd> ", 120)
> self.command = command
> return out
>
> maybe we need delete parameter "verify=False" in function
> execute_cmd,
> when we used execute_cmd for exec testpmd cmdline, the parameter
> only False.
Yes, I agree it.
> +
> + def execute_cmd(self, pmd_cmd, expected='testpmd> ',
> timeout=TIMEOUT,
> + alt_session=False, verify=False):
> + return self.dut.send_expect('%s' % pmd_cmd, expected,
> timeout=timeout,
> + alt_session=alt_session,
> verify=verify)
> +
> + def get_value_from_string(self, key_str, regx_str, string):
> + """
> + Get some values from the given string by the regular
> expression.
> + """
> + pattern = r"(?<=%s)%s" % (key_str, regx_str)
> + s = re.compile(pattern)
> + res = s.search(string)
> + if type(res).__name__ == 'NoneType':
> + return ' '
> + else:
> + return res.group(0)
> +
> + def get_detail_from_port_info(self, key_str, regx_str, port):
> + """
> + Get the detail info from the output of pmd cmd 'show port info
> <port num>'.
> + """
> + out = self.dut.send_expect("show port info %d" % port,
> "testpmd> ")
> + find_value = self.get_value_from_string(key_str, regx_str, out)
> + return find_value
> +
> + def get_port_mac(self, port_id):
> + """
> + Get the specified port MAC.
> + """
> + return self.get_detail_from_port_info("MAC address: ", "([0-
> 9A-F]{2}:){5}[0-9A-F]{2}", port_id)
> +
> + def get_port_connect_socket(self, port_id):
> + """
> + Get the socket id which the specified port is connectting with.
> + """
> + return self.get_detail_from_port_info("Connect to socket: ",
> "\d+", port_id)
> +
> + def get_port_memory_socket(self, port_id):
> + """
> + Get the socket id which the specified port memory is allocated
> on.
> + """
> + return self.get_detail_from_port_info("memory allocation on
> the socket: ", "\d+", port_id)
> +
> + def get_port_link_status(self, port_id):
> + """
> + Get the specified port link status now.
> + """
> + return self.get_detail_from_port_info("Link status: ", "\d+",
> port_id)
> +
> + def get_port_link_speed(self, port_id):
> + """
> + Get the specified port link speed now.
> + """
> + return self.get_detail_from_port_info("Link speed: ", "\d+",
> port_id)
> +
> + def get_port_link_duplex(self, port_id):
> + """
> + Get the specified port link mode, duplex or siplex.
> + """
> + return self.get_detail_from_port_info("Link duplex: ", "\S+",
> port_id)
> +
> + def get_port_promiscuous_mode(self, port_id):
> + """
> + Get the promiscuous mode of port.
> + """
> + return self.get_detail_from_port_info("Promiscuous mode: ",
> "\S+", port_id)
> +
> + def get_port_allmulticast_mode(self, port_id):
> + """
> + Get the allmulticast mode of port.
> + """
> + return self.get_detail_from_port_info("Allmulticast mode: ",
> "\S+", port_id)
> +
> + def get_port_vlan_offload(self, port_id):
> + """
> + Function: get the port vlan settting info.
> + return value:
> + 'strip':'on'
> + 'filter':'on'
> + 'qinq':'off'
> + """
> + vlan_info = {}
> + vlan_info['strip'] = self.get_detail_from_port_info(
> + "strip ", '\S+', port_id)
> + vlan_info['filter'] = self.get_detail_from_port_info(
> + 'filter', '\S+', port_id)
> + vlan_info['qinq'] = self.get_detail_from_port_info(
> + 'qinq\(extend\) ', '\S+', port_id)
> + return vlan_info
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module
2015-05-18 5:07 ` [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module sjiajiax
2015-05-18 8:23 ` Xu, HuilongX
@ 2015-05-18 13:57 ` Liu, Yong
2015-05-19 5:46 ` Jiajia, SunX
1 sibling, 1 reply; 34+ messages in thread
From: Liu, Yong @ 2015-05-18 13:57 UTC (permalink / raw)
To: Jiajia, SunX, dts
Jiajia, please see my comments below.
This patch is so huge and when edit this email sometime my outlook hang up. Can you separated this patch into two or three patches?
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and
> the virtual resource module
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> framework/qemu_kvm.py | 912
> +++++++++++++++++++++++++++++++++++++++++++++
> framework/virt_base.py | 250 +++++++++++++
> framework/virt_dut.py | 239 ++++++++++++
> framework/virt_resource.py | 486 ++++++++++++++++++++++++
> 4 files changed, 1887 insertions(+)
> create mode 100644 framework/qemu_kvm.py
> create mode 100644 framework/virt_base.py
> create mode 100644 framework/virt_dut.py
> create mode 100644 framework/virt_resource.py
>
> diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py
> new file mode 100644
> index 0000000..5f5f665
> --- /dev/null
> +++ b/framework/qemu_kvm.py
> @@ -0,0 +1,912 @@
> +# <COPYRIGHT_TAG>
> +
> +import time
> +import re
> +import os
> +
> +from virt_base import VirtBase
> +from exception import StartVMFailedException
> +
> +# This name is derictly defined in the qemu guest serivce
> +# So you can not change it except it is changed by the service
> +QGA_DEV_NAME = 'org.qemu.guest_agent.0'
> +# This path defines an socket path on the host connected with
> +# a specified VM
> +QGA_SOCK_PATH_TEMPLATE = '/tmp/%(vm_name)s_qga0.sock'
> +
> +
> +class QEMUKvm(VirtBase):
> +
> + DEFAULT_BRIDGE = 'br0'
> + QEMU_IFUP = """#!/bin/sh
> +
> +set -x
> +
> +switch=%(switch)s
> +
> +if [ -n "$1" ];then
> + tunctl -t $1
> + ip link set $1 up
> + sleep 0.5s
> + brctl addif $switch $1
> + exit 0
> +else
> + echo "Error: no interface specified"
> + exit 1
> +fi
> +"""
If this file not changed, can be just moved into dep folder. This will make this module more clear.
> + QEMU_IFUP_PATH = '/etc/qemu-ifup'
> +
> + def __init__(self, dut, vm_name, suite_name):
> + super(QEMUKvm, self).__init__(dut, vm_name, suite_name)
Can we auto-detected suite name? In test case we should not use hard code suite name.
> + self.set_vm_name(self.vm_name)
> + self.set_vm_enable_kvm()
> + self.set_vm_qga()
> + self.set_vm_daemon()
> +
It's better to use one function "set_vm_default" to replace these functions.
> + # initialize qemu emulator, example: qemu-system-x86_64
> + self.qemu_emulator = self.get_qemu_emulator()
> +
> + # initialize qemu boot command line
> + # example: qemu-system-x86_64 -name vm1 -m 2048 -vnc :1 -
> daemonize
> + self.whole_qemu_kvm_boot_line = ''
> +
The name is too long, please narrow it like "self.qemu_commmandline".
> + self.init_vm_request_resource()
Please add some description of this function.
> +
> + QGA_CLI_PATH = '-r dep/QMP/'
> + self.host_session.copy_file_to(QGA_CLI_PATH)
> +
> + def init_vm_request_resource(self):
> + """
> + initialize vcpus what will be pinned to the VM.
> + If specify this param, the specified vcpus will
> + be pinned to VM by the command 'taskset' when
> + starting the VM.
> + example:
> + vcpus_pinned_to_vm = '1 2 3 4'
> + taskset -c 1,2,3,4 qemu-boot-command-line
> + """
> + self.vcpus_pinned_to_vm = ''
> +
> + # initialize assigned PCI
> + self.assigned_pcis = []
> +
> + def get_virt_type(self):
> + """
> + Get the virtual type.
> + """
> + return 'KVM'
> +
> + def get_qemu_emulator(self):
> + """
> + Get the qemu emulator based on the crb.
> + """
> + arch = self.host_session.send_expect('uname -m', '# ')
> + return 'qemu-system-' + arch
> +
> + def set_qemu_emulator(self, qemu_emulator):
> + """
> + Set the qemu emulator explicitly.
> + """
> + out = self.host_session.send_expect(
> + 'whereis %s' % str(qemu_emulator), '[.*')
> + command_paths = out.split(':')[1:]
> + if command_paths[0].lstrip():
> + print "No emulator [ %s ] on the DUT [ %s ]" % \
> + (qemu_emulator, self.host_dut.get_ip_address())
> + return None
> + self.qemu_emulator = qemu_emulator
> +
This function not called by dts. If this function is for explicated qemu binary, there's no meaningful to use "whereis" find qemu.
> + def has_virtual_ability(self):
> + """
> + Check if host has the virtual ability.
> + """
> + out = self.host_session.send_expect('lsmod | grep kvm', '# ')
> + if 'kvm' in out and 'kvm_intel' in out:
> + return True
> + else:
> + return False
> +
We should also check whether "vmx" supported in cpuinfo.
> + def enable_virtual_ability(self):
> + """
> + Load the virutal module of kernel to enable the virutal ability.
> + """
> + self.host_session.send_expect('modprobe kvm', '# ')
> + self.host_session.send_expect('modprobe kvm_intel', '# ')
> + return True
> +
> + def disk_image_is_ok(self, image):
> + """
> + Check if the image is OK and no error.
> + """
> + pass
> +
> + def image_is_used(self, image_path):
> + """
> + Check if the image has been used on the host.
> + """
> + qemu_cmd_lines = self.host_session.send_expect(
> + "ps aux | grep qemu | grep -v grep", "# ")
> +
> + image_name_flag = '/' + image_path.strip().split('/')[-1] + ' '
> + if image_path in qemu_cmd_lines or \
> + image_name_flag in qemu_cmd_lines:
> + return True
> + return False
> +
> + def __add_boot_line(self, option_boot_line):
> + """
> + Add boot option into the boot line.
> + """
> + separator = ' '
> + self.whole_qemu_kvm_boot_line += separator + option_boot_line
> +
> + def set_vm_enable_kvm(self, enable='yes'):
> + """
> + Set VM boot option to enable the option 'enable-kvm'.
> + """
> + self.params.append({'enable_kvm': [{'enable': '%s' % enable}]})
> +
> + def add_vm_enable_kvm(self, **options):
> + """
> + 'enable': 'yes'
> + """
> + if 'enable' in options.keys() and \
> + options['enable'] == 'yes':
> + enable_kvm_boot_line = '-enable-kvm'
> + self.__add_boot_line(enable_kvm_boot_line)
> +
> + def set_vm_name(self, vm_name):
> + """
> + Set VM name.
> + """
> + self.params.append({'name': [{'name': '%s' % vm_name}]})
> +
> + def add_vm_name(self, **options):
> + """
> + name: vm1
> + """
> + if 'name' in options.keys() and \
> + options['name']:
> + name_boot_line = '-name %s' % options['name']
> + self.__add_boot_line(name_boot_line)
> +
> + def add_vm_cpu(self, **options):
> + """
> + model: [host | core2duo | ...]
> + usage:
> + choose model value from the command
> + qemu-system-x86_64 -cpu help
> + number: '4' #number of vcpus
> + cpupin: '3 4 5 6' # host cpu list
> + """
> + if 'model' in options.keys() and \
> + options['model']:
> + cpu_boot_line = '-cpu %s' % options['model']
> + self.__add_boot_line(cpu_boot_line)
> + if 'number' in options.keys() and \
> + options['number']:
> + smp_cmd_line = '-smp %d' % int(options['number'])
> + self.__add_boot_line(smp_cmd_line)
> + if 'cpupin' in options.keys() and \
> + options['cpupin']:
> + self.vcpus_pinned_to_vm = str(options['cpupin'])
> +
> + def add_vm_mem(self, **options):
> + """
> + size: 1024
> + """
> + if 'size' in options.keys():
> + mem_boot_line = '-m %s' % options['size']
> + self.__add_boot_line(mem_boot_line)
> +
> + def add_vm_disk(self, **options):
> + """
> + file: /home/image/test.img
> + """
> + if 'file' in options.keys():
> + disk_boot_line = '-drive file=%s' % options['file']
> + self.__add_boot_line(disk_boot_line)
> +
> + def add_vm_net(self, **options):
> + """
> + Add VM net device.
> + type: [nic | user | tap | bridge | ...]
> + opt_[vlan | fd | br | mac | ...]
> + note:the sub-option will be decided according to the net type.
> + """
> + if 'type' in options.keys():
> + if 'opt_vlan' not in options.keys():
> + options['opt_vlan'] = '0'
> + if options['type'] == 'nic':
> + self.__add_vm_net_nic(**options)
> + if options['type'] == 'user':
> + self.__add_vm_net_user(**options)
> + if options['type'] == 'tap':
> + self.__add_vm_net_tap(**options)
> +
> + if options['type'] == 'user':
> + self.net_type = 'hostfwd'
> + elif options['type'] in ['tap', 'bridge']:
> + self.net_type = 'bridge'
> +
Element "net_type" not used, why add this here?
> + def __add_vm_net_nic(self, **options):
> + """
> + type: nic
> + opt_vlan: 0
> + note: Default is 0.
> + opt_macaddr: 00:00:00:00:01:01
> + note: if creating a nic, it`s better to specify a MAC,
> + else it will get a random number.
> + opt_model:["e1000" | "virtio" | "i82551" | ...]
> + note: Default is e1000.
> + opt_name: 'nic1'
> + opt_addr: ''
> + note: PCI cards only.
> + opt_vectors:
> + note: This option currently only affects virtio cards.
> + """
> + net_boot_line = '-net nic'
> + separator = ','
> + if 'opt_vlan' in options.keys() and \
> + options['opt_vlan']:
> + net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
> +
> + # add MAC info
> + if 'opt_macaddr' in options.keys() and \
> + options['opt_macaddr']:
> + mac = options['opt_macaddr']
> + else:
> + mac = self.generate_unique_mac()
> + net_boot_line += separator + 'macaddr=%s' % mac
> +
> + if 'opt_model' in options.keys() and \
> + options['opt_model']:
> + net_boot_line += separator + 'model=%s' % options['opt_model']
> + if 'opt_name' in options.keys() and \
> + options['opt_name']:
> + net_boot_line += separator + 'name=%s' % options['opt_name']
> + if 'opt_addr' in options.keys() and \
> + options['opt_addr']:
> + net_boot_line += separator + 'addr=%s' % options['opt_addr']
> + if 'opt_vectors' in options.keys() and \
> + options['opt_vectors']:
> + net_boot_line += separator + 'vectors=%s' %
> options['opt_vectors']
> +
> + if self.__string_has_multi_fields(net_boot_line, separator):
> + self.__add_boot_line(net_boot_line)
> +
> + def __add_vm_net_user(self, **options):
> + """
> + type: user
> + opt_vlan: 0
> + note: default is 0.
> + opt_hostfwd: [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport
> + """
> + net_boot_line = '-net user'
> + separator = ','
> + if 'opt_vlan' in options.keys() and \
> + options['opt_vlan']:
> + net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
> + if 'opt_hostfwd' in options.keys() and \
> + options['opt_hostfwd']:
> + self.__check_net_user_opt_hostfwd(options['opt_hostfwd'])
> + opt_hostfwd = options['opt_hostfwd']
> + else:
> + opt_hostfwd = '::-:'
> + hostfwd_line = self.__parse_net_user_opt_hostfwd(opt_hostfwd)
> + net_boot_line += separator + 'hostfwd=%s' % hostfwd_line
> +
> + if self.__string_has_multi_fields(net_boot_line, separator):
> + self.__add_boot_line(net_boot_line)
> +
> + def __check_net_user_opt_hostfwd(self, opt_hostfwd):
> + """
> + Use regular expression to check if hostfwd value format is
> correct.
> + """
> + regx_ip = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
> + regx_hostfwd = r'["tcp" | "udp"]?:%s?:\d+-%s?:\d+' % (regx_ip,
> regx_ip)
> + if not re.match(regx_hostfwd, opt_hostfwd):
> + raise Exception("Option opt_hostfwd format is not correct,\n"
> +
> + "it is %s,\n " % opt_hostfwd +
> + "it should be [tcp|udp]:[hostaddr]:hostport-"
> +
> + "[guestaddr]:guestport.\n")
> +
> + def __parse_net_user_opt_hostfwd(self, opt_hostfwd):
> + """
> + Parse the boot option 'hostfwd'.
> + """
> + separator = ':'
> + field = lambda option, index, separator=':': \
> + option.split(separator)[index]
> +
> + # get the forword type
> + fwd_type = field(opt_hostfwd, 0)
> + if not fwd_type:
> + fwd_type = 'tcp'
> +
> + # get the host addr
> + host_addr = field(opt_hostfwd, 1)
> + if not host_addr:
> + host_addr = str(self.host_dut.get_ip_address())
> +
> + # get the host port in the option
> + host_port = field(opt_hostfwd, 2).split('-')[0]
> + if not host_port:
> + host_port = str(self.virt_pool.alloc_port(self.vm_name))
> + self.redir_port = host_port
> +
> + # get the guest addr
> + try:
> + guest_addr = str(field(opt_hostfwd, 2).split('-')[1])
> + except IndexError as e:
> + guest_addr = ''
> +
> + # get the guest port in the option
> + guest_port = str(field(opt_hostfwd, 3))
> + if not guest_port:
> + guest_port = '22'
> +
> + hostfwd_line = fwd_type + separator + \
> + host_addr + separator + \
> + host_port + \
> + '-' + \
> + guest_addr + separator + \
> + guest_port
> +
> + # init the redirect incoming TCP or UDP connections
> + # just combine host address and host port, it is enough
> + # for using ssh to connect with VM
> + self.hostfwd_addr = host_addr + separator + host_port
> +
> + return hostfwd_line
> +
> + def __add_vm_net_tap(self, **options):
> + """
> + type: tap
> + opt_vlan: 0
> + note: default is 0.
> + opt_br: br0
> + note: if choosing tap, need to specify bridge name,
> + else it will be br0.
> + opt_script: QEMU_IFUP_PATH
> + note: if not specified, default is self.QEMU_IFUP_PATH.
> + opt_downscript: QEMU_IFDOWN_PATH
> + note: if not specified, default is self.QEMU_IFDOWN_PATH.
> + """
> + net_boot_line = '-net tap'
> + separator = ','
> +
> + # add bridge info
> + if 'opt_br' in options.keys() and \
> + options['opt_br']:
> + bridge = options['opt_br']
> + else:
> + bridge = self.DEFAULT_BRIDGE
> + self.__generate_net_config_script(str(bridge))
> +
> + if 'opt_vlan' in options.keys() and \
> + options['opt_vlan']:
> + net_boot_line += separator + 'vlan=%s' % options['opt_vlan']
> +
> + # add network configure script path
> + if 'opt_script' in options.keys() and \
> + options['opt_script']:
> + script_path = options['opt_script']
> + else:
> + script_path = self.QEMU_IFUP_PATH
> + net_boot_line += separator + 'script=%s' % script_path
> +
> + # add network configure downscript path
> + if 'opt_downscript' in options.keys() and \
> + options['opt_downscript']:
> + net_boot_line += separator + \
> + 'downscript=%s' % options['opt_downscript']
> +
> + if self.__string_has_multi_fields(net_boot_line, separator):
> + self.__add_boot_line(net_boot_line)
> +
> + def __generate_net_config_script(self, switch=DEFAULT_BRIDGE):
> + """
> + Generate a script for qemu emulator to build a tap device
> + between host and guest.
> + """
> + qemu_ifup = self.QEMU_IFUP % {'switch': switch}
> + file_name = os.path.basename(self.QEMU_IFUP_PATH)
> + tmp_file_path = '/tmp/%s' % file_name
> + self.host_dut.create_file(qemu_ifup, tmp_file_path)
> + self.host_session.send_expect('mv -f ~/%s %s' % (file_name,
> +
> self.QEMU_IFUP_PATH), '# ')
> + self.host_session.send_expect(
> + 'chmod +x %s' % self.QEMU_IFUP_PATH, '# ')
> +
> + def set_vm_device(self, driver='pci-assign', **props):
> + """
> + Set VM device with specified driver.
> + """
> + props['driver'] = driver
> + index = self.find_option_index('device')
> + if index:
> + self.params[index]['device'].append(props)
> + else:
> + self.params.append({'device': [props]})
> +
> + def add_vm_device(self, **options):
> + """
> + driver: [pci-assign | virtio-net-pci | ...]
> + prop_[host | addr | ...]: value
> + note:the sub-property will be decided according to the driver.
> + """
> + if 'driver' in options.keys() and \
> + options['driver']:
> + if options['driver'] == 'pci-assign':
> + self.__add_vm_pci_assign(**options)
> + elif options['driver'] == 'virtio-net-pci':
> + self.__add_vm_virtio_net_pci(**options)
> +
> + def __add_vm_pci_assign(self, **options):
> + """
> + driver: pci-assign
> + prop_host: 08:00.0
> + prop_addr: 00:00:00:00:01:02
> + """
> + dev_boot_line = '-device pci-assign'
> + separator = ','
> + if 'prop_host' in options.keys() and \
> + options['prop_host']:
> + dev_boot_line += separator + 'host=%s' % options['prop_host']
> + if 'prop_addr' in options.keys() and \
> + options['prop_addr']:
> + dev_boot_line += separator + 'addr=%s' % options['prop_addr']
> + self.assigned_pcis.append(options['prop_addr'])
> +
> + if self.__string_has_multi_fields(dev_boot_line, separator):
> + self.__add_boot_line(dev_boot_line)
> +
> + def __add_vm_virtio_net_pci(self, **options):
> + """
> + driver: virtio-net-pci
> + prop_netdev: mynet1
> + prop_id: net1
> + prop_mac: 00:00:00:00:01:03
> + prop_bus: pci.0
> + prop_addr: 0x3
> + """
> + dev_boot_line = '-device virtio-net-pci'
> + separator = ','
> + if 'prop_netdev' in options.keys() and \
> + options['prop_netdev']:
> + dev_boot_line += separator + 'netdev=%s' %
> options['prop_netdev']
> + if 'prop_id' in options.keys() and \
> + options['prop_id']:
> + dev_boot_line += separator + 'id=%s' % options['prop_id']
> + if 'prop_mac' in options.keys() and \
> + options['prop_mac']:
> + dev_boot_line += separator + 'mac=%s' % options['prop_mac']
> + if 'prop_bus' in options.keys() and \
> + options['prop_bus']:
> + dev_boot_line += separator + 'bus=%s' % options['prop_bus']
> + if 'prop_addr' in options.keys() and \
> + options['prop_addr']:
> + dev_boot_line += separator + 'addr=%s' % options['prop_addr']
> +
> + if self.__string_has_multi_fields(self, string, separator):
> + self.__add_boot_line(dev_boot_line)
> +
What's the need to check multi_fields? Is it enough to check whether configuration available?
> + def __string_has_multi_fields(self, string, separator, field_num=2):
> + """
> + Check if string has multiple fields which is splited with
> + specified separator.
> + """
> + fields = string.split(separator)
> + number = 0
> + for field in fields:
> + if field:
> + number += 1
> + if number >= field_num:
> + return True
> + else:
> + return False
> +
> + def add_vm_monitor(self, **options):
> + """
> + port: 6061 # if adding monitor to vm, need to specicy
> + this port, else it will get a free port
> + on the host machine.
> + """
> + if 'port' in options.keys():
> + if options['port']:
> + port = options['port']
> + else:
> + port = self.virt_pool.alloc_port(self.vm_name)
> +
> + monitor_boot_line = '-monitor tcp::%d,server,nowait' %
> int(port)
> + self.__add_boot_line(monitor_boot_line)
> +
> + def set_vm_qga(self, enable='yes'):
> + """
> + Set VM qemu-guest-agent.
> + """
> + index = self.find_option_index('qga')
> + if index:
> + self.params[index] = {'qga': [{'enable': '%s' % enable}]}
> + else:
> + self.params.append({'qga': [{'enable': '%s' % enable}]})
> + QGA_SOCK_PATH = QGA_SOCK_PATH_TEMPLATE % {'vm_name': self.vm_name}
> + self.qga_sock_path = QGA_SOCK_PATH
> +
> + def add_vm_qga(self, **options):
> + """
> + enable: 'yes'
> + """
> + QGA_DEV_ID = '%(vm_name)s_qga0' % {'vm_name': self.vm_name}
> + QGA_SOCK_PATH = QGA_SOCK_PATH_TEMPLATE % {'vm_name': self.vm_name}
> +
> + separator = ' '
> +
> + if 'enable' in options.keys():
> + if options['enable'] == 'yes':
> + qga_boot_block = '-chardev
> socket,path=%(SOCK_PATH)s,server,nowait,id=%(ID)s' + \
> + separator + '-device virtio-serial' +
> separator + \
> + '-device
> virtserialport,chardev=%(ID)s,name=%(DEV_NAME)s'
> + qga_boot_line = qga_boot_block % {'SOCK_PATH':
> QGA_SOCK_PATH,
> + 'DEV_NAME':
> QGA_DEV_NAME,
> + 'ID': QGA_DEV_ID}
> + self.__add_boot_line(qga_boot_line)
> + self.qga_sock_path = QGA_SOCK_PATH
> + else:
> + self.qga_sock_path = ''
> +
> + def add_vm_serial_port(self, **options):
> + """
> + enable: 'yes'
> + """
> + SERAIL_SOCK_PATH = "/tmp/%s_serial.sock" % self.vm_name
> + if 'enable' in options.keys():
> + if options['enable'] == 'yes':
> + serial_boot_line = '-serial unix:%s,server,nowait' %
> SERIAL_SOCK_PATH
> + self.__add_boot_line(serial_boot_line)
> + else:
> + pass
> +
> + def add_vm_vnc(self, **options):
> + """
> + displayNum: 1
> + """
> + if 'displayNum' in options.keys() and \
> + options['displayNum']:
> + display_num = options['displayNum']
> + else:
> + display_num = self.virt_pool.alloc_vnc_num(self.vm_name)
> +
> + vnc_boot_line = '-vnc :%d' % int(display_num)
> + self.__add_boot_line(vnc_boot_line)
> +
> + def set_vm_daemon(self, enable='yes'):
> + """
> + Set VM daemon option.
> + """
> + index = self.find_option_index('daemon')
> + if index:
> + self.params[index] = {'daemon': [{'enable': '%s' % enable}]}
> + else:
> + self.params.append({'daemon': [{'enable': '%s' % enable}]})
> +
> + def add_vm_daemon(self, **options):
> + """
> + enable: 'yes'
> + note:
> + By default VM will start with the daemonize status.
> + Not support starting it on the stdin now.
> + """
> + if 'daemon' in options.keys() and \
> + options['enable'] == 'no':
> + pass
> + else:
> + daemon_boot_line = '-daemonize'
> + self.__add_boot_line(daemon_boot_line)
> +
> + def start_vm(self):
> + """
> + Start VM.
> + """
> + qemu_emulator = self.qemu_emulator
> +
> + self.__alloc_assigned_pcis()
> +
> + if self.vcpus_pinned_to_vm.strip():
> + vcpus = self.__alloc_vcpus()
> +
> + if vcpus.strip():
> + whole_qemu_kvm_boot_line = 'taskset -c %s ' % vcpus + \
> + qemu_emulator + ' ' + \
> + self.whole_qemu_kvm_boot_line
If here only to get vcpus for usage, better to use function replace codes here.
> + else:
> + whole_qemu_kvm_boot_line = qemu_emulator + ' ' + \
> + self.whole_qemu_kvm_boot_line
> +
> + # Start VM using the qemu command
> + out = self.host_session.send_expect(whole_qemu_kvm_boot_line, '#
> ')
> + time.sleep(30)
> + if out:
> + raise StartVMFailedException(out)
> +
> + def __alloc_vcpus(self):
> + """
> + Allocate virtual CPUs for VM.
> + """
> + req_cpus = self.vcpus_pinned_to_vm.split()
> + cpus = self.virt_pool.alloc_cpu(vm=self.vm_name,
> corelist=req_cpus)
> +
> + vcpus_pinned_to_vm = ''
> + for cpu in cpus:
> + vcpus_pinned_to_vm += ',' + cpu
> + vcpus_pinned_to_vm = vcpus_pinned_to_vm.lstrip(',')
> +
> + if len(req_cpus) != len(cpus):
> + print "WARNING: Just pin vcpus [ %s ] to VM!" %
> vcpus_pinned_to_vm
> +
If cannot allocate cpus, should raise failure.
> + return vcpus_pinned_to_vm
> +
> + def __alloc_assigned_pcis(self):
> + """
> + Record the PCI device info
> + Struct: {dev pci: {'is_vf': [True | False],
> + 'pf_pci': pci}}
> + example:
> + {'08:10.0':{'is_vf':True, 'pf_pci': 08:00.0}}
> + """
> + assigned_pcis_info = {}
> + for pci in self.assigned_pcis:
> + assigned_pcis_info[pci] = {}
> + if self.__is_vf_pci(pci):
> + assigned_pcis_info[pci]['is_vf'] = True
> + pf_pci = self.__map_vf_to_pf(pci)
> + assgined_pcis_info[pci]['pf_pci'] = pf_pci
> + if self.virt_pool.alloc_vf_from_pf(vm=self.vm_name,
> + pf_pci=pf_pci,
> + *[pci]):
> + port = self.__get_vf_port(pci)
> + port.unbind_driver()
> + port.bind_driver('pci-stub')
> + else:
> + # check that if any VF of specified PF has been
> + # used, raise exception
> + vf_pci = self.__vf_has_been_assinged(pci,
> **assinged_pcis_info)
> + if vf_pci:
> + raise Exception(
> + "Error: A VF [%s] generated by PF [%s] has " %
> + (vf_pci, pci) +
> + "been assigned to VM, so this PF can not be " +
> + "assigned to VM again!")
> + # get the port instance of PF
> + port = self.__get_net_device_by_pci(pci)
> +
> + if self.virt_pool.alloc_pf(vm=self.vm_name,
> + *[pci]):
> + port.unbind_driver()
> +
> + def __is_vf_pci(self, dev_pci):
> + """
> + Check if the specified PCI dev is a VF.
> + """
> + for port_info in self.host_dut.ports_info:
> + if 'sriov_vfs_pci' in port_info.keys():
> + if dev_pci in port_info['sriov_vfs_pci']:
> + return True
> + return False
> +
Vf pci device should be handled in virt_dut module and shared with different types of virtualization hypervisor.
> + def __map_vf_to_pf(self, dev_pci):
> + """
> + Map the specified VF to PF.
> + """
> + for port_info in self.host_dut.ports_info:
> + if 'sriov_vfs_pci' in port_info.keys():
> + if dev_pci in port_info['sriov_vfs_pci']:
> + return port_info['pci']
> + return None
> +
Same as above.
> + def __get_vf_port(self, dev_pci):
> + """
> + Get the NetDevice instance of specified VF.
> + """
> + for port_info in self.host_dut.ports_info:
> + if 'vfs_port' in port_info.keys():
> + for port in port_info['vfs_port']:
> + if dev_pci == port.pci:
> + return port
> + return None
> +
Same as above.
> + def __vf_has_been_assigned(self, pf_pci, **assigned_pcis_info):
> + """
> + Check if the specified VF has been used.
> + """
> + for pci in assigned_pcis_info.keys():
> + if assigned_pcis_info[pci]['is_vf'] and \
> + assigned_pcis_info[pci]['pf_pci'] == pf_pci:
> + return pci
> + return False
> +
VF device can’t be shared with VMs, this function should be in resource module.
> + def __get_net_device_by_pci(self, net_device_pci):
> + """
> + Get NetDevice instance by the specified PCI bus number.
> + """
> + port_info = self.host_dut.get_port_info(net_device_pci)
> + return port_info['port']
> +
Vf pci device should be handled in virt_dut module and shared with different types of virtualization hypervisor.
> + def get_vm_ip(self):
> + """
> + Get VM IP.
> + """
> + get_vm_ip = getattr(self, "get_vm_ip_%s" % self.net_type)
> + return get_vm_ip()
> +
> + def get_vm_ip_hostfwd(self):
> + """
> + Get IP which VM is connected by hostfwd.
> + """
> + return self.hostfwd_addr
> +
> + def get_vm_ip_bridge(self):
> + """
> + Get IP which VM is connected by bridge.
> + """
> + out = self.__control_session('ping', '60')
> + if not out:
> + time.sleep(10)
> + out = self.__control_session('ifconfig')
> + ips = re.findall(r'inet (\d+\.\d+\.\d+\.\d+)', out)
> +
> + if '127.0.0.1' in ips:
> + ips.remove('127.0.0.1')
> +
> + num = 3
> + for ip in ips:
> + out = self.host_session.send_expect(
> + 'ping -c %d %s' % (num, ip), '# ')
> + if '0% packet loss' in out:
> + return ip
The first pinged interface will be the interface of bridge, can we make sure that?
> + return ''
> +
> + def __control_session(self, command, *args):
> + """
> + Use the qemu guest agent service to control VM.
> + Note:
> + :command: there are these commands as below:
> + cat, fsfreeze, fstrim, halt, ifconfig, info,\
> + ping, powerdown, reboot, shutdown, suspend
> + :args: give different args by the different commands.
> + """
> + if not self.qga_sock_path:
> + self.host_logger.info(
> + "No QGA service between host [ %s ] and guest [ %s ]" %
> + (self.host_dut.Name, self.vm_name))
> + return None
> +
> + cmd_head = '~/QMP/' + \
> + "qemu-ga-client " + \
> + "--address=%s %s" % \
> + (self.qga_sock_path, command)
> +
> + cmd = cmd_head
> + for arg in args:
> + cmd = cmd_head + ' ' + str(arg)
> +
> + out = self.host_session.send_expect(cmd, '# ')
> +
> + return out
> +
> + def stop(self):
> + """
> + Stop VM.
> + """
> + self.__control_session('powerdown')
Here's need function to check whether shutdown successfully.
> + time.sleep(5)
> + self.virt_pool.free_all_resource(self.vm_name)
> +
> +
> +if __name__ == "__main__":
> + import subprocess
> + import sys
> + import pdb
> + from serializer import Serializer
> + from crbs import crbs
> + from tester import Tester
> + from dut import Dut
> + import dts
> + from virt_proxy import VirtProxy
> +
> + command = "ifconfig br0"
> + subp = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
> + subp.wait()
> +
> + intf_info = subp.stdout.readlines()
> + for line_info in intf_info:
> + regx = re.search(r'inet (\d+\.\d+\.\d+\.\d+)', line_info)
> + if regx:
> + dutIP = regx.group(1)
> + break
> +
> + print "DEBUG: dutIp: ", dutIP
> +
> + # look up in crbs - to find the matching IP
> + crbInst = None
> + for crb in crbs:
> + if crb['IP'] == dutIP:
> + crbInst = crb
> + break
> +
> + # only run on the dut in known crbs
> + if crbInst is None:
> + raise Exception("No available crb instance!!!")
> +
> + # initialize the dut and tester
> + serializer = Serializer()
> + serializer.set_serialized_filename('../.%s.cache' % crbInst['IP'])
> + serializer.load_from_file()
> +
> + read_cache = None
> + skip_setup = None
> +
> + project = "dpdk"
> + dts.Package = 'dep/dpdk.tar.gz'
> + dut = dts.get_project_obj(project, Dut, crbInst, serializer)
> + tester = dts.get_project_obj(project, Tester, crbInst, serializer)
> + dut.tester = tester
> + dut.base_dir = 'dpdk'
> + dut.set_nic_type('niantic')
> + tester.dut = dut
> +
> + tester.set_test_types(True, False)
> + dut.set_test_types(True, False)
> +
> + tester.set_speedup_options(read_cache, skip_setup)
> + tester.tester_prerequisites()
> + dut.set_speedup_options(read_cache, skip_setup)
> + dut.dut_prerequisites()
> +
> + # test that generating and destroying VF
> + port0 = dut.ports_info[0]['port']
> + dut.generate_sriov_vfs_by_port(0, 4)
> + print "port 0 sriov vfs: ", dut.ports_info[0]
> +
> + dut.destroy_sriov_vfs_by_port(0)
> +
> + time.sleep(2)
> +
> + # test that binding and unbing the NIC
> + port0_pci = dut.ports_info[0]['pci']
> + port0.unbind_driver()
> +
> + dut.logger.info("JUST TESTING!!!")
> +
> + # Start VM by the qemu kvm config file
> + vm1 = QEMUKvm(dut, 'vm1', 'pmd_sriov')
> + print "VM config params:"
> + print vm1.params
> + vm1_dut = vm1.start()
> +
> + try:
> + host_ip = vm1.session.send_expect("ifconfig", '# ')
> + print "Host IP:"
> + print host_ip
> +
> + vm1_ip = vm1.get_vm_ip()
> + print "VM1 IP:"
> + print vm1_ip
> +
> + print "VM1 PCI device:"
> + print vm_dut.session.send_expect('lspci -nn | grep -i eth', '# ')
> + except Exception as e:
> + print e
> + vm1_dut.stop()
> + port0.bind_driver()
> + # Stop VM
> + vm1.stop()
> + port0.bind_driver()
> +
> + dut.host_logger.logger_exit()
> + dut.logger.logger_exit()
> + tester.logger.logger_exit()
> +
> + print "Start and stop VM over!"
> diff --git a/framework/virt_base.py b/framework/virt_base.py
> new file mode 100644
> index 0000000..625c309
> --- /dev/null
> +++ b/framework/virt_base.py
> @@ -0,0 +1,250 @@
> +# <COPYRIGHT_TAG>
> +
> +from random import randint
> +from itertools import imap
> +
> +import dts
> +from dut import Dut
> +from config import VirtConf
> +from config import VIRTCONF
> +from logger import getLogger
> +from settings import CONFIG_ROOT_PATH
> +from virt_dut import VirtDut
> +
> +
> +class VirtBase(object):
> +
> + """
> + Basic module for customer special virtual type. This module implement
> functions
> + configurated and composed the VM boot command. With these function,
> we can get
> + and set the VM boot command, and instantiate the VM.
> + """
> +
> + def __init__(self, dut, vm_name, suite_name):
> + """
> + Initialize the VirtBase.
> + dut: the instance of Dut
> + vm_name: the name of VM which you have confiured in the configure
> + suite_name: the name of test suite
> + """
> + self.host_dut = dut
> + self.vm_name = vm_name
> + self.suite = suite_name
> +
> + # init the host session and logger for VM
> + self.host_dut.init_host_session()
> +
> + # replace dut session
> + self.host_session = self.host_dut.host_session
> + self.host_logger = self.host_dut.logger
> +
> + # init the host resouce pool for VM
> + self.virt_pool = self.host_dut.virt_pool
> +
> + if not self.has_virtual_ability():
> + if not self.enable_virtual_ability():
> + raise Exception(
> + "Dut [ %s ] cannot have the virtual ability!!!")
> +
We need handle those exception in virtualization module.
> + self.virt_type = self.get_virt_type()
> + self.load_global_config()
> + self.load_local_config(suite_name)
> +
> + def get_virt_type(self):
> + """
> + Get the virtual type, such as KVM, XEN or LIBVIRT.
> + """
> + NotImplemented
> +
> + def has_virtual_ability(self):
> + """
> + Check if the host have the ability of virtualization.
> + """
> + NotImplemented
> +
> + def enable_virtual_ability(self):
> + """
> + Enalbe the virtual ability on the DUT.
> + """
> + NotImplemented
> +
> + def load_global_config(self):
> + """
> + Load global configure in the path DTS_ROOT_PAHT/conf.
> + """
> + conf = VirtConf(VIRTCONF)
> + conf.load_virt_config(self.virt_type)
> + self.params = conf.get_virt_config()
> +
Need add check whether configuration file load successfully.
> + def load_local_config(self, suite_name):
> + """
> + Load local configure in the path DTS_ROOT_PATH/conf.
> + """
> + # load local configuration by suite and vm name
> + conf = VirtConf(CONFIG_ROOT_PATH + suite_name + '.cfg')
> + conf.load_virt_config(self.vm_name)
> + localparams = conf.get_virt_config()
Need add check whether configuration file load successfully.
> + # replace global configurations with local configurations
> + for param in localparams:
> + if 'mem' in param.keys():
> + self.__save_local_config('mem', param['mem'])
> + continue
> + if 'cpu' in param.keys():
> + self.__save_local_config('cpu', param['cpu'])
> + continue
> + # save local configurations
> + self.params.append(param)
> +
> + def __save_local_config(self, key, value):
> + """
> + Save the local config into the global dict self.param.
> + """
> + for param in self.params:
> + if key in param.keys():
> + param[key] = value
> +
> + def compose_boot_param(self):
> + """
> + Compose all boot param for starting the VM.
> + """
> + for param in self.params:
> + key = param.keys()[0]
> + value = param[key]
> + try:
> + param_func = getattr(self, 'add_vm_' + key)
> + if callable(param_func):
> + for option in value:
> + param_func(**option)
> + else:
> + print "Virt %s function not implemented!!!" % key
> + except Exception as e:
> + print "Failed: ", e
> +
Function call failed should log with error.
> + def find_option_index(self, option):
> + """
> + Find the boot option in the params which is generated from
> + the global and local configures, and this function will
> + return the index by which option can be indexed in the
> + param list.
> + """
> + index = 0
> + for param in self.params:
> + key = param.keys()[0]
> + if key.strip() == option.strip():
> + return index
> + index += 1
> +
> + return None
> +
> + def generate_unique_mac(self):
> + """
> + Generate a unique MAC based on the DUT.
> + """
> + mac_head = '00:00:00:'
> + mac_tail = ':'.join(
> + ['%02x' % x for x in imap(lambda x:randint(0, 255),
> range(3))])
> + return mac_head + mac_tail
> +
> + def get_vm_ip(self):
> + """
> + Get the VM IP.
> + """
> + NotImplemented
> +
> + def start(self):
> + """
> + Start VM and instantiate the VM with VirtDut.
> + """
> + self.compose_boot_param()
> + try:
> + self.start_vm()
> + except Exception as e:
> + self.host_logger.error(e)
> + return None
> + try:
> + vm_dut = self.instantiate_vm_dut()
> + except Exception as e:
> + self.host_logger.error(e)
> + self.stop()
After stop vm, need clean up resource like VFs and cores.
> + return None
> + return vm_dut
> +
> + def start_vm(self):
> + """
> + Start VM.
> + """
> + NotImplemented
> +
> + def instantiate_vm_dut(self):
> + """
> + Instantiate the Dut class for VM.
> + """
> + crb = self.host_dut.crb.copy()
> + crb['bypass core0'] = False
> + vm_ip = self.get_vm_ip()
Need check whether vm_ip valid.
> + crb['IP'] = vm_ip
> + if ':' not in vm_ip:
> + remote_ip = vm_ip.strip()
> + redirect_port = ''
> + else:
> + remote_addr = vm_ip.split(':')
> + remote_ip = remote_addr[0].strip()
> + redirect_port = remote_addr[1].strip()
> + self.__remove_old_rsa_key(remote_ip, redirect_port)
> +
These code can be moved to function "__remove_old_rsa_key".
> + serializer = self.host_dut.serializer
> +
> + try:
> + vm_dut = VirtDut(
> + crb,
> + serializer,
> + self.virt_type,
> + self.vm_name,
> + self.suite)
> + except Exception as e:
> + raise Exception(e)
If VirtDut instantiation failed, function instantiate_vm_dut should return failure and should not run remaining codes.
> + vm_dut.nic_type = 'any'
> + vm_dut.tester = self.host_dut.tester
> + vm_dut.host_dut = self.host_dut
> + vm_dut.host_session = self.host_session
> +
> + read_cache = False
> + skip_setup = self.host_dut.skip_setup
> + base_dir = self.host_dut.base_dir
> + vm_dut.set_speedup_options(read_cache, skip_setup)
> + func_only = self.host_dut.want_func_tests
> + perf_only = self.host_dut.want_perf_tests
> + vm_dut.set_test_types(func_tests=func_only, perf_tests=perf_only)
> + # base_dir should be set before prerequisites
> + vm_dut.set_directory(base_dir)
> +
> + # setting up dpdk in vm, must call at last
> + vm_dut.prerequisites(dts.Package, dts.Patches)
> +
Prerequisites maybe failed, need add check here.
> + target = self.host_dut.target
> + if target:
> + vm_dut.set_target(target)
> + else:
> + raise Exception("Cannot get the HOST DUT test target!")
> +
> + return vm_dut
> +
> + def __remove_old_rsa_key(self, remote_ip, redirect_port):
> + """
> + Remove the old RSA key of specified remote IP.
> + """
> + rsa_key_path = "~/.ssh/known_hosts"
> + if redirect_port:
> + remove_rsa_key_cmd = "sed -i '/^\[%s\]:%d/d' %s" % \
> + (remote_ip.strip(), int(
> + redirect_port), rsa_key_path)
> + else:
> + remove_rsa_key_cmd = "sed -i '/^%s/d' %s" % \
> + (remote_ip.strip(), rsa_key_path)
> + self.host_dut.tester.send_expect(remove_rsa_key_cmd, "# ")
> +
> + def stop(self):
> + """
> + Stop the VM by the name of VM.
> + """
> + NotImplemented
> diff --git a/framework/virt_dut.py b/framework/virt_dut.py
> new file mode 100644
> index 0000000..1073253
> --- /dev/null
> +++ b/framework/virt_dut.py
> @@ -0,0 +1,239 @@
> +# BSD LICENSE
> +#
> +# Copyright(c) 2010-2015 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.
> +
> +import os
> +import re
> +import time
> +import dts
> +import settings
> +from config import PortConf
> +from settings import NICS, LOG_NAME_SEP
> +from ssh_connection import SSHConnection
> +from project_dpdk import DPDKdut
> +from dut import Dut
> +from net_device import NetDevice
> +from logger import getLogger
> +
> +
> +class VirtDut(DPDKdut):
> +
> + """
> + A connection to the CRB under test.
> + This class sends commands to the CRB and validates the responses. It
> is
> + implemented using either ssh for linuxapp or the terminal server for
> + baremetal.
> + All operations are in fact delegated to an instance of either
> CRBLinuxApp
> + or CRBBareMetal.
> + """
> +
> + def __init__(self, crb, serializer, virttype, vm_name, suite):
> + super(Dut, self).__init__(crb, serializer)
> + self.vm_ip = self.get_ip_address()
> + self.NAME = 'virtdut' + LOG_NAME_SEP + '%s' % self.vm_ip
> + # load port config from suite cfg
> + self.suite = suite
> + self.logger = getLogger(self.NAME)
> + self.logger.config_execution('vmdut')
> + self.session = SSHConnection(self.vm_ip, self.NAME,
> + self.get_password())
> + self.session.init_log(self.logger)
> +
> + # if redirect ssh port, there's only one session enabled
> + self.alt_session = SSHConnection(self.vm_ip, self.NAME + '_alt',
> + self.get_password())
> + self.alt_session.init_log(self.logger)
> +
> + self.number_of_cores = 0
> + self.tester = None
> + self.cores = []
> + self.architecture = None
> + self.ports_info = None
> + self.ports_map = []
> + self.virttype = virttype
> + self.vmtype = ''
> + if self.virttype == 'XEN':
> + self.vmtype = 'domu'
Change virttype to virt_type, and why not check only by virt_type? What's the difference of vmtype?
> + self.virttype = 'host'
> +
> + def set_nic_type(self, nic_type):
> + """
> + Set CRB NICS ready to validated.
> + """
> + self.nic_type = nic_type
> + # vm_dut config will load from vm configuration file
> +
> + def load_portconf(self):
> + """
> + Load port config for this virtual machine
> + """
> + return
> +
> + def set_target(self, target):
> + """
> + Set env variable, these have to be setup all the time. Some tests
> + need to compile example apps by themselves and will fail
> otherwise.
> + Set hugepage on DUT and install modules required by DPDK.
> + Configure default ixgbe PMD function.
> + """
> + self.set_toolchain(target)
> +
> + # set env variable
> + # These have to be setup all the time. Some tests need to compile
> + # example apps by themselves and will fail otherwise.
> + self.send_expect("export RTE_TARGET=" + target, "#")
> + self.send_expect("export RTE_SDK=`pwd`", "#")
> +
> + if not self.skip_setup:
> + self.build_install_dpdk(target)
> +
> + self.setup_memory(hugepages=512)
512M maybe not available, this value should calculated by virtual machine memory size or value stripped from configuration file.
> + self.setup_modules(target)
> +
> + self.bind_interfaces_linux('igb_uio')
Module should also stripped from configuration file.
> +
> + def prerequisites(self, pkgName, patch):
> + """
> + Prerequest function should be called before execute any test case.
> + Will call function to scan all lcore's information which on DUT.
> + Then call pci scan function to collect nic device information.
> + At last setup DUT' environment for validation.
> + """
> + self.prepare_package(pkgName, patch)
> +
> + self.send_expect("cd %s" % self.base_dir, "# ")
> + self.host_session.send_expect("cd %s" % self.base_dir, "# ")
> + self.send_expect("alias ls='ls --color=none'", "#")
> +
> + if self.get_os_type() == 'freebsd':
> + self.send_expect('alias make=gmake', '# ')
> + self.send_expect('alias sed=gsed', '# ')
> +
We do not support freebsd guest, those code should removed.
> + self.init_core_list()
> + self.pci_devices_information()
> +
> + # scan ports before restore interface
> + self.scan_ports()
> + # restore dut ports to kernel
> + if self.vmtype != 'domu':
> + self.restore_interfaces()
> + else:
> + self.restore_interfaces_domu()
> + # rescan ports after interface up
Duplicated concept with virt_type. If functions different between hypervisors, we need implemented them in qemu_{virt_type}.
> + self.rescan_ports()
> +
> + # no need to rescan ports for guest os just bootup
> + # load port infor from config file
> + self.load_portconf()
> +
Need check whether load failed.
> + # enable tester port ipv6
> + self.host_dut.enable_tester_ipv6()
> + self.mount_procfs()
> + # auto detect network topology
> + self.map_available_ports()
> + # disable tester port ipv6
> + self.host_dut.disable_tester_ipv6()
> +
> + # print latest ports_info
> + for port_info in self.ports_info:
> + self.logger.info(port_info)
> +
> + def restore_interfaces_domu(self):
> + """
> + Restore Linux interfaces.
> + """
> + for port in self.ports_info:
> + pci_bus = port['pci']
> + pci_id = port['type']
> + driver = settings.get_nic_driver(pci_id)
> + if driver is not None:
> + addr_array = pci_bus.split(':')
> + bus_id = addr_array[0]
> + devfun_id = addr_array[1]
> + port = NetDevice(self, bus_id, devfun_id)
Port object is temporary used, why use NetDevice module create another one? We can just use port['port'] to use NetDevice object.
> + itf = port.get_interface_name()
> + self.send_expect("ifconfig %s up" % itf, "# ")
> + time.sleep(30)
Sleep 30 seconds is too long and every port will wait so long. Is there any need to wait so long? We should call all ports up and then wait few seconds.
> + print self.send_expect("ip link ls %s" % itf, "# ")
> + else:
> + self.logger.info(
> + "NOT FOUND DRIVER FOR PORT (%s|%s)!!!" % (pci_bus,
> pci_id))
> +
> + def pci_devices_information(self):
> + self.pci_devices_information_uncached()
> +
> + def get_memory_channels(self):
> + """
> + Virtual machine has no memory channel concept, so always return 1
> + """
> + return 1
> +
> + def check_ports_available(self, pci_bus, pci_id):
> + """
> + Check that whether auto scanned ports ready to use
> + """
> + pci_addr = "%s:%s" % (pci_bus, pci_id)
> + if pci_id == "8086:100e":
> + return False
Why e1000 default pci_id is invalided, need comments here.
> + return True
> + # pci_addr = "%s:%s" % (pci_bus, pci_id)
> + # if self.nic_type == 'any':
> + # load vm port conf need another function
> + # need add vitrual function device into NICS
Missing functions here.
> +
> + def scan_ports(self):
> + """
> + Scan ports information, for vm will always scan
> + """
> + self.scan_ports_uncached()
> +
> + def scan_ports_uncached(self):
> + """
> + Scan ports and collect port's pci id, mac adress, ipv6 address.
> + """
> + scan_ports_uncached = getattr(
> + self, 'scan_ports_uncached_%s' % self.get_os_type())
> + return scan_ports_uncached()
> +
> + def map_available_ports(self):
> + """
> + Load or generate network connection mapping list.
> + """
> + self.map_available_ports_uncached()
> + self.logger.warning("DUT PORT MAP: " + str(self.ports_map))
> +
> + def send_ping6(self, localPort, ipv6, mac=''):
> + """
> + Send ping6 packet from local port with destination ipv6 address.
> + """
> + if self.ports_info[localPort]['type'] == 'ixia':
> + pass
> + else:
> + return self.send_expect("ping6 -w 1 -c 1 -A -I %s %s" %
> (self.ports_info[localPort]['intf'], ipv6), "# ", 10)
> diff --git a/framework/virt_resource.py b/framework/virt_resource.py
> new file mode 100644
> index 0000000..856f9dc
> --- /dev/null
> +++ b/framework/virt_resource.py
> @@ -0,0 +1,486 @@
> +#!/usr/bin/python
> +# BSD LICENSE
> +#
> +# Copyright(c) 2010-2015 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.
> +from random import randint
> +
> +from utils import get_obj_funcs
> +
> +INIT_FREE_PORT = 6060
> +
> +
> +class VirtResource(object):
> +
> + """
> + Class handle dut resource, like cpu, memory, net devices
> + """
> +
> + def __init__(self, dut):
> + self.dut = dut
> +
> + self.cores = [int(core['thread']) for core in dut.cores]
> + # initialized unused cores
> + self.unused_cores = self.cores[:]
> + # initialized used cores
> + self.used_cores = [-1] * len(self.unused_cores)
> +
Need macro INVL replace of "-1".
> + self.ports_info = dut.ports_info
> + # initialized unused ports
> + self.ports = [port['pci'] for port in dut.ports_info]
> + self.unused_ports = self.ports[:]
> + # initialized used ports
> + self.used_ports = ['unused'] * len(self.unused_ports)
> +
> + # initialized vf ports
> + self.vfs_info = []
> + self.vfs = []
> + self.unused_vfs = []
> + self.used_vfs = []
> +
> + # save allocated cores and related vm
> + self.allocated_info = {}
> +
> + def __port_used(self, pci):
> + index = self.ports.index(pci)
Add check not found the pci device.
> + self.used_ports[index] = pci
> + self.unused_ports[index] = 'used'
> +
> + def __port_unused(self, pci):
> + index = self.ports.index(pci)
Add check not found the pci device.
> + self.unused_ports[index] = pci
> + self.used_ports[index] = 'unused'
> +
> + def __port_on_socket(self, pci, socket):
> + for port in self.ports_info:
> + if port['pci'] == pci:
> + if socket is -1:
> + return True
> +
> + if port['numa'] == socket:
> + return True
> + else:
> + return False
> +
> + return False
> +
> + def __vf_used(self, pci):
> + index = self.vfs.index(pci)
Add check not found the pci device.
> + self.used_vfs[index] = pci
> + self.unused_vfs[index] = 'used'
> +
> + def __vf_unused(self, pci):
> + index = self.vfs.index(pci)
Add check not found the pci device.
> + self.used_vfs[index] = 'unused'
> + self.unused_vfs[index] = pci
> +
> + def __core_used(self, core):
> + core = int(core)
> + index = self.cores.index(core)
Add check not found core.
> + self.used_cores[index] = core
> + self.unused_cores[index] = -1
> +
> + def __core_unused(self, core):
> + core = int(core)
> + index = self.cores.index(core)
Add check not found core.
> + self.unused_cores[index] = core
> + self.used_cores[index] = -1
> +
> + def __core_on_socket(self, core, socket):
> + for dut_core in self.dut.cores:
> + if int(dut_core['thread']) == core:
> + if socket is -1:
> + return True
> +
> + if int(dut_core['socket']) == socket:
> + return True
> + else:
> + return False
> +
> + return False
> +
> + def __core_isused(self, core):
> + index = self.cores.index(core)
> + if self.used_cores[index] != -1:
> + return True
> + else:
> + return False
> +
> + def reserve_cpu(self, coremask=''):
> + """
> + Reserve dpdk used cpus by mask
> + """
Add comments how to calculate cpus.
> + val = int(coremask, base=16)
> + cpus = []
> + index = 0
> + while val != 0:
> + if val & 0x1:
> + cpus.append(index)
> +
> + val = val >> 1
> + index += 1
> +
> + for cpu in cpus:
> + self.__core_used(cpu)
> +
> + def alloc_cpu(self, vm='', number=-1, socket=-1, corelist=None):
> + """
> + There're two options for request cpu resouce for vm.
> + If number is not -1, just allocate cpu from not used cores.
> + If list is not None, will allocate cpu after checked.
> + """
> + cores = []
> +
> + if vm == '':
> + print "Alloc cpu request vitual machine name!!!"
> + return cores
> +
> + if number != -1:
> + for core in self.unused_cores:
> + if core != -1 and number != 0:
-1 should be replaced by macro INVAL.
> + if self.__core_on_socket(core, socket) is True:
> + self.__core_used(core)
> + cores.append(str(core))
> + number = number - 1
> + if number != 0:
> + print "Can't allocated requested cpu!!!"
> +
Should return error and free used cores.
> + if corelist is not None:
> + for core in corelist:
> + if self.__core_isused(int(core)) is True:
> + print "Core %s has been used!!!" % core
Should return error here.
> + else:
> + if self.__core_on_socket(int(core), socket) is True:
> + self.__core_used(int(core))
> + cores.append(core)
> +
> + if vm not in self.allocated_info:
> + self.allocated_info[vm] = {}
> +
> + self.allocated_info[vm]['cores'] = cores
> + return cores
> +
> + def __vm_has_resource(self, vm, resource=''):
> + if vm == '':
> + self.dut.logger.info("VM name cannt be NULL!!!")
> + raise Exception("VM name cannt be NULL!!!")
How to handle this exception?
> + if vm not in self.allocated_info:
> + self.dut.logger.info(
> + "There is no resource allocated to VM [%s]." % vm)
> + return False
> + if resource == '':
> + return True
> + if resource not in self.allocated_info[vm]:
> + self.dut.logger.info(
> + "There is no resource [%s] allocated to VM [%s] " %
> + (resource, vm))
> + return False
> + return True
> +
> + def free_cpu(self, vm):
> + if self.__vm_has_resource(vm, 'cores'):
> + for core in self.allocated_info[vm]['cores']:
> + self.__core_unused(core)
> + self.allocated_info[vm].pop('cores')
> +
> + def alloc_pf(self, vm='', number=-1, socket=-1, pflist=[]):
> + """
> + There're two options for request pf devices for vm.
> + If number is not -1, just allocate pf device from not used pfs.
> + If list is not None, will allocate pf devices after checked.
> + """
> + ports = []
> +
> + if number != -1:
> + for pci in self.unused_ports:
> + if pci != 'unused' and number != 0:
> + if self.__port_on_socket(pci, socket) is True:
> + self.__port_used(pci)
> + ports.append(pci)
> + number = number - 1
> + if number != 0:
> + print "Can't allocated requested PF devices!!!"
> +
Should free used ports and return error.
> + if pflist is not None:
> + for pci in pflist:
> + if self.__port_isused(pci) is True:
> + print "Port %s has been used!!!" % pci
Should return error.
> + else:
> + if self.__port_on_socket(pci, socket) is True:
> + self.__port_used(core)
> + ports.append(core)
> +
> + if vm not in self.allocated_info:
> + self.allocated_info[vm] = {}
> +
> + self.allocated_info[vm]['ports'] = ports
> + return ports
> +
> + def free_pf(self, vm):
> + if self.__vm_has_resource(vm, 'ports'):
> + for pci in self.allocated_info[vm]['ports']:
> + self.__port_unused(pci)
> + self.allocated_info[vm].pop('ports')
> +
> + def alloc_vf_from_pf(self, vm='', pf_pci='', number=-1, vflist=[]):
> + """
> + There're two options for request vf devices of pf device.
> + If number is not -1, just allocate vf device from not used vfs.
> + If list is not None, will allocate vf devices after checked.
> + """
> + vfs = []
> + if vm == '':
> + print "Alloc VF request vitual machine name!!!"
> + return vfs
> +
> + if pf_pci == '':
> + print "Alloc VF request PF pci address!!!"
> + return vfs
> +
> + for vf_info in self.vfs_info:
> + if vf_info['pf_pci'] == pf_pci:
> + if vf_info['pci'] in vflist:
> + vfs.append(vf_info['pci'])
> + continue
> +
> + if number > 0:
> + vfs.append(vf_info['pci'])
> + number = number - 1
> +
> + for vf in vfs:
> + self.__vf_used(vf)
> +
> + if vm not in self.allocated_info:
> + self.allocated_info[vm] = {}
> +
> + self.allocated_info[vm]['vfs'] = vfs
> + return vfs
> +
> + def free_vf(self, vm):
> + if self.__vm_has_resource(vm, 'vfs'):
> + for pci in self.allocated_info[vm]['vfs']:
> + self.__vf_unused(pci)
> + self.allocated_info[vm].pop('vfs')
> +
> + def add_vf_on_pf(self, pf_pci='', vflist=[]):
> + """
> + Add vf devices generated by specified pf devices.
> + """
> + # add vfs into vf info list
> + vfs = []
> + for vf in vflist:
> + if vf not in self.vfs:
> + self.vfs_info.append({'pci': vf, 'pf_pci': pf_pci})
> + vfs.append(vf)
> + used_vfs = ['unused'] * len(vflist)
> + self.unused_vfs += vfs
> + self.used_vfs += used_vfs
> + self.vfs += vfs
> +
> + def del_vf_on_pf(self, pf_pci='', vflist=[]):
> + """
> + Remove vf devices generated by specified pf devices.
> + """
> + vfs = []
> + for vf in vflist:
> + for vfs_info in self.vfs_info:
> + if vfs_info['pci'] == vf:
> + vfs.append(vf)
> +
> + for vf in vfs:
> + try:
> + index = self.vfs.index(vf)
> + except:
> + continue
> + del self.vfs_info[index]
> + del self.unused_vfs[index]
> + del self.used_vfs[index]
> + del self.vfs[index]
> +
> + def alloc_port(self, vm=''):
> + """
> + Allocate unused host port for vm
> + """
> + if vm == '':
> + print "Alloc host port request vitual machine name!!!"
> + return None
> +
> + port_start = INIT_FREE_PORT + randint(1, 100)
> + port_step = randint(1, 10)
> + port = None
> + count = 20
> + while True:
> + if self.dut.check_port_occupied(port_start) is False:
> + port = port_start
> + break
> + count -= 1
> + if count < 0:
> + print 'No available port on the host!!!'
> + break
> + port_start += port_step
> +
> + if vm not in self.allocated_info:
> + self.allocated_info[vm] = {}
> +
> + self.allocated_info[vm]['hostport'] = port
> + return port
> +
> + def free_port(self, vm):
> + if self.__vm_has_resource(vm, 'hostport'):
> + self.allocated_info[vm].pop('hostport')
> +
> + def alloc_vnc_num(self, vm=''):
> + """
> + Allocate unused host VNC display number for VM.
> + """
> + if vm == '':
> + print "Alloc vnc display number request vitual machine
> name!!!"
> + return None
> +
> + max_vnc_display_num = self.dut.get_maximal_vnc_num()
> + free_vnc_display_num = max_vnc_display_num + 1
> +
> + if vm not in self.allocated_info:
> + self.allocated_info[vm] = {}
> +
> + self.allocated_info[vm]['vnc_display_num'] = free_vnc_display_num
> +
> + return free_vnc_display_num
> +
> + def free_vnc_num(self, vm):
> + if self.__vm_has_resource(vm, 'vnc_display_num'):
> + self.allocated_info[vm].pop('vnc_display_num')
> +
> + def free_all_resource(self, vm):
> + all_free_funcs = get_obj_funcs(self, r'free_')
> + for func in all_free_funcs:
> + if func.__name__ == 'free_all_resource':
> + continue
> + func(vm)
> + if self.__vm_has_resource(vm):
> + self.allocated_info.pop(vm)
> +
> + def get_cpu_on_vm(self, vm=''):
> + """
> + Return core list on specifid VM.
> + """
> + if vm in self.allocated_info:
> + if "cores" in self.allocated_info[vm]:
> + return self.allocated_info[vm]['cores']
> +
So many duplicated codes in get_?_on_vm functions, should use simple function replace of them.
> + def get_vfs_on_vm(self, vm=''):
> + """
> + Return vf device list on specifid VM.
> + """
> + if vm in self.allocated_info:
> + if 'vfs' in self.allocated_info[vm]:
> + return self.allocated_info[vm]['vfs']
> +
> + def get_pfs_on_vm(self, vm=''):
> + """
> + Return pf device list on specifid VM.
> + """
> + if vm in self.allocated_info:
> + if 'ports' in self.allocated_info[vm]:
> + return self.allocated_info[vm]['ports']
> +
> +
> +class simple_dut(object):
> +
> + def __init__(self):
> + self.ports_info = []
> + self.cores = []
> +
> + def check_port_occupied(self, port):
> + return False
> +
> +if __name__ == "__main__":
> + dut = simple_dut()
> + dut.cores = [{'thread': '1', 'socket': '0'}, {'thread': '2', 'socket':
> '0'},
> + {'thread': '3', 'socket': '0'}, {'thread': '4', 'socket':
> '0'},
> + {'thread': '5', 'socket': '0'}, {'thread': '6', 'socket':
> '0'},
> + {'thread': '7', 'socket': '1'}, {'thread': '8', 'socket':
> '1'},
> + {'thread': '9', 'socket': '1'}, {'thread': '10',
> 'socket': '1'},
> + {'thread': '11', 'socket': '1'}, {'thread': '12',
> 'socket': '1'}]
> +
> + dut.ports_info = [{'intf': 'p786p1', 'source': 'cfg', 'mac':
> '90:e2:ba:69:e5:e4',
> + 'pci': '08:00.0', 'numa': 0, 'ipv6':
> 'fe80::92e2:baff:fe69:e5e4',
> + 'peer': 'IXIA:6.5', 'type': '8086:10fb'},
> + {'intf': 'p786p2', 'source': 'cfg', 'mac':
> '90:e2:ba:69:e5:e5',
> + 'pci': '08:00.1', 'numa': 0, 'ipv6':
> 'fe80::92e2:baff:fe69:e5e5',
> + 'peer': 'IXIA:6.6', 'type': '8086:10fb'},
> + {'intf': 'p787p1', 'source': 'cfg', 'mac':
> '90:e2:ba:69:e5:e6',
> + 'pci': '84:00.0', 'numa': 1, 'ipv6':
> 'fe80::92e2:baff:fe69:e5e6',
> + 'peer': 'IXIA:6.7', 'type': '8086:10fb'},
> + {'intf': 'p787p2', 'source': 'cfg', 'mac':
> '90:e2:ba:69:e5:e7',
> + 'pci': '84:00.1', 'numa': 1, 'ipv6':
> 'fe80::92e2:baff:fe69:e5e7',
> + 'peer': 'IXIA:6.8', 'type': '8086:10fb'}]
> +
> + virt_pool = VirtResource(dut)
> + print "Alloc two PF devices on socket 1 from VM"
> + print virt_pool.alloc_pf(vm='test1', number=2, socket=1)
> +
> + virt_pool.add_vf_on_pf(pf_pci='08:00.0', vflist=[
> + '08:10.0', '08:10.2', '08:10.4', '08:10.6'])
> + virt_pool.add_vf_on_pf(pf_pci='08:00.1', vflist=[
> + '08:10.1', '08:10.3', '08:10.5', '08:10.7'])
> + print "Add VF devices to resource pool"
> + print virt_pool.vfs_info
> +
> + print "Alloc VF device from resource pool"
> + print virt_pool.alloc_vf_from_pf(vm='test1', pf_pci='08:00.0',
> number=2)
> + print virt_pool.used_vfs
> + print "Alloc VF device from resource pool"
> + print virt_pool.alloc_vf_from_pf(vm='test2', pf_pci='08:00.1',
> vflist=['08:10.3', '08:10.5'])
> + print virt_pool.used_vfs
> +
> + print "Del VF devices from resource pool"
> + virt_pool.del_vf_on_pf(pf_pci='08:00.0', vflist=['08:10.4',
> '08:10.2'])
> + print virt_pool.vfs_info
> +
> + virt_pool.reserve_cpu('e')
> + print "Reserve three cores from resource pool"
> + print virt_pool.unused_cores
> + print "Alloc two cores on socket1 for VM-test1"
> + print virt_pool.alloc_cpu(vm="test1", number=2, socket=1)
> + print "Alloc two cores in list for VM-test2"
> + print virt_pool.alloc_cpu(vm="test2", corelist=['4', '5'])
> + print "Alloc two cores for VM-test3"
> + print virt_pool.alloc_cpu(vm="test3", number=2)
> + print "Alloc port for VM-test1"
> + print virt_pool.alloc_port(vm='test1')
> + print "Alloc information after allcated"
> + print virt_pool.allocated_info
> +
> + print "Get cores on VM-test1"
> + print virt_pool.get_cpu_on_vm("test1")
> + print "Get pfs on VM-test1"
> + print virt_pool.get_pfs_on_vm("test1")
> + print "Get vfs on VM-test2"
> + print virt_pool.get_vfs_on_vm("test2")
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 5/9] Add qemu-agent-guest for QEMU VM
2015-05-18 5:07 ` [dts] [‘dts-v1’ 5/9] Add qemu-agent-guest for QEMU VM sjiajiax
@ 2015-05-18 14:00 ` Liu, Yong
0 siblings, 0 replies; 34+ messages in thread
From: Liu, Yong @ 2015-05-18 14:00 UTC (permalink / raw)
To: Jiajia, SunX, dts
Need check copyright whether qemu-agent can be used here.
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 5/9] Add qemu-agent-guest for QEMU VM
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> dep/QMP/qemu-ga-client | 299
> +++++++++++++++++++++++++++++++++++++++++++++++++
> dep/QMP/qmp.py | 193 +++++++++++++++++++++++++++++++
> 2 files changed, 492 insertions(+)
> create mode 100644 dep/QMP/qemu-ga-client
> create mode 100644 dep/QMP/qmp.py
>
> diff --git a/dep/QMP/qemu-ga-client b/dep/QMP/qemu-ga-client
> new file mode 100644
> index 0000000..46676c3
> --- /dev/null
> +++ b/dep/QMP/qemu-ga-client
> @@ -0,0 +1,299 @@
> +#!/usr/bin/python
> +
> +# QEMU Guest Agent Client
> +#
> +# Copyright (C) 2012 Ryota Ozaki <ozaki.ryota@gmail.com>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2. See
> +# the COPYING file in the top-level directory.
> +#
> +# Usage:
> +#
> +# Start QEMU with:
> +#
> +# # qemu [...] -chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
> +# -device virtio-serial -device
> virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
> +#
> +# Run the script:
> +#
> +# $ qemu-ga-client --address=/tmp/qga.sock <command> [args...]
> +#
> +# or
> +#
> +# $ export QGA_CLIENT_ADDRESS=/tmp/qga.sock
> +# $ qemu-ga-client <command> [args...]
> +#
> +# For example:
> +#
> +# $ qemu-ga-client cat /etc/resolv.conf
> +# # Generated by NetworkManager
> +# nameserver 10.0.2.3
> +# $ qemu-ga-client fsfreeze status
> +# thawed
> +# $ qemu-ga-client fsfreeze freeze
> +# 2 filesystems frozen
> +#
> +# See also: http://wiki.qemu.org/Features/QAPI/GuestAgent
> +#
> +
> +import base64
> +import random
> +
> +import qmp
> +
> +
> +class QemuGuestAgent(qmp.QEMUMonitorProtocol):
> + def __getattr__(self, name):
> + def wrapper(**kwds):
> + return self.command('guest-' + name.replace('_', '-'), **kwds)
> + return wrapper
> +
> +
> +class QemuGuestAgentClient:
> + error = QemuGuestAgent.error
> +
> + def __init__(self, address):
> + self.qga = QemuGuestAgent(address)
> + self.qga.connect(negotiate=False)
> +
> + def sync(self, timeout=3):
> + # Avoid being blocked forever
> + if not self.ping(timeout):
> + raise EnvironmentError('Agent seems not alive')
> + uid = random.randint(0, (1 << 32) - 1)
> + while True:
> + ret = self.qga.sync(id=uid)
> + if isinstance(ret, int) and int(ret) == uid:
> + break
> +
> + def __file_read_all(self, handle):
> + eof = False
> + data = ''
> + while not eof:
> + ret = self.qga.file_read(handle=handle, count=1024)
> + _data = base64.b64decode(ret['buf-b64'])
> + data += _data
> + eof = ret['eof']
> + return data
> +
> + def read(self, path):
> + handle = self.qga.file_open(path=path)
> + try:
> + data = self.__file_read_all(handle)
> + finally:
> + self.qga.file_close(handle=handle)
> + return data
> +
> + def info(self):
> + info = self.qga.info()
> +
> + msgs = []
> + msgs.append('version: ' + info['version'])
> + msgs.append('supported_commands:')
> + enabled = [c['name'] for c in info['supported_commands'] if
> c['enabled']]
> + msgs.append('\tenabled: ' + ', '.join(enabled))
> + disabled = [c['name'] for c in info['supported_commands'] if not
> c['enabled']]
> + msgs.append('\tdisabled: ' + ', '.join(disabled))
> +
> + return '\n'.join(msgs)
> +
> + def __gen_ipv4_netmask(self, prefixlen):
> + mask = int('1' * prefixlen + '0' * (32 - prefixlen), 2)
> + return '.'.join([str(mask >> 24),
> + str((mask >> 16) & 0xff),
> + str((mask >> 8) & 0xff),
> + str(mask & 0xff)])
> +
> + def ifconfig(self):
> + nifs = self.qga.network_get_interfaces()
> +
> + msgs = []
> + for nif in nifs:
> + msgs.append(nif['name'] + ':')
> + if 'ip-addresses' in nif:
> + for ipaddr in nif['ip-addresses']:
> + if ipaddr['ip-address-type'] == 'ipv4':
> + addr = ipaddr['ip-address']
> + mask =
> self.__gen_ipv4_netmask(int(ipaddr['prefix']))
> + msgs.append("\tinet %s netmask %s" % (addr,
> mask))
> + elif ipaddr['ip-address-type'] == 'ipv6':
> + addr = ipaddr['ip-address']
> + prefix = ipaddr['prefix']
> + msgs.append("\tinet6 %s prefixlen %s" % (addr,
> prefix))
> + if nif['hardware-address'] != '00:00:00:00:00:00':
> + msgs.append("\tether " + nif['hardware-address'])
> +
> + return '\n'.join(msgs)
> +
> + def ping(self, timeout):
> + self.qga.settimeout(timeout)
> + try:
> + self.qga.ping()
> + except self.qga.timeout:
> + return False
> + return True
> +
> + def fsfreeze(self, cmd):
> + if cmd not in ['status', 'freeze', 'thaw']:
> + raise StandardError('Invalid command: ' + cmd)
> +
> + return getattr(self.qga, 'fsfreeze' + '_' + cmd)()
> +
> + def fstrim(self, minimum=0):
> + return getattr(self.qga, 'fstrim')(minimum=minimum)
> +
> + def suspend(self, mode):
> + if mode not in ['disk', 'ram', 'hybrid']:
> + raise StandardError('Invalid mode: ' + mode)
> +
> + try:
> + getattr(self.qga, 'suspend' + '_' + mode)()
> + # On error exception will raise
> + except self.qga.timeout:
> + # On success command will timed out
> + return
> +
> + def shutdown(self, mode='powerdown'):
> + if mode not in ['powerdown', 'halt', 'reboot']:
> + raise StandardError('Invalid mode: ' + mode)
> +
> + try:
> + self.qga.shutdown(mode=mode)
> + except self.qga.timeout:
> + return
> +
> +
> +def _cmd_cat(client, args):
> + if len(args) != 1:
> + print('Invalid argument')
> + print('Usage: cat <file>')
> + sys.exit(1)
> + print(client.read(args[0]))
> +
> +
> +def _cmd_fsfreeze(client, args):
> + usage = 'Usage: fsfreeze status|freeze|thaw'
> + if len(args) != 1:
> + print('Invalid argument')
> + print(usage)
> + sys.exit(1)
> + if args[0] not in ['status', 'freeze', 'thaw']:
> + print('Invalid command: ' + args[0])
> + print(usage)
> + sys.exit(1)
> + cmd = args[0]
> + ret = client.fsfreeze(cmd)
> + if cmd == 'status':
> + print(ret)
> + elif cmd == 'freeze':
> + print("%d filesystems frozen" % ret)
> + else:
> + print("%d filesystems thawed" % ret)
> +
> +
> +def _cmd_fstrim(client, args):
> + if len(args) == 0:
> + minimum = 0
> + else:
> + minimum = int(args[0])
> + print(client.fstrim(minimum))
> +
> +
> +def _cmd_ifconfig(client, args):
> + print(client.ifconfig())
> +
> +
> +def _cmd_info(client, args):
> + print(client.info())
> +
> +
> +def _cmd_ping(client, args):
> + if len(args) == 0:
> + timeout = 3
> + else:
> + timeout = float(args[0])
> + alive = client.ping(timeout)
> + if not alive:
> + print("Not responded in %s sec" % args[0])
> + sys.exit(1)
> +
> +
> +def _cmd_suspend(client, args):
> + usage = 'Usage: suspend disk|ram|hybrid'
> + if len(args) != 1:
> + print('Less argument')
> + print(usage)
> + sys.exit(1)
> + if args[0] not in ['disk', 'ram', 'hybrid']:
> + print('Invalid command: ' + args[0])
> + print(usage)
> + sys.exit(1)
> + client.suspend(args[0])
> +
> +
> +def _cmd_shutdown(client, args):
> + client.shutdown()
> +_cmd_powerdown = _cmd_shutdown
> +
> +
> +def _cmd_halt(client, args):
> + client.shutdown('halt')
> +
> +
> +def _cmd_reboot(client, args):
> + client.shutdown('reboot')
> +
> +
> +commands = [m.replace('_cmd_', '') for m in dir() if '_cmd_' in m]
> +
> +
> +def main(address, cmd, args):
> + if not os.path.exists(address):
> + print('%s not found' % address)
> + sys.exit(1)
> +
> + if cmd not in commands:
> + print('Invalid command: ' + cmd)
> + print('Available commands: ' + ', '.join(commands))
> + sys.exit(1)
> +
> + try:
> + client = QemuGuestAgentClient(address)
> + except QemuGuestAgent.error, e:
> + import errno
> +
> + print(e)
> + if e.errno == errno.ECONNREFUSED:
> + print('Hint: qemu is not running?')
> + sys.exit(1)
> +
> + if cmd != 'ping':
> + client.sync()
> +
> + globals()['_cmd_' + cmd](client, args)
> +
> +
> +if __name__ == '__main__':
> + import sys
> + import os
> + import optparse
> +
> + address = os.environ['QGA_CLIENT_ADDRESS'] if 'QGA_CLIENT_ADDRESS' in
> os.environ else None
> +
> + usage = "%prog [--address=<unix_path>|<ipv4_address>] <command>
> [args...]\n"
> + usage += '<command>: ' + ', '.join(commands)
> + parser = optparse.OptionParser(usage=usage)
> + parser.add_option('--address', action='store', type='string',
> + default=address, help='Specify a ip:port pair or a
> unix socket path')
> + options, args = parser.parse_args()
> +
> + address = options.address
> + if address is None:
> + parser.error('address is not specified')
> + sys.exit(1)
> +
> + if len(args) == 0:
> + parser.error('Less argument')
> + sys.exit(1)
> +
> + main(address, args[0], args[1:])
> diff --git a/dep/QMP/qmp.py b/dep/QMP/qmp.py
> new file mode 100644
> index 0000000..4ade3ce
> --- /dev/null
> +++ b/dep/QMP/qmp.py
> @@ -0,0 +1,193 @@
> +# QEMU Monitor Protocol Python class
> +#
> +# Copyright (C) 2009, 2010 Red Hat Inc.
> +#
> +# Authors:
> +# Luiz Capitulino <lcapitulino@redhat.com>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2. See
> +# the COPYING file in the top-level directory.
> +
> +import json
> +import errno
> +import socket
> +
> +class QMPError(Exception):
> + pass
> +
> +class QMPConnectError(QMPError):
> + pass
> +
> +class QMPCapabilitiesError(QMPError):
> + pass
> +
> +class QEMUMonitorProtocol:
> + def __init__(self, address, server=False):
> + """
> + Create a QEMUMonitorProtocol class.
> +
> + @param address: QEMU address, can be either a unix socket path
> (string)
> + or a tuple in the form ( address, port ) for a
> TCP
> + connection
> + @param server: server mode listens on the socket (bool)
> + @raise socket.error on socket connection errors
> + @note No connection is established, this is done by the connect()
> or
> + accept() methods
> + """
> + self.__events = []
> + self.__address = address
> + self.__sock = self.__get_sock()
> + if server:
> + self.__sock.bind(self.__address)
> + self.__sock.listen(1)
> +
> + def __get_sock(self):
> + if isinstance(self.__address, tuple):
> + family = socket.AF_INET
> + else:
> + family = socket.AF_UNIX
> + return socket.socket(family, socket.SOCK_STREAM)
> +
> + def __negotiate_capabilities(self):
> + greeting = self.__json_read()
> + if greeting is None or not greeting.has_key('QMP'):
> + raise QMPConnectError
> + # Greeting seems ok, negotiate capabilities
> + resp = self.cmd('qmp_capabilities')
> + if "return" in resp:
> + return greeting
> + raise QMPCapabilitiesError
> +
> + def __json_read(self, only_event=False):
> + while True:
> + data = self.__sockfile.readline()
> + if not data:
> + return
> + resp = json.loads(data)
> + if 'event' in resp:
> + self.__events.append(resp)
> + if not only_event:
> + continue
> + return resp
> +
> + error = socket.error
> +
> + def connect(self, negotiate=True):
> + """
> + Connect to the QMP Monitor and perform capabilities negotiation.
> +
> + @return QMP greeting dict
> + @raise socket.error on socket connection errors
> + @raise QMPConnectError if the greeting is not received
> + @raise QMPCapabilitiesError if fails to negotiate capabilities
> + """
> + self.__sock.connect(self.__address)
> + self.__sockfile = self.__sock.makefile()
> + if negotiate:
> + return self.__negotiate_capabilities()
> +
> + def accept(self):
> + """
> + Await connection from QMP Monitor and perform capabilities
> negotiation.
> +
> + @return QMP greeting dict
> + @raise socket.error on socket connection errors
> + @raise QMPConnectError if the greeting is not received
> + @raise QMPCapabilitiesError if fails to negotiate capabilities
> + """
> + self.__sock, _ = self.__sock.accept()
> + self.__sockfile = self.__sock.makefile()
> + return self.__negotiate_capabilities()
> +
> + def cmd_obj(self, qmp_cmd):
> + """
> + Send a QMP command to the QMP Monitor.
> +
> + @param qmp_cmd: QMP command to be sent as a Python dict
> + @return QMP response as a Python dict or None if the connection
> has
> + been closed
> + """
> + try:
> + self.__sock.sendall(json.dumps(qmp_cmd))
> + except socket.error, err:
> + if err[0] == errno.EPIPE:
> + return
> + raise socket.error(err)
> + return self.__json_read()
> +
> + def cmd(self, name, args=None, id=None):
> + """
> + Build a QMP command and send it to the QMP Monitor.
> +
> + @param name: command name (string)
> + @param args: command arguments (dict)
> + @param id: command id (dict, list, string or int)
> + """
> + qmp_cmd = { 'execute': name }
> + if args:
> + qmp_cmd['arguments'] = args
> + if id:
> + qmp_cmd['id'] = id
> + return self.cmd_obj(qmp_cmd)
> +
> + def command(self, cmd, **kwds):
> + ret = self.cmd(cmd, kwds)
> + if not ret:
> + return
> + else:
> + if ret.has_key('error'):
> + raise Exception(ret['error']['desc'])
> + return ret['return']
> +
> + def pull_event(self, wait=False):
> + """
> + Get and delete the first available QMP event.
> +
> + @param wait: block until an event is available (bool)
> + """
> + self.__sock.setblocking(0)
> + try:
> + self.__json_read()
> + except socket.error, err:
> + if err[0] == errno.EAGAIN:
> + # No data available
> + pass
> + self.__sock.setblocking(1)
> + if not self.__events and wait:
> + self.__json_read(only_event=True)
> + event = self.__events[0]
> + del self.__events[0]
> + return event
> +
> + def get_events(self, wait=False):
> + """
> + Get a list of available QMP events.
> +
> + @param wait: block until an event is available (bool)
> + """
> + self.__sock.setblocking(0)
> + try:
> + self.__json_read()
> + except socket.error, err:
> + if err[0] == errno.EAGAIN:
> + # No data available
> + pass
> + self.__sock.setblocking(1)
> + if not self.__events and wait:
> + self.__json_read(only_event=True)
> + return self.__events
> +
> + def clear_events(self):
> + """
> + Clear current list of pending events.
> + """
> + self.__events = []
> +
> + def close(self):
> + self.__sock.close()
> + self.__sockfile.close()
> +
> + timeout = socket.timeout
> +
> + def settimeout(self, timeout):
> + self.__sock.settimeout(timeout)
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing
2015-05-18 5:07 ` [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing sjiajiax
@ 2015-05-18 14:02 ` Liu, Yong
2015-05-19 5:49 ` Jiajia, SunX
0 siblings, 1 reply; 34+ messages in thread
From: Liu, Yong @ 2015-05-18 14:02 UTC (permalink / raw)
To: Jiajia, SunX, dts
These two files should be released with acl suite. Please remove them.
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts@dpdk.org
> Subject: [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing
>
> Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> ---
> dep/aclpcap.tgz | Bin 0 -> 82103 bytes
> dep/aclrule.tgz | Bin 0 -> 161037 bytes
> 2 files changed, 0 insertions(+), 0 deletions(-)
> create mode 100644 dep/aclpcap.tgz
> create mode 100644 dep/aclrule.tgz
>
> diff --git a/dep/aclpcap.tgz b/dep/aclpcap.tgz
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..d10df6f5af0e8eeb0c48d10f8fed0a29
> 3ce10864
> GIT binary patch
> literal 82103
> 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
> A%m4rY
>
> literal 0
> HcmV?d00001
>
> diff --git a/dep/aclrule.tgz b/dep/aclrule.tgz
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..cc662ce2a3f528c29c394a0839fc5384
> 479105f8
> GIT binary patch
> literal 161037
> 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�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
>
> literal 0
> HcmV?d00001
>
> --
> 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
2015-05-18 7:43 ` Jiajia, SunX
@ 2015-05-19 0:38 ` Liu, Yong
2015-05-19 7:05 ` Jiajia, SunX
0 siblings, 1 reply; 34+ messages in thread
From: Liu, Yong @ 2015-05-19 0:38 UTC (permalink / raw)
To: Jiajia, SunX, dts
Jiajia, about get_obj_funcs, it’s common function and can be in utils.py. What I mean is that in free_all_resource, do not use get_obj_funcs to extract all free functions.
It's unclear about what need to be freed and maybe will be sequence issue.
> -----Original Message-----
> From: Jiajia, SunX
> Sent: Monday, May 18, 2015 3:43 PM
> To: Liu, Yong; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
>
> Hi Yong,
>
> I have replied the comments as below.
>
> > -----Original Message-----
> > From: Liu, Yong
> > Sent: Monday, May 18, 2015 3:06 PM
> > To: Jiajia, SunX; dts@dpdk.org
> > Subject: RE: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
> >
> > Jiajia,
> > Please see my comments below.
> >
> > > -----Original Message-----
> > > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > > Sent: Monday, May 18, 2015 1:07 PM
> > > To: dts@dpdk.org
> > > Subject: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
> > >
> > > Optimize configure parse
> > >
> > > Move some functions in dts to an common utils module
> > >
> > > Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> > > ---
> > > framework/config.py | 171
> > +++++++++++++++++++++++++++++++++++----
> > > -----
> > > framework/ssh_connection.py | 5 ++
> > > framework/ssh_pexpect.py | 63 +++++++++++++---
> > > framework/utils.py | 77 ++++++++++++++++++++
> > > 4 files changed, 270 insertions(+), 46 deletions(-)
> > > mode change 100755 => 100644 framework/config.py
> > > create mode 100644 framework/utils.py
> > >
> > > diff --git a/framework/config.py b/framework/config.py
> > > old mode 100755
> > > new mode 100644
> > > index d2548e8..927c846
> > > --- a/framework/config.py
> > > +++ b/framework/config.py
> > > @@ -37,45 +37,133 @@ import re
> > > import ConfigParser # config parse module
> > > import argparse # prase arguments module
> > >
> > > -portconf = "conf/ports.cfg"
> > > -crbconf = "conf/crbs.cfg"
> > > +PORTCONF = "conf/ports.cfg"
> > > +CRBCONF = "conf/crbs.cfg"
> > > +VIRTCONF = "conf/virt_global.cfg"
> > >
> > >
> > > class UserConf():
> > >
> > > - def __init__(self, port_conf=portconf, crb_conf=crbconf):
> > > - self.port_config = port_conf
> > > - self.crb_config = crb_conf
> > > + def __init__(self, config):
> > > + self.conf = ConfigParser.SafeConfigParser()
> > > + load_files = self.conf.read(config)
> > > + if load_files == []:
> > > + print "FAILED LOADING %s!!!" % config
> > > + self.conf = None
> > > + raise
> > > +
> >
> > There's need one special exception for configuration parsed failure.
>
> Yes, I think it is good to do that.
>
> >
> > > + def get_sections(self):
> > > + if self.conf is None:
> > > + return None
> > > +
> > > + return self.conf.sections()
> > > +
> > > + def load_section(self, section):
> > > + if self.conf is None:
> > > + return None
> > > +
> > > + items = None
> > > + for conf_sect in self.conf.sections():
> > > + if conf_sect == section:
> > > + items = self.conf.items(section)
> > > +
> > > + return items
> > > +
> > > + def load_config(self, item):
> > > + confs = [conf.strip() for conf in item.split(';')]
> > > + if '' in confs:
> > > + confs.remove('')
> > > + return confs
> > > +
> > > + def load_param(self, conf):
> > > + paramDict = dict()
> > > +
> > > + for param in conf.split(','):
> > > + (key, _, value) = param.partition('=')
> > > + paramDict[key] = value
> > > + return paramDict
> > > +
> > > +
> > > +class VirtConf(UserConf):
> > > +
> > > + def __init__(self, virt_conf=VIRTCONF):
> > > + self.config_file = virt_conf
> > > + self.virt_cfg = {}
> > > + try:
> > > + self.virt_conf = UserConf(self.config_file)
> > > + except Exception as e:
> > > + print "FAILED LOADING VIRT CONFIG!!!"
> > > + self.virt_conf = None
> > > +
> > There's need one special exception for configuration parsed failure.
>
> I will do it in the next version.
>
> >
> > > + def load_virt_config(self, name):
> > > + self.virt_cfgs = []
> > > +
> > > + try:
> > > + virt_confs = self.virt_conf.load_section(name)
> > > + except:
> > > + print "FAILED FIND SECTION %s!!!" % name
> > > + return
> > > +
> > Add exception for load section failed.
>
> I will do it in the next version.
>
> >
> > > + for virt_conf in virt_confs:
> > > + virt_cfg = {}
> > > + virt_params = []
> > > + key, config = virt_conf
> > > + confs = self.virt_conf.load_config(config)
> > > + for config in confs:
> > > + virt_params.append(self.load_virt_param(config))
> > > + virt_cfg[key] = virt_params
> > > + self.virt_cfgs.append(virt_cfg)
> > > +
> > > + def get_virt_config(self):
> > > + return self.virt_cfgs
> > > +
> > > + def load_virt_param(self, config):
> > > + cfg_params = self.virt_conf.load_param(config)
> > > + return cfg_params
> > > +
> > > +
> > > +class PortConf(UserConf):
> > > +
> > > + def __init__(self, port_conf=PORTCONF):
> > > + self.config_file = port_conf
> > > self.ports_cfg = {}
> > > self.pci_regex = "([\da-f]{2}:[\da-f]{2}.\d{1})$"
> > > try:
> > > - self.port_conf = ConfigParser.SafeConfigParser()
> > > - self.port_conf.read(self.port_config)
> > > + self.port_conf = UserConf(self.config_file)
> > > except Exception as e:
> > > print "FAILED LOADING PORT CONFIG!!!"
> > > + self.port_conf = None
> > >
> > There's need one special exception for configuration parsed failure.
>
> I will do it in the next version.
>
> >
> > > def load_ports_config(self, crbIP):
> > > - ports = []
> > > - for crb in self.port_conf.sections():
> > > - if crb != crbIP:
> > > - continue
> > > - ports = [port.strip()
> > > - for port in self.port_conf.get(crb,
> > > 'ports').split(';')]
> > > + self.ports_cfg = {}
> > > + if self.port_conf is None:
> > > + return
> > > +
> > > + ports = self.port_conf.load_section(crbIP)
> > > + if ports is None:
> > > + return
> > > + key, config = ports[0]
> > > + confs = self.port_conf.load_config(config)
> > > +
> > > + for config in confs:
> > > + port_param = self.port_conf.load_param(config)
> > >
> > > - for port in ports:
> > > - port_cfg = self.__parse_port_param(port)
> > > # check pci BDF validity
> > > - if 'pci' not in port_cfg:
> > > + if 'pci' not in port_param:
> > > print "NOT FOUND CONFIG FOR NO PCI ADDRESS!!!"
> > > continue
> > > - m = re.match(self.pci_regex, port_cfg['pci'])
> > > + m = re.match(self.pci_regex, port_param['pci'])
> > > if m is None:
> > > print "INVALID CONFIG FOR NO PCI ADDRESS!!!"
> > > continue
> > >
> > > - keys = port_cfg.keys()
> > > + keys = port_param.keys()
> > > keys.remove('pci')
> > > - self.ports_cfg[port_cfg['pci']] = {key: port_cfg[key]
> > for key
> > > in keys}
> > > + self.ports_cfg[port_param['pci']] = {
> > > + key: port_param[key] for key in keys}
> > > + if 'numa' in self.ports_cfg[port_param['pci']]:
> > > + numa_str = self.ports_cfg[port_param['pci']]['numa']
> > > + self.ports_cfg[port_param['pci']]['numa'] =
> > int(numa_str)
> > >
> > > def get_ports_config(self):
> > > return self.ports_cfg
> > > @@ -86,23 +174,36 @@ class UserConf():
> > > else:
> > > return False
> > >
> > > - def __parse_port_param(self, port):
> > > - portDict = dict()
> > > -
> > > - for param in port.split(','):
> > > - (key, _, value) = param.partition('=')
> > > - if key == 'numa':
> > > - portDict[key] = int(value)
> > > - else:
> > > - portDict[key] = value
> > > - return portDict
> > > +
> > >
> > >
> > > if __name__ == '__main__':
> > > - parser = argparse.ArgumentParser(description="Load DTS
> > configuration
> > > files")
> > > - parser.add_argument("-p", "--portconf", default=portconf)
> > > - parser.add_argument("-c", "--crbconf", default=crbconf)
> > > + parser = argparse.ArgumentParser(
> > > + description="Load DTS configuration files")
> > > + parser.add_argument("-p", "--portconf", default=PORTCONF)
> > > + parser.add_argument("-c", "--crbconf", default=CRBCONF)
> > > + parser.add_argument("-v", "--virtconf", default=VIRTCONF)
> > > args = parser.parse_args()
> > > - conf = UserConf()
> > > - conf.load_ports_config('192.168.1.1')
> > > - conf.check_port_available('0000:86:00.0')
> > > +
> > > + # not existed configuration file
> > > + VirtConf('/tmp/not-existed.cfg')
> > > +
> > > + # example for basic use configuration file
> > > + conf = UserConf(PORTCONF)
> > > + for section in conf.get_sections():
> > > + items = conf.load_section(section)
> > > + key, value = items[0]
> > > + confs = conf.load_config(value)
> > > + for config in confs:
> > > + conf.load_param(config)
> > > +
> > > + # example for port configuration file
> > > + portconf = PortConf(PORTCONF)
> > > + portconf.load_ports_config('DUT IP')
> > > + print portconf.get_ports_config()
> > > + portconf.check_port_available('86:00.0')
> > > +
> > > + # example for global virtualization configuration file
> > > + virtconf = VirtConf(VIRTCONF)
> > > + virtconf.load_virt_config('LIBVIRT')
> > > + print virtconf.get_virt_config()
> > > diff --git a/framework/ssh_connection.py
> > b/framework/ssh_connection.py
> > > index 18a6517..7286b14 100644
> > > --- a/framework/ssh_connection.py
> > > +++ b/framework/ssh_connection.py
> > > @@ -62,6 +62,11 @@ class SSHConnection(object):
> > > self.logger.debug(out)
> > > return out
> > >
> > > + def get_session_before(self, timeout=15):
> > > + out = self.session.get_session_before(timeout)
> > > + self.logger.debug(out)
> > > + return out
> > > +
> >
> > I've sent out this patch, please make sure there's no gap there.
> > You'd better remove those from your patch work.
> >
>
> About this, I have checked it, yes, you have sent it, I will remove it
> from my patch work.
>
> > > def close(self):
> > > self.session.close()
> > >
> > > diff --git a/framework/ssh_pexpect.py b/framework/ssh_pexpect.py
> > > index 735df44..4193020 100644
> > > --- a/framework/ssh_pexpect.py
> > > +++ b/framework/ssh_pexpect.py
> > > @@ -2,7 +2,8 @@ import time
> > > import pexpect
> > > import pxssh
> > > from debugger import ignore_keyintr, aware_keyintr
> > > -from exception import TimeoutException, SSHConnectionException
> > > +from exception import TimeoutException, SSHConnectionException,
> > > SSHSessionDeadException
> > > +from utils import RED, GREEN
> > >
> > > """
> > > Module handle ssh sessions between tester and DUT.
> > > @@ -14,16 +15,28 @@ Aslo support transfer files to tester or DUT.
> > > class SSHPexpect(object):
> > >
> > > def __init__(self, host, username, password):
> > > - self.magic_prompt = "[MAGIC PROMPT]"
> > > + self.magic_prompt = "MAGIC PROMPT"
> > > try:
> > > self.session = pxssh.pxssh()
> > > - self.username = username
> > > self.host = host
> > > + self.username = username
> > > self.password = password
> > > - self.session.login(self.host, self.username,
> > > - self.password,
> > original_prompt='[$#>]')
> > > + if ':' in host:
> > > + self.ip = host.split(':')[0]
> > > + self.port = int(host.split(':')[1])
> > > + self.session.login(self.ip, self.username,
> > > + self.password,
> > original_prompt='[$#>]',
> > > + port=self.port, login_timeout=20)
> > > + else:
> > > + self.session.login(self.host, self.username,
> > > + self.password,
> > original_prompt='[$#>]')
> > > self.send_expect('stty -echo', '# ', timeout=2)
> > > - except Exception:
> > > + except Exception, e:
> > > + print RED(e)
> > > + if getattr(self, 'port', None):
> > > + suggestion = "\nSuggession: Check if the fireware on
> > > [ %s ] " % \
> > > + self.ip + "is stoped\n"
> > > + print GREEN(suggestion)
> > > raise SSHConnectionException(host)
> > >
> > > def init_log(self, logger, name):
> > > @@ -33,7 +46,7 @@ class SSHPexpect(object):
> > >
> > > def send_expect_base(self, command, expected, timeout=15):
> > > ignore_keyintr()
> > > - self.__flush() # clear buffer
> > > + self.__flush() # clear buffer
> > > self.session.PROMPT = expected
> > > self.__sendline(command)
> > > self.__prompt(command, timeout)
> > > @@ -45,7 +58,7 @@ class SSHPexpect(object):
> > > def send_expect(self, command, expected, timeout=15,
> > verify=False):
> > > ret = self.send_expect_base(command, expected, timeout)
> > > if verify:
> > > - ret_status = self.send_expect_base("echo $?", expected)
> > > + ret_status = self.send_expect_base("echo $?", expected,
> > > timeout)
> > > if not int(ret_status):
> > > return ret
> > > else:
> > > @@ -54,21 +67,44 @@ class SSHPexpect(object):
> > > else:
> > > return ret
> > >
> > > - def __flush(self):
> > > + def get_session_before(self, timeout=15):
> > > + """
> > > + Get all output before timeout
> > > + """
> > > + ignore_keyintr()
> > > self.session.PROMPT = self.magic_prompt
> > > - self.session.prompt(0.1)
> > > + try:
> > > + self.session.prompt(timeout)
> > > + except Exception as e:
> > > + pass
> > > +
> > > + aware_keyintr()
> > > + before = self.get_output_before()
> > > + self.__flush()
> > > + return before
> > > +
> > > + def __flush(self):
> > > + """
> > > + Clear all session buffer
> > > + """
> > > + self.session.buffer = ""
> > > + self.session.before = ""
> > >
> > > def __prompt(self, command, timeout):
> > > if not self.session.prompt(timeout):
> > > raise TimeoutException(command, self.get_output_all())
> > >
> > > def __sendline(self, command):
> > > + if not self.isalive():
> > > + raise SSHSessionDeadException(self.host)
> > > if len(command) == 2 and command.startswith('^'):
> > > self.session.sendcontrol(command[1])
> > > else:
> > > self.session.sendline(command)
> > >
> > > def get_output_before(self):
> > > + if not self.isalive():
> > > + raise SSHSessionDeadException(self.host)
> > > self.session.flush()
> > > before = self.session.before.rsplit('\r\n', 1)
> > > if before[0] == "[PEXPECT]":
> > > @@ -103,7 +139,12 @@ class SSHPexpect(object):
> > > """
> > > Sends a local file to a remote place.
> > > """
> > > - command = 'scp {0} {1}@{2}:{3}'.format(src, self.username,
> > > self.host, dst)
> > > + if ':' in self.host:
> > > + command = 'scp -P {0} -o
> > NoHostAuthenticationForLocalhost=yes
> > > {1} {2}@{3}:{4}'.format(
> > > + str(self.port), src, self.username, self.ip, dst)
> > > + else:
> > > + command = 'scp {0} {1}@{2}:{3}'.format(
> > > + src, self.username, self.host, dst)
> > > if password == '':
> > > self._spawn_scp(command, self.password)
> > > else:
> > > diff --git a/framework/utils.py b/framework/utils.py
> > > new file mode 100644
> > > index 0000000..57eb988
> > > --- /dev/null
> > > +++ b/framework/utils.py
> > > @@ -0,0 +1,77 @@
> > > +# 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.
> > > +
> > > +import json # json format
> > > +import re
> > > +
> > > +
> > > +def RED(text):
> > > + return "\x1B[" + "31;1m" + str(text) + "\x1B[" + "0m"
> > > +
> > > +
> > > +def BLUE(text):
> > > + return "\x1B[" + "36;1m" + str(text) + "\x1B[" + "0m"
> > > +
> > > +
> > > +def GREEN(text):
> > > + return "\x1B[" + "32;1m" + str(text) + "\x1B[" + "0m"
> > > +
> > > +
> > > +def pprint(some_dict):
> > > + """
> > > + Print JSON format dictionary object.
> > > + """
> > > + return json.dumps(some_dict, sort_keys=True, indent=4)
> > > +
> > > +
> > > +def regexp(s, to_match, allString=False):
> > > + """
> > > + Ensure that the re `to_match' only has one group in it.
> > > + """
> > > +
> > > + scanner = re.compile(to_match, re.DOTALL)
> > > + if allString:
> > > + return scanner.findall(s)
> > > + m = scanner.search(s)
> > > + if m is None:
> > > + print RED("Failed to match " + to_match + " in the string "
> > + s)
> > > + return None
> > > + return m.group(1)
> > > +
> > > +
> > > +def get_obj_funcs(obj, func_name_regex):
> > > + """
> > > + Return function list which name matched regex.
> > > + """
> > > + for func_name in dir(obj):
> > > + func = getattr(obj, func_name)
> > > + if callable(func) and re.match(func_name_regex,
> > func.__name__):
> > > + yield func
> > > --
> > This function now used to free resource of virtualization machine, I
> > think it's better to call free functions directly.
> > Maybe there will be dependency of these free functions. What's your
> > idea about it?
>
> No, now it is just used on the module of virtual resource.
> But I think this is common function, it can be used in other module if
> there
> is a demand.
>
> >
> > > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module
2015-05-18 13:57 ` Liu, Yong
@ 2015-05-19 5:46 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-19 5:46 UTC (permalink / raw)
To: Liu, Yong, dts
> -----Original Message-----
> From: Liu, Yong
> Sent: Monday, May 18, 2015 9:58 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT
> class and the virtual resource module
>
> Jiajia, please see my comments below.
> This patch is so huge and when edit this email sometime my outlook hang
> up. Can you separated this patch into two or three patches?
>
> > -----Original Message-----
> > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > Sent: Monday, May 18, 2015 1:07 PM
> > To: dts@dpdk.org
> > Subject: [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class
> and
> > the virtual resource module
> >
> > Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> > ---
> > framework/qemu_kvm.py | 912
> > +++++++++++++++++++++++++++++++++++++++++++++
> > framework/virt_base.py | 250 +++++++++++++
> > framework/virt_dut.py | 239 ++++++++++++
> > framework/virt_resource.py | 486 ++++++++++++++++++++++++
> > 4 files changed, 1887 insertions(+)
> > create mode 100644 framework/qemu_kvm.py
> > create mode 100644 framework/virt_base.py
> > create mode 100644 framework/virt_dut.py
> > create mode 100644 framework/virt_resource.py
> >
> > diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py
> > new file mode 100644
> > index 0000000..5f5f665
> > --- /dev/null
> > +++ b/framework/qemu_kvm.py
> > @@ -0,0 +1,912 @@
> > +# <COPYRIGHT_TAG>
> > +
> > +import time
> > +import re
> > +import os
> > +
> > +from virt_base import VirtBase
> > +from exception import StartVMFailedException
> > +
> > +# This name is derictly defined in the qemu guest serivce
> > +# So you can not change it except it is changed by the service
> > +QGA_DEV_NAME = 'org.qemu.guest_agent.0'
> > +# This path defines an socket path on the host connected with
> > +# a specified VM
> > +QGA_SOCK_PATH_TEMPLATE = '/tmp/%(vm_name)s_qga0.sock'
> > +
> > +
> > +class QEMUKvm(VirtBase):
> > +
> > + DEFAULT_BRIDGE = 'br0'
> > + QEMU_IFUP = """#!/bin/sh
> > +
> > +set -x
> > +
> > +switch=%(switch)s
> > +
> > +if [ -n "$1" ];then
> > + tunctl -t $1
> > + ip link set $1 up
> > + sleep 0.5s
> > + brctl addif $switch $1
> > + exit 0
> > +else
> > + echo "Error: no interface specified"
> > + exit 1
> > +fi
> > +"""
>
> If this file not changed, can be just moved into dep folder. This will
> make this module more clear.
>
Ok, it will be moved into the dep folder in the next version.
> > + QEMU_IFUP_PATH = '/etc/qemu-ifup'
> > +
> > + def __init__(self, dut, vm_name, suite_name):
> > + super(QEMUKvm, self).__init__(dut, vm_name, suite_name)
> Can we auto-detected suite name? In test case we should not use hard
> code suite name.
>
> > + self.set_vm_name(self.vm_name)
> > + self.set_vm_enable_kvm()
> > + self.set_vm_qga()
> > + self.set_vm_daemon()
> > +
>
> It's better to use one function "set_vm_default" to replace these
> functions.
>
Ok, it will be changed.
> > + # initialize qemu emulator, example: qemu-system-x86_64
> > + self.qemu_emulator = self.get_qemu_emulator()
> > +
> > + # initialize qemu boot command line
> > + # example: qemu-system-x86_64 -name vm1 -m 2048 -vnc :1 -
> > daemonize
> > + self.whole_qemu_kvm_boot_line = ''
> > +
>
> The name is too long, please narrow it like "self.qemu_commmandline".
>
Ok, I will try.
> > + self.init_vm_request_resource()
>
> Please add some description of this function.
It will be done next version.
> > +
> > + QGA_CLI_PATH = '-r dep/QMP/'
> > + self.host_session.copy_file_to(QGA_CLI_PATH)
> > +
> > + def init_vm_request_resource(self):
> > + """
> > + initialize vcpus what will be pinned to the VM.
> > + If specify this param, the specified vcpus will
> > + be pinned to VM by the command 'taskset' when
> > + starting the VM.
> > + example:
> > + vcpus_pinned_to_vm = '1 2 3 4'
> > + taskset -c 1,2,3,4 qemu-boot-command-line
> > + """
> > + self.vcpus_pinned_to_vm = ''
> > +
> > + # initialize assigned PCI
> > + self.assigned_pcis = []
> > +
> > + def get_virt_type(self):
> > + """
> > + Get the virtual type.
> > + """
> > + return 'KVM'
> > +
> > + def get_qemu_emulator(self):
> > + """
> > + Get the qemu emulator based on the crb.
> > + """
> > + arch = self.host_session.send_expect('uname -m', '# ')
> > + return 'qemu-system-' + arch
> > +
> > + def set_qemu_emulator(self, qemu_emulator):
> > + """
> > + Set the qemu emulator explicitly.
> > + """
> > + out = self.host_session.send_expect(
> > + 'whereis %s' % str(qemu_emulator), '[.*')
> > + command_paths = out.split(':')[1:]
> > + if command_paths[0].lstrip():
> > + print "No emulator [ %s ] on the DUT [ %s ]" % \
> > + (qemu_emulator, self.host_dut.get_ip_address())
> > + return None
> > + self.qemu_emulator = qemu_emulator
> > +
> This function not called by dts. If this function is for explicated
> qemu binary, there's no meaningful to use "whereis" find qemu.
>
Yes, you are right, I will try to find another tool to replace it.
> > + def has_virtual_ability(self):
> > + """
> > + Check if host has the virtual ability.
> > + """
> > + out = self.host_session.send_expect('lsmod | grep kvm', '# ')
> > + if 'kvm' in out and 'kvm_intel' in out:
> > + return True
> > + else:
> > + return False
> > +
>
> We should also check whether "vmx" supported in cpuinfo.
>
Right, I lose it, I will add it in the next version.
> > + def enable_virtual_ability(self):
> > + """
> > + Load the virutal module of kernel to enable the virutal
> ability.
> > + """
> > + self.host_session.send_expect('modprobe kvm', '# ')
> > + self.host_session.send_expect('modprobe kvm_intel', '# ')
> > + return True
> > +
> > + def disk_image_is_ok(self, image):
> > + """
> > + Check if the image is OK and no error.
> > + """
> > + pass
> > +
> > + def image_is_used(self, image_path):
> > + """
> > + Check if the image has been used on the host.
> > + """
> > + qemu_cmd_lines = self.host_session.send_expect(
> > + "ps aux | grep qemu | grep -v grep", "# ")
> > +
> > + image_name_flag = '/' + image_path.strip().split('/')[-1] +
> ' '
> > + if image_path in qemu_cmd_lines or \
> > + image_name_flag in qemu_cmd_lines:
> > + return True
> > + return False
> > +
> > + def __add_boot_line(self, option_boot_line):
> > + """
> > + Add boot option into the boot line.
> > + """
> > + separator = ' '
> > + self.whole_qemu_kvm_boot_line += separator +
> option_boot_line
> > +
> > + def set_vm_enable_kvm(self, enable='yes'):
> > + """
> > + Set VM boot option to enable the option 'enable-kvm'.
> > + """
> > + self.params.append({'enable_kvm': [{'enable': '%s' %
> enable}]})
> > +
> > + def add_vm_enable_kvm(self, **options):
> > + """
> > + 'enable': 'yes'
> > + """
> > + if 'enable' in options.keys() and \
> > + options['enable'] == 'yes':
> > + enable_kvm_boot_line = '-enable-kvm'
> > + self.__add_boot_line(enable_kvm_boot_line)
> > +
> > + def set_vm_name(self, vm_name):
> > + """
> > + Set VM name.
> > + """
> > + self.params.append({'name': [{'name': '%s' % vm_name}]})
> > +
> > + def add_vm_name(self, **options):
> > + """
> > + name: vm1
> > + """
> > + if 'name' in options.keys() and \
> > + options['name']:
> > + name_boot_line = '-name %s' % options['name']
> > + self.__add_boot_line(name_boot_line)
> > +
> > + def add_vm_cpu(self, **options):
> > + """
> > + model: [host | core2duo | ...]
> > + usage:
> > + choose model value from the command
> > + qemu-system-x86_64 -cpu help
> > + number: '4' #number of vcpus
> > + cpupin: '3 4 5 6' # host cpu list
> > + """
> > + if 'model' in options.keys() and \
> > + options['model']:
> > + cpu_boot_line = '-cpu %s' % options['model']
> > + self.__add_boot_line(cpu_boot_line)
> > + if 'number' in options.keys() and \
> > + options['number']:
> > + smp_cmd_line = '-smp %d' % int(options['number'])
> > + self.__add_boot_line(smp_cmd_line)
> > + if 'cpupin' in options.keys() and \
> > + options['cpupin']:
> > + self.vcpus_pinned_to_vm = str(options['cpupin'])
> > +
> > + def add_vm_mem(self, **options):
> > + """
> > + size: 1024
> > + """
> > + if 'size' in options.keys():
> > + mem_boot_line = '-m %s' % options['size']
> > + self.__add_boot_line(mem_boot_line)
> > +
> > + def add_vm_disk(self, **options):
> > + """
> > + file: /home/image/test.img
> > + """
> > + if 'file' in options.keys():
> > + disk_boot_line = '-drive file=%s' % options['file']
> > + self.__add_boot_line(disk_boot_line)
> > +
> > + def add_vm_net(self, **options):
> > + """
> > + Add VM net device.
> > + type: [nic | user | tap | bridge | ...]
> > + opt_[vlan | fd | br | mac | ...]
> > + note:the sub-option will be decided according to the net
> type.
> > + """
> > + if 'type' in options.keys():
> > + if 'opt_vlan' not in options.keys():
> > + options['opt_vlan'] = '0'
> > + if options['type'] == 'nic':
> > + self.__add_vm_net_nic(**options)
> > + if options['type'] == 'user':
> > + self.__add_vm_net_user(**options)
> > + if options['type'] == 'tap':
> > + self.__add_vm_net_tap(**options)
> > +
> > + if options['type'] == 'user':
> > + self.net_type = 'hostfwd'
> > + elif options['type'] in ['tap', 'bridge']:
> > + self.net_type = 'bridge'
> > +
>
> Element "net_type" not used, why add this here?
>
When trying to get Guest IP, it will be used.
> > + def __add_vm_net_nic(self, **options):
> > + """
> > + type: nic
> > + opt_vlan: 0
> > + note: Default is 0.
> > + opt_macaddr: 00:00:00:00:01:01
> > + note: if creating a nic, it`s better to specify a MAC,
> > + else it will get a random number.
> > + opt_model:["e1000" | "virtio" | "i82551" | ...]
> > + note: Default is e1000.
> > + opt_name: 'nic1'
> > + opt_addr: ''
> > + note: PCI cards only.
> > + opt_vectors:
> > + note: This option currently only affects virtio cards.
> > + """
> > + net_boot_line = '-net nic'
> > + separator = ','
> > + if 'opt_vlan' in options.keys() and \
> > + options['opt_vlan']:
> > + net_boot_line += separator + 'vlan=%s' %
> options['opt_vlan']
> > +
> > + # add MAC info
> > + if 'opt_macaddr' in options.keys() and \
> > + options['opt_macaddr']:
> > + mac = options['opt_macaddr']
> > + else:
> > + mac = self.generate_unique_mac()
> > + net_boot_line += separator + 'macaddr=%s' % mac
> > +
> > + if 'opt_model' in options.keys() and \
> > + options['opt_model']:
> > + net_boot_line += separator + 'model=%s' %
> options['opt_model']
> > + if 'opt_name' in options.keys() and \
> > + options['opt_name']:
> > + net_boot_line += separator + 'name=%s' %
> options['opt_name']
> > + if 'opt_addr' in options.keys() and \
> > + options['opt_addr']:
> > + net_boot_line += separator + 'addr=%s' %
> options['opt_addr']
> > + if 'opt_vectors' in options.keys() and \
> > + options['opt_vectors']:
> > + net_boot_line += separator + 'vectors=%s' %
> > options['opt_vectors']
> > +
> > + if self.__string_has_multi_fields(net_boot_line, separator):
> > + self.__add_boot_line(net_boot_line)
> > +
> > + def __add_vm_net_user(self, **options):
> > + """
> > + type: user
> > + opt_vlan: 0
> > + note: default is 0.
> > + opt_hostfwd: [tcp|udp]:[hostaddr]:hostport-
> [guestaddr]:guestport
> > + """
> > + net_boot_line = '-net user'
> > + separator = ','
> > + if 'opt_vlan' in options.keys() and \
> > + options['opt_vlan']:
> > + net_boot_line += separator + 'vlan=%s' %
> options['opt_vlan']
> > + if 'opt_hostfwd' in options.keys() and \
> > + options['opt_hostfwd']:
> > + self.__check_net_user_opt_hostfwd(options['opt_hostfwd'])
> > + opt_hostfwd = options['opt_hostfwd']
> > + else:
> > + opt_hostfwd = '::-:'
> > + hostfwd_line = self.__parse_net_user_opt_hostfwd(opt_hostfwd)
> > + net_boot_line += separator + 'hostfwd=%s' % hostfwd_line
> > +
> > + if self.__string_has_multi_fields(net_boot_line, separator):
> > + self.__add_boot_line(net_boot_line)
> > +
> > + def __check_net_user_opt_hostfwd(self, opt_hostfwd):
> > + """
> > + Use regular expression to check if hostfwd value format is
> > correct.
> > + """
> > + regx_ip = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
> > + regx_hostfwd = r'["tcp" | "udp"]?:%s?:\d+-%s?:\d+' %
> (regx_ip,
> > regx_ip)
> > + if not re.match(regx_hostfwd, opt_hostfwd):
> > + raise Exception("Option opt_hostfwd format is not
> correct,\n"
> > +
> > + "it is %s,\n " % opt_hostfwd +
> > + "it should be
> [tcp|udp]:[hostaddr]:hostport-"
> > +
> > + "[guestaddr]:guestport.\n")
> > +
> > + def __parse_net_user_opt_hostfwd(self, opt_hostfwd):
> > + """
> > + Parse the boot option 'hostfwd'.
> > + """
> > + separator = ':'
> > + field = lambda option, index, separator=':': \
> > + option.split(separator)[index]
> > +
> > + # get the forword type
> > + fwd_type = field(opt_hostfwd, 0)
> > + if not fwd_type:
> > + fwd_type = 'tcp'
> > +
> > + # get the host addr
> > + host_addr = field(opt_hostfwd, 1)
> > + if not host_addr:
> > + host_addr = str(self.host_dut.get_ip_address())
> > +
> > + # get the host port in the option
> > + host_port = field(opt_hostfwd, 2).split('-')[0]
> > + if not host_port:
> > + host_port = str(self.virt_pool.alloc_port(self.vm_name))
> > + self.redir_port = host_port
> > +
> > + # get the guest addr
> > + try:
> > + guest_addr = str(field(opt_hostfwd, 2).split('-')[1])
> > + except IndexError as e:
> > + guest_addr = ''
> > +
> > + # get the guest port in the option
> > + guest_port = str(field(opt_hostfwd, 3))
> > + if not guest_port:
> > + guest_port = '22'
> > +
> > + hostfwd_line = fwd_type + separator + \
> > + host_addr + separator + \
> > + host_port + \
> > + '-' + \
> > + guest_addr + separator + \
> > + guest_port
> > +
> > + # init the redirect incoming TCP or UDP connections
> > + # just combine host address and host port, it is enough
> > + # for using ssh to connect with VM
> > + self.hostfwd_addr = host_addr + separator + host_port
> > +
> > + return hostfwd_line
> > +
> > + def __add_vm_net_tap(self, **options):
> > + """
> > + type: tap
> > + opt_vlan: 0
> > + note: default is 0.
> > + opt_br: br0
> > + note: if choosing tap, need to specify bridge name,
> > + else it will be br0.
> > + opt_script: QEMU_IFUP_PATH
> > + note: if not specified, default is self.QEMU_IFUP_PATH.
> > + opt_downscript: QEMU_IFDOWN_PATH
> > + note: if not specified, default is self.QEMU_IFDOWN_PATH.
> > + """
> > + net_boot_line = '-net tap'
> > + separator = ','
> > +
> > + # add bridge info
> > + if 'opt_br' in options.keys() and \
> > + options['opt_br']:
> > + bridge = options['opt_br']
> > + else:
> > + bridge = self.DEFAULT_BRIDGE
> > + self.__generate_net_config_script(str(bridge))
> > +
> > + if 'opt_vlan' in options.keys() and \
> > + options['opt_vlan']:
> > + net_boot_line += separator + 'vlan=%s' %
> options['opt_vlan']
> > +
> > + # add network configure script path
> > + if 'opt_script' in options.keys() and \
> > + options['opt_script']:
> > + script_path = options['opt_script']
> > + else:
> > + script_path = self.QEMU_IFUP_PATH
> > + net_boot_line += separator + 'script=%s' % script_path
> > +
> > + # add network configure downscript path
> > + if 'opt_downscript' in options.keys() and \
> > + options['opt_downscript']:
> > + net_boot_line += separator + \
> > + 'downscript=%s' % options['opt_downscript']
> > +
> > + if self.__string_has_multi_fields(net_boot_line, separator):
> > + self.__add_boot_line(net_boot_line)
> > +
> > + def __generate_net_config_script(self, switch=DEFAULT_BRIDGE):
> > + """
> > + Generate a script for qemu emulator to build a tap device
> > + between host and guest.
> > + """
> > + qemu_ifup = self.QEMU_IFUP % {'switch': switch}
> > + file_name = os.path.basename(self.QEMU_IFUP_PATH)
> > + tmp_file_path = '/tmp/%s' % file_name
> > + self.host_dut.create_file(qemu_ifup, tmp_file_path)
> > + self.host_session.send_expect('mv -f ~/%s %s' % (file_name,
> > +
> > self.QEMU_IFUP_PATH), '# ')
> > + self.host_session.send_expect(
> > + 'chmod +x %s' % self.QEMU_IFUP_PATH, '# ')
> > +
> > + def set_vm_device(self, driver='pci-assign', **props):
> > + """
> > + Set VM device with specified driver.
> > + """
> > + props['driver'] = driver
> > + index = self.find_option_index('device')
> > + if index:
> > + self.params[index]['device'].append(props)
> > + else:
> > + self.params.append({'device': [props]})
> > +
> > + def add_vm_device(self, **options):
> > + """
> > + driver: [pci-assign | virtio-net-pci | ...]
> > + prop_[host | addr | ...]: value
> > + note:the sub-property will be decided according to the
> driver.
> > + """
> > + if 'driver' in options.keys() and \
> > + options['driver']:
> > + if options['driver'] == 'pci-assign':
> > + self.__add_vm_pci_assign(**options)
> > + elif options['driver'] == 'virtio-net-pci':
> > + self.__add_vm_virtio_net_pci(**options)
> > +
> > + def __add_vm_pci_assign(self, **options):
> > + """
> > + driver: pci-assign
> > + prop_host: 08:00.0
> > + prop_addr: 00:00:00:00:01:02
> > + """
> > + dev_boot_line = '-device pci-assign'
> > + separator = ','
> > + if 'prop_host' in options.keys() and \
> > + options['prop_host']:
> > + dev_boot_line += separator + 'host=%s' %
> options['prop_host']
> > + if 'prop_addr' in options.keys() and \
> > + options['prop_addr']:
> > + dev_boot_line += separator + 'addr=%s' %
> options['prop_addr']
> > + self.assigned_pcis.append(options['prop_addr'])
> > +
> > + if self.__string_has_multi_fields(dev_boot_line, separator):
> > + self.__add_boot_line(dev_boot_line)
> > +
> > + def __add_vm_virtio_net_pci(self, **options):
> > + """
> > + driver: virtio-net-pci
> > + prop_netdev: mynet1
> > + prop_id: net1
> > + prop_mac: 00:00:00:00:01:03
> > + prop_bus: pci.0
> > + prop_addr: 0x3
> > + """
> > + dev_boot_line = '-device virtio-net-pci'
> > + separator = ','
> > + if 'prop_netdev' in options.keys() and \
> > + options['prop_netdev']:
> > + dev_boot_line += separator + 'netdev=%s' %
> > options['prop_netdev']
> > + if 'prop_id' in options.keys() and \
> > + options['prop_id']:
> > + dev_boot_line += separator + 'id=%s' % options['prop_id']
> > + if 'prop_mac' in options.keys() and \
> > + options['prop_mac']:
> > + dev_boot_line += separator + 'mac=%s' %
> options['prop_mac']
> > + if 'prop_bus' in options.keys() and \
> > + options['prop_bus']:
> > + dev_boot_line += separator + 'bus=%s' %
> options['prop_bus']
> > + if 'prop_addr' in options.keys() and \
> > + options['prop_addr']:
> > + dev_boot_line += separator + 'addr=%s' %
> options['prop_addr']
> > +
> > + if self.__string_has_multi_fields(self, string, separator):
> > + self.__add_boot_line(dev_boot_line)
> > +
>
> What's the need to check multi_fields? Is it enough to check whether
> configuration available?
>
First, this function gets error params, this issue is not tested, the params should
be 'dev_boot_line' and 'separator'.
Second, because 'dev_boot_line' is initialized with '-device virtio-net-pci', and the
separator is ',', though there is not an option, the 'dev_boot_line' is not NULL,
if there is no judgment to the param, we don`t know if there is a definition of
virtio device in the configuration.
> > + def __string_has_multi_fields(self, string, separator,
> field_num=2):
> > + """
> > + Check if string has multiple fields which is splited with
> > + specified separator.
> > + """
> > + fields = string.split(separator)
> > + number = 0
> > + for field in fields:
> > + if field:
> > + number += 1
> > + if number >= field_num:
> > + return True
> > + else:
> > + return False
> > +
> > + def add_vm_monitor(self, **options):
> > + """
> > + port: 6061 # if adding monitor to vm, need to specicy
> > + this port, else it will get a free port
> > + on the host machine.
> > + """
> > + if 'port' in options.keys():
> > + if options['port']:
> > + port = options['port']
> > + else:
> > + port = self.virt_pool.alloc_port(self.vm_name)
> > +
> > + monitor_boot_line = '-monitor tcp::%d,server,nowait' %
> > int(port)
> > + self.__add_boot_line(monitor_boot_line)
> > +
> > + def set_vm_qga(self, enable='yes'):
> > + """
> > + Set VM qemu-guest-agent.
> > + """
> > + index = self.find_option_index('qga')
> > + if index:
> > + self.params[index] = {'qga': [{'enable': '%s' % enable}]}
> > + else:
> > + self.params.append({'qga': [{'enable': '%s' % enable}]})
> > + QGA_SOCK_PATH = QGA_SOCK_PATH_TEMPLATE % {'vm_name':
> self.vm_name}
> > + self.qga_sock_path = QGA_SOCK_PATH
> > +
> > + def add_vm_qga(self, **options):
> > + """
> > + enable: 'yes'
> > + """
> > + QGA_DEV_ID = '%(vm_name)s_qga0' % {'vm_name': self.vm_name}
> > + QGA_SOCK_PATH = QGA_SOCK_PATH_TEMPLATE % {'vm_name':
> self.vm_name}
> > +
> > + separator = ' '
> > +
> > + if 'enable' in options.keys():
> > + if options['enable'] == 'yes':
> > + qga_boot_block = '-chardev
> > socket,path=%(SOCK_PATH)s,server,nowait,id=%(ID)s' + \
> > + separator + '-device virtio-serial'
> +
> > separator + \
> > + '-device
> > virtserialport,chardev=%(ID)s,name=%(DEV_NAME)s'
> > + qga_boot_line = qga_boot_block % {'SOCK_PATH':
> > QGA_SOCK_PATH,
> > + 'DEV_NAME':
> > QGA_DEV_NAME,
> > + 'ID': QGA_DEV_ID}
> > + self.__add_boot_line(qga_boot_line)
> > + self.qga_sock_path = QGA_SOCK_PATH
> > + else:
> > + self.qga_sock_path = ''
> > +
> > + def add_vm_serial_port(self, **options):
> > + """
> > + enable: 'yes'
> > + """
> > + SERAIL_SOCK_PATH = "/tmp/%s_serial.sock" % self.vm_name
> > + if 'enable' in options.keys():
> > + if options['enable'] == 'yes':
> > + serial_boot_line = '-serial unix:%s,server,nowait' %
> > SERIAL_SOCK_PATH
> > + self.__add_boot_line(serial_boot_line)
> > + else:
> > + pass
> > +
> > + def add_vm_vnc(self, **options):
> > + """
> > + displayNum: 1
> > + """
> > + if 'displayNum' in options.keys() and \
> > + options['displayNum']:
> > + display_num = options['displayNum']
> > + else:
> > + display_num = self.virt_pool.alloc_vnc_num(self.vm_name)
> > +
> > + vnc_boot_line = '-vnc :%d' % int(display_num)
> > + self.__add_boot_line(vnc_boot_line)
> > +
> > + def set_vm_daemon(self, enable='yes'):
> > + """
> > + Set VM daemon option.
> > + """
> > + index = self.find_option_index('daemon')
> > + if index:
> > + self.params[index] = {'daemon': [{'enable': '%s' %
> enable}]}
> > + else:
> > + self.params.append({'daemon': [{'enable': '%s' %
> enable}]})
> > +
> > + def add_vm_daemon(self, **options):
> > + """
> > + enable: 'yes'
> > + note:
> > + By default VM will start with the daemonize status.
> > + Not support starting it on the stdin now.
> > + """
> > + if 'daemon' in options.keys() and \
> > + options['enable'] == 'no':
> > + pass
> > + else:
> > + daemon_boot_line = '-daemonize'
> > + self.__add_boot_line(daemon_boot_line)
> > +
> > + def start_vm(self):
> > + """
> > + Start VM.
> > + """
> > + qemu_emulator = self.qemu_emulator
> > +
> > + self.__alloc_assigned_pcis()
> > +
> > + if self.vcpus_pinned_to_vm.strip():
> > + vcpus = self.__alloc_vcpus()
> > +
> > + if vcpus.strip():
> > + whole_qemu_kvm_boot_line = 'taskset -c %s ' % vcpus
> + \
> > + qemu_emulator + ' ' + \
> > + self.whole_qemu_kvm_boot_line
>
> If here only to get vcpus for usage, better to use function replace
> codes here.
>
Ok, I will do it next version.
> > + else:
> > + whole_qemu_kvm_boot_line = qemu_emulator + ' ' + \
> > + self.whole_qemu_kvm_boot_line
> > +
> > + # Start VM using the qemu command
> > + out = self.host_session.send_expect(whole_qemu_kvm_boot_line,
> '#
> > ')
> > + time.sleep(30)
> > + if out:
> > + raise StartVMFailedException(out)
> > +
> > + def __alloc_vcpus(self):
> > + """
> > + Allocate virtual CPUs for VM.
> > + """
> > + req_cpus = self.vcpus_pinned_to_vm.split()
> > + cpus = self.virt_pool.alloc_cpu(vm=self.vm_name,
> > corelist=req_cpus)
> > +
> > + vcpus_pinned_to_vm = ''
> > + for cpu in cpus:
> > + vcpus_pinned_to_vm += ',' + cpu
> > + vcpus_pinned_to_vm = vcpus_pinned_to_vm.lstrip(',')
> > +
> > + if len(req_cpus) != len(cpus):
> > + print "WARNING: Just pin vcpus [ %s ] to VM!" %
> > vcpus_pinned_to_vm
> > +
>
> If cannot allocate cpus, should raise failure.
>
Maybe it is better to raise failure, if the user must need to get
the cpus, Ok, I will do it next version.
> > + return vcpus_pinned_to_vm
> > +
> > + def __alloc_assigned_pcis(self):
> > + """
> > + Record the PCI device info
> > + Struct: {dev pci: {'is_vf': [True | False],
> > + 'pf_pci': pci}}
> > + example:
> > + {'08:10.0':{'is_vf':True, 'pf_pci': 08:00.0}}
> > + """
> > + assigned_pcis_info = {}
> > + for pci in self.assigned_pcis:
> > + assigned_pcis_info[pci] = {}
> > + if self.__is_vf_pci(pci):
> > + assigned_pcis_info[pci]['is_vf'] = True
> > + pf_pci = self.__map_vf_to_pf(pci)
> > + assgined_pcis_info[pci]['pf_pci'] = pf_pci
> > + if self.virt_pool.alloc_vf_from_pf(vm=self.vm_name,
> > + pf_pci=pf_pci,
> > + *[pci]):
> > + port = self.__get_vf_port(pci)
> > + port.unbind_driver()
> > + port.bind_driver('pci-stub')
> > + else:
> > + # check that if any VF of specified PF has been
> > + # used, raise exception
> > + vf_pci = self.__vf_has_been_assinged(pci,
> > **assinged_pcis_info)
> > + if vf_pci:
> > + raise Exception(
> > + "Error: A VF [%s] generated by PF [%s] has
> " %
> > + (vf_pci, pci) +
> > + "been assigned to VM, so this PF can not be
> " +
> > + "assigned to VM again!")
> > + # get the port instance of PF
> > + port = self.__get_net_device_by_pci(pci)
> > +
> > + if self.virt_pool.alloc_pf(vm=self.vm_name,
> > + *[pci]):
> > + port.unbind_driver()
> > +
> > + def __is_vf_pci(self, dev_pci):
> > + """
> > + Check if the specified PCI dev is a VF.
> > + """
> > + for port_info in self.host_dut.ports_info:
> > + if 'sriov_vfs_pci' in port_info.keys():
> > + if dev_pci in port_info['sriov_vfs_pci']:
> > + return True
> > + return False
> > +
>
> Vf pci device should be handled in virt_dut module and shared with
> different types of virtualization hypervisor.
>
Do you mean I should move this function to other module?
> > + def __map_vf_to_pf(self, dev_pci):
> > + """
> > + Map the specified VF to PF.
> > + """
> > + for port_info in self.host_dut.ports_info:
> > + if 'sriov_vfs_pci' in port_info.keys():
> > + if dev_pci in port_info['sriov_vfs_pci']:
> > + return port_info['pci']
> > + return None
> > +
> Same as above.
>
> > + def __get_vf_port(self, dev_pci):
> > + """
> > + Get the NetDevice instance of specified VF.
> > + """
> > + for port_info in self.host_dut.ports_info:
> > + if 'vfs_port' in port_info.keys():
> > + for port in port_info['vfs_port']:
> > + if dev_pci == port.pci:
> > + return port
> > + return None
> > +
>
> Same as above.
> > + def __vf_has_been_assigned(self, pf_pci, **assigned_pcis_info):
> > + """
> > + Check if the specified VF has been used.
> > + """
> > + for pci in assigned_pcis_info.keys():
> > + if assigned_pcis_info[pci]['is_vf'] and \
> > + assigned_pcis_info[pci]['pf_pci'] == pf_pci:
> > + return pci
> > + return False
> > +
> VF device can’t be shared with VMs, this function should be in resource
> module.
>
> > + def __get_net_device_by_pci(self, net_device_pci):
> > + """
> > + Get NetDevice instance by the specified PCI bus number.
> > + """
> > + port_info = self.host_dut.get_port_info(net_device_pci)
> > + return port_info['port']
> > +
>
> Vf pci device should be handled in virt_dut module and shared with
> different types of virtualization hypervisor.
>
> > + def get_vm_ip(self):
> > + """
> > + Get VM IP.
> > + """
> > + get_vm_ip = getattr(self, "get_vm_ip_%s" % self.net_type)
> > + return get_vm_ip()
> > +
> > + def get_vm_ip_hostfwd(self):
> > + """
> > + Get IP which VM is connected by hostfwd.
> > + """
> > + return self.hostfwd_addr
> > +
> > + def get_vm_ip_bridge(self):
> > + """
> > + Get IP which VM is connected by bridge.
> > + """
> > + out = self.__control_session('ping', '60')
> > + if not out:
> > + time.sleep(10)
> > + out = self.__control_session('ifconfig')
> > + ips = re.findall(r'inet (\d+\.\d+\.\d+\.\d+)', out)
> > +
> > + if '127.0.0.1' in ips:
> > + ips.remove('127.0.0.1')
> > +
> > + num = 3
> > + for ip in ips:
> > + out = self.host_session.send_expect(
> > + 'ping -c %d %s' % (num, ip), '# ')
> > + if '0% packet loss' in out:
> > + return ip
>
> The first pinged interface will be the interface of bridge, can we make
> sure that?
I think it is enough for us to check if there is a connection between host
and guest.
> > + return ''
> > +
> > + def __control_session(self, command, *args):
> > + """
> > + Use the qemu guest agent service to control VM.
> > + Note:
> > + :command: there are these commands as below:
> > + cat, fsfreeze, fstrim, halt, ifconfig, info,\
> > + ping, powerdown, reboot, shutdown, suspend
> > + :args: give different args by the different commands.
> > + """
> > + if not self.qga_sock_path:
> > + self.host_logger.info(
> > + "No QGA service between host [ %s ] and guest
> [ %s ]" %
> > + (self.host_dut.Name, self.vm_name))
> > + return None
> > +
> > + cmd_head = '~/QMP/' + \
> > + "qemu-ga-client " + \
> > + "--address=%s %s" % \
> > + (self.qga_sock_path, command)
> > +
> > + cmd = cmd_head
> > + for arg in args:
> > + cmd = cmd_head + ' ' + str(arg)
> > +
> > + out = self.host_session.send_expect(cmd, '# ')
> > +
> > + return out
> > +
> > + def stop(self):
> > + """
> > + Stop VM.
> > + """
> > + self.__control_session('powerdown')
>
> Here's need function to check whether shutdown successfully.
>
Ok, it will be done.
> > + time.sleep(5)
> > + self.virt_pool.free_all_resource(self.vm_name)
> > +
> > +
> > +if __name__ == "__main__":
> > + import subprocess
> > + import sys
> > + import pdb
> > + from serializer import Serializer
> > + from crbs import crbs
> > + from tester import Tester
> > + from dut import Dut
> > + import dts
> > + from virt_proxy import VirtProxy
> > +
> > + command = "ifconfig br0"
> > + subp = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
> > + subp.wait()
> > +
> > + intf_info = subp.stdout.readlines()
> > + for line_info in intf_info:
> > + regx = re.search(r'inet (\d+\.\d+\.\d+\.\d+)', line_info)
> > + if regx:
> > + dutIP = regx.group(1)
> > + break
> > +
> > + print "DEBUG: dutIp: ", dutIP
> > +
> > + # look up in crbs - to find the matching IP
> > + crbInst = None
> > + for crb in crbs:
> > + if crb['IP'] == dutIP:
> > + crbInst = crb
> > + break
> > +
> > + # only run on the dut in known crbs
> > + if crbInst is None:
> > + raise Exception("No available crb instance!!!")
> > +
> > + # initialize the dut and tester
> > + serializer = Serializer()
> > + serializer.set_serialized_filename('../.%s.cache' %
> crbInst['IP'])
> > + serializer.load_from_file()
> > +
> > + read_cache = None
> > + skip_setup = None
> > +
> > + project = "dpdk"
> > + dts.Package = 'dep/dpdk.tar.gz'
> > + dut = dts.get_project_obj(project, Dut, crbInst, serializer)
> > + tester = dts.get_project_obj(project, Tester, crbInst,
> serializer)
> > + dut.tester = tester
> > + dut.base_dir = 'dpdk'
> > + dut.set_nic_type('niantic')
> > + tester.dut = dut
> > +
> > + tester.set_test_types(True, False)
> > + dut.set_test_types(True, False)
> > +
> > + tester.set_speedup_options(read_cache, skip_setup)
> > + tester.tester_prerequisites()
> > + dut.set_speedup_options(read_cache, skip_setup)
> > + dut.dut_prerequisites()
> > +
> > + # test that generating and destroying VF
> > + port0 = dut.ports_info[0]['port']
> > + dut.generate_sriov_vfs_by_port(0, 4)
> > + print "port 0 sriov vfs: ", dut.ports_info[0]
> > +
> > + dut.destroy_sriov_vfs_by_port(0)
> > +
> > + time.sleep(2)
> > +
> > + # test that binding and unbing the NIC
> > + port0_pci = dut.ports_info[0]['pci']
> > + port0.unbind_driver()
> > +
> > + dut.logger.info("JUST TESTING!!!")
> > +
> > + # Start VM by the qemu kvm config file
> > + vm1 = QEMUKvm(dut, 'vm1', 'pmd_sriov')
> > + print "VM config params:"
> > + print vm1.params
> > + vm1_dut = vm1.start()
> > +
> > + try:
> > + host_ip = vm1.session.send_expect("ifconfig", '# ')
> > + print "Host IP:"
> > + print host_ip
> > +
> > + vm1_ip = vm1.get_vm_ip()
> > + print "VM1 IP:"
> > + print vm1_ip
> > +
> > + print "VM1 PCI device:"
> > + print vm_dut.session.send_expect('lspci -nn | grep -i eth',
> '# ')
> > + except Exception as e:
> > + print e
> > + vm1_dut.stop()
> > + port0.bind_driver()
> > + # Stop VM
> > + vm1.stop()
> > + port0.bind_driver()
> > +
> > + dut.host_logger.logger_exit()
> > + dut.logger.logger_exit()
> > + tester.logger.logger_exit()
> > +
> > + print "Start and stop VM over!"
> > diff --git a/framework/virt_base.py b/framework/virt_base.py
> > new file mode 100644
> > index 0000000..625c309
> > --- /dev/null
> > +++ b/framework/virt_base.py
> > @@ -0,0 +1,250 @@
> > +# <COPYRIGHT_TAG>
> > +
> > +from random import randint
> > +from itertools import imap
> > +
> > +import dts
> > +from dut import Dut
> > +from config import VirtConf
> > +from config import VIRTCONF
> > +from logger import getLogger
> > +from settings import CONFIG_ROOT_PATH
> > +from virt_dut import VirtDut
> > +
> > +
> > +class VirtBase(object):
> > +
> > + """
> > + Basic module for customer special virtual type. This module
> implement
> > functions
> > + configurated and composed the VM boot command. With these
> function,
> > we can get
> > + and set the VM boot command, and instantiate the VM.
> > + """
> > +
> > + def __init__(self, dut, vm_name, suite_name):
> > + """
> > + Initialize the VirtBase.
> > + dut: the instance of Dut
> > + vm_name: the name of VM which you have confiured in the
> configure
> > + suite_name: the name of test suite
> > + """
> > + self.host_dut = dut
> > + self.vm_name = vm_name
> > + self.suite = suite_name
> > +
> > + # init the host session and logger for VM
> > + self.host_dut.init_host_session()
> > +
> > + # replace dut session
> > + self.host_session = self.host_dut.host_session
> > + self.host_logger = self.host_dut.logger
> > +
> > + # init the host resouce pool for VM
> > + self.virt_pool = self.host_dut.virt_pool
> > +
> > + if not self.has_virtual_ability():
> > + if not self.enable_virtual_ability():
> > + raise Exception(
> > + "Dut [ %s ] cannot have the virtual ability!!!")
> > +
>
> We need handle those exception in virtualization module.
>
I don`t think it should be handled here, because the virtual module is initialized
in the cases, if we handle this exception, how to know if the virtual module is
initialized successfully?
Or we should define a guideline, all exceptions in the framework should be handled itself,
If failed, just return None, else return the correct result. What do you think?
> > + self.virt_type = self.get_virt_type()
> > + self.load_global_config()
> > + self.load_local_config(suite_name)
> > +
> > + def get_virt_type(self):
> > + """
> > + Get the virtual type, such as KVM, XEN or LIBVIRT.
> > + """
> > + NotImplemented
> > +
> > + def has_virtual_ability(self):
> > + """
> > + Check if the host have the ability of virtualization.
> > + """
> > + NotImplemented
> > +
> > + def enable_virtual_ability(self):
> > + """
> > + Enalbe the virtual ability on the DUT.
> > + """
> > + NotImplemented
> > +
> > + def load_global_config(self):
> > + """
> > + Load global configure in the path DTS_ROOT_PAHT/conf.
> > + """
> > + conf = VirtConf(VIRTCONF)
> > + conf.load_virt_config(self.virt_type)
> > + self.params = conf.get_virt_config()
> > +
> Need add check whether configuration file load successfully.
>
Yes, it should be done.
> > + def load_local_config(self, suite_name):
> > + """
> > + Load local configure in the path DTS_ROOT_PATH/conf.
> > + """
> > + # load local configuration by suite and vm name
> > + conf = VirtConf(CONFIG_ROOT_PATH + suite_name + '.cfg')
> > + conf.load_virt_config(self.vm_name)
> > + localparams = conf.get_virt_config()
>
> Need add check whether configuration file load successfully.
Yes, it should be done.
> > + # replace global configurations with local configurations
> > + for param in localparams:
> > + if 'mem' in param.keys():
> > + self.__save_local_config('mem', param['mem'])
> > + continue
> > + if 'cpu' in param.keys():
> > + self.__save_local_config('cpu', param['cpu'])
> > + continue
> > + # save local configurations
> > + self.params.append(param)
> > +
> > + def __save_local_config(self, key, value):
> > + """
> > + Save the local config into the global dict self.param.
> > + """
> > + for param in self.params:
> > + if key in param.keys():
> > + param[key] = value
> > +
> > + def compose_boot_param(self):
> > + """
> > + Compose all boot param for starting the VM.
> > + """
> > + for param in self.params:
> > + key = param.keys()[0]
> > + value = param[key]
> > + try:
> > + param_func = getattr(self, 'add_vm_' + key)
> > + if callable(param_func):
> > + for option in value:
> > + param_func(**option)
> > + else:
> > + print "Virt %s function not implemented!!!" %
> key
> > + except Exception as e:
> > + print "Failed: ", e
> > +
>
> Function call failed should log with error.
Ok, it will be done.
>
> > + def find_option_index(self, option):
> > + """
> > + Find the boot option in the params which is generated from
> > + the global and local configures, and this function will
> > + return the index by which option can be indexed in the
> > + param list.
> > + """
> > + index = 0
> > + for param in self.params:
> > + key = param.keys()[0]
> > + if key.strip() == option.strip():
> > + return index
> > + index += 1
> > +
> > + return None
> > +
> > + def generate_unique_mac(self):
> > + """
> > + Generate a unique MAC based on the DUT.
> > + """
> > + mac_head = '00:00:00:'
> > + mac_tail = ':'.join(
> > + ['%02x' % x for x in imap(lambda x:randint(0, 255),
> > range(3))])
> > + return mac_head + mac_tail
> > +
> > + def get_vm_ip(self):
> > + """
> > + Get the VM IP.
> > + """
> > + NotImplemented
> > +
> > + def start(self):
> > + """
> > + Start VM and instantiate the VM with VirtDut.
> > + """
> > + self.compose_boot_param()
> > + try:
> > + self.start_vm()
> > + except Exception as e:
> > + self.host_logger.error(e)
> > + return None
> > + try:
> > + vm_dut = self.instantiate_vm_dut()
> > + except Exception as e:
> > + self.host_logger.error(e)
> > + self.stop()
> After stop vm, need clean up resource like VFs and cores.
>
It should be done, this need some efforts.
> > + return None
> > + return vm_dut
> > +
> > + def start_vm(self):
> > + """
> > + Start VM.
> > + """
> > + NotImplemented
> > +
> > + def instantiate_vm_dut(self):
> > + """
> > + Instantiate the Dut class for VM.
> > + """
> > + crb = self.host_dut.crb.copy()
> > + crb['bypass core0'] = False
> > + vm_ip = self.get_vm_ip()
> Need check whether vm_ip valid.
>
It should be done.
> > + crb['IP'] = vm_ip
> > + if ':' not in vm_ip:
> > + remote_ip = vm_ip.strip()
> > + redirect_port = ''
> > + else:
> > + remote_addr = vm_ip.split(':')
> > + remote_ip = remote_addr[0].strip()
> > + redirect_port = remote_addr[1].strip()
> > + self.__remove_old_rsa_key(remote_ip, redirect_port)
> > +
>
> These code can be moved to function "__remove_old_rsa_key".
>
Yes, it is better.
> > + serializer = self.host_dut.serializer
> > +
> > + try:
> > + vm_dut = VirtDut(
> > + crb,
> > + serializer,
> > + self.virt_type,
> > + self.vm_name,
> > + self.suite)
> > + except Exception as e:
> > + raise Exception(e)
>
> If VirtDut instantiation failed, function instantiate_vm_dut should
> return failure and should not run remaining codes.
>
Yes, do you mean I just need to log the error info and return failure?
> > + vm_dut.nic_type = 'any'
> > + vm_dut.tester = self.host_dut.tester
> > + vm_dut.host_dut = self.host_dut
> > + vm_dut.host_session = self.host_session
> > +
> > + read_cache = False
> > + skip_setup = self.host_dut.skip_setup
> > + base_dir = self.host_dut.base_dir
> > + vm_dut.set_speedup_options(read_cache, skip_setup)
> > + func_only = self.host_dut.want_func_tests
> > + perf_only = self.host_dut.want_perf_tests
> > + vm_dut.set_test_types(func_tests=func_only,
> perf_tests=perf_only)
> > + # base_dir should be set before prerequisites
> > + vm_dut.set_directory(base_dir)
> > +
> > + # setting up dpdk in vm, must call at last
> > + vm_dut.prerequisites(dts.Package, dts.Patches)
> > +
> Prerequisites maybe failed, need add check here.
>
> > + target = self.host_dut.target
> > + if target:
> > + vm_dut.set_target(target)
> > + else:
> > + raise Exception("Cannot get the HOST DUT test target!")
> > +
> > + return vm_dut
> > +
> > + def __remove_old_rsa_key(self, remote_ip, redirect_port):
> > + """
> > + Remove the old RSA key of specified remote IP.
> > + """
> > + rsa_key_path = "~/.ssh/known_hosts"
> > + if redirect_port:
> > + remove_rsa_key_cmd = "sed -i '/^\[%s\]:%d/d' %s" % \
> > + (remote_ip.strip(), int(
> > + redirect_port), rsa_key_path)
> > + else:
> > + remove_rsa_key_cmd = "sed -i '/^%s/d' %s" % \
> > + (remote_ip.strip(), rsa_key_path)
> > + self.host_dut.tester.send_expect(remove_rsa_key_cmd, "# ")
> > +
> > + def stop(self):
> > + """
> > + Stop the VM by the name of VM.
> > + """
> > + NotImplemented
> > diff --git a/framework/virt_dut.py b/framework/virt_dut.py
> > new file mode 100644
> > index 0000000..1073253
> > --- /dev/null
> > +++ b/framework/virt_dut.py
> > @@ -0,0 +1,239 @@
> > +# BSD LICENSE
> > +#
> > +# Copyright(c) 2010-2015 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.
> > +
> > +import os
> > +import re
> > +import time
> > +import dts
> > +import settings
> > +from config import PortConf
> > +from settings import NICS, LOG_NAME_SEP
> > +from ssh_connection import SSHConnection
> > +from project_dpdk import DPDKdut
> > +from dut import Dut
> > +from net_device import NetDevice
> > +from logger import getLogger
> > +
> > +
> > +class VirtDut(DPDKdut):
> > +
> > + """
> > + A connection to the CRB under test.
> > + This class sends commands to the CRB and validates the responses.
> It
> > is
> > + implemented using either ssh for linuxapp or the terminal server
> for
> > + baremetal.
> > + All operations are in fact delegated to an instance of either
> > CRBLinuxApp
> > + or CRBBareMetal.
> > + """
> > +
> > + def __init__(self, crb, serializer, virttype, vm_name, suite):
> > + super(Dut, self).__init__(crb, serializer)
> > + self.vm_ip = self.get_ip_address()
> > + self.NAME = 'virtdut' + LOG_NAME_SEP + '%s' % self.vm_ip
> > + # load port config from suite cfg
> > + self.suite = suite
> > + self.logger = getLogger(self.NAME)
> > + self.logger.config_execution('vmdut')
> > + self.session = SSHConnection(self.vm_ip, self.NAME,
> > + self.get_password())
> > + self.session.init_log(self.logger)
> > +
> > + # if redirect ssh port, there's only one session enabled
> > + self.alt_session = SSHConnection(self.vm_ip, self.NAME +
> '_alt',
> > + self.get_password())
> > + self.alt_session.init_log(self.logger)
> > +
> > + self.number_of_cores = 0
> > + self.tester = None
> > + self.cores = []
> > + self.architecture = None
> > + self.ports_info = None
> > + self.ports_map = []
> > + self.virttype = virttype
> > + self.vmtype = ''
> > + if self.virttype == 'XEN':
> > + self.vmtype = 'domu'
>
> Change virttype to virt_type, and why not check only by virt_type?
> What's the difference of vmtype?
>
I need to check it with Huilong.
> > + self.virttype = 'host'
> > +
> > + def set_nic_type(self, nic_type):
> > + """
> > + Set CRB NICS ready to validated.
> > + """
> > + self.nic_type = nic_type
> > + # vm_dut config will load from vm configuration file
> > +
> > + def load_portconf(self):
> > + """
> > + Load port config for this virtual machine
> > + """
> > + return
> > +
> > + def set_target(self, target):
> > + """
> > + Set env variable, these have to be setup all the time. Some
> tests
> > + need to compile example apps by themselves and will fail
> > otherwise.
> > + Set hugepage on DUT and install modules required by DPDK.
> > + Configure default ixgbe PMD function.
> > + """
> > + self.set_toolchain(target)
> > +
> > + # set env variable
> > + # These have to be setup all the time. Some tests need to
> compile
> > + # example apps by themselves and will fail otherwise.
> > + self.send_expect("export RTE_TARGET=" + target, "#")
> > + self.send_expect("export RTE_SDK=`pwd`", "#")
> > +
> > + if not self.skip_setup:
> > + self.build_install_dpdk(target)
> > +
> > + self.setup_memory(hugepages=512)
> 512M maybe not available, this value should calculated by virtual
> machine memory size or value stripped from configuration file.
>
You are right, it will be done next version.
> > + self.setup_modules(target)
> > +
> > + self.bind_interfaces_linux('igb_uio')
>
> Module should also stripped from configuration file.
>
What`s meaning?
> > +
> > + def prerequisites(self, pkgName, patch):
> > + """
> > + Prerequest function should be called before execute any test
> case.
> > + Will call function to scan all lcore's information which on
> DUT.
> > + Then call pci scan function to collect nic device
> information.
> > + At last setup DUT' environment for validation.
> > + """
> > + self.prepare_package(pkgName, patch)
> > +
> > + self.send_expect("cd %s" % self.base_dir, "# ")
> > + self.host_session.send_expect("cd %s" % self.base_dir, "# ")
> > + self.send_expect("alias ls='ls --color=none'", "#")
> > +
> > + if self.get_os_type() == 'freebsd':
> > + self.send_expect('alias make=gmake', '# ')
> > + self.send_expect('alias sed=gsed', '# ')
> > +
> We do not support freebsd guest, those code should removed.
>
It will be done.
> > + self.init_core_list()
> > + self.pci_devices_information()
> > +
> > + # scan ports before restore interface
> > + self.scan_ports()
> > + # restore dut ports to kernel
> > + if self.vmtype != 'domu':
> > + self.restore_interfaces()
> > + else:
> > + self.restore_interfaces_domu()
> > + # rescan ports after interface up
> Duplicated concept with virt_type. If functions different between
> hypervisors, we need implemented them in qemu_{virt_type}.
>
Right, it will be done.
> > + self.rescan_ports()
> > +
> > + # no need to rescan ports for guest os just bootup
> > + # load port infor from config file
> > + self.load_portconf()
> > +
> Need check whether load failed.
>
Right, it will be done.
> > + # enable tester port ipv6
> > + self.host_dut.enable_tester_ipv6()
> > + self.mount_procfs()
> > + # auto detect network topology
> > + self.map_available_ports()
> > + # disable tester port ipv6
> > + self.host_dut.disable_tester_ipv6()
> > +
> > + # print latest ports_info
> > + for port_info in self.ports_info:
> > + self.logger.info(port_info)
> > +
> > + def restore_interfaces_domu(self):
> > + """
> > + Restore Linux interfaces.
> > + """
> > + for port in self.ports_info:
> > + pci_bus = port['pci']
> > + pci_id = port['type']
> > + driver = settings.get_nic_driver(pci_id)
> > + if driver is not None:
> > + addr_array = pci_bus.split(':')
> > + bus_id = addr_array[0]
> > + devfun_id = addr_array[1]
> > + port = NetDevice(self, bus_id, devfun_id)
>
> Port object is temporary used, why use NetDevice module create another
> one? We can just use port['port'] to use NetDevice object.
Right, it will be replaced.
> > + itf = port.get_interface_name()
> > + self.send_expect("ifconfig %s up" % itf, "# ")
> > + time.sleep(30)
>
> Sleep 30 seconds is too long and every port will wait so long. Is there
> any need to wait so long? We should call all ports up and then wait few
> seconds.
I will check it.
> > + print self.send_expect("ip link ls %s" % itf, "# ")
> > + else:
> > + self.logger.info(
> > + "NOT FOUND DRIVER FOR PORT (%s|%s)!!!" %
> (pci_bus,
> > pci_id))
> > +
> > + def pci_devices_information(self):
> > + self.pci_devices_information_uncached()
> > +
> > + def get_memory_channels(self):
> > + """
> > + Virtual machine has no memory channel concept, so always
> return 1
> > + """
> > + return 1
> > +
> > + def check_ports_available(self, pci_bus, pci_id):
> > + """
> > + Check that whether auto scanned ports ready to use
> > + """
> > + pci_addr = "%s:%s" % (pci_bus, pci_id)
> > + if pci_id == "8086:100e":
> > + return False
>
> Why e1000 default pci_id is invalided, need comments here.
>
Ok, it will be checked.
> > + return True
> > + # pci_addr = "%s:%s" % (pci_bus, pci_id)
> > + # if self.nic_type == 'any':
> > + # load vm port conf need another function
> > + # need add vitrual function device into NICS
>
> Missing functions here.
>
It should be checked here.
> > +
> > + def scan_ports(self):
> > + """
> > + Scan ports information, for vm will always scan
> > + """
> > + self.scan_ports_uncached()
> > +
> > + def scan_ports_uncached(self):
> > + """
> > + Scan ports and collect port's pci id, mac adress, ipv6
> address.
> > + """
> > + scan_ports_uncached = getattr(
> > + self, 'scan_ports_uncached_%s' % self.get_os_type())
> > + return scan_ports_uncached()
> > +
> > + def map_available_ports(self):
> > + """
> > + Load or generate network connection mapping list.
> > + """
> > + self.map_available_ports_uncached()
> > + self.logger.warning("DUT PORT MAP: " + str(self.ports_map))
> > +
> > + def send_ping6(self, localPort, ipv6, mac=''):
> > + """
> > + Send ping6 packet from local port with destination ipv6
> address.
> > + """
> > + if self.ports_info[localPort]['type'] == 'ixia':
> > + pass
> > + else:
> > + return self.send_expect("ping6 -w 1 -c 1 -A -I %s %s" %
> > (self.ports_info[localPort]['intf'], ipv6), "# ", 10)
> > diff --git a/framework/virt_resource.py b/framework/virt_resource.py
> > new file mode 100644
> > index 0000000..856f9dc
> > --- /dev/null
> > +++ b/framework/virt_resource.py
> > @@ -0,0 +1,486 @@
> > +#!/usr/bin/python
> > +# BSD LICENSE
> > +#
> > +# Copyright(c) 2010-2015 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.
> > +from random import randint
> > +
> > +from utils import get_obj_funcs
> > +
> > +INIT_FREE_PORT = 6060
> > +
> > +
> > +class VirtResource(object):
> > +
> > + """
> > + Class handle dut resource, like cpu, memory, net devices
> > + """
> > +
> > + def __init__(self, dut):
> > + self.dut = dut
> > +
> > + self.cores = [int(core['thread']) for core in dut.cores]
> > + # initialized unused cores
> > + self.unused_cores = self.cores[:]
> > + # initialized used cores
> > + self.used_cores = [-1] * len(self.unused_cores)
> > +
> Need macro INVL replace of "-1".
>
Ok.
> > + self.ports_info = dut.ports_info
> > + # initialized unused ports
> > + self.ports = [port['pci'] for port in dut.ports_info]
> > + self.unused_ports = self.ports[:]
> > + # initialized used ports
> > + self.used_ports = ['unused'] * len(self.unused_ports)
> > +
> > + # initialized vf ports
> > + self.vfs_info = []
> > + self.vfs = []
> > + self.unused_vfs = []
> > + self.used_vfs = []
> > +
> > + # save allocated cores and related vm
> > + self.allocated_info = {}
> > +
> > + def __port_used(self, pci):
> > + index = self.ports.index(pci)
> Add check not found the pci device.
>
Yes, it will be added.
> > + self.used_ports[index] = pci
> > + self.unused_ports[index] = 'used'
> > +
> > + def __port_unused(self, pci):
> > + index = self.ports.index(pci)
> Add check not found the pci device.
Yes, it will be added.
> > + self.unused_ports[index] = pci
> > + self.used_ports[index] = 'unused'
> > +
> > + def __port_on_socket(self, pci, socket):
> > + for port in self.ports_info:
> > + if port['pci'] == pci:
> > + if socket is -1:
> > + return True
> > +
> > + if port['numa'] == socket:
> > + return True
> > + else:
> > + return False
> > +
> > + return False
> > +
> > + def __vf_used(self, pci):
> > + index = self.vfs.index(pci)
> Add check not found the pci device.
Yes, it will be added.
> > + self.used_vfs[index] = pci
> > + self.unused_vfs[index] = 'used'
> > +
> > + def __vf_unused(self, pci):
> > + index = self.vfs.index(pci)
> Add check not found the pci device.
Yes, it will be added.
> > + self.used_vfs[index] = 'unused'
> > + self.unused_vfs[index] = pci
> > +
> > + def __core_used(self, core):
> > + core = int(core)
> > + index = self.cores.index(core)
> Add check not found core.
Yes, it will be added.
> > + self.used_cores[index] = core
> > + self.unused_cores[index] = -1
> > +
> > + def __core_unused(self, core):
> > + core = int(core)
> > + index = self.cores.index(core)
> Add check not found core.
Yes, it will be added.
> > + self.unused_cores[index] = core
> > + self.used_cores[index] = -1
> > +
> > + def __core_on_socket(self, core, socket):
> > + for dut_core in self.dut.cores:
> > + if int(dut_core['thread']) == core:
> > + if socket is -1:
> > + return True
> > +
> > + if int(dut_core['socket']) == socket:
> > + return True
> > + else:
> > + return False
> > +
> > + return False
> > +
> > + def __core_isused(self, core):
> > + index = self.cores.index(core)
> > + if self.used_cores[index] != -1:
> > + return True
> > + else:
> > + return False
> > +
> > + def reserve_cpu(self, coremask=''):
> > + """
> > + Reserve dpdk used cpus by mask
> > + """
> Add comments how to calculate cpus.
>
Ok, it will be added.
> > + val = int(coremask, base=16)
> > + cpus = []
> > + index = 0
> > + while val != 0:
> > + if val & 0x1:
> > + cpus.append(index)
> > +
> > + val = val >> 1
> > + index += 1
> > +
> > + for cpu in cpus:
> > + self.__core_used(cpu)
> > +
> > + def alloc_cpu(self, vm='', number=-1, socket=-1, corelist=None):
> > + """
> > + There're two options for request cpu resouce for vm.
> > + If number is not -1, just allocate cpu from not used cores.
> > + If list is not None, will allocate cpu after checked.
> > + """
> > + cores = []
> > +
> > + if vm == '':
> > + print "Alloc cpu request vitual machine name!!!"
> > + return cores
> > +
> > + if number != -1:
> > + for core in self.unused_cores:
> > + if core != -1 and number != 0:
> -1 should be replaced by macro INVAL.
Ok, it will be added.
> > + if self.__core_on_socket(core, socket) is True:
> > + self.__core_used(core)
> > + cores.append(str(core))
> > + number = number - 1
> > + if number != 0:
> > + print "Can't allocated requested cpu!!!"
> > +
> Should return error and free used cores.
Ok, it will be added.
>
> > + if corelist is not None:
> > + for core in corelist:
> > + if self.__core_isused(int(core)) is True:
> > + print "Core %s has been used!!!" % core
> Should return error here.
> > + else:
> > + if self.__core_on_socket(int(core), socket) is
> True:
> > + self.__core_used(int(core))
> > + cores.append(core)
> > +
> > + if vm not in self.allocated_info:
> > + self.allocated_info[vm] = {}
> > +
> > + self.allocated_info[vm]['cores'] = cores
> > + return cores
> > +
> > + def __vm_has_resource(self, vm, resource=''):
> > + if vm == '':
> > + self.dut.logger.info("VM name cannt be NULL!!!")
> > + raise Exception("VM name cannt be NULL!!!")
>
> How to handle this exception?
>
> > + if vm not in self.allocated_info:
> > + self.dut.logger.info(
> > + "There is no resource allocated to VM [%s]." % vm)
> > + return False
> > + if resource == '':
> > + return True
> > + if resource not in self.allocated_info[vm]:
> > + self.dut.logger.info(
> > + "There is no resource [%s] allocated to VM [%s] " %
> > + (resource, vm))
> > + return False
> > + return True
> > +
> > + def free_cpu(self, vm):
> > + if self.__vm_has_resource(vm, 'cores'):
> > + for core in self.allocated_info[vm]['cores']:
> > + self.__core_unused(core)
> > + self.allocated_info[vm].pop('cores')
> > +
> > + def alloc_pf(self, vm='', number=-1, socket=-1, pflist=[]):
> > + """
> > + There're two options for request pf devices for vm.
> > + If number is not -1, just allocate pf device from not used
> pfs.
> > + If list is not None, will allocate pf devices after checked.
> > + """
> > + ports = []
> > +
> > + if number != -1:
> > + for pci in self.unused_ports:
> > + if pci != 'unused' and number != 0:
> > + if self.__port_on_socket(pci, socket) is True:
> > + self.__port_used(pci)
> > + ports.append(pci)
> > + number = number - 1
> > + if number != 0:
> > + print "Can't allocated requested PF devices!!!"
> > +
> Should free used ports and return error.
>
> > + if pflist is not None:
> > + for pci in pflist:
> > + if self.__port_isused(pci) is True:
> > + print "Port %s has been used!!!" % pci
>
> Should return error.
> > + else:
> > + if self.__port_on_socket(pci, socket) is True:
> > + self.__port_used(core)
> > + ports.append(core)
> > +
> > + if vm not in self.allocated_info:
> > + self.allocated_info[vm] = {}
> > +
> > + self.allocated_info[vm]['ports'] = ports
> > + return ports
> > +
> > + def free_pf(self, vm):
> > + if self.__vm_has_resource(vm, 'ports'):
> > + for pci in self.allocated_info[vm]['ports']:
> > + self.__port_unused(pci)
> > + self.allocated_info[vm].pop('ports')
> > +
> > + def alloc_vf_from_pf(self, vm='', pf_pci='', number=-1,
> vflist=[]):
> > + """
> > + There're two options for request vf devices of pf device.
> > + If number is not -1, just allocate vf device from not used
> vfs.
> > + If list is not None, will allocate vf devices after checked.
> > + """
> > + vfs = []
> > + if vm == '':
> > + print "Alloc VF request vitual machine name!!!"
> > + return vfs
> > +
> > + if pf_pci == '':
> > + print "Alloc VF request PF pci address!!!"
> > + return vfs
> > +
> > + for vf_info in self.vfs_info:
> > + if vf_info['pf_pci'] == pf_pci:
> > + if vf_info['pci'] in vflist:
> > + vfs.append(vf_info['pci'])
> > + continue
> > +
> > + if number > 0:
> > + vfs.append(vf_info['pci'])
> > + number = number - 1
> > +
> > + for vf in vfs:
> > + self.__vf_used(vf)
> > +
> > + if vm not in self.allocated_info:
> > + self.allocated_info[vm] = {}
> > +
> > + self.allocated_info[vm]['vfs'] = vfs
> > + return vfs
> > +
> > + def free_vf(self, vm):
> > + if self.__vm_has_resource(vm, 'vfs'):
> > + for pci in self.allocated_info[vm]['vfs']:
> > + self.__vf_unused(pci)
> > + self.allocated_info[vm].pop('vfs')
> > +
> > + def add_vf_on_pf(self, pf_pci='', vflist=[]):
> > + """
> > + Add vf devices generated by specified pf devices.
> > + """
> > + # add vfs into vf info list
> > + vfs = []
> > + for vf in vflist:
> > + if vf not in self.vfs:
> > + self.vfs_info.append({'pci': vf, 'pf_pci': pf_pci})
> > + vfs.append(vf)
> > + used_vfs = ['unused'] * len(vflist)
> > + self.unused_vfs += vfs
> > + self.used_vfs += used_vfs
> > + self.vfs += vfs
> > +
> > + def del_vf_on_pf(self, pf_pci='', vflist=[]):
> > + """
> > + Remove vf devices generated by specified pf devices.
> > + """
> > + vfs = []
> > + for vf in vflist:
> > + for vfs_info in self.vfs_info:
> > + if vfs_info['pci'] == vf:
> > + vfs.append(vf)
> > +
> > + for vf in vfs:
> > + try:
> > + index = self.vfs.index(vf)
> > + except:
> > + continue
> > + del self.vfs_info[index]
> > + del self.unused_vfs[index]
> > + del self.used_vfs[index]
> > + del self.vfs[index]
> > +
> > + def alloc_port(self, vm=''):
> > + """
> > + Allocate unused host port for vm
> > + """
> > + if vm == '':
> > + print "Alloc host port request vitual machine name!!!"
> > + return None
> > +
> > + port_start = INIT_FREE_PORT + randint(1, 100)
> > + port_step = randint(1, 10)
> > + port = None
> > + count = 20
> > + while True:
> > + if self.dut.check_port_occupied(port_start) is False:
> > + port = port_start
> > + break
> > + count -= 1
> > + if count < 0:
> > + print 'No available port on the host!!!'
> > + break
> > + port_start += port_step
> > +
> > + if vm not in self.allocated_info:
> > + self.allocated_info[vm] = {}
> > +
> > + self.allocated_info[vm]['hostport'] = port
> > + return port
> > +
> > + def free_port(self, vm):
> > + if self.__vm_has_resource(vm, 'hostport'):
> > + self.allocated_info[vm].pop('hostport')
> > +
> > + def alloc_vnc_num(self, vm=''):
> > + """
> > + Allocate unused host VNC display number for VM.
> > + """
> > + if vm == '':
> > + print "Alloc vnc display number request vitual machine
> > name!!!"
> > + return None
> > +
> > + max_vnc_display_num = self.dut.get_maximal_vnc_num()
> > + free_vnc_display_num = max_vnc_display_num + 1
> > +
> > + if vm not in self.allocated_info:
> > + self.allocated_info[vm] = {}
> > +
> > + self.allocated_info[vm]['vnc_display_num'] =
> free_vnc_display_num
> > +
> > + return free_vnc_display_num
> > +
> > + def free_vnc_num(self, vm):
> > + if self.__vm_has_resource(vm, 'vnc_display_num'):
> > + self.allocated_info[vm].pop('vnc_display_num')
> > +
> > + def free_all_resource(self, vm):
> > + all_free_funcs = get_obj_funcs(self, r'free_')
> > + for func in all_free_funcs:
> > + if func.__name__ == 'free_all_resource':
> > + continue
> > + func(vm)
> > + if self.__vm_has_resource(vm):
> > + self.allocated_info.pop(vm)
> > +
> > + def get_cpu_on_vm(self, vm=''):
> > + """
> > + Return core list on specifid VM.
> > + """
> > + if vm in self.allocated_info:
> > + if "cores" in self.allocated_info[vm]:
> > + return self.allocated_info[vm]['cores']
> > +
> So many duplicated codes in get_?_on_vm functions, should use simple
> function replace of them.
>
> > + def get_vfs_on_vm(self, vm=''):
> > + """
> > + Return vf device list on specifid VM.
> > + """
> > + if vm in self.allocated_info:
> > + if 'vfs' in self.allocated_info[vm]:
> > + return self.allocated_info[vm]['vfs']
> > +
> > + def get_pfs_on_vm(self, vm=''):
> > + """
> > + Return pf device list on specifid VM.
> > + """
> > + if vm in self.allocated_info:
> > + if 'ports' in self.allocated_info[vm]:
> > + return self.allocated_info[vm]['ports']
> > +
> > +
> > +class simple_dut(object):
> > +
> > + def __init__(self):
> > + self.ports_info = []
> > + self.cores = []
> > +
> > + def check_port_occupied(self, port):
> > + return False
> > +
> > +if __name__ == "__main__":
> > + dut = simple_dut()
> > + dut.cores = [{'thread': '1', 'socket': '0'}, {'thread': '2',
> 'socket':
> > '0'},
> > + {'thread': '3', 'socket': '0'}, {'thread': '4',
> 'socket':
> > '0'},
> > + {'thread': '5', 'socket': '0'}, {'thread': '6',
> 'socket':
> > '0'},
> > + {'thread': '7', 'socket': '1'}, {'thread': '8',
> 'socket':
> > '1'},
> > + {'thread': '9', 'socket': '1'}, {'thread': '10',
> > 'socket': '1'},
> > + {'thread': '11', 'socket': '1'}, {'thread': '12',
> > 'socket': '1'}]
> > +
> > + dut.ports_info = [{'intf': 'p786p1', 'source': 'cfg', 'mac':
> > '90:e2:ba:69:e5:e4',
> > + 'pci': '08:00.0', 'numa': 0, 'ipv6':
> > 'fe80::92e2:baff:fe69:e5e4',
> > + 'peer': 'IXIA:6.5', 'type': '8086:10fb'},
> > + {'intf': 'p786p2', 'source': 'cfg', 'mac':
> > '90:e2:ba:69:e5:e5',
> > + 'pci': '08:00.1', 'numa': 0, 'ipv6':
> > 'fe80::92e2:baff:fe69:e5e5',
> > + 'peer': 'IXIA:6.6', 'type': '8086:10fb'},
> > + {'intf': 'p787p1', 'source': 'cfg', 'mac':
> > '90:e2:ba:69:e5:e6',
> > + 'pci': '84:00.0', 'numa': 1, 'ipv6':
> > 'fe80::92e2:baff:fe69:e5e6',
> > + 'peer': 'IXIA:6.7', 'type': '8086:10fb'},
> > + {'intf': 'p787p2', 'source': 'cfg', 'mac':
> > '90:e2:ba:69:e5:e7',
> > + 'pci': '84:00.1', 'numa': 1, 'ipv6':
> > 'fe80::92e2:baff:fe69:e5e7',
> > + 'peer': 'IXIA:6.8', 'type': '8086:10fb'}]
> > +
> > + virt_pool = VirtResource(dut)
> > + print "Alloc two PF devices on socket 1 from VM"
> > + print virt_pool.alloc_pf(vm='test1', number=2, socket=1)
> > +
> > + virt_pool.add_vf_on_pf(pf_pci='08:00.0', vflist=[
> > + '08:10.0', '08:10.2', '08:10.4',
> '08:10.6'])
> > + virt_pool.add_vf_on_pf(pf_pci='08:00.1', vflist=[
> > + '08:10.1', '08:10.3', '08:10.5',
> '08:10.7'])
> > + print "Add VF devices to resource pool"
> > + print virt_pool.vfs_info
> > +
> > + print "Alloc VF device from resource pool"
> > + print virt_pool.alloc_vf_from_pf(vm='test1', pf_pci='08:00.0',
> > number=2)
> > + print virt_pool.used_vfs
> > + print "Alloc VF device from resource pool"
> > + print virt_pool.alloc_vf_from_pf(vm='test2', pf_pci='08:00.1',
> > vflist=['08:10.3', '08:10.5'])
> > + print virt_pool.used_vfs
> > +
> > + print "Del VF devices from resource pool"
> > + virt_pool.del_vf_on_pf(pf_pci='08:00.0', vflist=['08:10.4',
> > '08:10.2'])
> > + print virt_pool.vfs_info
> > +
> > + virt_pool.reserve_cpu('e')
> > + print "Reserve three cores from resource pool"
> > + print virt_pool.unused_cores
> > + print "Alloc two cores on socket1 for VM-test1"
> > + print virt_pool.alloc_cpu(vm="test1", number=2, socket=1)
> > + print "Alloc two cores in list for VM-test2"
> > + print virt_pool.alloc_cpu(vm="test2", corelist=['4', '5'])
> > + print "Alloc two cores for VM-test3"
> > + print virt_pool.alloc_cpu(vm="test3", number=2)
> > + print "Alloc port for VM-test1"
> > + print virt_pool.alloc_port(vm='test1')
> > + print "Alloc information after allcated"
> > + print virt_pool.allocated_info
> > +
> > + print "Get cores on VM-test1"
> > + print virt_pool.get_cpu_on_vm("test1")
> > + print "Get pfs on VM-test1"
> > + print virt_pool.get_pfs_on_vm("test1")
> > + print "Get vfs on VM-test2"
> > + print virt_pool.get_vfs_on_vm("test2")
> > --
> > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing
2015-05-18 14:02 ` Liu, Yong
@ 2015-05-19 5:49 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-19 5:49 UTC (permalink / raw)
To: Liu, Yong, dts
It will be removed next version.
> -----Original Message-----
> From: Liu, Yong
> Sent: Monday, May 18, 2015 10:03 PM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing
>
> These two files should be released with acl suite. Please remove them.
>
> > -----Original Message-----
> > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > Sent: Monday, May 18, 2015 1:07 PM
> > To: dts@dpdk.org
> > Subject: [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing
> >
> > Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> > ---
> > dep/aclpcap.tgz | Bin 0 -> 82103 bytes
> > dep/aclrule.tgz | Bin 0 -> 161037 bytes
> > 2 files changed, 0 insertions(+), 0 deletions(-)
> > create mode 100644 dep/aclpcap.tgz
> > create mode 100644 dep/aclrule.tgz
> >
> > diff --git a/dep/aclpcap.tgz b/dep/aclpcap.tgz
> > new file mode 100644
> > index
> >
> 0000000000000000000000000000000000000000..d10df6f5af0e8eeb0c48d10f8fed0
> a29
> > 3ce10864
> > GIT binary patch
> > literal 82103
> > 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
> > A%m4rY
> >
> > literal 0
> > HcmV?d00001
> >
> > diff --git a/dep/aclrule.tgz b/dep/aclrule.tgz
> > new file mode 100644
> > index
> >
> 0000000000000000000000000000000000000000..cc662ce2a3f528c29c394a0839fc5
> 384
> > 479105f8
> > GIT binary patch
> > literal 161037
> > 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�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
> >
> > literal 0
> > HcmV?d00001
> >
> > --
> > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
2015-05-19 0:38 ` Liu, Yong
@ 2015-05-19 7:05 ` Jiajia, SunX
0 siblings, 0 replies; 34+ messages in thread
From: Jiajia, SunX @ 2015-05-19 7:05 UTC (permalink / raw)
To: Liu, Yong, dts
Ok, I will try to do it.
> -----Original Message-----
> From: Liu, Yong
> Sent: Tuesday, May 19, 2015 8:39 AM
> To: Jiajia, SunX; dts@dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
>
> Jiajia, about get_obj_funcs, it’s common function and can be in
> utils.py. What I mean is that in free_all_resource, do not use
> get_obj_funcs to extract all free functions.
>
> It's unclear about what need to be freed and maybe will be sequence
> issue.
>
> > -----Original Message-----
> > From: Jiajia, SunX
> > Sent: Monday, May 18, 2015 3:43 PM
> > To: Liu, Yong; dts@dpdk.org
> > Subject: RE: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
> >
> > Hi Yong,
> >
> > I have replied the comments as below.
> >
> > > -----Original Message-----
> > > From: Liu, Yong
> > > Sent: Monday, May 18, 2015 3:06 PM
> > > To: Jiajia, SunX; dts@dpdk.org
> > > Subject: RE: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
> > >
> > > Jiajia,
> > > Please see my comments below.
> > >
> > > > -----Original Message-----
> > > > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of sjiajiax
> > > > Sent: Monday, May 18, 2015 1:07 PM
> > > > To: dts@dpdk.org
> > > > Subject: [dts] [‘dts-v1’ 2/9] Optimize ssh connection
> > > >
> > > > Optimize configure parse
> > > >
> > > > Move some functions in dts to an common utils module
> > > >
> > > > Signed-off-by: sjiajiax <sunx.jiajia@intel.com>
> > > > ---
> > > > framework/config.py | 171
> > > +++++++++++++++++++++++++++++++++++----
> > > > -----
> > > > framework/ssh_connection.py | 5 ++
> > > > framework/ssh_pexpect.py | 63 +++++++++++++---
> > > > framework/utils.py | 77 ++++++++++++++++++++
> > > > 4 files changed, 270 insertions(+), 46 deletions(-)
> > > > mode change 100755 => 100644 framework/config.py
> > > > create mode 100644 framework/utils.py
> > > >
> > > > diff --git a/framework/config.py b/framework/config.py
> > > > old mode 100755
> > > > new mode 100644
> > > > index d2548e8..927c846
> > > > --- a/framework/config.py
> > > > +++ b/framework/config.py
> > > > @@ -37,45 +37,133 @@ import re
> > > > import ConfigParser # config parse module
> > > > import argparse # prase arguments module
> > > >
> > > > -portconf = "conf/ports.cfg"
> > > > -crbconf = "conf/crbs.cfg"
> > > > +PORTCONF = "conf/ports.cfg"
> > > > +CRBCONF = "conf/crbs.cfg"
> > > > +VIRTCONF = "conf/virt_global.cfg"
> > > >
> > > >
> > > > class UserConf():
> > > >
> > > > - def __init__(self, port_conf=portconf, crb_conf=crbconf):
> > > > - self.port_config = port_conf
> > > > - self.crb_config = crb_conf
> > > > + def __init__(self, config):
> > > > + self.conf = ConfigParser.SafeConfigParser()
> > > > + load_files = self.conf.read(config)
> > > > + if load_files == []:
> > > > + print "FAILED LOADING %s!!!" % config
> > > > + self.conf = None
> > > > + raise
> > > > +
> > >
> > > There's need one special exception for configuration parsed failure.
> >
> > Yes, I think it is good to do that.
> >
> > >
> > > > + def get_sections(self):
> > > > + if self.conf is None:
> > > > + return None
> > > > +
> > > > + return self.conf.sections()
> > > > +
> > > > + def load_section(self, section):
> > > > + if self.conf is None:
> > > > + return None
> > > > +
> > > > + items = None
> > > > + for conf_sect in self.conf.sections():
> > > > + if conf_sect == section:
> > > > + items = self.conf.items(section)
> > > > +
> > > > + return items
> > > > +
> > > > + def load_config(self, item):
> > > > + confs = [conf.strip() for conf in item.split(';')]
> > > > + if '' in confs:
> > > > + confs.remove('')
> > > > + return confs
> > > > +
> > > > + def load_param(self, conf):
> > > > + paramDict = dict()
> > > > +
> > > > + for param in conf.split(','):
> > > > + (key, _, value) = param.partition('=')
> > > > + paramDict[key] = value
> > > > + return paramDict
> > > > +
> > > > +
> > > > +class VirtConf(UserConf):
> > > > +
> > > > + def __init__(self, virt_conf=VIRTCONF):
> > > > + self.config_file = virt_conf
> > > > + self.virt_cfg = {}
> > > > + try:
> > > > + self.virt_conf = UserConf(self.config_file)
> > > > + except Exception as e:
> > > > + print "FAILED LOADING VIRT CONFIG!!!"
> > > > + self.virt_conf = None
> > > > +
> > > There's need one special exception for configuration parsed failure.
> >
> > I will do it in the next version.
> >
> > >
> > > > + def load_virt_config(self, name):
> > > > + self.virt_cfgs = []
> > > > +
> > > > + try:
> > > > + virt_confs = self.virt_conf.load_section(name)
> > > > + except:
> > > > + print "FAILED FIND SECTION %s!!!" % name
> > > > + return
> > > > +
> > > Add exception for load section failed.
> >
> > I will do it in the next version.
> >
> > >
> > > > + for virt_conf in virt_confs:
> > > > + virt_cfg = {}
> > > > + virt_params = []
> > > > + key, config = virt_conf
> > > > + confs = self.virt_conf.load_config(config)
> > > > + for config in confs:
> > > > + virt_params.append(self.load_virt_param(config))
> > > > + virt_cfg[key] = virt_params
> > > > + self.virt_cfgs.append(virt_cfg)
> > > > +
> > > > + def get_virt_config(self):
> > > > + return self.virt_cfgs
> > > > +
> > > > + def load_virt_param(self, config):
> > > > + cfg_params = self.virt_conf.load_param(config)
> > > > + return cfg_params
> > > > +
> > > > +
> > > > +class PortConf(UserConf):
> > > > +
> > > > + def __init__(self, port_conf=PORTCONF):
> > > > + self.config_file = port_conf
> > > > self.ports_cfg = {}
> > > > self.pci_regex = "([\da-f]{2}:[\da-f]{2}.\d{1})$"
> > > > try:
> > > > - self.port_conf = ConfigParser.SafeConfigParser()
> > > > - self.port_conf.read(self.port_config)
> > > > + self.port_conf = UserConf(self.config_file)
> > > > except Exception as e:
> > > > print "FAILED LOADING PORT CONFIG!!!"
> > > > + self.port_conf = None
> > > >
> > > There's need one special exception for configuration parsed failure.
> >
> > I will do it in the next version.
> >
> > >
> > > > def load_ports_config(self, crbIP):
> > > > - ports = []
> > > > - for crb in self.port_conf.sections():
> > > > - if crb != crbIP:
> > > > - continue
> > > > - ports = [port.strip()
> > > > - for port in self.port_conf.get(crb,
> > > > 'ports').split(';')]
> > > > + self.ports_cfg = {}
> > > > + if self.port_conf is None:
> > > > + return
> > > > +
> > > > + ports = self.port_conf.load_section(crbIP)
> > > > + if ports is None:
> > > > + return
> > > > + key, config = ports[0]
> > > > + confs = self.port_conf.load_config(config)
> > > > +
> > > > + for config in confs:
> > > > + port_param = self.port_conf.load_param(config)
> > > >
> > > > - for port in ports:
> > > > - port_cfg = self.__parse_port_param(port)
> > > > # check pci BDF validity
> > > > - if 'pci' not in port_cfg:
> > > > + if 'pci' not in port_param:
> > > > print "NOT FOUND CONFIG FOR NO PCI ADDRESS!!!"
> > > > continue
> > > > - m = re.match(self.pci_regex, port_cfg['pci'])
> > > > + m = re.match(self.pci_regex, port_param['pci'])
> > > > if m is None:
> > > > print "INVALID CONFIG FOR NO PCI ADDRESS!!!"
> > > > continue
> > > >
> > > > - keys = port_cfg.keys()
> > > > + keys = port_param.keys()
> > > > keys.remove('pci')
> > > > - self.ports_cfg[port_cfg['pci']] = {key: port_cfg[key]
> > > for key
> > > > in keys}
> > > > + self.ports_cfg[port_param['pci']] = {
> > > > + key: port_param[key] for key in keys}
> > > > + if 'numa' in self.ports_cfg[port_param['pci']]:
> > > > + numa_str =
> self.ports_cfg[port_param['pci']]['numa']
> > > > + self.ports_cfg[port_param['pci']]['numa'] =
> > > int(numa_str)
> > > >
> > > > def get_ports_config(self):
> > > > return self.ports_cfg
> > > > @@ -86,23 +174,36 @@ class UserConf():
> > > > else:
> > > > return False
> > > >
> > > > - def __parse_port_param(self, port):
> > > > - portDict = dict()
> > > > -
> > > > - for param in port.split(','):
> > > > - (key, _, value) = param.partition('=')
> > > > - if key == 'numa':
> > > > - portDict[key] = int(value)
> > > > - else:
> > > > - portDict[key] = value
> > > > - return portDict
> > > > +
> > > >
> > > >
> > > > if __name__ == '__main__':
> > > > - parser = argparse.ArgumentParser(description="Load DTS
> > > configuration
> > > > files")
> > > > - parser.add_argument("-p", "--portconf", default=portconf)
> > > > - parser.add_argument("-c", "--crbconf", default=crbconf)
> > > > + parser = argparse.ArgumentParser(
> > > > + description="Load DTS configuration files")
> > > > + parser.add_argument("-p", "--portconf", default=PORTCONF)
> > > > + parser.add_argument("-c", "--crbconf", default=CRBCONF)
> > > > + parser.add_argument("-v", "--virtconf", default=VIRTCONF)
> > > > args = parser.parse_args()
> > > > - conf = UserConf()
> > > > - conf.load_ports_config('192.168.1.1')
> > > > - conf.check_port_available('0000:86:00.0')
> > > > +
> > > > + # not existed configuration file
> > > > + VirtConf('/tmp/not-existed.cfg')
> > > > +
> > > > + # example for basic use configuration file
> > > > + conf = UserConf(PORTCONF)
> > > > + for section in conf.get_sections():
> > > > + items = conf.load_section(section)
> > > > + key, value = items[0]
> > > > + confs = conf.load_config(value)
> > > > + for config in confs:
> > > > + conf.load_param(config)
> > > > +
> > > > + # example for port configuration file
> > > > + portconf = PortConf(PORTCONF)
> > > > + portconf.load_ports_config('DUT IP')
> > > > + print portconf.get_ports_config()
> > > > + portconf.check_port_available('86:00.0')
> > > > +
> > > > + # example for global virtualization configuration file
> > > > + virtconf = VirtConf(VIRTCONF)
> > > > + virtconf.load_virt_config('LIBVIRT')
> > > > + print virtconf.get_virt_config()
> > > > diff --git a/framework/ssh_connection.py
> > > b/framework/ssh_connection.py
> > > > index 18a6517..7286b14 100644
> > > > --- a/framework/ssh_connection.py
> > > > +++ b/framework/ssh_connection.py
> > > > @@ -62,6 +62,11 @@ class SSHConnection(object):
> > > > self.logger.debug(out)
> > > > return out
> > > >
> > > > + def get_session_before(self, timeout=15):
> > > > + out = self.session.get_session_before(timeout)
> > > > + self.logger.debug(out)
> > > > + return out
> > > > +
> > >
> > > I've sent out this patch, please make sure there's no gap there.
> > > You'd better remove those from your patch work.
> > >
> >
> > About this, I have checked it, yes, you have sent it, I will remove
> it
> > from my patch work.
> >
> > > > def close(self):
> > > > self.session.close()
> > > >
> > > > diff --git a/framework/ssh_pexpect.py b/framework/ssh_pexpect.py
> > > > index 735df44..4193020 100644
> > > > --- a/framework/ssh_pexpect.py
> > > > +++ b/framework/ssh_pexpect.py
> > > > @@ -2,7 +2,8 @@ import time
> > > > import pexpect
> > > > import pxssh
> > > > from debugger import ignore_keyintr, aware_keyintr
> > > > -from exception import TimeoutException, SSHConnectionException
> > > > +from exception import TimeoutException, SSHConnectionException,
> > > > SSHSessionDeadException
> > > > +from utils import RED, GREEN
> > > >
> > > > """
> > > > Module handle ssh sessions between tester and DUT.
> > > > @@ -14,16 +15,28 @@ Aslo support transfer files to tester or DUT.
> > > > class SSHPexpect(object):
> > > >
> > > > def __init__(self, host, username, password):
> > > > - self.magic_prompt = "[MAGIC PROMPT]"
> > > > + self.magic_prompt = "MAGIC PROMPT"
> > > > try:
> > > > self.session = pxssh.pxssh()
> > > > - self.username = username
> > > > self.host = host
> > > > + self.username = username
> > > > self.password = password
> > > > - self.session.login(self.host, self.username,
> > > > - self.password,
> > > original_prompt='[$#>]')
> > > > + if ':' in host:
> > > > + self.ip = host.split(':')[0]
> > > > + self.port = int(host.split(':')[1])
> > > > + self.session.login(self.ip, self.username,
> > > > + self.password,
> > > original_prompt='[$#>]',
> > > > + port=self.port,
> login_timeout=20)
> > > > + else:
> > > > + self.session.login(self.host, self.username,
> > > > + self.password,
> > > original_prompt='[$#>]')
> > > > self.send_expect('stty -echo', '# ', timeout=2)
> > > > - except Exception:
> > > > + except Exception, e:
> > > > + print RED(e)
> > > > + if getattr(self, 'port', None):
> > > > + suggestion = "\nSuggession: Check if the
> fireware on
> > > > [ %s ] " % \
> > > > + self.ip + "is stoped\n"
> > > > + print GREEN(suggestion)
> > > > raise SSHConnectionException(host)
> > > >
> > > > def init_log(self, logger, name):
> > > > @@ -33,7 +46,7 @@ class SSHPexpect(object):
> > > >
> > > > def send_expect_base(self, command, expected, timeout=15):
> > > > ignore_keyintr()
> > > > - self.__flush() # clear buffer
> > > > + self.__flush() # clear buffer
> > > > self.session.PROMPT = expected
> > > > self.__sendline(command)
> > > > self.__prompt(command, timeout)
> > > > @@ -45,7 +58,7 @@ class SSHPexpect(object):
> > > > def send_expect(self, command, expected, timeout=15,
> > > verify=False):
> > > > ret = self.send_expect_base(command, expected, timeout)
> > > > if verify:
> > > > - ret_status = self.send_expect_base("echo $?",
> expected)
> > > > + ret_status = self.send_expect_base("echo $?",
> expected,
> > > > timeout)
> > > > if not int(ret_status):
> > > > return ret
> > > > else:
> > > > @@ -54,21 +67,44 @@ class SSHPexpect(object):
> > > > else:
> > > > return ret
> > > >
> > > > - def __flush(self):
> > > > + def get_session_before(self, timeout=15):
> > > > + """
> > > > + Get all output before timeout
> > > > + """
> > > > + ignore_keyintr()
> > > > self.session.PROMPT = self.magic_prompt
> > > > - self.session.prompt(0.1)
> > > > + try:
> > > > + self.session.prompt(timeout)
> > > > + except Exception as e:
> > > > + pass
> > > > +
> > > > + aware_keyintr()
> > > > + before = self.get_output_before()
> > > > + self.__flush()
> > > > + return before
> > > > +
> > > > + def __flush(self):
> > > > + """
> > > > + Clear all session buffer
> > > > + """
> > > > + self.session.buffer = ""
> > > > + self.session.before = ""
> > > >
> > > > def __prompt(self, command, timeout):
> > > > if not self.session.prompt(timeout):
> > > > raise TimeoutException(command,
> self.get_output_all())
> > > >
> > > > def __sendline(self, command):
> > > > + if not self.isalive():
> > > > + raise SSHSessionDeadException(self.host)
> > > > if len(command) == 2 and command.startswith('^'):
> > > > self.session.sendcontrol(command[1])
> > > > else:
> > > > self.session.sendline(command)
> > > >
> > > > def get_output_before(self):
> > > > + if not self.isalive():
> > > > + raise SSHSessionDeadException(self.host)
> > > > self.session.flush()
> > > > before = self.session.before.rsplit('\r\n', 1)
> > > > if before[0] == "[PEXPECT]":
> > > > @@ -103,7 +139,12 @@ class SSHPexpect(object):
> > > > """
> > > > Sends a local file to a remote place.
> > > > """
> > > > - command = 'scp {0} {1}@{2}:{3}'.format(src,
> self.username,
> > > > self.host, dst)
> > > > + if ':' in self.host:
> > > > + command = 'scp -P {0} -o
> > > NoHostAuthenticationForLocalhost=yes
> > > > {1} {2}@{3}:{4}'.format(
> > > > + str(self.port), src, self.username, self.ip, dst)
> > > > + else:
> > > > + command = 'scp {0} {1}@{2}:{3}'.format(
> > > > + src, self.username, self.host, dst)
> > > > if password == '':
> > > > self._spawn_scp(command, self.password)
> > > > else:
> > > > diff --git a/framework/utils.py b/framework/utils.py
> > > > new file mode 100644
> > > > index 0000000..57eb988
> > > > --- /dev/null
> > > > +++ b/framework/utils.py
> > > > @@ -0,0 +1,77 @@
> > > > +# 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.
> > > > +
> > > > +import json # json format
> > > > +import re
> > > > +
> > > > +
> > > > +def RED(text):
> > > > + return "\x1B[" + "31;1m" + str(text) + "\x1B[" + "0m"
> > > > +
> > > > +
> > > > +def BLUE(text):
> > > > + return "\x1B[" + "36;1m" + str(text) + "\x1B[" + "0m"
> > > > +
> > > > +
> > > > +def GREEN(text):
> > > > + return "\x1B[" + "32;1m" + str(text) + "\x1B[" + "0m"
> > > > +
> > > > +
> > > > +def pprint(some_dict):
> > > > + """
> > > > + Print JSON format dictionary object.
> > > > + """
> > > > + return json.dumps(some_dict, sort_keys=True, indent=4)
> > > > +
> > > > +
> > > > +def regexp(s, to_match, allString=False):
> > > > + """
> > > > + Ensure that the re `to_match' only has one group in it.
> > > > + """
> > > > +
> > > > + scanner = re.compile(to_match, re.DOTALL)
> > > > + if allString:
> > > > + return scanner.findall(s)
> > > > + m = scanner.search(s)
> > > > + if m is None:
> > > > + print RED("Failed to match " + to_match + " in the
> string "
> > > + s)
> > > > + return None
> > > > + return m.group(1)
> > > > +
> > > > +
> > > > +def get_obj_funcs(obj, func_name_regex):
> > > > + """
> > > > + Return function list which name matched regex.
> > > > + """
> > > > + for func_name in dir(obj):
> > > > + func = getattr(obj, func_name)
> > > > + if callable(func) and re.match(func_name_regex,
> > > func.__name__):
> > > > + yield func
> > > > --
> > > This function now used to free resource of virtualization machine,
> I
> > > think it's better to call free functions directly.
> > > Maybe there will be dependency of these free functions. What's your
> > > idea about it?
> >
> > No, now it is just used on the module of virtual resource.
> > But I think this is common function, it can be used in other module
> if
> > there
> > is a demand.
> >
> > >
> > > > 1.9.0
^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2015-05-19 7:05 UTC | newest]
Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-18 5:07 [dts] [‘dts-v1’ 0/9] sjiajiax
2015-05-18 5:07 ` [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice sjiajiax
2015-05-18 7:46 ` Xu, HuilongX
2015-05-18 8:58 ` Jiajia, SunX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 2/9] Optimize ssh connection sjiajiax
2015-05-18 7:06 ` Liu, Yong
2015-05-18 7:43 ` Jiajia, SunX
2015-05-19 0:38 ` Liu, Yong
2015-05-19 7:05 ` Jiajia, SunX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 3/9] Add some params and functions related to the virtual test sjiajiax
2015-05-18 7:26 ` Liu, Yong
2015-05-18 8:08 ` Jiajia, SunX
2015-05-18 7:59 ` Xu, HuilongX
2015-05-18 9:08 ` Jiajia, SunX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 4/9] Add VM class and the virtual DUT class and the virtual resource module sjiajiax
2015-05-18 8:23 ` Xu, HuilongX
2015-05-18 13:57 ` Liu, Yong
2015-05-19 5:46 ` Jiajia, SunX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 5/9] Add qemu-agent-guest for QEMU VM sjiajiax
2015-05-18 14:00 ` Liu, Yong
2015-05-18 5:07 ` [dts] [‘dts-v1’ 6/9] Add a global virtual configure sjiajiax
2015-05-18 6:32 ` Liu, Yong
2015-05-18 6:48 ` Jiajia, SunX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 7/9] add some pmd functions for tester to code the testpmd cases sjiajiax
2015-05-18 8:28 ` Xu, HuilongX
2015-05-18 8:45 ` Liu, Yong
2015-05-18 9:05 ` Jiajia, SunX
2015-05-18 9:20 ` Jiajia, SunX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 8/9] Add two tar files for ACL testing sjiajiax
2015-05-18 14:02 ` Liu, Yong
2015-05-19 5:49 ` Jiajia, SunX
2015-05-18 5:07 ` [dts] [‘dts-v1’ 9/9] Add a suite to test SRIOV mirror with KVM sjiajiax
2015-05-18 6:29 ` [dts] [‘dts-v1’ 0/9] Liu, Yong
2015-05-18 6:47 ` Jiajia, SunX
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).