test suite reviews and discussions
 help / color / mirror / Atom feed
* [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).