All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/18] KVM autotest network patchset v3
@ 2010-09-14 22:25 Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 01/18] KVM test: Add a new macaddress pool algorithm Lucas Meneghel Rodrigues
                   ` (17 more replies)
  0 siblings, 18 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm, Lucas Meneghel Rodrigues

This is Amos's patchset rebased, with some cleanups and additions:

- New method to generate MAC address prefixes
- Fix some tests to use new management
- Remove the dependency on address_pools.cfg
- Coding style fixes

We still have to do some work before the patches can be applied,
the good news is, we're getting closer :)

Amos Kong (12):
  KVM test: Add a new macaddress pool algorithm
  KVM test: Add a new subtest ping
  KVM test: Add basic file transfer test
  KVM test: Add a subtest of load/unload nic driver
  KVM test: Add a subtest of nic promisc
  KVM test: Add a subtest of multicast
  KVM test: Add a subtest of pxe
  KVM test: Add a subtest of changing MAC address
  KVM test: Add a netperf subtest
  KVM test: kvm_utils - Add support of check if remote port free
  KVM test: Improve vlan subtest
  KVM test: vlan subtest - Replace extra_params '-snapshot' with
    image_snapshot

Lucas Meneghel Rodrigues (6):
  KVM test: Make physical_resources_check to work with MAC management
  KVM test: Remove address_pools.cfg dependency
  KVM test: Add a get_ifname function
  KVM Test: Add a common ping module for network related tests
  KVM test: Add a subtest jumbo
  KVM test: Add subtest of testing offload by ethtool

 client/tests/kvm/address_pools.cfg.sample          |   65 ------
 client/tests/kvm/control                           |    8 -
 client/tests/kvm/control.parallel                  |    9 -
 client/tests/kvm/get_started.py                    |    4 +-
 client/tests/kvm/kvm_test_utils.py                 |  112 ++++++++++-
 client/tests/kvm/kvm_utils.py                      |  137 ++++++++++++-
 client/tests/kvm/kvm_vm.py                         |  104 +++++++++-
 client/tests/kvm/scripts/join_mcast.py             |   37 ++++
 client/tests/kvm/tests/ethtool.py                  |  215 ++++++++++++++++++++
 client/tests/kvm/tests/file_transfer.py            |   58 ++++++
 client/tests/kvm/tests/jumbo.py                    |  130 ++++++++++++
 client/tests/kvm/tests/mac_change.py               |   65 ++++++
 client/tests/kvm/tests/multicast.py                |   83 ++++++++
 client/tests/kvm/tests/netperf.py                  |   56 +++++
 client/tests/kvm/tests/nic_promisc.py              |  103 ++++++++++
 client/tests/kvm/tests/nicdriver_unload.py         |  115 +++++++++++
 client/tests/kvm/tests/physical_resources_check.py |    7 +-
 client/tests/kvm/tests/ping.py                     |   72 +++++++
 client/tests/kvm/tests/pxe.py                      |   31 +++
 client/tests/kvm/tests/vlan.py                     |  186 +++++++++++++++++
 client/tests/kvm/tests/vlan_tag.py                 |   68 ------
 client/tests/kvm/tests_base.cfg.sample             |   97 ++++++++-
 22 files changed, 1584 insertions(+), 178 deletions(-)
 delete mode 100644 client/tests/kvm/address_pools.cfg.sample
 create mode 100755 client/tests/kvm/scripts/join_mcast.py
 create mode 100644 client/tests/kvm/tests/ethtool.py
 create mode 100644 client/tests/kvm/tests/file_transfer.py
 create mode 100644 client/tests/kvm/tests/jumbo.py
 create mode 100644 client/tests/kvm/tests/mac_change.py
 create mode 100644 client/tests/kvm/tests/multicast.py
 create mode 100644 client/tests/kvm/tests/netperf.py
 create mode 100644 client/tests/kvm/tests/nic_promisc.py
 create mode 100644 client/tests/kvm/tests/nicdriver_unload.py
 create mode 100644 client/tests/kvm/tests/ping.py
 create mode 100644 client/tests/kvm/tests/pxe.py
 create mode 100644 client/tests/kvm/tests/vlan.py
 delete mode 100644 client/tests/kvm/tests/vlan_tag.py

-- 
1.7.2.2


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 01/18] KVM test: Add a new macaddress pool algorithm
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 02/18] KVM test: Make physical_resources_check to work with MAC management Lucas Meneghel Rodrigues
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

Old method uses the addresses in the config files which could lead serious
problem when multiple tests running in different hosts.
This patch adds a new macaddress pool algorithm, it generates the mac prefix
based on mac address of the host, and fix it to correspond to IEEE802.
When user have set the mac_prefix in the config file, we should use it instead
of the dynamic generated mac prefix.
Add a parameter like 'preserve_mac', to preserve the original mac address, for
things like migration.

MAC addresses are recorded into a dictionary 'address_pool' in following
format: {{'20100310-165222-Wt7l:0' : 'AE:9D:94:6A:9b:f9'},...}
  20100310-165222-Wt7l : instance attribute of VM
  0                    : index of NIC
  AE:9D:94:6A:9b:f9    : mac address
Use 'vm instance' + 'nic index' as the key, macaddress is the value.

Changes from v2:
- Instead of basing ourselves in a physical interface address to get
an address prefix, just generate one with the prefix 0x9a (convention)
randomly and add it to the address pool. If there's already one
prefix, keep it there and just return it.
- Made messages more consistent and informative
- Made function names consistent all across the board
- Fixed some single line spacing between functions

Changs from v1:
- Use 'vm instance' + 'nic index' as the key of address_pool, address is value.
- Put 'mac_lock' and 'address_pool' to '/tmp', for sharing them to other
  autotest instances running on the same host.
- Change function names for less confusion.
- Do not copy 'vm.instance' in vm.clone()
- Split 'adding get_ifname function' to another patch

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Feng Yang <fyang@redhat.com>
Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/kvm_utils.py          |  114 ++++++++++++++++++++++++++++++++
 client/tests/kvm/kvm_vm.py             |   83 ++++++++++++++++++++++--
 client/tests/kvm/tests_base.cfg.sample |    2 +-
 3 files changed, 193 insertions(+), 6 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index fb2d1c2..bb5c868 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -5,6 +5,7 @@ KVM test utility functions.
 """
 
 import time, string, random, socket, os, signal, re, logging, commands, cPickle
+import fcntl, shelve
 from autotest_lib.client.bin import utils
 from autotest_lib.client.common_lib import error, logging_config
 import kvm_subprocess
@@ -82,6 +83,119 @@ def get_sub_dict_names(dict, keyword):
 
 # Functions related to MAC/IP addresses
 
+def _generate_mac_address_prefix():
+    """
+    Generate a MAC address prefix. By convention we will set KVM autotest
+    MAC addresses to start with 0x9a.
+    """
+    l = [0x9a, random.randint(0x00, 0x7f), random.randint(0x00, 0x7f),
+         random.randint(0x00, 0xff)]
+    prefix = ':'.join(map(lambda x: "%02x" % x, l)) + ":"
+    return prefix
+
+
+def generate_mac_address_prefix():
+    """
+    Generate a random MAC address prefix and add it to the MAC pool dictionary.
+    If there's a MAC prefix there already, do not update the MAC pool and just
+    return what's in there.
+    """
+    lock_file = open("/tmp/mac_lock", 'w')
+    fcntl.lockf(lock_file.fileno() ,fcntl.LOCK_EX)
+    mac_pool = shelve.open("/tmp/address_pool", writeback=False)
+
+    if mac_pool.get('prefix'):
+        prefix = mac_pool.get('prefix')
+        logging.debug('Retrieved previously generated MAC prefix for this '
+                      'host: %s', prefix)
+    else:
+        prefix = _generate_mac_address_prefix()
+        mac_pool['prefix'] = prefix
+        logging.debug('Generated MAC address prefix for this host: %s', prefix)
+
+    mac_pool.close()
+    fcntl.lockf(lock_file.fileno(), fcntl.LOCK_UN)
+    lock_file.close()
+
+    return prefix
+
+
+def generate_mac_address(root_dir, instance_vm, nic_index, prefix=None):
+    """
+    Random generate a MAC address and add it to the MAC pool.
+
+    Try to generate macaddress based on the mac address prefix, add it to a
+    dictionary 'address_pool'.
+    key = VM instance + nic index, value = mac address
+    {['20100310-165222-Wt7l:0'] : 'AE:9D:94:6A:9b:f9'}
+
+    @param root_dir: Root dir for kvm.
+    @param instance_vm: Here we use instance of vm.
+    @param nic_index: The index of nic.
+    @param prefix: Prefix of MAC address.
+    @return: MAC address string.
+    """
+    if prefix is None:
+        prefix = generate_mac_address_prefix()
+
+    lock_file = open("/tmp/mac_lock", 'w')
+    fcntl.lockf(lock_file.fileno() ,fcntl.LOCK_EX)
+    mac_pool = shelve.open("/tmp/address_pool", writeback=False)
+    found = False
+    key = "%s:%s" % (instance_vm, nic_index)
+
+    if mac_pool.get(key):
+        found = True
+        mac = mac_pool.get(key)
+
+    while not found:
+        suffix = "%02x:%02x" % (random.randint(0x00,0xfe),
+                                random.randint(0x00,0xfe))
+        mac = prefix + suffix
+        mac_list = mac.split(":")
+        # Clear multicast bit
+        mac_list[0] = int(mac_list[0],16) & 0xfe
+        # Set local assignment bit (IEEE802)
+        mac_list[0] = mac_list[0] | 0x02
+        mac_list[0] = "%02x" % mac_list[0]
+        mac = ":".join(mac_list)
+        if mac in [mac_pool.get(k) for k in mac_pool.keys()]:
+                continue
+        mac_pool[key] = mac
+        found = True
+    logging.debug("Generated MAC address for NIC %s: %s ", key, mac)
+
+    mac_pool.close()
+    fcntl.lockf(lock_file.fileno(), fcntl.LOCK_UN)
+    lock_file.close()
+    return mac
+
+
+def free_mac_address(root_dir, instance_vm, nic_index):
+    """
+    Free mac address from address pool
+
+    @param root_dir: Root dir for kvm
+    @param instance_vm: Here we use instance attribute of vm
+    @param nic_index: The index of nic
+    """
+    lock_file = open("/tmp/mac_lock", 'w')
+    fcntl.lockf(lock_file.fileno() ,fcntl.LOCK_EX)
+    mac_pool = shelve.open("/tmp/address_pool", writeback=False)
+    key = "%s:%s" % (instance_vm, nic_index)
+    if not mac_pool or (not key in mac_pool.keys()):
+        logging.debug("NIC not present in the MAC pool, not modifying pool")
+        logging.debug("NIC: %s" % key)
+        logging.debug("Contents of MAC pool: %s" % mac_pool)
+    else:
+        logging.debug("Freeing MAC addr for NIC %s: %s", key, mac_pool[key])
+        mac_pool.pop(key)
+
+    mac_pool.close()
+    fcntl.lockf(lock_file.fileno(), fcntl.LOCK_UN)
+    lock_file.close()
+
+
 def mac_str_to_int(addr):
     """
     Convert MAC address string to integer.
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 135d08e..13eaac1 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -5,7 +5,7 @@ Utility classes and functions to handle Virtual Machine creation using qemu.
 @copyright: 2008-2009 Red Hat Inc.
 """
 
-import time, socket, os, logging, fcntl, re, commands, glob
+import time, socket, os, logging, fcntl, re, commands, shelve, glob
 import kvm_utils, kvm_subprocess, kvm_monitor, rss_file_transfer
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.bin import utils
@@ -117,6 +117,7 @@ class VM:
         self.params = params
         self.root_dir = root_dir
         self.address_cache = address_cache
+        self.mac_prefix = params.get('mac_prefix')
         self.netdev_id = []
 
         # Find a unique identifier for this VM
@@ -126,8 +127,12 @@ class VM:
             if not glob.glob("/tmp/*%s" % self.instance):
                 break
 
+        if self.mac_prefix is None:
+            self.mac_prefix = kvm_utils.generate_mac_address_prefix()
 
-    def clone(self, name=None, params=None, root_dir=None, address_cache=None):
+
+    def clone(self, name=None, params=None, root_dir=None,
+                    address_cache=None, preserve_mac=True):
         """
         Return a clone of the VM object with optionally modified parameters.
         The clone is initially not alive and needs to be started using create().
@@ -138,6 +143,7 @@ class VM:
         @param params: Optional new VM creation parameters
         @param root_dir: Optional new base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
+        @param preserve_mac: Clone mac address or not.
         """
         if name is None:
             name = self.name
@@ -147,7 +153,20 @@ class VM:
             root_dir = self.root_dir
         if address_cache is None:
             address_cache = self.address_cache
-        return VM(name, params, root_dir, address_cache)
+        vm = VM(name, params, root_dir, address_cache)
+        if preserve_mac:
+            vlan = 0
+            for nic_name in kvm_utils.get_sub_dict_names(params, "nics"):
+                nic_params = kvm_utils.get_sub_dict(params, nic_name)
+                vm.set_mac_address(self.get_mac_address(vlan), vlan, True)
+                vlan += 1
+        return vm
+
+
+    def free_mac_addresses(self):
+        nic_num = len(kvm_utils.get_sub_dict_names(self.params, "nics"))
+        for i in range(nic_num):
+            kvm_utils.free_mac_address(self.root_dir, self.instance, i)
 
 
     def make_qemu_command(self, name=None, params=None, root_dir=None):
@@ -387,6 +406,13 @@ class VM:
             mac = None
             if "address_index" in nic_params:
                 mac = kvm_utils.get_mac_ip_pair_from_dict(nic_params)[0]
+                self.set_mac_address(mac=mac, nic_index=vlan)
+            else:
+                mac = kvm_utils.generate_mac_address(self.root_dir,
+                                                     self.instance,
+                                                     vlan,
+                                                     self.mac_prefix)
+
             qemu_cmd += add_nic(help, vlan, nic_params.get("nic_model"), mac,
                                 self.netdev_id[vlan])
             # Handle the '-net tap' or '-net user' part
@@ -750,11 +776,15 @@ class VM:
                         logging.debug("Shutdown command sent; waiting for VM "
                                       "to go down...")
                         if kvm_utils.wait_for(self.is_dead, 60, 1, 1):
-                            logging.debug("VM is down")
+                            logging.debug("VM is down, freeing mac address.")
+                            self.free_mac_addresses()
                             return
                     finally:
                         session.close()
 
+            # Free mac addresses
+            self.free_mac_addresses()
+
             if self.monitor:
                 # Try to destroy with a monitor command
                 logging.debug("Trying to kill VM with monitor command...")
@@ -880,10 +910,13 @@ class VM:
         nic_name = nics[index]
         nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
         if nic_params.get("nic_mode") == "tap":
-            mac, ip = kvm_utils.get_mac_ip_pair_from_dict(nic_params)
+            mac = self.get_mac_address(index)
             if not mac:
                 logging.debug("MAC address unavailable")
                 return None
+            mac = mac.lower()
+            ip = None
+
             if not ip or nic_params.get("always_use_tcpdump") == "yes":
                 # Get the IP address from the cache
                 ip = self.address_cache.get(mac)
@@ -896,6 +929,7 @@ class VM:
                              for nic in nics]
                 macs = [kvm_utils.get_mac_ip_pair_from_dict(dict)[0]
                         for dict in nic_dicts]
+                macs.append(mac)
                 if not kvm_utils.verify_ip_address_ownership(ip, macs):
                     logging.debug("Could not verify MAC-IP address mapping: "
                                   "%s ---> %s" % (mac, ip))
@@ -925,6 +959,45 @@ class VM:
             return self.redirs.get(port)
 
 
+    def get_mac_address(self, nic_index=0):
+        """
+        Return the macaddr of guest nic.
+
+        @param nic_index: Index of the NIC
+        """
+        mac_pool = shelve.open("/tmp/address_pool", writeback=False)
+        key = "%s:%s" % (self.instance, nic_index)
+        if key in mac_pool.keys():
+            return mac_pool[key]
+        else:
+            return None
+
+
+    def set_mac_address(self, mac, nic_index=0, shareable=False):
+        """
+        Set mac address for guest. Note: It just update address pool.
+
+        @param mac: address will set to guest
+        @param nic_index: Index of the NIC
+        @param shareable: Where VM can share mac with other VM or not.
+        """
+        lock_file = open("/tmp/mac_lock", 'w')
+        fcntl.lockf(lock_file.fileno() ,fcntl.LOCK_EX)
+        mac_pool = shelve.open("/tmp/address_pool", writeback=False)
+        key = "%s:%s" % (self.instance, nic_index)
+
+        if not mac in [mac_pool[i] for i in mac_pool.keys()]:
+            mac_pool[key] = mac
+        else:
+            if shareable:
+                mac_pool[key] = mac
+            else:
+                logging.error("MAC address %s is already in use!", mac)
+        mac_pool.close()
+        fcntl.lockf(lock_file.fileno(), fcntl.LOCK_UN)
+        lock_file.close()
+
+
     def get_pid(self):
         """
         Return the VM's PID.  If the VM is dead return None.
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 7556693..9739a50 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -54,7 +54,7 @@ guest_port_remote_shell = 22
 nic_mode = user
 #nic_mode = tap
 nic_script = scripts/qemu-ifup
-address_index = 0
+#address_index = 0
 run_tcpdump = yes
 
 # Misc
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 02/18] KVM test: Make physical_resources_check to work with MAC management
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 01/18] KVM test: Add a new macaddress pool algorithm Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 03/18] KVM test: Remove address_pools.cfg dependency Lucas Meneghel Rodrigues
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

The previous MAC address management breaks up the
physical_resources_check test (the test picks up NIC MAC parameters
from test parameters). Let's fix it by making it retrieve params
from the method VM.get_mac_address()

Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com>
---
 client/tests/kvm/tests/physical_resources_check.py |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/tests/physical_resources_check.py b/client/tests/kvm/tests/physical_resources_check.py
index 0f7cab3..6c8e154 100644
--- a/client/tests/kvm/tests/physical_resources_check.py
+++ b/client/tests/kvm/tests/physical_resources_check.py
@@ -123,9 +123,14 @@ def run_physical_resources_check(test, params, env):
     found_mac_addresses = re.findall("macaddr=(\S+)", o)
     logging.debug("Found MAC adresses: %s" % found_mac_addresses)
 
+    nic_index = 0
     for nic_name in kvm_utils.get_sub_dict_names(params, "nics"):
         nic_params = kvm_utils.get_sub_dict(params, nic_name)
-        mac, ip = kvm_utils.get_mac_ip_pair_from_dict(nic_params)
+        if "address_index" in nic_params:
+            mac, ip = kvm_utils.get_mac_ip_pair_from_dict(nic_params)
+        else:
+            mac = vm.get_mac_address(nic_index)
+            nic_index += 1
         if not string.lower(mac) in found_mac_addresses:
             n_fail += 1
             logging.error("MAC address mismatch:")
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 03/18] KVM test: Remove address_pools.cfg dependency
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 01/18] KVM test: Add a new macaddress pool algorithm Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 02/18] KVM test: Make physical_resources_check to work with MAC management Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 04/18] KVM test: Add a get_ifname function Lucas Meneghel Rodrigues
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

Since the previous patch introduces an automated management
mechanism for MAC addresses, let's simplify things a bit
by removing address_pools.cfg parsing from the control files,
as well as just removing address_pools.cfg.sample.

Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com>
---
 client/tests/kvm/address_pools.cfg.sample |   65 -----------------------------
 client/tests/kvm/control                  |    8 ----
 client/tests/kvm/control.parallel         |    9 ----
 client/tests/kvm/get_started.py           |    4 +-
 4 files changed, 2 insertions(+), 84 deletions(-)
 delete mode 100644 client/tests/kvm/address_pools.cfg.sample

diff --git a/client/tests/kvm/address_pools.cfg.sample b/client/tests/kvm/address_pools.cfg.sample
deleted file mode 100644
index b5967ce..0000000
--- a/client/tests/kvm/address_pools.cfg.sample
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copy this file to address_pools.cfg and edit it.
-#
-# This file specifies several MAC-IP ranges for each host in the network that
-# may run KVM tests.  A MAC address must not be used twice, so these ranges
-# must not overlap.  The VMs running on each host will only use MAC addresses
-# from the pool of that host.
-# If you wish to use a static MAC-IP mapping, where each MAC address range is
-# mapped to a known corresponding IP address range, specify the bases of the IP
-# address ranges in this file.
-# If you specify a MAC address range without a corresponding IP address range,
-# the IP addresses for that range will be determined at runtime by listening
-# to DHCP traffic using tcpdump.
-# If you wish to determine IP addresses using tcpdump in any case, regardless
-# of any # IP addresses specified in this file, uncomment the following line:
-#always_use_tcpdump = yes
-# You may also specify this parameter for specific hosts by adding it in the
-# appropriate sections below.
-
-variants:
-    # Rename host1 to an actual (short) hostname in the network that will be running the Autotest client
-    - @host1:
-        # Add/remove ranges here
-        address_ranges = r1 r2
-
-        # Modify the following parameters to reflect the DHCP server's configuration
-        address_range_base_mac_r1 = 52:54:00:12:35:56
-        #address_range_base_ip_r1 = 10.0.2.20
-        address_range_size_r1 = 16
-
-        # Modify the following parameters to reflect the DHCP server's configuration
-        address_range_base_mac_r2 = 52:54:00:12:35:80
-        #address_range_base_ip_r2 = 10.0.2.40
-        address_range_size_r2 = 16
-
-    # Rename host2 to an actual (short) hostname in the network that will be running the Autotest client
-    - @host2:
-        # Add/remove ranges here
-        address_ranges = r1 r2
-
-        # Modify the following parameters to reflect the DHCP server's configuration
-        address_range_base_mac_r1 = 52:54:00:12:36:56
-        #address_range_base_ip_r1 = 10.0.3.20
-        address_range_size_r1 = 16
-
-        # Modify the following parameters to reflect the DHCP server's configuration
-        address_range_base_mac_r2 = 52:54:00:12:36:80
-        #address_range_base_ip_r2 = 10.0.3.40
-        address_range_size_r2 = 16
-
-    # Add additional hosts here...
-
-    # This will be used for hosts that do not appear on the list
-    - @default_host:
-        # Add/remove ranges here
-        address_ranges = r1 r2
-
-        # Modify the following parameters to reflect the DHCP server's configuration
-        address_range_base_mac_r1 = 52:54:00:12:34:56
-        #address_range_base_ip_r1 = 10.0.1.20
-        address_range_size_r1 = 16
-
-        # Modify the following parameters to reflect the DHCP server's configuration
-        address_range_base_mac_r2 = 52:54:00:12:34:80
-        #address_range_base_ip_r2 = 10.0.1.40
-        address_range_size_r2 = 16
diff --git a/client/tests/kvm/control b/client/tests/kvm/control
index a69eacf..63bbe5d 100644
--- a/client/tests/kvm/control
+++ b/client/tests/kvm/control
@@ -55,14 +55,6 @@ tests_cfg = kvm_config.config()
 tests_cfg_path = os.path.join(kvm_test_dir, "tests.cfg")
 tests_cfg.fork_and_parse(tests_cfg_path, str)
 
-pools_cfg_path = os.path.join(kvm_test_dir, "address_pools.cfg")
-tests_cfg.parse_file(pools_cfg_path)
-hostname = os.uname()[1].split(".")[0]
-if tests_cfg.count("^" + hostname):
-    tests_cfg.parse_string("only ^%s" % hostname)
-else:
-    tests_cfg.parse_string("only ^default_host")
-
 # Run the tests
 kvm_utils.run_tests(tests_cfg.get_generator(), job)
 
diff --git a/client/tests/kvm/control.parallel b/client/tests/kvm/control.parallel
index 07bc6e5..ac84638 100644
--- a/client/tests/kvm/control.parallel
+++ b/client/tests/kvm/control.parallel
@@ -171,15 +171,6 @@ cfg = kvm_config.config()
 filename = os.path.join(pwd, "tests.cfg")
 cfg.fork_and_parse(filename, str)
 
-filename = os.path.join(pwd, "address_pools.cfg")
-if os.path.exists(filename):
-    cfg.parse_file(filename)
-    hostname = os.uname()[1].split(".")[0]
-    if cfg.count("^" + hostname):
-        cfg.parse_string("only ^%s" % hostname)
-    else:
-        cfg.parse_string("only ^default_host")
-
 tests = cfg.get_list()
 
 
diff --git a/client/tests/kvm/get_started.py b/client/tests/kvm/get_started.py
index 00b5f6b..6fa6b5f 100755
--- a/client/tests/kvm/get_started.py
+++ b/client/tests/kvm/get_started.py
@@ -68,8 +68,8 @@ if __name__ == "__main__":
                  "config samples to actual config files)")
     kvm_test_dir = os.path.dirname(sys.modules[__name__].__file__)
     kvm_test_dir = os.path.abspath(kvm_test_dir)
-    config_file_list = ["address_pools.cfg", "build.cfg", "cdkeys.cfg",
-                        "tests_base.cfg", "tests.cfg", "unittests.cfg"]
+    config_file_list = ["build.cfg", "cdkeys.cfg", "tests_base.cfg",
+                        "tests.cfg", "unittests.cfg"]
     for config_file in config_file_list:
         src_file = os.path.join(kvm_test_dir, "%s.sample" % config_file)
         dst_file = os.path.join(kvm_test_dir, config_file)
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 04/18] KVM test: Add a get_ifname function
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (2 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 03/18] KVM test: Remove address_pools.cfg dependency Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 05/18] KVM Test: Add a common ping module for network related tests Lucas Meneghel Rodrigues
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

It's clearer to use 'nic_mode + nic_index + vnc_port' than 'tap0',
It's also unique for one guest.

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/kvm_vm.py |   21 ++++++++++++++++++++-
 1 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 13eaac1..a473bb4 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -426,7 +426,7 @@ class VM:
             if tftp:
                 tftp = kvm_utils.get_path(root_dir, tftp)
             qemu_cmd += add_net(help, vlan, nic_params.get("nic_mode", "user"),
-                                nic_params.get("nic_ifname"),
+                                self.get_ifname(vlan),
                                 script, downscript, tftp,
                                 nic_params.get("bootp"), redirs,
                                 self.netdev_id[vlan])
@@ -959,6 +959,25 @@ class VM:
             return self.redirs.get(port)
 
 
+    def get_ifname(self, nic_index=0):
+        """
+        Return the ifname of tap device for the guest nic.
+
+        The vnc_port is unique for each VM, nic_index is unique for each nic
+        of one VM, it can avoid repeated ifname.
+
+        @param nic_index: Index of the NIC
+        """
+        nics = kvm_utils.get_sub_dict_names(self.params, "nics")
+        nic_name = nics[nic_index]
+        nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
+        if nic_params.get("nic_ifname"):
+            return nic_params.get("nic_ifname")
+        else:
+            return "%s_%s_%s" % (nic_params.get("nic_model"),
+                                 nic_index, self.vnc_port)
+
+
     def get_mac_address(self, nic_index=0):
         """
         Return the macaddr of guest nic.
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 05/18] KVM Test: Add a common ping module for network related tests
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (3 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 04/18] KVM test: Add a get_ifname function Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 06/18] KVM test: Add a new subtest ping Lucas Meneghel Rodrigues
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

The kvm_net_utils.py is a just a place that wraps common network
related commands which is used to do the network-related tests.
Use -1 as the packet ratio for loss analysis.
Use quiet mode when doing the flood ping.

Changes from v1:
- Use None to indicate that the session should be local in raw_ping
- Use session.sendline("\003") to send (ctrl+c) signal
- Use None to indicate that the session should be local
- Fix of coding style

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/kvm_test_utils.py |  112 +++++++++++++++++++++++++++++++++++-
 1 files changed, 111 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm_test_utils.py b/client/tests/kvm/kvm_test_utils.py
index 5412aac..1e4bd9d 100644
--- a/client/tests/kvm/kvm_test_utils.py
+++ b/client/tests/kvm/kvm_test_utils.py
@@ -21,7 +21,7 @@ More specifically:
 @copyright: 2008-2009 Red Hat Inc.
 """
 
-import time, os, logging, re, commands
+import time, os, logging, re, commands, signal
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.bin import utils
 import kvm_utils, kvm_vm, kvm_subprocess, scan_results
@@ -505,3 +505,113 @@ def run_autotest(vm, session, control_path, timeout, outputdir):
             e_msg = ("Tests %s failed during control file execution" %
                      " ".join(bad_results))
         raise error.TestFail(e_msg)
+
+
+def get_loss_ratio(output):
+    """
+    Get the packet loss ratio from the output of ping
+.
+    @param output: Ping output.
+    """
+    try:
+        return int(re.findall('(\d+)% packet loss', output)[0])
+    except IndexError:
+        logging.debug(output)
+        return -1
+
+
+def raw_ping(command, timeout, session, output_func):
+    """
+    Low-level ping command execution.
+
+    @param command: Ping command.
+    @param timeout: Timeout of the ping command.
+    @param session: Local executon hint or session to execute the ping command.
+    """
+    if session is None:
+        process = kvm_subprocess.run_bg(command, output_func=output_func,
+                                        timeout=timeout)
+
+        # Send SIGINT signal to notify the timeout of running ping process,
+        # Because ping have the ability to catch the SIGINT signal so we can
+        # always get the packet loss ratio even if timeout.
+        if process.is_alive():
+            kvm_utils.kill_process_tree(process.get_pid(), signal.SIGINT)
+
+        status = process.get_status()
+        output = process.get_output()
+
+        process.close()
+        return status, output
+    else:
+        session.sendline(command)
+        status, output = session.read_up_to_prompt(timeout=timeout,
+                                                   print_func=output_func)
+        if not status:
+            # Send ctrl+c (SIGINT) through ssh session
+            session.send("\003")
+            status, output2 = session.read_up_to_prompt(print_func=output_func)
+            output += output2
+            if not status:
+                # We also need to use this session to query the return value
+                session.send("\003")
+
+        session.sendline(session.status_test_command)
+        s2, o2 = session.read_up_to_prompt()
+        if not s2:
+            status = -1
+        else:
+            try:
+                status = int(re.findall("\d+", o2)[0])
+            except:
+                status = -1
+
+        return status, output
+
+
+def ping(dest=None, count=None, interval=None, interface=None,
+         packetsize=None, ttl=None, hint=None, adaptive=False,
+         broadcast=False, flood=False, timeout=0,
+         output_func=logging.debug, session=None):
+    """
+    Wrapper of ping.
+
+    @param dest: Destination address.
+    @param count: Count of icmp packet.
+    @param interval: Interval of two icmp echo request.
+    @param interface: Specified interface of the source address.
+    @param packetsize: Packet size of icmp.
+    @param ttl: IP time to live.
+    @param hint: Path mtu discovery hint.
+    @param adaptive: Adaptive ping flag.
+    @param broadcast: Broadcast ping flag.
+    @param flood: Flood ping flag.
+    @param timeout: Timeout for the ping command.
+    @param output_func: Function used to log the result of ping.
+    @param session: Local executon hint or session to execute the ping command.
+    """
+    if dest is not None:
+        command = "ping %s " % dest
+    else:
+        command = "ping localhost "
+    if count is not None:
+        command += " -c %s" % count
+    if interval is not None:
+        command += " -i %s" % interval
+    if interface is not None:
+        command += " -I %s" % interface
+    if packetsize is not None:
+        command += " -s %s" % packetsize
+    if ttl is not None:
+        command += " -t %s" % ttl
+    if hint is not None:
+        command += " -M %s" % hint
+    if adaptive:
+        command += " -A"
+    if broadcast:
+        command += " -b"
+    if flood:
+        command += " -f -q"
+        output_func = None
+
+    return raw_ping(command, timeout, session, output_func)
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 06/18] KVM test: Add a new subtest ping
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (4 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 05/18] KVM Test: Add a common ping module for network related tests Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 07/18] KVM test: Add a subtest jumbo Lucas Meneghel Rodrigues
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

This test use ping to check the virtual nics, it contains two kinds of test:
1. Packet loss ratio test, ping the guest with different size of packets.
2. Stress test, flood ping guest then use ordinary ping to test the network.

We could not raise an error when flood ping failed, it's too strict.
But we must check the ping result before/after flood-ping.
The interval and packet size could be configurated through tests_base.cfg

Changes from v2:
- Coding style fixes

Changes from v1:
- Improve error message

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/ping.py         |   72 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |    5 ++
 2 files changed, 77 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/tests/ping.py

diff --git a/client/tests/kvm/tests/ping.py b/client/tests/kvm/tests/ping.py
new file mode 100644
index 0000000..9b2308f
--- /dev/null
+++ b/client/tests/kvm/tests/ping.py
@@ -0,0 +1,72 @@
+import logging
+from autotest_lib.client.common_lib import error
+import kvm_test_utils
+
+
+def run_ping(test, params, env):
+    """
+    Ping the guest with different size of packets.
+
+    Packet Loss Test:
+    1) Ping the guest with different size/interval of packets.
+
+    Stress Test:
+    1) Flood ping the guest.
+    2) Check if the network is still usable.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm)
+
+    counts = params.get("ping_counts", 100)
+    flood_minutes = float(params.get("flood_minutes", 10))
+    nics = params.get("nics").split()
+    strict_check = params.get("strict_check", "no") == "yes"
+
+    packet_size = [0, 1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096, 4192,
+                   8878, 9000, 32767, 65507]
+
+    try:
+        for i, nic in enumerate(nics):
+            ip = vm.get_address(i)
+            if not ip:
+                logging.error("Could not get the ip of nic index %d", i)
+                continue
+
+            for size in packet_size:
+                logging.info("Ping with packet size %s", size)
+                status, output = kvm_test_utils.ping(ip, 10,
+                                                     packetsize=size,
+                                                     timeout=20)
+                if strict_check:
+                    ratio = kvm_test_utils.get_loss_ratio(output)
+                    if ratio != 0:
+                        raise error.TestFail("Loss ratio is %s for packet size"
+                                             " %s" % (ratio, size))
+                else:
+                    if status != 0:
+                        raise error.TestFail("Ping failed, status: %s,"
+                                             " output: %s" % (status, output))
+
+            logging.info("Flood ping test")
+            kvm_test_utils.ping(ip, None, flood=True, output_func=None,
+                                timeout=flood_minutes * 60)
+
+            logging.info("Final ping test")
+            status, output = kvm_test_utils.ping(ip, counts,
+                                                 timeout=float(counts) * 1.5)
+            if strict_check:
+                ratio = kvm_test_utils.get_loss_ratio(output)
+                if ratio != 0:
+                    raise error.TestFail("Ping failed, status: %s,"
+                                         " output: %s" % (status, output))
+            else:
+                if status != 0:
+                    raise error.TestFail("Ping returns non-zero value %s" %
+                                         output)
+    finally:
+        session.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 9739a50..90c1f69 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -469,6 +469,11 @@ variants:
         kill_vm_gracefully_vm2 = no
         address_index_vm2 = 1
 
+    - ping: install setup unattended_install.cdrom
+        type = ping
+        counts = 100
+        flood_minutes = 10
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 07/18] KVM test: Add a subtest jumbo
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (5 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 06/18] KVM test: Add a new subtest ping Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-24  8:16   ` [Autotest] " pradeep
  2010-09-14 22:25 ` [PATCH 08/18] KVM test: Add basic file transfer test Lucas Meneghel Rodrigues
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

According to different nic model set different MTU for it. And ping from
guest to host, to see whether tested size can be received by host.

Changes from v2:
- Coding style fixes

Changes from v1:
- Make standard of lost ratio can be configured

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/jumbo.py        |  130 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |   11 +++-
 2 files changed, 140 insertions(+), 1 deletions(-)
 create mode 100644 client/tests/kvm/tests/jumbo.py

diff --git a/client/tests/kvm/tests/jumbo.py b/client/tests/kvm/tests/jumbo.py
new file mode 100644
index 0000000..9c36951
--- /dev/null
+++ b/client/tests/kvm/tests/jumbo.py
@@ -0,0 +1,130 @@
+import logging, commands, random
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+import kvm_test_utils, kvm_utils
+
+def run_jumbo(test, params, env):
+    """
+    Test the RX jumbo frame function of vnics:
+
+    1) Boot the VM.
+    2) Change the MTU of guest nics and host taps depending on the NIC model.
+    3) Add the static ARP entry for guest NIC.
+    4) Wait for the MTU ok.
+    5) Verify the path MTU using ping.
+    6) Ping the guest with large frames.
+    7) Increment size ping.
+    8) Flood ping the guest with large frames.
+    9) Verify the path MTU.
+    10) Recover the MTU.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm)
+    mtu = params.get("mtu", "1500")
+    flood_time = params.get("flood_time", "300")
+    max_icmp_pkt_size = int(mtu) - 28
+
+    ifname = vm.get_ifname(0)
+    ip = vm.get_address(0)
+    if ip is None:
+        raise error.TestError("Could not get the IP address")
+
+    try:
+        # Environment preparation
+        ethname = kvm_test_utils.get_linux_ifname(session, vm.get_macaddr(0))
+
+        logging.info("Changing the MTU of guest ...")
+        guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname , mtu)
+        s, o = session.get_command_status_output(guest_mtu_cmd)
+        if s != 0:
+            logging.error(o)
+            raise error.TestError("Fail to set the MTU of guest NIC: %s" %
+                                  ethname)
+
+        logging.info("Chaning the MTU of host tap ...")
+        host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu)
+        utils.run(host_mtu_cmd)
+
+        logging.info("Add a temporary static ARP entry ...")
+        arp_add_cmd = "arp -s %s %s -i %s" % (ip, vm.get_macaddr(0), ifname)
+        utils.run(arp_add_cmd)
+
+        def is_mtu_ok():
+            s, o = kvm_test_utils.ping(ip, 1, interface=ifname,
+                                       packetsize=max_icmp_pkt_size,
+                                       hint="do", timeout=2)
+            return s == 0
+
+        def verify_mtu():
+            logging.info("Verify the path MTU")
+            s, o = kvm_test_utils.ping(ip, 10, interface=ifname,
+                                       packetsize=max_icmp_pkt_size,
+                                       hint="do", timeout=15)
+            if s != 0 :
+                logging.error(o)
+                raise error.TestFail("Path MTU is not as expected")
+            if kvm_test_utils.get_loss_ratio(o) != 0:
+                logging.error(o)
+                raise error.TestFail("Packet loss ratio during MTU "
+                                     "verification is not zero")
+
+        def flood_ping():
+            logging.info("Flood with large frames")
+            kvm_test_utils.ping(ip, interface=ifname,
+                                packetsize=max_icmp_pkt_size,
+                                flood=True, timeout=float(flood_time))
+
+        def large_frame_ping(count=100):
+            logging.info("Large frame ping")
+            s, o = kvm_test_utils.ping(ip, count, interface=ifname,
+                                       packetsize=max_icmp_pkt_size,
+                                       timeout=float(count) * 2)
+            ratio = kvm_test_utils.get_loss_ratio(o)
+            if ratio != 0:
+                raise error.TestFail("Loss ratio of large frame ping is %s" %
+                                     ratio)
+
+        def size_increase_ping(step=random.randrange(90, 110)):
+            logging.info("Size increase ping")
+            for size in range(0, max_icmp_pkt_size + 1, step):
+                logging.info("Ping %s with size %s" % (ip, size))
+                s, o = kvm_test_utils.ping(ip, 1, interface=ifname,
+                                           packetsize=size,
+                                           hint="do", timeout=1)
+                if s != 0:
+                    s, o = kvm_test_utils.ping(ip, 10, interface=ifname,
+                                               packetsize=size,
+                                               adaptive=True, hint="do",
+                                               timeout=20)
+
+                    if kvm_test_utils.get_loss_ratio(o) > int(params.get(
+                                                      "fail_ratio", 50)):
+                        raise error.TestFail("Ping loss ratio is greater "
+                                             "than 50% for size %s" % size)
+
+        logging.info("Waiting for the MTU to be OK")
+        wait_mtu_ok = 10
+        if not kvm_utils.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1):
+            logging.debug(commands.getoutput("ifconfig -a"))
+            raise error.TestError("MTU is not as expected even after %s"
+                                  "seconds" % wait_mtu_ok)
+
+        # Functional Test
+        verify_mtu()
+        large_frame_ping()
+        size_increase_ping()
+
+        # Stress test
+        flood_ping()
+        verify_mtu()
+
+    finally:
+        # Environment clean
+        session.close()
+        logging.info("Removing the temporary ARP entry")
+        utils.run("arp -d %s -i %s" % (ip, ifname))
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 90c1f69..70929b0 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -474,6 +474,9 @@ variants:
         counts = 100
         flood_minutes = 10
 
+    - jumbo: install setup unattended_install.cdrom
+        type = jumbo
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
@@ -620,10 +623,16 @@ variants:
 variants:
     - @rtl8139:
         nic_model = rtl8139
+        jumbo:
+            mtu = 1500
     - e1000:
         nic_model = e1000
+        jumbo:
+            mtu = 16110
     - virtio_net:
         nic_model = virtio
+        jumbo:
+            mtu = 65520
 
 
 # Guests
@@ -1185,7 +1194,7 @@ variants:
 
     # Windows section
     - @Windows:
-        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks)
+        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo
         shutdown_command = shutdown /s /f /t 0
         reboot_command = shutdown /r /f /t 0
         status_test_command = echo %errorlevel%
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 08/18] KVM test: Add basic file transfer test
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (6 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 07/18] KVM test: Add a subtest jumbo Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 09/18] KVM test: Add a subtest of load/unload nic driver Lucas Meneghel Rodrigues
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

This test is the basic test of transfering file between host and guest.
Try to transfer a large file from host to guest, and transfer it back
to host, then compare the files by calculate their md5 hash.

The default file size is 4000M, scp timeout is 1000s. It means if the
average speed is less than 4M/s, this test will be fail. We can extend
this test by using another disk later, then we can transfer larger
files without the limit of first disk size.

Changes from v1:
- Use md5 to verify the integrity of files
- Try to use autotest API, such as, utils.system()

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/file_transfer.py |   55 +++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample  |    7 +++-
 2 files changed, 61 insertions(+), 1 deletions(-)
 create mode 100644 client/tests/kvm/tests/file_transfer.py

diff --git a/client/tests/kvm/tests/file_transfer.py b/client/tests/kvm/tests/file_transfer.py
new file mode 100644
index 0000000..c9a3476
--- /dev/null
+++ b/client/tests/kvm/tests/file_transfer.py
@@ -0,0 +1,55 @@
+import logging, commands, re
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+import kvm_utils, kvm_test_utils
+
+def run_file_transfer(test, params, env):
+    """
+    Test ethrnet device function by ethtool
+
+    1) Boot up a virtual machine
+    2) Create a large file by dd on host
+    3) Copy this file from host to guest
+    4) Copy this file from guest to host
+    5) Check if file transfers good
+
+    @param test: Kvm test object
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    timeout=int(params.get("login_timeout", 360))
+    logging.info("Trying to log into guest '%s' by serial", vm.name)
+    session = kvm_utils.wait_for(lambda: vm.serial_login(),
+                                 timeout, 0, step=2)
+    if not session:
+        raise error.TestFail("Could not log into guest '%s'" % vm.name)
+
+    dir = test.tmpdir
+    scp_timeout = int(params.get("scp_timeout"))
+    cmd = "dd if=/dev/urandom of=%s/a.out bs=1M count=%d" %  (dir, int(
+                                         params.get("filesize", 4000)))
+    try:
+        logging.info("Create file by dd command on host, cmd: %s" % cmd)
+        utils.run(cmd)
+
+        logging.info("Transfer file from host to guest")
+        if not vm.copy_files_to("%s/a.out" % dir, "/tmp/b.out",
+                                                        timeout=scp_timeout):
+            raise error.TestFail("Fail to transfer file from host to guest")
+
+        logging.info("Transfer file from guest to host")
+        if not vm.copy_files_from("/tmp/b.out", "%s/c.out" % dir,
+                                                        timeout=scp_timeout):
+            raise error.TestFail("Fail to transfer file from guest to host")
+
+        logging.debug(commands.getoutput("ls -l %s/[ac].out" % dir))
+        md5_orig = utils.hash_file("%s/a.out" % dir, method="md5")
+        md5_new = utils.hash_file("%s/c.out" % dir, method="md5")
+
+        if md5_orig != md5_new:
+            raise error.TestFail("File changed after transfer")
+    finally:
+        session.get_command_status("rm -f /tmp/b.out")
+        utils.run("rm -f %s/[ac].out" % dir)
+        session.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 70929b0..4b424da 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -477,6 +477,11 @@ variants:
     - jumbo: install setup unattended_install.cdrom
         type = jumbo
 
+    - file_transfer: install setup unattended_install.cdrom
+        type = file_transfer
+        filesize = 4000
+        scp_timeout = 1000
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
@@ -1194,7 +1199,7 @@ variants:
 
     # Windows section
     - @Windows:
-        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo
+        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer
         shutdown_command = shutdown /s /f /t 0
         reboot_command = shutdown /r /f /t 0
         status_test_command = echo %errorlevel%
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 09/18] KVM test: Add a subtest of load/unload nic driver
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (7 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 08/18] KVM test: Add basic file transfer test Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 10/18] KVM test: Add a subtest of nic promisc Lucas Meneghel Rodrigues
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

Repeatedly load/unload nic driver, try to transfer file between guest and host
by threads at the same time, and check the md5sum.

Changes from v1:
- Use a new method to get nic driver name
- Use utils.hash_file() to get md5sum

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/file_transfer.py    |   19 +++--
 client/tests/kvm/tests/nicdriver_unload.py |  115 ++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample     |   10 ++-
 3 files changed, 135 insertions(+), 9 deletions(-)
 create mode 100644 client/tests/kvm/tests/nicdriver_unload.py

diff --git a/client/tests/kvm/tests/file_transfer.py b/client/tests/kvm/tests/file_transfer.py
index c9a3476..a0c6cff 100644
--- a/client/tests/kvm/tests/file_transfer.py
+++ b/client/tests/kvm/tests/file_transfer.py
@@ -7,18 +7,19 @@ def run_file_transfer(test, params, env):
     """
     Test ethrnet device function by ethtool
 
-    1) Boot up a virtual machine
-    2) Create a large file by dd on host
-    3) Copy this file from host to guest
-    4) Copy this file from guest to host
-    5) Check if file transfers good
+    1) Boot up a VM.
+    2) Create a large file by dd on host.
+    3) Copy this file from host to guest.
+    4) Copy this file from guest to host.
+    5) Check if file transfers ended good.
 
-    @param test: Kvm test object
+    @param test: KVM test object.
     @param params: Dictionary with the test parameters.
     @param env: Dictionary with test environment.
     """
     vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
     timeout=int(params.get("login_timeout", 360))
+
     logging.info("Trying to log into guest '%s' by serial", vm.name)
     session = kvm_utils.wait_for(lambda: vm.serial_login(),
                                  timeout, 0, step=2)
@@ -29,18 +30,19 @@ def run_file_transfer(test, params, env):
     scp_timeout = int(params.get("scp_timeout"))
     cmd = "dd if=/dev/urandom of=%s/a.out bs=1M count=%d" %  (dir, int(
                                          params.get("filesize", 4000)))
+
     try:
         logging.info("Create file by dd command on host, cmd: %s" % cmd)
         utils.run(cmd)
 
         logging.info("Transfer file from host to guest")
         if not vm.copy_files_to("%s/a.out" % dir, "/tmp/b.out",
-                                                        timeout=scp_timeout):
+                                timeout=scp_timeout):
             raise error.TestFail("Fail to transfer file from host to guest")
 
         logging.info("Transfer file from guest to host")
         if not vm.copy_files_from("/tmp/b.out", "%s/c.out" % dir,
-                                                        timeout=scp_timeout):
+                                  timeout=scp_timeout):
             raise error.TestFail("Fail to transfer file from guest to host")
 
         logging.debug(commands.getoutput("ls -l %s/[ac].out" % dir))
@@ -49,6 +51,7 @@ def run_file_transfer(test, params, env):
 
         if md5_orig != md5_new:
             raise error.TestFail("File changed after transfer")
+
     finally:
         session.get_command_status("rm -f /tmp/b.out")
         utils.run("rm -f %s/[ac].out" % dir)
diff --git a/client/tests/kvm/tests/nicdriver_unload.py b/client/tests/kvm/tests/nicdriver_unload.py
new file mode 100644
index 0000000..8630f88
--- /dev/null
+++ b/client/tests/kvm/tests/nicdriver_unload.py
@@ -0,0 +1,115 @@
+import logging, threading, os
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+import kvm_utils, kvm_test_utils
+
+def run_nicdriver_unload(test, params, env):
+    """
+    Test nic driver.
+
+    1) Boot a VM.
+    2) Get the NIC driver name.
+    3) Repeatedly unload/load NIC driver.
+    4) Multi-session TCP transfer on test interface.
+    5) Check whether the test interface should still work.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    timeout = int(params.get("login_timeout", 360))
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
+    logging.info("Trying to log into guest '%s' by serial", vm.name)
+    session2 = kvm_utils.wait_for(lambda: vm.serial_login(),
+                                  timeout, 0, step=2)
+    if not session2:
+        raise error.TestFail("Could not log into guest '%s'" % vm.name)
+
+    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_macaddr(0))
+    temp_path = "/sys/class/net/%s/device/driver" % (ethname)
+    if os.path.islink(temp_path):
+        driver = os.path.split(os.path.realpath(temp_path))[-1]
+    else:
+        raise error.TestError("Could not find driver name")
+    logging.info("driver is %s", driver)
+
+    class ThreadScp(threading.Thread):
+        def run(self):
+            remote_file = '/tmp/' + self.getName()
+            file_list.append(remote_file)
+            ret = vm.copy_files_to(file_name, remote_file, timeout=scp_timeout)
+            if ret:
+                logging.debug("File %s was transfered successfuly", remote_file)
+            else:
+                logging.debug("Failed to transfer file %s", remote_file)
+
+    def compare(origin_file, receive_file):
+        cmd = "md5sum %s"
+        check_sum1 = utils.hash_file(origin_file, method="md5")
+        s, output2 = session.get_command_status_output(cmd % receive_file)
+        if s != 0:
+            logging.error("Could not get md5sum of receive_file")
+            return False
+        check_sum2 = output2.strip().split()[0]
+        logging.debug("original file md5: %s, received file md5: %s",
+                      check_sum1, check_sum2)
+        if check_sum1 != check_sum2:
+            logging.error("MD5 hash of origin and received files doesn't match")
+            return False
+        return True
+
+    #produce sized file in host
+    file_size = params.get("file_size")
+    file_name = "/tmp/nicdriver_unload_file"
+    cmd = "dd if=/dev/urandom of=%s bs=%sM count=1"
+    utils.system(cmd % (file_name, file_size))
+
+    file_list = []
+    connect_time = params.get("connect_time")
+    scp_timeout = int(params.get("scp_timeout"))
+    thread_num = int(params.get("thread_num"))
+    unload_load_cmd = ("sleep %s && ifconfig %s down && modprobe -r %s && "
+                       "sleep 1 && modprobe %s && ifconfig %s up" %
+                       (connect_time, ethname, driver, driver, ethname))
+    pid = os.fork()
+    if pid != 0:
+        logging.info("Unload/load NIC driver repeatedly in guest...")
+        while True:
+            logging.debug("Try to unload/load nic drive once")
+            if session2.get_command_status(unload_load_cmd, timeout=120) != 0:
+                session.get_command_output("rm -rf /tmp/Thread-*")
+                raise error.TestFail("Unload/load nic driver failed")
+            pid, s = os.waitpid(pid, os.WNOHANG)
+            status = os.WEXITSTATUS(s)
+            if (pid, status) != (0, 0):
+                logging.debug("Child process ending")
+                break
+    else:
+        logging.info("Multi-session TCP data transfer")
+        threads = []
+        for i in range(thread_num):
+            t = ThreadScp()
+            t.start()
+            threads.append(t)
+        for t in threads:
+            t.join(timeout = scp_timeout)
+        os._exit(0)
+
+    session2.close()
+
+    try:
+        logging.info("Check MD5 hash for received files in multi-session")
+        for f in file_list:
+            if not compare(file_name, f):
+                raise error.TestFail("Fail to compare (guest) file %s" % f)
+
+        logging.info("Test nic function after load/unload")
+        if not vm.copy_files_to(file_name, file_name):
+            raise error.TestFail("Fail to copy file from host to guest")
+        if not compare(file_name, file_name):
+            raise error.TestFail("Test nic function after load/unload fail")
+
+    finally:
+        session.get_command_output("rm -rf /tmp/Thread-*")
+        session.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 4b424da..8443fee 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -482,6 +482,14 @@ variants:
         filesize = 4000
         scp_timeout = 1000
 
+    - nicdriver_unload:  install setup unattended_install.cdrom
+        type = nicdriver_unload
+        nic_mode = tap
+        file_size = 100
+        connect_time = 4
+        scp_timeout = 300
+        thread_num = 10
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
@@ -1199,7 +1207,7 @@ variants:
 
     # Windows section
     - @Windows:
-        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer
+        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload
         shutdown_command = shutdown /s /f /t 0
         reboot_command = shutdown /r /f /t 0
         status_test_command = echo %errorlevel%
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 10/18] KVM test: Add a subtest of nic promisc
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (8 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 09/18] KVM test: Add a subtest of load/unload nic driver Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 11/18] KVM test: Add a subtest of multicast Lucas Meneghel Rodrigues
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

This test mainly covers TCP sent from host to guest and from guest to host
with repeatedly turn on/off NIC promiscuous mode.

Changes from v1:
- Don't abruptly fail the whole test if we get a failure for a single size

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/nic_promisc.py  |  103 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |    6 ++-
 2 files changed, 108 insertions(+), 1 deletions(-)
 create mode 100644 client/tests/kvm/tests/nic_promisc.py

diff --git a/client/tests/kvm/tests/nic_promisc.py b/client/tests/kvm/tests/nic_promisc.py
new file mode 100644
index 0000000..e13820a
--- /dev/null
+++ b/client/tests/kvm/tests/nic_promisc.py
@@ -0,0 +1,103 @@
+import logging
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+import kvm_utils, kvm_test_utils
+
+def run_nic_promisc(test, params, env):
+    """
+    Test nic driver in promisc mode:
+
+    1) Boot up a VM.
+    2) Repeatedly enable/disable promiscuous mode in guest.
+    3) TCP data transmission from host to guest, and from guest to host,
+       with 1/1460/65000/100000000 bytes payloads.
+    4) Clean temporary files.
+    5) Stop enable/disable promiscuous mode change.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    timeout = int(params.get("login_timeout", 360))
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
+
+    logging.info("Trying to log into guest '%s' by serial", vm.name)
+    session2 = kvm_utils.wait_for(lambda: vm.serial_login(),
+                                  timeout, 0, step=2)
+    if not session2:
+        raise error.TestFail("Could not log into guest '%s'" % vm.name)
+
+    def compare(filename):
+        cmd = "md5sum %s" % filename
+        md5_host = utils.hash_file(filename, method="md5")
+        rc_guest, md5_guest = session.get_command_status_output(cmd)
+        if rc_guest:
+            logging.debug("Could not get MD5 hash for file %s on guest,"
+                          "output: %s", filename, md5_guest)
+            return False
+        md5_guest = md5_guest.split()[0]
+        if md5_host != md5_guest:
+            logging.error("MD5 hash mismatch between file %s "
+                          "present on guest and on host", filename)
+            logging.error("MD5 hash for file on guest: %s,"
+                          "MD5 hash for file on host: %s", md5_host, md5_guest)
+            return False
+        return True
+
+    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_macaddr(0))
+    set_promisc_cmd = ("ip link set %s promisc on; sleep 0.01;"
+                       "ip link set %s promisc off; sleep 0.01" %
+                       (ethname, ethname))
+    logging.info("Set promisc change repeatedly in guest")
+    session2.sendline("while true; do %s; done" % set_promisc_cmd)
+
+    dd_cmd = "dd if=/dev/urandom of=%s bs=%d count=1"
+    filename = "/tmp/nic_promisc_file"
+    file_size = params.get("file_size", "1, 1460, 65000, 100000000").split(",")
+    success_counter = 0
+    try:
+        for size in file_size:
+            logging.info("Create %s bytes file on host" % size)
+            utils.run(dd_cmd % (filename, int(size)))
+
+            logging.info("Transfer file from host to guest")
+            if not vm.copy_files_to(filename, filename):
+                logging.error("File transfer failed")
+                continue
+            if not compare(filename):
+                logging.error("Compare file failed")
+                continue
+            else:
+                success_counter += 1
+
+            logging.info("Create %s bytes file on guest" % size)
+            if session.get_command_status(dd_cmd % (filename, int(size)),
+                                                    timeout=100) != 0:
+                logging.error("Create file on guest failed")
+                continue
+
+            logging.info("Transfer file from guest to host")
+            if not vm.copy_files_from(filename, filename):
+                logging.error("File transfer failed")
+                continue
+            if not compare(filename):
+                logging.error("Compare file failed")
+                continue
+            else:
+                success_counter += 1
+
+            logging.info("Clean temporary files")
+            cmd = "rm -f %s" % filename
+            utils.run(cmd)
+            session.get_command_status(cmd)
+
+    finally:
+        logging.info("Restore the %s to the nonpromisc mode", ethname)
+        session2.close()
+        session.get_command_status("ip link set %s promisc off" % ethname)
+        session.close()
+
+    if success_counter != 2 * len(file_size):
+        raise error.TestFail("Some tests failed, succss_ratio : %s/%s" %
+                             (success_counter, len(file_size)))
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 8443fee..38e9890 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -490,6 +490,10 @@ variants:
         scp_timeout = 300
         thread_num = 10
 
+    - nic_promisc:  install setup unattended_install.cdrom
+        type = nic_promisc
+        file_size = 1, 1460, 65000, 100000000
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
@@ -1207,7 +1211,7 @@ variants:
 
     # Windows section
     - @Windows:
-        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload
+        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc
         shutdown_command = shutdown /s /f /t 0
         reboot_command = shutdown /r /f /t 0
         status_test_command = echo %errorlevel%
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 11/18] KVM test: Add a subtest of multicast
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (9 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 10/18] KVM test: Add a subtest of nic promisc Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 12/18] KVM test: Add a subtest of pxe Lucas Meneghel Rodrigues
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

Use 'ping' to test send/recive multicat packets. Flood ping test is also added.
Limit guest network as 'bridge' mode, because multicast packets could not be
transmitted to guest when using 'user' network.
Add join_mcast.py for joining machine into multicast groups.

Changes from v1:
- Just flush the firewall rules with iptables -F

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/scripts/join_mcast.py |   37 ++++++++++++++
 client/tests/kvm/tests/multicast.py    |   83 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |    9 +++-
 3 files changed, 128 insertions(+), 1 deletions(-)
 create mode 100755 client/tests/kvm/scripts/join_mcast.py
 create mode 100644 client/tests/kvm/tests/multicast.py

diff --git a/client/tests/kvm/scripts/join_mcast.py b/client/tests/kvm/scripts/join_mcast.py
new file mode 100755
index 0000000..350cd5f
--- /dev/null
+++ b/client/tests/kvm/scripts/join_mcast.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+import socket, struct, os, signal, sys
+# -*- coding: utf-8 -*-
+
+"""
+Script used to join machine into multicast groups.
+
+@author Amos Kong <akong@redhat.com>
+"""
+
+if __name__ == "__main__":
+    if len(sys.argv) < 4:
+        print """%s [mgroup_count] [prefix] [suffix]
+        mgroup_count: count of multicast addresses
+        prefix: multicast address prefix
+        suffix: multicast address suffix""" % sys.argv[0]
+        sys.exit()
+
+    mgroup_count = int(sys.argv[1])
+    prefix = sys.argv[2]
+    suffix = int(sys.argv[3])
+
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    for i in range(mgroup_count):
+        mcast = prefix + "." + str(suffix + i)
+        try:
+            mreq = struct.pack("4sl", socket.inet_aton(mcast),
+                               socket.INADDR_ANY)
+            s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
+        except:
+            s.close()
+            print "Could not join multicast: %s" % mcast
+            raise
+
+    print "join_mcast_pid:%s" % os.getpid()
+    os.kill(os.getpid(), signal.SIGSTOP)
+    s.close()
diff --git a/client/tests/kvm/tests/multicast.py b/client/tests/kvm/tests/multicast.py
new file mode 100644
index 0000000..00261f7
--- /dev/null
+++ b/client/tests/kvm/tests/multicast.py
@@ -0,0 +1,83 @@
+import logging, os, re
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+import kvm_test_utils
+
+
+def run_multicast(test, params, env):
+    """
+    Test multicast function of nic (rtl8139/e1000/virtio)
+
+    1) Create a VM.
+    2) Join guest into multicast groups.
+    3) Ping multicast addresses on host.
+    4) Flood ping test with different size of packets.
+    5) Final ping test and check if lose packet.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm,
+                                  timeout=int(params.get("login_timeout", 360)))
+
+    # flush the firewall rules
+    cmd = "iptables -F; test -e /selinux/enforce && echo 0 >/selinux/enforce"
+    session.get_command_status(cmd)
+    utils.run(cmd)
+    # make sure guest replies to broadcasts
+    cmd_broadcast = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore"
+    cmd_broadcast_2 = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all"
+    s1 = session.get_command_status(cmd_broadcast)
+    s2 = session.get_command_status(cmd_broadcast_2)
+    if s1 != 0:
+        logging.warning("Command %s return exit status %s", cmd_broadcast, s1)
+    if s2 != 0:
+        logging.warning("Command %s return exit status %s", cmd_broadcast_2, s2)
+
+    # base multicast address
+    mcast = params.get("mcast", "225.0.0.1")
+    # count of multicast addresses, less than 20
+    mgroup_count = int(params.get("mgroup_count", 5))
+    flood_minutes = float(params.get("flood_minutes", 10))
+    ifname = vm.get_ifname()
+    prefix = re.findall("\d+.\d+.\d+", mcast)[0]
+    suffix = int(re.findall("\d+", mcast)[-1])
+    # copy python script to guest for joining guest to multicast groups
+    mcast_path = os.path.join(test.bindir, "scripts/join_mcast.py")
+    if not vm.copy_files_to(mcast_path, "/tmp"):
+        raise error.TestError("Fail to copy %s to guest" % mcast_path)
+    output = session.get_command_output("python /tmp/join_mcast.py %d %s %d" %
+                                        (mgroup_count, prefix, suffix))
+
+    # if success to join multicast, the process will be paused, and return PID.
+    try:
+        pid = re.findall("join_mcast_pid:(\d+)", output)[0]
+    except IndexError:
+        raise error.TestFail("Can't join multicast groups,output:%s" % output)
+
+    try:
+        for i in range(mgroup_count):
+            new_suffix = suffix + i
+            mcast = "%s.%d" % (prefix, new_suffix)
+
+            logging.info("Initial ping test, mcast: %s", mcast)
+            s, o = kvm_test_utils.ping(mcast, 10, interface=ifname, timeout=20)
+            if s != 0:
+                raise error.TestFail(" Ping return non-zero value %s" % o)
+
+            logging.info("Flood ping test, mcast: %s", mcast)
+            kvm_test_utils.ping(mcast, None, interface=ifname, flood=True,
+                                output_func=None, timeout=flood_minutes*60)
+
+            logging.info("Final ping test, mcast: %s", mcast)
+            s, o = kvm_test_utils.ping(mcast, 10, interface=ifname, timeout=20)
+            if s != 0:
+                raise error.TestFail("Ping failed, status: %s, output: %s" %
+                                     (s, o))
+
+    finally:
+        logging.debug(session.get_command_output("ipmaddr show"))
+        session.get_command_output("kill -s SIGCONT %s" % pid)
+        session.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 38e9890..19750ed 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -494,6 +494,13 @@ variants:
         type = nic_promisc
         file_size = 1, 1460, 65000, 100000000
 
+    - multicast: install setup unattended_install.cdrom
+        type = multicast
+        nic_mode = tap
+        mcast = 225.0.0.1
+        mgroup_count = 20
+        flood_minutes = 1
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
@@ -1211,7 +1218,7 @@ variants:
 
     # Windows section
     - @Windows:
-        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc
+        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast
         shutdown_command = shutdown /s /f /t 0
         reboot_command = shutdown /r /f /t 0
         status_test_command = echo %errorlevel%
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 12/18] KVM test: Add a subtest of pxe
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (10 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 11/18] KVM test: Add a subtest of multicast Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 13/18] KVM test: Add a subtest of changing MAC address Lucas Meneghel Rodrigues
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

This case just snoop tftp packet through tcpdump, it depends on public dhcp
server, better to test it through dnsmasq.

FIXME: Use dnsmasq for pxe test

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/pxe.py          |   31 +++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |   13 +++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/tests/pxe.py

diff --git a/client/tests/kvm/tests/pxe.py b/client/tests/kvm/tests/pxe.py
new file mode 100644
index 0000000..ec9a549
--- /dev/null
+++ b/client/tests/kvm/tests/pxe.py
@@ -0,0 +1,31 @@
+import logging
+from autotest_lib.client.common_lib import error
+import kvm_subprocess, kvm_test_utils
+
+
+def run_pxe(test, params, env):
+    """
+    PXE test:
+
+    1) Snoop the tftp packet in the tap device.
+    2) Wait for some seconds.
+    3) Check whether we could capture TFTP packets.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    timeout = int(params.get("pxe_timeout", 60))
+
+    logging.info("Try to boot from PXE")
+    status, output = kvm_subprocess.run_fg("tcpdump -nli %s" % vm.get_ifname(),
+                                           logging.debug,
+                                           "(pxe capture) ",
+                                           timeout)
+
+    logging.info("Analyzing the tcpdump result...")
+    if not "tftp" in output:
+        raise error.TestFail("Couldn't find any TFTP packets after %s seconds" %
+                             timeout)
+    logging.info("Found TFTP packet")
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 19750ed..6bbc33e 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -501,6 +501,19 @@ variants:
         mgroup_count = 20
         flood_minutes = 1
 
+    - pxe:
+        type = pxe
+        images = pxe
+        image_name_pxe = pxe-test
+        image_size_pxe = 1G
+        force_create_image_pxe = yes
+        remove_image_pxe = yes
+        extra_params += ' -boot n'
+        kill_vm_on_error = yes
+        network = bridge
+        restart_vm = yes
+        pxe_timeout = 60
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 13/18] KVM test: Add a subtest of changing MAC address
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (11 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 12/18] KVM test: Add a subtest of pxe Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 14/18] KVM test: Add a netperf subtest Lucas Meneghel Rodrigues
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

Test steps:

1. Get a new mac from pool, and the old mac addr of guest.
2. Execute the mac_change.sh in guest.
3. Relogin to guest and query the interfaces info by `ifconfig`

Signed-off-by: Cao, Chen <kcao@redhat.com>
Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/mac_change.py   |   65 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |    6 ++-
 2 files changed, 70 insertions(+), 1 deletions(-)
 create mode 100644 client/tests/kvm/tests/mac_change.py

diff --git a/client/tests/kvm/tests/mac_change.py b/client/tests/kvm/tests/mac_change.py
new file mode 100644
index 0000000..b97c99a
--- /dev/null
+++ b/client/tests/kvm/tests/mac_change.py
@@ -0,0 +1,65 @@
+import logging
+from autotest_lib.client.common_lib import error
+import kvm_utils, kvm_test_utils
+
+
+def run_mac_change(test, params, env):
+    """
+    Change MAC address of guest.
+
+    1) Get a new mac from pool, and the old mac addr of guest.
+    2) Set new mac in guest and regain new IP.
+    3) Re-log into guest with new MAC.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    timeout = int(params.get("login_timeout", 360))
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    logging.info("Trying to log into guest '%s' by serial", vm.name)
+    session = kvm_utils.wait_for(lambda: vm.serial_login(),
+                                  timeout, 0, step=2)
+    if not session:
+        raise error.TestFail("Could not log into guest '%s'" % vm.name)
+
+    old_mac = vm.get_macaddr(0)
+    kvm_utils.free_mac_address(vm.root_dir, vm, 0)
+    new_mac = kvm_utils.generate_mac_address(vm.root_dir,
+                                             vm.instance,
+                                             0, vm.mac_prefix)
+    logging.info("The initial MAC address is %s", old_mac)
+    interface = kvm_test_utils.get_linux_ifname(session, old_mac)
+
+    # Start change MAC address
+    logging.info("Changing MAC address to %s", new_mac)
+    change_cmd = ("ifconfig %s down && ifconfig %s hw ether %s && "
+                  "ifconfig %s up" % (interface, interface, new_mac, interface))
+    if session.get_command_status(change_cmd) != 0:
+        raise error.TestFail("Fail to send mac_change command")
+
+    # Verify whether MAC address was changed to the new one
+    logging.info("Verifying the new mac address")
+    if session.get_command_status("ifconfig | grep -i %s" % new_mac) != 0:
+        raise error.TestFail("Fail to change MAC address")
+
+    # Restart `dhclient' to regain IP for new mac address
+    logging.info("Restart the network to gain new IP")
+    dhclient_cmd = "dhclient -r && dhclient %s" % interface
+    session.sendline(dhclient_cmd)
+
+    # Re-log into the guest after changing mac address
+    if kvm_utils.wait_for(session.is_responsive, 120, 20, 3):
+        # Just warning when failed to see the session become dead,
+        # because there is a little chance the ip does not change.
+        logging.warn("The session is still responsive, settings may fail.")
+    session.close()
+
+    # Re-log into guest and check if session is responsive
+    logging.info("Re-log into the guest")
+    session = kvm_test_utils.wait_for_login(vm,
+              timeout=int(params.get("login_timeout", 360)))
+    if not session.is_responsive():
+        raise error.TestFail("The new session is not responsive.")
+
+    session.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 6bbc33e..a710bc0 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -514,6 +514,10 @@ variants:
         restart_vm = yes
         pxe_timeout = 60
 
+    - mac_change: install setup unattended_install.cdrom
+        type = mac_change
+        kill_vm = yes
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
@@ -1231,7 +1235,7 @@ variants:
 
     # Windows section
     - @Windows:
-        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast
+        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast mac_change
         shutdown_command = shutdown /s /f /t 0
         reboot_command = shutdown /r /f /t 0
         status_test_command = echo %errorlevel%
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 14/18] KVM test: Add a netperf subtest
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (12 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 13/18] KVM test: Add a subtest of changing MAC address Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 15/18] KVM test: kvm_utils - Add support of check if remote port free Lucas Meneghel Rodrigues
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

Add network load by netperf, server is launched on guest, execute netperf
client with different protocols on host. if all clients execute successfully,
case will be pass. Test result will be record into result.txt.

Now this case only tests with "TCP_RR TCP_CRR UDP_RR TCP_STREAM TCP_MAERTS
TCP_SENDFILE UDP_STREAM". DLPI only supported by Unix, unix domain test is
not necessary, so drop test of DLPI and unix domain.

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/netperf.py      |   56 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |   10 ++++++
 2 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/tests/netperf.py

diff --git a/client/tests/kvm/tests/netperf.py b/client/tests/kvm/tests/netperf.py
new file mode 100644
index 0000000..acdd2f8
--- /dev/null
+++ b/client/tests/kvm/tests/netperf.py
@@ -0,0 +1,56 @@
+import logging, commands, os
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+import kvm_test_utils
+
+def run_netperf(test, params, env):
+    """
+    Network stress test with netperf.
+
+    1) Boot up a VM.
+    2) Launch netserver on guest.
+    3) Execute netperf client on host with different protocols.
+    4) Output the test result.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm,
+                                  timeout=int(params.get("login_timeout", 360)))
+    netperf_dir = os.path.join(os.environ['AUTODIR'], "tests/netperf2")
+    setup_cmd = params.get("setup_cmd")
+    guest_ip = vm.get_address()
+    result_file = os.path.join(test.resultsdir, "output_%s" % test.iteration)
+
+    session.get_command_output("iptables -F")
+    for i in params.get("netperf_files").split():
+        if not vm.copy_files_to(os.path.join(netperf_dir, i), "/tmp"):
+            raise error.TestError("Could not copy files to guest")
+    if session.get_command_status(setup_cmd % "/tmp", timeout=200) != 0:
+        raise error.TestFail("Fail to setup netperf on guest")
+    if session.get_command_status(params.get("netserver_cmd") % "/tmp") != 0:
+        raise error.TestFail("Fail to start netperf server on guest")
+
+    try:
+        logging.info("Setup and run netperf client on host")
+        utils.run(setup_cmd % netperf_dir)
+        success = True
+        file(result_file, "w").write("Netperf Test Result\n")
+        for i in params.get("protocols").split():
+            cmd = params.get("netperf_cmd") % (netperf_dir, i, guest_ip)
+            logging.debug("Execute netperf client test: %s", cmd)
+            s, o = commands.getstatusoutput(cmd)
+            if s != 0:
+                logging.error("Fail to execute netperf test, protocol:%s", i)
+                success = False
+            else:
+                logging.info(o)
+                file(result_file, "a+").write("%s\n" % o)
+        if not success:
+            raise error.TestFail("Some of the netperf tests failed")
+
+    finally:
+        session.get_command_output("killall netserver")
+        session.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index a710bc0..29fe984 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -518,6 +518,16 @@ variants:
         type = mac_change
         kill_vm = yes
 
+    - netperf: install setup unattended_install.cdrom
+        type = netperf
+        nic_mode = tap
+        netperf_files = netperf-2.4.5.tar.bz2 wait_before_data.patch
+        setup_cmd = "cd %s && tar xvfj netperf-2.4.5.tar.bz2 && cd netperf-2.4.5 && patch -p0 < ../wait_before_data.patch && ./configure && make"
+        netserver_cmd =  %s/netperf-2.4.5/src/netserver
+        # test time is 60 seconds, set the buffer size to 1 for more hardware interrupt
+        netperf_cmd = %s/netperf-2.4.5/src/netperf -t %s -H %s -l 60 -- -m 1
+        protocols = "TCP_STREAM TCP_MAERTS TCP_RR TCP_CRR UDP_RR TCP_SENDFILE UDP_STREAM"
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 15/18] KVM test: kvm_utils - Add support of check if remote port free
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (13 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 14/18] KVM test: Add a netperf subtest Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 16/18] KVM test: Improve vlan subtest Lucas Meneghel Rodrigues
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/kvm_utils.py |   23 +++++++++++++++--------
 1 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index bb5c868..71ab7d1 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -829,7 +829,7 @@ def scp_from_remote(host, port, username, password, remote_path, local_path,
 
 # The following are utility functions related to ports.
 
-def is_port_free(port):
+def is_port_free(port, address):
     """
     Return True if the given port is available for use.
 
@@ -838,15 +838,22 @@ def is_port_free(port):
     try:
         s = socket.socket()
         #s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-        s.bind(("localhost", port))
-        free = True
+        if address == "localhost":
+            s.bind(("localhost", port))
+            free = True
+        else:
+            s.connect((address, port))
+            free = False
     except socket.error:
-        free = False
+        if address == "localhost":
+            free = False
+        else:
+            free = True
     s.close()
     return free
 
 
-def find_free_port(start_port, end_port):
+def find_free_port(start_port, end_port, address="localhost"):
     """
     Return a host free port in the range [start_port, end_port].
 
@@ -854,12 +861,12 @@ def find_free_port(start_port, end_port):
     @param end_port: Port immediately after the last one that will be checked.
     """
     for i in range(start_port, end_port):
-        if is_port_free(i):
+        if is_port_free(i, address):
             return i
     return None
 
 
-def find_free_ports(start_port, end_port, count):
+def find_free_ports(start_port, end_port, count, address="localhost"):
     """
     Return count of host free ports in the range [start_port, end_port].
 
@@ -870,7 +877,7 @@ def find_free_ports(start_port, end_port, count):
     ports = []
     i = start_port
     while i < end_port and count > 0:
-        if is_port_free(i):
+        if is_port_free(i, address):
             ports.append(i)
             count -= 1
         i += 1
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 16/18] KVM test: Improve vlan subtest
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (14 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 15/18] KVM test: kvm_utils - Add support of check if remote port free Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 17/18] KVM test: vlan subtest - Replace extra_params '-snapshot' with image_snapshot Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 18/18] KVM test: Add subtest of testing offload by ethtool Lucas Meneghel Rodrigues
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

This is an enhancement of existed vlan test. Rename the vlan_tag.py to vlan.py,
it is more reasonable.
. Setup arp from "/proc/sys/net/ipv4/conf/all/arp_ignore"
. Multiple vlans exist simultaneously
. Test ping between same and different vlans
. Test by TCP data transfer, floop ping between same vlan
. Maximal plumb/unplumb vlans

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/vlan.py         |  186 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests/vlan_tag.py     |   68 ------------
 client/tests/kvm/tests_base.cfg.sample |   16 ++-
 3 files changed, 196 insertions(+), 74 deletions(-)
 create mode 100644 client/tests/kvm/tests/vlan.py
 delete mode 100644 client/tests/kvm/tests/vlan_tag.py

diff --git a/client/tests/kvm/tests/vlan.py b/client/tests/kvm/tests/vlan.py
new file mode 100644
index 0000000..fb2a8d7
--- /dev/null
+++ b/client/tests/kvm/tests/vlan.py
@@ -0,0 +1,186 @@
+import logging, time, re
+from autotest_lib.client.common_lib import error
+import kvm_test_utils, kvm_utils
+
+def run_vlan(test, params, env):
+    """
+    Test 802.1Q vlan of NIC, config it by vconfig command.
+
+    1) Create two VMs.
+    2) Setup guests in 10 different vlans by vconfig and using hard-coded
+       ip address.
+    3) Test by ping between same and different vlans of two VMs.
+    4) Test by TCP data transfer, floop ping between same vlan of two VMs.
+    5) Test maximal plumb/unplumb vlans.
+    6) Recover the vlan config.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+
+    vm = []
+    session = []
+    vm_ip = []
+    digest_origin = []
+    vlan_ip = ['', '']
+    ip_unit = ['1', '2']
+    subnet = params.get("subnet")
+    vlan_num = int(params.get("vlan_num"))
+    maximal = int(params.get("maximal"))
+    file_size = params.get("file_size")
+
+    vm.append(kvm_test_utils.get_living_vm(env, params.get("main_vm")))
+    vm.append(kvm_test_utils.get_living_vm(env, "vm2"))
+
+    def add_vlan(session, id, iface="eth0"):
+        if session.get_command_status("vconfig add %s %s" % (iface, id)) != 0:
+            raise error.TestError("Fail to add %s.%s" % (iface, id))
+
+
+    def set_ip_vlan(session, id, ip, iface="eth0"):
+        iface = "%s.%s" % (iface, id)
+        if session.get_command_status("ifconfig %s %s" % (iface, ip)) != 0:
+            raise error.TestError("Fail to configure ip for %s" % iface)
+
+
+    def set_arp_ignore(session, iface="eth0"):
+        ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore"
+        if session.get_command_status(ignore_cmd) != 0:
+            raise error.TestError("Fail to set arp_ignore of %s" % session)
+
+
+    def rem_vlan(session, id, iface="eth0"):
+        rem_vlan_cmd = "if [[ -e /proc/net/vlan/%s ]];then vconfig rem %s;fi"
+        iface = "%s.%s" % (iface, id)
+        s = session.get_command_status(rem_vlan_cmd % (iface, iface))
+        return s
+
+
+    def nc_transfer(src, dst):
+        nc_port = kvm_utils.find_free_port(1025, 5334, vm_ip[dst])
+        listen_cmd = params.get("listen_cmd")
+        send_cmd = params.get("send_cmd")
+
+        #listen in dst
+        listen_cmd = listen_cmd % (nc_port, "receive")
+        session[dst].sendline(listen_cmd)
+        time.sleep(2)
+        #send file from src to dst
+        send_cmd = send_cmd % (vlan_ip[dst], str(nc_port), "file")
+        if session[src].get_command_status(send_cmd, timeout = 60) != 0:
+            raise error.TestFail ("Fail to send file"
+                                    " from vm%s to vm%s" % (src+1, dst+1))
+        s, o = session[dst].read_up_to_prompt(timeout=60)
+        if s != True:
+            raise error.TestFail ("Fail to receive file"
+                                    " from vm%s to vm%s" % (src+1, dst+1))
+        #check MD5 message digest of receive file in dst
+        output = session[dst].get_command_output("md5sum receive").strip()
+        digest_receive = re.findall(r'(\w+)', output)[0]
+        if digest_receive == digest_origin[src]:
+            logging.info("file succeed received in vm %s" % vlan_ip[dst])
+        else:
+            logging.info("digest_origin is  %s" % digest_origin[src])
+            logging.info("digest_receive is %s" % digest_receive)
+            raise error.TestFail("File transfered differ from origin")
+        session[dst].get_command_status("rm -f receive")
+
+
+    for i in range(2):
+        session.append(kvm_test_utils.wait_for_login(vm[i],
+                       timeout=int(params.get("login_timeout", 360))))
+        if not session[i] :
+            raise error.TestError("Could not log into guest(vm%d)" % i)
+        logging.info("Logged in")
+
+        #get guest ip
+        vm_ip.append(vm[i].get_address())
+
+        #produce sized file in vm
+        dd_cmd = "dd if=/dev/urandom of=file bs=1024k count=%s"
+        if session[i].get_command_status(dd_cmd % file_size) != 0:
+            raise error.TestFail("File producing failed")
+        #record MD5 message digest of file
+        s, output =session[i].get_command_status_output("md5sum file",
+                                                        timeout=60)
+        if s != 0:
+            raise error.TestFail("File MD5_checking failed" )
+        digest_origin.append(re.findall(r'(\w+)', output)[0])
+
+        #stop firewall in vm
+        session[i].get_command_status("/etc/init.d/iptables stop")
+
+        #load 8021q module for vconfig
+        load_8021q_cmd = "modprobe 8021q"
+        if session[i].get_command_status(load_8021q_cmd) != 0:
+            raise error.TestError("Fail to load 8021q module on VM%s" % i)
+
+    try:
+        for i in range(2):
+            for vlan_i in range(1, vlan_num+1):
+                add_vlan(session[i], vlan_i)
+                set_ip_vlan(session[i], vlan_i, "%s.%s.%s" % \
+                                          (subnet, vlan_i, ip_unit[i]))
+            set_arp_ignore(session[i])
+
+        for vlan in range(1, vlan_num+1):
+            logging.info("Test for vlan %s" % vlan)
+
+            logging.info("Ping between vlans")
+            interface = 'eth0.' + str(vlan)
+            for vlan2 in range(1, vlan_num+1):
+                for i in range(2):
+                    dest = subnet +'.'+ str(vlan2)+ '.' + ip_unit[(i+1)%2]
+                    s, o = kvm_test_utils.ping(dest, count=2,
+                                              interface=interface,
+                                              session=session[i], timeout=30)
+                    if ((vlan == vlan2) ^ (s == 0)):
+                        raise error.TestFail ("%s ping %s unexpected" %
+                                                    (interface, dest))
+
+            vlan_ip[0] = subnet + '.' + str(vlan) + '.' + ip_unit[0]
+            vlan_ip[1] = subnet + '.' + str(vlan) + '.' + ip_unit[1]
+
+            logging.info("Flood ping")
+            def flood_ping(src, dst):
+                # we must use a dedicated session becuase the kvm_subprocess
+                # does not have the other method to interrupt the process in
+                # the guest rather than close the session.
+                session_flood = kvm_test_utils.wait_for_login(vm[src],
+                                                              timeout = 60)
+                kvm_test_utils.ping(vlan_ip[dst], flood=True,
+                                   interface=interface,
+                                   session=session_flood, timeout=10)
+                session_flood.close()
+
+            flood_ping(0,1)
+            flood_ping(1,0)
+
+            logging.info("Transfering data through nc")
+            nc_transfer(0, 1)
+            nc_transfer(1, 0)
+
+    finally:
+        for vlan in range(1, vlan_num+1):
+            rem_vlan(session[0], vlan)
+            rem_vlan(session[1], vlan)
+            logging.info("rem eth0.%s" % vlan)
+
+    # Plumb/unplumb maximal unber of vlan interfaces
+    i = 1
+    s = 0
+    try:
+        logging.info("Testing the plumb of vlan interface")
+        for i in range (1, maximal+1):
+            add_vlan(session[0], i)
+    finally:
+        for j in range (1, i+1):
+            s = s or rem_vlan(session[0], j)
+        if s == 0:
+            logging.info("maximal interface plumb test done")
+        else:
+            logging.error("maximal interface plumb test failed")
+
+    session[0].close()
+    session[1].close()
diff --git a/client/tests/kvm/tests/vlan_tag.py b/client/tests/kvm/tests/vlan_tag.py
deleted file mode 100644
index cafd8fe..0000000
--- a/client/tests/kvm/tests/vlan_tag.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import logging, time
-from autotest_lib.client.common_lib import error
-import kvm_subprocess, kvm_test_utils, kvm_utils
-
-
-def run_vlan_tag(test, params, env):
-    """
-    Test 802.1Q vlan of NIC, config it by vconfig command.
-
-    1) Create two VMs.
-    2) Setup guests in different VLANs by vconfig and test communication by
-       ping using hard-coded ip addresses.
-    3) Setup guests in same vlan and test communication by ping.
-    4) Recover the vlan config.
-
-    @param test: KVM test object.
-    @param params: Dictionary with the test parameters.
-    @param env: Dictionary with test environment.
-    """
-    subnet = params.get("subnet")
-    vlans = params.get("vlans").split()
-
-    vm1 = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
-    vm2 = kvm_test_utils.get_living_vm(env, "vm2")
-
-    timeout = int(params.get("login_timeout", 360))
-    session1 = kvm_test_utils.wait_for_login(vm1, timeout=timeout)
-    session2 = kvm_test_utils.wait_for_login(vm2, timeout=timeout)
-
-    try:
-        ip_cfg_base = "vconfig add eth0 %s && ifconfig eth0.%s %s.%s"
-        ip_cfg_cmd1 = ip_cfg_base % (vlans[0], vlans[0], subnet, "11")
-        ip_cfg_cmd2 = ip_cfg_base % (vlans[1], vlans[1], subnet, "12")
-
-        # Configure VM1 and VM2 in different VLANs
-        ip_cfg_vm1 = session1.get_command_status(ip_cfg_cmd1)
-        if ip_cfg_vm1 != 0:
-            raise error.TestError("Failed to config VM 1 IP address")
-        ip_cfg_vm2 = session2.get_command_status(ip_cfg_cmd2)
-        if ip_cfg_vm2 != 0:
-            raise error.TestError("Failed to config VM 2 IP address")
-
-        # Trying to ping VM 2 from VM 1, this shouldn't work
-        ping_cmd = "ping -c 2 -I eth0.%s %s.%s" % (vlans[0], subnet, "12")
-        ping_diff_vlan = session1.get_command_status(ping_cmd)
-        if ping_diff_vlan == 0:
-            raise error.TestFail("VM 2 can be reached even though it was "
-                                 "configured on a different VLAN")
-
-        # Now let's put VM 2 in the same VLAN as VM 1
-        ip_cfg_reconfig= ("vconfig rem eth0.%s && vconfig add eth0 %s && "
-                          "ifconfig eth0.%s %s.%s" % (vlans[1], vlans[0],
-                                                      vlans[0], subnet, "12"))
-        ip_cfg_vm2 = session2.get_command_status(ip_cfg_reconfig)
-        if ip_cfg_vm2 != 0:
-            raise error.TestError("Failed to re-config IP address of VM 2")
-
-        # Try to ping VM 2 from VM 1, this should work
-        ping_same_vlan = session1.get_command_status(ping_cmd)
-        if ping_same_vlan != 0:
-            raise error.TestFail("Failed to ping VM 2 even though it was "
-                                 "configured on the same VLAN")
-
-    finally:
-        session1.get_command_status("vconfig rem eth0.%s" % vlans[0])
-        session1.close()
-        session2.get_command_status("vconfig rem eth0.%s" % vlans[0])
-        session2.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 29fe984..f53b3f7 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -457,17 +457,21 @@ variants:
             - fmt_raw:
                 image_format_stg = raw
 
-    - vlan_tag:  install setup unattended_install.cdrom
-        type = vlan_tag
+    - vlan:  install setup unattended_install.cdrom
+        type = vlan
         # subnet should not be used by host
-        subnet = 192.168.123
-        vlans = "10 20"
+        subnet = "192.168"
+        vlan_num = 5
+        file_size = 10
+        maximal = 4094
+        listen_cmd = "nc -l %s > %s"
+        send_cmd = "nc %s %s < %s"
         nic_mode = tap
         vms += " vm2"
         extra_params_vm1 += " -snapshot"
         extra_params_vm2 += " -snapshot"
+        kill_vm_vm2 = yes
         kill_vm_gracefully_vm2 = no
-        address_index_vm2 = 1
 
     - ping: install setup unattended_install.cdrom
         type = ping
@@ -1245,7 +1249,7 @@ variants:
 
     # Windows section
     - @Windows:
-        no autotest linux_s3 vlan_tag ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast mac_change
+        no autotest linux_s3 vlan ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast mac_change
         shutdown_command = shutdown /s /f /t 0
         reboot_command = shutdown /r /f /t 0
         status_test_command = echo %errorlevel%
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 17/18] KVM test: vlan subtest - Replace extra_params '-snapshot' with image_snapshot
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (15 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 16/18] KVM test: Improve vlan subtest Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-14 22:25 ` [PATCH 18/18] KVM test: Add subtest of testing offload by ethtool Lucas Meneghel Rodrigues
  17 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

From: Amos Kong <akong@redhat.com>

Framework could not totalise default extra_params and extra_params_vm1 in the
following condition, it's difficult to realise when parsing config file or
calling get_sub_dict*().

extra_params += ' str1'
- case:
extra_params_vm1 += " str2"

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests_base.cfg.sample |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index f53b3f7..b543606 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -468,8 +468,7 @@ variants:
         send_cmd = "nc %s %s < %s"
         nic_mode = tap
         vms += " vm2"
-        extra_params_vm1 += " -snapshot"
-        extra_params_vm2 += " -snapshot"
+        image_snapshot = yes
         kill_vm_vm2 = yes
         kill_vm_gracefully_vm2 = no
 
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 18/18] KVM test: Add subtest of testing offload by ethtool
  2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
                   ` (16 preceding siblings ...)
  2010-09-14 22:25 ` [PATCH 17/18] KVM test: vlan subtest - Replace extra_params '-snapshot' with image_snapshot Lucas Meneghel Rodrigues
@ 2010-09-14 22:25 ` Lucas Meneghel Rodrigues
  2010-09-23 13:41   ` [Autotest] " pradeep
  17 siblings, 1 reply; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-14 22:25 UTC (permalink / raw)
  To: autotest; +Cc: kvm

The latest case contains TX/RX/SG/TSO/GSO/GRO/LRO test.
RTL8139 NIC doesn't support TSO, LRO, it's too old, so
drop offload test from rtl8139. LRO, GRO are only
supported by latest kernel, virtio nic doesn't support
receive offloading function.

Initialize the callbacks first and execute all the sub
tests one by one, all the result will be check at the
end. When execute this test, vhost should be enabled,
then most of new features can be used. Vhost doesn't
support VIRTIO_NET_F_MRG_RXBUF, so do not check large
packets in received offload test.

Transfer files by scp between host and guest, match
new opened TCP port by netstat. Capture the packages
info by tcpdump, it contains package length.

TODO: Query supported offload function by 'ethtool'

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/tests/ethtool.py      |  215 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |   13 ++-
 2 files changed, 226 insertions(+), 2 deletions(-)
 create mode 100644 client/tests/kvm/tests/ethtool.py

diff --git a/client/tests/kvm/tests/ethtool.py b/client/tests/kvm/tests/ethtool.py
new file mode 100644
index 0000000..c0bab12
--- /dev/null
+++ b/client/tests/kvm/tests/ethtool.py
@@ -0,0 +1,215 @@
+import logging, commands, re
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+import kvm_test_utils, kvm_utils
+
+def run_ethtool(test, params, env):
+    """
+    Test offload functions of ethernet device by ethtool
+
+    1) Log into a guest.
+    2) Initialize the callback of sub functions.
+    3) Enable/disable sub function of NIC.
+    4) Execute callback function.
+    5) Check the return value.
+    6) Restore original configuration.
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    def ethtool_get(type):
+        feature_pattern = {
+            'tx':  'tx.*checksumming',
+            'rx':  'rx.*checksumming',
+            'sg':  'scatter.*gather',
+            'tso': 'tcp.*segmentation.*offload',
+            'gso': 'generic.*segmentation.*offload',
+            'gro': 'generic.*receive.*offload',
+            'lro': 'large.*receive.*offload',
+            }
+        s, o = session.get_command_status_output("ethtool -k %s" % ethname)
+        try:
+            return re.findall("%s: (.*)" % feature_pattern.get(type), o)[0]
+        except IndexError:
+            logging.debug("Could not get %s status" % type)
+
+
+    def ethtool_set(type, status):
+        """
+        Set ethernet device offload status
+
+        @param type: Offload type name
+        @param status: New status will be changed to
+        """
+        logging.info("Try to set %s %s" % (type, status))
+        if status not in ["off", "on"]:
+            return False
+        cmd = "ethtool -K %s %s %s" % (ethname, type, status)
+        if ethtool_get(type) != status:
+            return session.get_command_status(cmd) == 0
+        if ethtool_get(type) != status:
+            logging.error("Fail to set %s %s" % (type, status))
+            return False
+        return True
+
+
+    def ethtool_save_params():
+        logging.info("Save ethtool configuration")
+        for i in supported_features:
+            feature_status[i] = ethtool_get(i)
+
+
+    def ethtool_restore_params():
+        logging.info("Restore ethtool configuration")
+        for i in supported_features:
+            ethtool_set(i, feature_status[i])
+
+
+    def compare_md5sum(name):
+        logging.info("Compare md5sum of the files on guest and host")
+        host_result = utils.hash_file(name, method="md5")
+        try:
+            o = session.get_command_output("md5sum %s" % name)
+            guest_result = re.findall("\w+", o)[0]
+        except IndexError:
+            logging.error("Could not get file md5sum in guest")
+            return False
+        logging.debug("md5sum: guest(%s), host(%s)" %
+                      (guest_result, host_result))
+        return guest_result == host_result
+
+
+    def transfer_file(src="guest"):
+        """
+        Transfer file by scp, use tcpdump to capture packets, then check the
+        return string.
+
+        @param src: Source host of transfer file
+        @return: Tuple (status, error msg/tcpdump result)
+        """
+        session2.get_command_status("rm -rf %s" % filename)
+        dd_cmd = "dd if=/dev/urandom of=%s bs=1M count=%s" % (filename,
+                                                   params.get("filesize"))
+        logging.info("Creat file in source host, cmd: %s" % dd_cmd)
+        tcpdump_cmd = "tcpdump -lep -s 0 tcp -vv port ssh"
+        if src == "guest":
+            s = session.get_command_status(dd_cmd, timeout=360)
+            tcpdump_cmd += " and src %s" % guest_ip
+            copy_files_fun = vm.copy_files_from
+        else:
+            s, o = commands.getstatusoutput(dd_cmd)
+            tcpdump_cmd += " and dst %s" % guest_ip
+            copy_files_fun = vm.copy_files_to
+        if s != 0:
+            return (False, "Fail to create file by dd, cmd: %s" % dd_cmd)
+
+        # only capture the new tcp port after offload setup
+        original_tcp_ports = re.findall("tcp.*:(\d+).*%s" % guest_ip,
+                                      utils.system_output("/bin/netstat -nap"))
+        for i in original_tcp_ports:
+            tcpdump_cmd += " and not port %s" % i
+        logging.debug("Listen by command: %s" % tcpdump_cmd)
+        session2.sendline(tcpdump_cmd)
+        if not kvm_utils.wait_for(lambda: session.get_command_status(
+                                           "pgrep tcpdump") == 0, 30):
+            return (False, "Tcpdump process wasn't launched")
+
+        logging.info("Start to transfer file")
+        if not copy_files_fun(filename, filename):
+            return (False, "Child process transfer file failed")
+        logging.info("Transfer file completed")
+        if session.get_command_status("killall tcpdump") != 0:
+            return (False, "Could not kill all tcpdump process")
+        s, tcpdump_string = session2.read_up_to_prompt(timeout=60)
+        if not s:
+            return (False, "Fail to read tcpdump's output")
+
+        if not compare_md5sum(filename):
+            return (False, "Files' md5sum mismatched")
+        return (True, tcpdump_string)
+
+
+    def tx_callback(status="on"):
+        s, o = transfer_file(src="guest")
+        if not s:
+            logging.error(o)
+            return False
+        return True
+
+
+    def rx_callback(status="on"):
+        s, o = transfer_file(src="host")
+        if not s:
+            logging.error(o)
+            return False
+        return True
+
+
+    def so_callback(status="on"):
+        s, o = transfer_file(src="guest")
+        if not s:
+            logging.error(o)
+            return False
+        logging.info("Check if contained large frame")
+        # MTU: default IPv4 MTU is 1500 Bytes, ethernet header is 14 Bytes
+        return (status == "on") ^ (len([i for i in re.findall(
+                                   "length (\d*):", o) if int(i) > mtu]) == 0)
+
+
+    def ro_callback(status="on"):
+        s, o = transfer_file(src="host")
+        if not s:
+            logging.error(o)
+            return False
+        return True
+
+
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm,
+                  timeout=int(params.get("login_timeout", 360)))
+    session2 = kvm_test_utils.wait_for_login(vm,
+                  timeout=int(params.get("login_timeout", 360)))
+    mtu = 1514
+    feature_status = {}
+    filename = "/tmp/ethtool.dd"
+    guest_ip = vm.get_address()
+    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_macaddr(0))
+    supported_features = params.get("supported_features").split()
+    test_matrix = {
+        # type:(callback,    (dependence), (exclude)
+        "tx":  (tx_callback, (), ()),
+        "rx":  (rx_callback, (), ()),
+        "sg":  (tx_callback, ("tx",), ()),
+        "tso": (so_callback, ("tx", "sg",), ("gso",)),
+        "gso": (so_callback, (), ("tso",)),
+        "gro": (ro_callback, ("rx",), ("lro",)),
+        "lro": (rx_callback, (), ("gro",)),
+        }
+    ethtool_save_params()
+    success = True
+    try:
+        for type in supported_features:
+            callback = test_matrix[type][0]
+            for i in test_matrix[type][2]:
+                if not ethtool_set(i, "off"):
+                    logging.error("Fail to disable %s" % i)
+                    success = False
+            for i in [f for f in test_matrix[type][1]] + [type]:
+                if not ethtool_set(i, "on"):
+                    logging.error("Fail to enable %s" % i)
+                    success = False
+            if not callback():
+                raise error.TestFail("Test failed, %s: on" % type)
+
+            if not ethtool_set(type, "off"):
+                logging.error("Fail to disable %s" % type)
+                success = False
+            if not callback(status="off"):
+                raise error.TestFail("Test failed, %s: off" % type)
+        if not success:
+            raise error.TestError("Enable/disable offload function fail")
+    finally:
+        ethtool_restore_params()
+        session.close()
+        session2.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index b543606..22e9494 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -531,6 +531,11 @@ variants:
         netperf_cmd = %s/netperf-2.4.5/src/netperf -t %s -H %s -l 60 -- -m 1
         protocols = "TCP_STREAM TCP_MAERTS TCP_RR TCP_CRR UDP_RR TCP_SENDFILE UDP_STREAM"
 
+    - ethtool: install setup unattended_install.cdrom
+        type = ethtool
+        filesize = 512
+        nic_mode = tap
+
     - physical_resources_check: install setup unattended_install.cdrom
         type = physical_resources_check
         catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}'
@@ -683,11 +688,15 @@ variants:
         nic_model = e1000
         jumbo:
             mtu = 16110
+        ethtool:
+                # gso gro lro is only supported by latest kernel
+                supported_features = "tx rx sg tso gso gro lro"
     - virtio_net:
         nic_model = virtio
         jumbo:
             mtu = 65520
-
+        ethtool:
+            supported_features = "tx sg tso gso"
 
 # Guests
 variants:
@@ -1248,7 +1257,7 @@ variants:
 
     # Windows section
     - @Windows:
-        no autotest linux_s3 vlan ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast mac_change
+        no autotest linux_s3 vlan ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast mac_change ethtool
         shutdown_command = shutdown /s /f /t 0
         reboot_command = shutdown /r /f /t 0
         status_test_command = echo %errorlevel%
-- 
1.7.2.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [Autotest] [PATCH 18/18] KVM test: Add subtest of testing offload by ethtool
  2010-09-14 22:25 ` [PATCH 18/18] KVM test: Add subtest of testing offload by ethtool Lucas Meneghel Rodrigues
@ 2010-09-23 13:41   ` pradeep
  2010-09-23 13:47     ` Lucas Meneghel Rodrigues
  0 siblings, 1 reply; 22+ messages in thread
From: pradeep @ 2010-09-23 13:41 UTC (permalink / raw)
  To: Lucas Meneghel Rodrigues; +Cc: autotest, kvm

On Tue, 14 Sep 2010 19:25:43 -0300
Lucas Meneghel Rodrigues <lmr@redhat.com> wrote:

> The latest case contains TX/RX/SG/TSO/GSO/GRO/LRO test.
> RTL8139 NIC doesn't support TSO, LRO, it's too old, so
> drop offload test from rtl8139. LRO, GRO are only
> supported by latest kernel, virtio nic doesn't support
> receive offloading function.
> 
> Initialize the callbacks first and execute all the sub
> tests one by one, all the result will be check at the
> end. When execute this test, vhost should be enabled,
> then most of new features can be used. Vhost doesn't
> support VIRTIO_NET_F_MRG_RXBUF, so do not check large
> packets in received offload test.
> 
> Transfer files by scp between host and guest, match
> new opened TCP port by netstat. Capture the packages
> info by tcpdump, it contains package length.
> 
> TODO: Query supported offload function by 'ethtool'
> 

Hi Lucas/AMos

Thanks for the patches. 

Please find below error, when  i try to run  ethtool test on
my guest (kernel: 2.6.32-71.el6.i386) which is on host (Kernel
2.6.32-71.el6.x86_64).


'module' object has no attribute 'get_linux_ifname'..



04:23:59 DEBUG| Got shell prompt -- logged in
04:23:59 INFO | Logged into guest 'vm1'
04:23:59 ERROR| Test failed: AttributeError: 'module' object has no
attribute 'get_linux_ifname' 04:23:59 DEBUG| Postprocessing VM 'vm1'...

Ethtool is trying to access get_linux_ifname which is not present in
kvm_test_utils.py. AM i missing any patches?



Thanks
Pradeep



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Autotest] [PATCH 18/18] KVM test: Add subtest of testing offload by ethtool
  2010-09-23 13:41   ` [Autotest] " pradeep
@ 2010-09-23 13:47     ` Lucas Meneghel Rodrigues
  0 siblings, 0 replies; 22+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-09-23 13:47 UTC (permalink / raw)
  To: pradeep; +Cc: autotest, kvm

On Thu, 2010-09-23 at 19:11 +0530, pradeep wrote:
> On Tue, 14 Sep 2010 19:25:43 -0300
> Lucas Meneghel Rodrigues <lmr@redhat.com> wrote:
> 
> > The latest case contains TX/RX/SG/TSO/GSO/GRO/LRO test.
> > RTL8139 NIC doesn't support TSO, LRO, it's too old, so
> > drop offload test from rtl8139. LRO, GRO are only
> > supported by latest kernel, virtio nic doesn't support
> > receive offloading function.
> > 
> > Initialize the callbacks first and execute all the sub
> > tests one by one, all the result will be check at the
> > end. When execute this test, vhost should be enabled,
> > then most of new features can be used. Vhost doesn't
> > support VIRTIO_NET_F_MRG_RXBUF, so do not check large
> > packets in received offload test.
> > 
> > Transfer files by scp between host and guest, match
> > new opened TCP port by netstat. Capture the packages
> > info by tcpdump, it contains package length.
> > 
> > TODO: Query supported offload function by 'ethtool'
> > 
> 
> Hi Lucas/AMos
> 
> Thanks for the patches. 
> 
> Please find below error, when  i try to run  ethtool test on
> my guest (kernel: 2.6.32-71.el6.i386) which is on host (Kernel
> 2.6.32-71.el6.x86_64).
> 
> 
> 'module' object has no attribute 'get_linux_ifname'..
> 
> 
> 
> 04:23:59 DEBUG| Got shell prompt -- logged in
> 04:23:59 INFO | Logged into guest 'vm1'
> 04:23:59 ERROR| Test failed: AttributeError: 'module' object has no
> attribute 'get_linux_ifname' 04:23:59 DEBUG| Postprocessing VM 'vm1'...
> 
> Ethtool is trying to access get_linux_ifname which is not present in
> kvm_test_utils.py. AM i missing any patches?
> 

Yes, please verify http://patchwork.test.kernel.org/patch/2540/

Cheers!

Lucas


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Autotest] [PATCH 07/18] KVM test: Add a subtest jumbo
  2010-09-14 22:25 ` [PATCH 07/18] KVM test: Add a subtest jumbo Lucas Meneghel Rodrigues
@ 2010-09-24  8:16   ` pradeep
  0 siblings, 0 replies; 22+ messages in thread
From: pradeep @ 2010-09-24  8:16 UTC (permalink / raw)
  To: Lucas Meneghel Rodrigues; +Cc: autotest, kvm

On Tue, 14 Sep 2010 19:25:32 -0300
Lucas Meneghel Rodrigues <lmr@redhat.com> wrote:

> +        session.close()
> +        logging.info("Removing the temporary ARP entry")
> +        utils.run("arp -d %s -i %s" % (ip, ifname))
> 

Hi Lucas

Tried different combinations for this jumbo test case. it dint work for
me. I guess there is a problem while trying to remove ARP entry.
ARP entry can be removed from cache using ip and network
interface (for ex: eth0)

arp -d <ip> -i eth0


Error which i got:

23:06:14 DEBUG| Running 'arp -d 192.168.122.104 -i rtl8139_0_5900'
23:06:14 ERROR| Test failed: CmdError: Command <arp -d 192.168.122.104
-i rtl8139_0_5900> failed, rc=255, Command returned non-zero exit status
* Command: 
    arp -d 192.168.122.104 -i rtl8139_0_5900
Exit status: 255
Duration: 0.00138521194458

stderr:
SIOCDARP(pub): No such file or directory

When i try manually this one works for me.

Gues ip: 192.168.122.104

try "arp -i 192.168.122.1 -i eth0"


--Thanks
Pradeep

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2010-09-24  8:16 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-14 22:25 [PATCH 00/18] KVM autotest network patchset v3 Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 01/18] KVM test: Add a new macaddress pool algorithm Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 02/18] KVM test: Make physical_resources_check to work with MAC management Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 03/18] KVM test: Remove address_pools.cfg dependency Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 04/18] KVM test: Add a get_ifname function Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 05/18] KVM Test: Add a common ping module for network related tests Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 06/18] KVM test: Add a new subtest ping Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 07/18] KVM test: Add a subtest jumbo Lucas Meneghel Rodrigues
2010-09-24  8:16   ` [Autotest] " pradeep
2010-09-14 22:25 ` [PATCH 08/18] KVM test: Add basic file transfer test Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 09/18] KVM test: Add a subtest of load/unload nic driver Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 10/18] KVM test: Add a subtest of nic promisc Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 11/18] KVM test: Add a subtest of multicast Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 12/18] KVM test: Add a subtest of pxe Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 13/18] KVM test: Add a subtest of changing MAC address Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 14/18] KVM test: Add a netperf subtest Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 15/18] KVM test: kvm_utils - Add support of check if remote port free Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 16/18] KVM test: Improve vlan subtest Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 17/18] KVM test: vlan subtest - Replace extra_params '-snapshot' with image_snapshot Lucas Meneghel Rodrigues
2010-09-14 22:25 ` [PATCH 18/18] KVM test: Add subtest of testing offload by ethtool Lucas Meneghel Rodrigues
2010-09-23 13:41   ` [Autotest] " pradeep
2010-09-23 13:47     ` Lucas Meneghel Rodrigues

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.