* [dts] [PATCH 0/5] Optimize virtualization automation framework.
@ 2015-06-04 6:28 Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 1/5] Add virttype parameter into virtual machine instantiation Yong Liu
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Yong Liu @ 2015-06-04 6:28 UTC (permalink / raw)
To: dts
From: Marvin Liu <yong.liu@intel.com>
Optimize for stability of virtualiztion framework.
Add debugcase command in dts arguments for case development.
Support rerun interrupted test case in debug mode.
Marvin Liu (5):
Add virttype parameter into virtual machine instantiation.
Change virtual machine default directory to host base_dir.
Optimize qemu kvm module functions and code style.
Add session close function in virt_dut module.
Support dynamic load test case in debug mode.
Use can use "rerun" command to re-run the interrupted case.
framework/debugger.py | 36 ++++++-
framework/dts.py | 37 ++++++-
framework/main.py | 12 ++-
framework/qemu_kvm.py | 274 ++++++++++++++++++++++---------------------------
framework/virt_base.py | 21 +++-
framework/virt_dut.py | 45 +++++++-
6 files changed, 260 insertions(+), 165 deletions(-)
--
1.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dts] [PATCH 1/5] Add virttype parameter into virtual machine instantiation.
2015-06-04 6:28 [dts] [PATCH 0/5] Optimize virtualization automation framework Yong Liu
@ 2015-06-04 6:28 ` Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 2/5] Change virtual machine default directory to host base_dir Yong Liu
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Yong Liu @ 2015-06-04 6:28 UTC (permalink / raw)
To: dts
From: Marvin Liu <yong.liu@intel.com>
When virtype is XEN, request addtional host port operation.
Signed-off-by: Marvin Liu <yong.liu@intel.com>
diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py
index e762695..707dd7b 100644
--- a/framework/qemu_kvm.py
+++ b/framework/qemu_kvm.py
@@ -1,6 +1,6 @@
# BSD LICENSE
#
-# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
diff --git a/framework/virt_base.py b/framework/virt_base.py
index 285c1d6..12aa318 100644
--- a/framework/virt_base.py
+++ b/framework/virt_base.py
@@ -241,13 +241,13 @@ class VirtBase(object):
return True
elif type(vm_except) is exception.VirtDutConnectException:
# need stop vm
- self.virt_obj.stop()
+ self.stop()
return True
elif type(vm_except) is exception.VirtDutInitException:
# need close session
vm_except.vm_dut.close_sessions()
# need stop vm
- self.virt_obj.stop()
+ self.stop()
return True
else:
return False
@@ -276,6 +276,7 @@ class VirtBase(object):
vm_dut = VirtDut(
crb,
serializer,
+ self.virt_type,
self.vm_name,
self.suite)
except:
diff --git a/framework/virt_dut.py b/framework/virt_dut.py
index 273b29e..b087220 100644
--- a/framework/virt_dut.py
+++ b/framework/virt_dut.py
@@ -54,7 +54,7 @@ class VirtDut(DPDKdut):
or CRBBareMetal.
"""
- def __init__(self, crb, serializer, vm_name, suite):
+ 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
@@ -77,6 +77,7 @@ class VirtDut(DPDKdut):
self.architecture = None
self.ports_info = None
self.ports_map = []
+ self.virttype = virttype
def set_nic_type(self, nic_type):
"""
@@ -133,7 +134,10 @@ class VirtDut(DPDKdut):
# scan ports before restore interface
self.scan_ports()
# restore dut ports to kernel
- self.restore_interfaces()
+ if self.virttype != 'XEN':
+ self.restore_interfaces()
+ else:
+ self.restore_interfaces_domu()
# rescan ports after interface up
self.rescan_ports()
@@ -153,6 +157,27 @@ class VirtDut(DPDKdut):
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()
@@ -170,6 +195,8 @@ class VirtDut(DPDKdut):
if pci_id == "8086:100e":
return False
return True
+ # load vm port conf need another function
+ # need add vitrual function device into NICS
def scan_ports(self):
"""
--
1.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dts] [PATCH 2/5] Change virtual machine default directory to host base_dir.
2015-06-04 6:28 [dts] [PATCH 0/5] Optimize virtualization automation framework Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 1/5] Add virttype parameter into virtual machine instantiation Yong Liu
@ 2015-06-04 6:28 ` Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 3/5] Optimize qemu kvm module functions and code style Yong Liu
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Yong Liu @ 2015-06-04 6:28 UTC (permalink / raw)
To: dts
From: Marvin Liu <yong.liu@intel.com>
Add islive function in virt_base module to check whether vm is alive.
Signed-off-by: Marvin Liu <yong.liu@intel.com>
diff --git a/framework/virt_base.py b/framework/virt_base.py
index 12aa318..3daf42f 100644
--- a/framework/virt_base.py
+++ b/framework/virt_base.py
@@ -69,6 +69,8 @@ class VirtBase(object):
# replace dut session
self.host_session = self.host_dut.host_session
self.host_logger = self.host_dut.logger
+ # base_dir existed for host dut has prepared it
+ self.host_session.send_expect("cd %s" % self.host_dut.base_dir, "# ")
# init the host resouce pool for VM
self.virt_pool = self.host_dut.virt_pool
@@ -81,6 +83,7 @@ class VirtBase(object):
self.virt_type = self.get_virt_type()
self.params = []
+
# default call back function is None
self.callback = None
@@ -141,6 +144,7 @@ class VirtBase(object):
if key in param.keys():
param[key] = value
return
+
self.params.append({key: value})
def compose_boot_param(self):
@@ -193,6 +197,18 @@ class VirtBase(object):
"""
NotImplemented
+ def isalive(self):
+ """
+ Check whether VM existed.
+ """
+ vm_status = self.host_session.send_expect(
+ "ps aux | grep qemu | grep 'name %s '| grep -v grep" % self.vm_name, "# ")
+
+ if self.vm_name in vm_status:
+ return True
+ else:
+ return False
+
def start(self):
"""
Start VM and instantiate the VM with VirtDut.
--
1.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dts] [PATCH 3/5] Optimize qemu kvm module functions and code style.
2015-06-04 6:28 [dts] [PATCH 0/5] Optimize virtualization automation framework Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 1/5] Add virttype parameter into virtual machine instantiation Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 2/5] Change virtual machine default directory to host base_dir Yong Liu
@ 2015-06-04 6:28 ` Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 4/5] Add session close function in virt_dut module Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 5/5] Support dynamic load test case in debug mode. Use can use "rerun" command to re-run the interrupted case Yong Liu
4 siblings, 0 replies; 6+ messages in thread
From: Yong Liu @ 2015-06-04 6:28 UTC (permalink / raw)
To: dts
From: Marvin Liu <yong.liu@intel.com>
1)Support vhost net user net device options.
2)Support hugepage based memory options.
3)Add default options when qemu_kvm object initialized.
4)Fix bug in virtio-net-pci device add funtion.
5)Optimize virtual machine start and check function.
6)Optimize variable code name.
7)Remove debug function from qemu_kvm module.
Signed-off-by: Marvin Liu <yong.liu@intel.com>
diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py
index 707dd7b..8e0582a 100644
--- a/framework/qemu_kvm.py
+++ b/framework/qemu_kvm.py
@@ -84,12 +84,22 @@ class QEMUKvm(VirtBase):
QGA_CLI_PATH = '-r dep/QMP/'
self.host_session.copy_file_to(QGA_CLI_PATH)
+ # charater and network device default index
+ self.char_idx = 0
+ self.netdev_idx = 0
+
def set_vm_default(self):
self.set_vm_name(self.vm_name)
self.set_vm_enable_kvm()
self.set_vm_qga()
self.set_vm_daemon()
+ # add default control interface
+ def_nic = {'type': 'nic', 'opt_vlan': '0'}
+ self.set_vm_net(**def_nic)
+ def_net = {'type': 'user', 'opt_vlan': '0'}
+ self.set_vm_net(**def_net)
+
def init_vm_request_resource(self):
"""
initialize some resource used by VM.
@@ -129,12 +139,12 @@ class QEMUKvm(VirtBase):
out = self.host_session.send_expect(
'ls %s' % qemu_emulator_path, '[.*')
if 'No such file or directory' in out:
- self.host_logger.error("No emulator [ %s ] on the DUT [ %s ]" % \
+ self.host_logger.error("No emulator [ %s ] on the DUT [ %s ]" %
(qemu_emulator, self.host_dut.get_ip_address()))
return None
out = self.host_session.send_expect("[ -x %s ];echo $?" % qemu_emulator_path, '# ')
if out == '1':
- self.host_logger.error("Emulator [ %s ] not executable on the DUT [ %s ]" % \
+ self.host_logger.error("Emulator [ %s ] not executable on the DUT [ %s ]" %
(qemu_emulator, self.host_dut.get_ip_address()))
return None
self.qemu_emulator = qemu_emulator
@@ -250,6 +260,15 @@ class QEMUKvm(VirtBase):
if 'size' in options.keys():
mem_boot_line = '-m %s' % options['size']
self.__add_boot_line(mem_boot_line)
+ if 'hugepage' in options.keys():
+ if options['hugepage'] == 'yes':
+ mem_boot_huge = '-object memory-backend-file,' \
+ + 'id=mem,size=%sM,mem-path=%s,share=on' \
+ % (options['size'], self.host_dut.hugepage_path)
+
+ self.__add_boot_line(mem_boot_huge)
+ mem_boot_huge_opt = "-numa node,memdev=mem -mem-prealloc"
+ self.__add_boot_line(mem_boot_huge_opt)
def add_vm_disk(self, **options):
"""
@@ -259,6 +278,13 @@ class QEMUKvm(VirtBase):
disk_boot_line = '-drive file=%s' % options['file']
self.__add_boot_line(disk_boot_line)
+ def set_vm_net(self, **options):
+ index = self.find_option_index('net')
+ if index:
+ self.params[index]['net'].append(options)
+ else:
+ self.params.append({'net': [options]})
+
def add_vm_net(self, **options):
"""
Add VM net device.
@@ -471,22 +497,22 @@ class QEMUKvm(VirtBase):
self.host_session.send_expect(
'chmod +x %s' % self.QEMU_IFUP_PATH, '# ')
- def set_vm_device(self, driver='pci-assign', **props):
+ def set_vm_device(self, driver='pci-assign', **opts):
"""
Set VM device with specified driver.
"""
- props['driver'] = driver
+ opts['driver'] = driver
index = self.find_option_index('device')
if index:
- self.params[index]['device'].append(props)
+ self.params[index]['device'].append(opts)
else:
- self.params.append({'device': [props]})
+ self.params.append({'device': [opts]})
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.
+ opt_[host | addr | ...]: value
+ note:the sub-opterty will be decided according to the driver.
"""
if 'driver' in options.keys() and \
options['driver']:
@@ -494,54 +520,84 @@ class QEMUKvm(VirtBase):
self.__add_vm_pci_assign(**options)
elif options['driver'] == 'virtio-net-pci':
self.__add_vm_virtio_net_pci(**options)
+ elif options['driver'] == 'vhost-user':
+ self.__add_vm_virtio_user_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
+ opt_host: 08:00.0
+ opt_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 'opt_host' in options.keys() and \
+ options['opt_host']:
+ dev_boot_line += separator + 'host=%s' % options['opt_host']
+ if 'opt_addr' in options.keys() and \
+ options['opt_addr']:
+ dev_boot_line += separator + 'addr=%s' % options['opt_addr']
+ self.assigned_pcis.append(options['opt_addr'])
if self.__string_has_multi_fields(dev_boot_line, separator):
self.__add_boot_line(dev_boot_line)
+ def __add_vm_virtio_user_pci(self, **options):
+ """
+ driver virtio-net-pci
+ opt_path: /tmp/vhost-net
+ opt_mac: 00:00:20:00:00:00
+ """
+ separator = ','
+ # chardev parameter
+ if 'opt_path' in options.keys() and \
+ options['opt_path']:
+ dev_boot_line = '-chardev socket'
+ char_id = 'char%d' % self.char_idx
+ dev_boot_line += separator + 'id=%s' % char_id + separator + 'path=%s' % options['opt_path']
+ self.char_idx += 1
+ self.__add_boot_line(dev_boot_line)
+ # netdev parameter
+ netdev_id = 'netdev%d' % self.netdev_idx
+ self.netdev_idx += 1
+ dev_boot_line = '-netdev type=vhost-user,id=%s,chardev=%s,vhostforce' % (netdev_id, char_id)
+ self.__add_boot_line(dev_boot_line)
+ # device parameter
+ opts = {'opt_netdev': '%s' % netdev_id}
+ if 'opt_mac' in options.keys() and \
+ options['opt_mac']:
+ opts['opt_mac'] = options['opt_mac']
+
+ self.__add_vm_virtio_net_pci(**opts)
+
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
+ opt_netdev: mynet1
+ opt_id: net1
+ opt_mac: 00:00:00:00:01:03
+ opt_bus: pci.0
+ opt_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):
+ if 'opt_netdev' in options.keys() and \
+ options['opt_netdev']:
+ dev_boot_line += separator + 'netdev=%s' % options['opt_netdev']
+ if 'opt_id' in options.keys() and \
+ options['opt_id']:
+ dev_boot_line += separator + 'id=%s' % options['opt_id']
+ if 'opt_mac' in options.keys() and \
+ options['opt_mac']:
+ dev_boot_line += separator + 'mac=%s' % options['opt_mac']
+ if 'opt_bus' in options.keys() and \
+ options['opt_bus']:
+ dev_boot_line += separator + 'bus=%s' % options['opt_bus']
+ if 'opt_addr' in options.keys() and \
+ options['opt_addr']:
+ dev_boot_line += separator + 'addr=%s' % options['opt_addr']
+
+ if self.__string_has_multi_fields(dev_boot_line, separator):
self.__add_boot_line(dev_boot_line)
def __string_has_multi_fields(self, string, separator, field_num=2):
@@ -665,11 +721,15 @@ class QEMUKvm(VirtBase):
qemu_boot_line = self.generate_qemu_boot_line()
- # Start VM using the qemu command
+ # Start VM using the qemu command
ret = self.host_session.send_expect(qemu_boot_line, '# ', verify=True)
- time.sleep(30)
if type(ret) is int and ret != 0:
raise StartVMFailedException('Start VM failed!!!')
+ out = self.__control_session('ping', '120')
+ if "Not responded" in out:
+ raise StartVMFailedException('Not response in 60 seconds!!!')
+
+ self.__wait_vmnet_ready()
def generate_qemu_boot_line(self):
"""
@@ -690,6 +750,21 @@ class QEMUKvm(VirtBase):
return qemu_boot_line
+ def __wait_vmnet_ready(self):
+ """
+ wait for 120 seconds for vm net ready
+ 10.0.2.* is the default ip address allocated by qemu
+ """
+ count = 20
+ while count:
+ out = self.__control_session('ifconfig')
+ if "10.0.2" in out:
+ return True
+ time.sleep(6)
+ count -= 1
+
+ raise StartVMFailedException('Virtual machine control net not ready in 120 seconds!!!')
+
def __alloc_vcpus(self):
"""
Allocate virtual CPUs for VM.
@@ -698,8 +773,8 @@ class QEMUKvm(VirtBase):
cpus = self.virt_pool.alloc_cpu(vm=self.vm_name, corelist=req_cpus)
if len(req_cpus) != len(cpus):
- self.host_logger.warn("VCPUs not enough, required [ %s ], just [ %s ]" % \
- (req_cpus, cpus))
+ self.host_logger.warn("VCPUs not enough, required [ %s ], just [ %s ]" %
+ (req_cpus, cpus))
raise Exception("No enough required vcpus!!!")
vcpus_pinned_to_vm = ''
@@ -853,7 +928,10 @@ class QEMUKvm(VirtBase):
for arg in args:
cmd = cmd_head + ' ' + str(arg)
- out = self.host_session.send_expect(cmd, '# ')
+ if command is "ping":
+ out = self.host_session.send_expect(cmd, '# ', int(args[0]))
+ else:
+ out = self.host_session.send_expect(cmd, '# ')
return out
@@ -864,109 +942,3 @@ class QEMUKvm(VirtBase):
self.__control_session('powerdown')
time.sleep(5)
self.virt_pool.free_all_resource(self.vm_name)
-
-
-if __name__ == "__main__":
- import subprocess
- import sys
- 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!"
--
1.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dts] [PATCH 4/5] Add session close function in virt_dut module.
2015-06-04 6:28 [dts] [PATCH 0/5] Optimize virtualization automation framework Yong Liu
` (2 preceding siblings ...)
2015-06-04 6:28 ` [dts] [PATCH 3/5] Optimize qemu kvm module functions and code style Yong Liu
@ 2015-06-04 6:28 ` Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 5/5] Support dynamic load test case in debug mode. Use can use "rerun" command to re-run the interrupted case Yong Liu
4 siblings, 0 replies; 6+ messages in thread
From: Yong Liu @ 2015-06-04 6:28 UTC (permalink / raw)
To: dts
From: Marvin Liu <yong.liu@intel.com>
Signed-off-by: Marvin Liu <yong.liu@intel.com>
diff --git a/framework/virt_dut.py b/framework/virt_dut.py
index b087220..b52109d 100644
--- a/framework/virt_dut.py
+++ b/framework/virt_dut.py
@@ -79,6 +79,12 @@ class VirtDut(DPDKdut):
self.ports_map = []
self.virttype = virttype
+ def close_sessions(self):
+ if self.session:
+ self.session.close()
+ if self.alt_session:
+ self.alt_session.close()
+
def set_nic_type(self, nic_type):
"""
Set CRB NICS ready to validated.
@@ -122,12 +128,16 @@ class VirtDut(DPDKdut):
Then call pci scan function to collect nic device information.
At last setup DUT' environment for validation.
"""
- self.prepare_package(pkgName, patch)
+ if not self.skip_setup:
+ 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()
--
1.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dts] [PATCH 5/5] Support dynamic load test case in debug mode. Use can use "rerun" command to re-run the interrupted case.
2015-06-04 6:28 [dts] [PATCH 0/5] Optimize virtualization automation framework Yong Liu
` (3 preceding siblings ...)
2015-06-04 6:28 ` [dts] [PATCH 4/5] Add session close function in virt_dut module Yong Liu
@ 2015-06-04 6:28 ` Yong Liu
4 siblings, 0 replies; 6+ messages in thread
From: Yong Liu @ 2015-06-04 6:28 UTC (permalink / raw)
To: dts
From: Marvin Liu <yong.liu@intel.com>
Signed-off-by: Marvin Liu <yong.liu@intel.com>
diff --git a/framework/debugger.py b/framework/debugger.py
index a5f3e84..4151196 100644
--- a/framework/debugger.py
+++ b/framework/debugger.py
@@ -28,10 +28,16 @@ import signal
import code
import time
import dts
+import imp
+import dts
+from test_case import TestCase
-console = None # global console object
-debug_cmd = '' # global debug state
+console = None # global console object
+debug_cmd = '' # global debug state
+AliveSuite = None # global suite for run command
+AliveModule = None # global module for reload
+AliveCase = None # global case name for run command
def help_command():
@@ -45,6 +51,7 @@ def help_command():
console.push('print \' - quit: quit debug module\'')
console.push('print \' - exit: exit processing procedure\'')
console.push('print \' - debug: call python debug module for further debug\'')
+ console.push('print \' - debugcase: jump into debug mode before first testcase run \'')
def list_command():
@@ -70,6 +77,30 @@ def connect_command(connect):
session.session.interact()
+def rerun_command():
+ """
+ Rerun test case specified in command line
+ """
+ global AliveSuite, AliveModule, AliveCase
+ new_module = imp.reload(AliveModule)
+
+ # save arguments required to initialize suite
+ dut = AliveSuite.__dict__['dut']
+ tester = AliveSuite.__dict__['tester']
+ target = AliveSuite.__dict__['target']
+ suite = AliveSuite.__dict__['suite']
+
+ for test_classname, test_class in dts.get_subclasses(new_module, TestCase):
+ suite_obj = test_class(dut, tester, target, suite)
+
+ # copy all element from previous suite to reloaded suite
+ dts.copy_instance_attr(AliveSuite, suite_obj)
+ # re-run specified test case
+ for case in dts.get_test_cases(suite_obj, r'%s' % AliveCase):
+ if callable(case):
+ case()
+
+
def exit_command():
"""
Exit dts framework.
@@ -108,6 +139,7 @@ def keyboard_handle(signum, frame):
command['debug'] = debug_command
command['help'] = help_command
command['connect'] = connect_command
+ command['rerun'] = rerun_command
console.push('print \"Use help command for detail information\"')
try:
code.interact(local=command)
diff --git a/framework/dts.py b/framework/dts.py
index f6a14ad..cf07d51 100644
--- a/framework/dts.py
+++ b/framework/dts.py
@@ -37,6 +37,7 @@ import traceback # exception traceback
import inspect # load attribute
import atexit # register callback when exit
import json # json format
+import signal # signal module for debug mode
import rst # rst file support
from crbs import crbs
@@ -53,6 +54,7 @@ from utils import *
from exception import TimeoutException
from logger import getLogger
import logger
+import debugger
import sys
reload(sys)
@@ -61,6 +63,7 @@ sys.setdefaultencoding('UTF8')
PROJECT_MODULE_PREFIX = 'project_'
debug_mode = False
+debug_case = False
config = None
table = None
results_table_rows = []
@@ -75,6 +78,7 @@ result = None
excel_report = None
stats = None
log_handler = None
+module = None
Package = ''
Patches = []
drivername = ""
@@ -100,7 +104,7 @@ def close_crb_sessions():
if tester is not None:
tester.close()
log_handler.info("DTS ended")
-
+
def get_crb_os(crb):
if 'OS' in crb:
@@ -208,7 +212,7 @@ 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.
"""
@@ -221,6 +225,7 @@ def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir, nic):
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)
@@ -297,6 +302,8 @@ def dts_run_suite(crbInst, test_suites, target, nic):
result.test_suite = test_suite
rst.generate_results_rst(crbInst['name'], target, nic, test_suite, performance_only)
test_module = __import__('TestSuite_' + test_suite)
+ global module
+ module = test_module
for test_classname, test_class in get_subclasses(test_module, TestCase):
test_suite = test_class(dut, tester, target, test_suite)
@@ -328,7 +335,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, debugcase):
"""
Main process of DTS, it will run all test suites in the config file.
"""
@@ -342,6 +349,7 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
global stats
global log_handler
global debug_mode
+ global debug_case
global Package
global Patches
@@ -361,6 +369,8 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
# enable debug mode
if debug is True:
debug_mode = True
+ if debugcase is True:
+ debug_case = True
# init log_handler handler
if verbose is True:
@@ -414,7 +424,7 @@ 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:
@@ -451,6 +461,11 @@ def get_subclasses(module, clazz):
yield (subclazz_name, subclazz)
+def copy_instance_attr(from_inst, to_inst):
+ for key in from_inst.__dict__.keys():
+ to_inst.__dict__[key] = from_inst.__dict__[key]
+
+
def get_functional_test_cases(test_suite):
"""
Get all functional test cases.
@@ -516,6 +531,9 @@ def execute_test_case(test_suite, test_case):
Execute specified test case in specified suite. If any exception occured in
validation process, save the result and tear down this case.
"""
+ global debug_mode
+ global debug_case
+ global module
result.test_case = test_case.__name__
rst.write_title("Test Case: " + test_case.__name__)
@@ -523,8 +541,17 @@ def execute_test_case(test_suite, test_case):
rst.write_annex_title("Annex: " + test_case.__name__)
try:
log_handler.info('Test Case %s Begin' % test_case.__name__)
+ test_suite.running_case = test_case.__name__
test_suite.set_up()
- test_case()
+ # prepare debugger re-run case environment
+ if debug_mode or debug_case:
+ debugger.AliveSuite = test_suite
+ debugger.AliveModule = module
+ debugger.AliveCase = test_case.__name__
+ if debug_case:
+ debugger.keyboard_handle(signal.SIGINT, None)
+ else:
+ test_case()
result.test_case_passed()
diff --git a/framework/main.py b/framework/main.py
index 3e467d0..6b771a5 100755
--- a/framework/main.py
+++ b/framework/main.py
@@ -63,6 +63,7 @@ def git_build_package(gitLabel, pkgName, depot="dep"):
if ret is not 0:
raise EnvironmentError
+
# Read cmd-line args
parser = argparse.ArgumentParser(description='DPDK test framework.')
@@ -117,10 +118,18 @@ 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')
+parser.add_argument('--debugcase',
+ action='store_true',
+ help='enable debug mode in the first case, user can further debug')
+
args = parser.parse_args()
@@ -136,4 +145,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, args.debugcase)
--
1.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-06-04 6:29 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-04 6:28 [dts] [PATCH 0/5] Optimize virtualization automation framework Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 1/5] Add virttype parameter into virtual machine instantiation Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 2/5] Change virtual machine default directory to host base_dir Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 3/5] Optimize qemu kvm module functions and code style Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 4/5] Add session close function in virt_dut module Yong Liu
2015-06-04 6:28 ` [dts] [PATCH 5/5] Support dynamic load test case in debug mode. Use can use "rerun" command to re-run the interrupted case Yong Liu
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).