ia64/xen-unstable

changeset 9937:51908f382f92

Add new networking infrastructure to Xm-Test. The goal is to make
creating domains with networking very easy. This patch:

1) Adds new XenDevice class, with the XenNetDevice subclass. These
classes represent devices for xm-test and are tied to XenDomains.
This can eventually be used for block devices as well. Currently,
devices must be added to domains prior to starting the domain. The
attach and detach needs to be handled.

2) Adds a new NetConfig class to handle configuring the network
environment in which the tests run. This patch only handles ranges
of IPs in a bridged environment. DHCP needs to be added as well as
handling NAT and routed environments.

3) Modifies XenDomain class to handle XenDevices.

4) Adds new configuration options for defining a range of IPs, their
network address, and their netmask.

5) Removes the old Network.py and Network class.

6) Modifies the existing tests to use the new infrastructure.

7) Adds some documentation to help creating domains.

Signed-off-by: Daniel Stekloff <dsteklof@us.ibm.com>
author stekloff@dyn9047022152.beaverton.ibm.com
date Thu May 04 14:22:29 2006 +0100 (2006-05-04)
parents bef7f5fcf207
children 39fa9a75d84b
files tools/xm-test/configure.ac tools/xm-test/lib/XmTestLib/NetConfig.py tools/xm-test/lib/XmTestLib/Network.py tools/xm-test/lib/XmTestLib/XenDevice.py tools/xm-test/lib/XmTestLib/XenDomain.py tools/xm-test/lib/XmTestLib/__init__.py tools/xm-test/lib/XmTestLib/config.py.in tools/xm-test/tests/create/13_create_multinic_pos.py tools/xm-test/tests/network/02_network_local_ping_pos.py tools/xm-test/tests/network/03_network_local_tcp_pos.py tools/xm-test/tests/network/04_network_local_udp_pos.py tools/xm-test/tests/network/05_network_dom0_ping_pos.py tools/xm-test/tests/network/06_network_dom0_tcp_pos.py tools/xm-test/tests/network/07_network_dom0_udp_pos.py tools/xm-test/tests/network/11_network_domU_ping_pos.py tools/xm-test/tests/network/12_network_domU_tcp_pos.py tools/xm-test/tests/network/13_network_domU_udp_pos.py
line diff
     1.1 --- a/tools/xm-test/configure.ac	Thu May 04 14:22:17 2006 +0100
     1.2 +++ b/tools/xm-test/configure.ac	Thu May 04 14:22:29 2006 +0100
     1.3 @@ -38,6 +38,36 @@ fi
     1.4  AM_CONDITIONAL(HVM, test x$ENABLE_HVM = xTrue)
     1.5  AC_SUBST(ENABLE_HVM)
     1.6  
     1.7 +# Network needs to know ips to use: dhcp or a range of IPs in the form
     1.8 +# of: 192.168.1.1-192.168.1.100
     1.9 +# If not dhcp, a netmask and network address must be supplied. Defaults to
    1.10 +# zeroconf range.
    1.11 +NET_IP_RANGE="169.254.0.1-169.254.255.255"
    1.12 +AC_ARG_WITH(net-ip-range,
    1.13 +	[  --with-net-ip-range=ip-range	Set a range of ip addresses to use for xm-test guest domain networks. Can specify dhcp or a range of IPs: 192.168.1.1-192.168.1.100 [[default="169.254.0.1-169.254.255.255"]]],
    1.14 +	[ NET_IP_RANGE="$withval" ])
    1.15 +
    1.16 +iprange=`echo $NET_IP_RANGE | perl -e 'while(<>) { print if /\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+/ }'`
    1.17 +
    1.18 +NETWORK_ADDRESS="169.254.0.0"
    1.19 +AC_ARG_WITH(network-address,
    1.20 +	[ --with-network-address=ip Set network address to use with ip range [[default="169.254.0.0"]]],
    1.21 +	[ NETWORK_ADDRESS="$withval" ])
    1.22 +
    1.23 +NETMASK="255.255.0.0"
    1.24 +AC_ARG_WITH(netmask,
    1.25 +	[ --with-netmask=mask Set netmask to use with ip range [[default="255.255.0.0"]]],
    1.26 +	[ NETMASK="$withval" ])
    1.27 +
    1.28 +if test "x$NET_IP_RANGE" != "xdhcp" && test -z "$iprange"
    1.29 +then
    1.30 +	AC_MSG_ERROR(Invalid net-ip-range.)
    1.31 +fi
    1.32 +
    1.33 +AC_SUBST(NET_IP_RANGE)
    1.34 +AC_SUBST(NETWORK_ADDRESS)
    1.35 +AC_SUBST(NETMASK)
    1.36 +
    1.37  AC_ARG_WITH(hvm-kernel,
    1.38        [[  --with-hvm-kernel=kernel       Use this kernel for hvm disk.img testing]],
    1.39        HVMKERNEL=$withval,
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/xm-test/lib/XmTestLib/NetConfig.py	Thu May 04 14:22:29 2006 +0100
     2.3 @@ -0,0 +1,264 @@
     2.4 +#!/usr/bin/python
     2.5 +"""
     2.6 + Copyright (C) International Business Machines Corp., 2005, 2006
     2.7 + Authors: Dan Smith <danms@us.ibm.com>
     2.8 +          Daniel Stekloff <dsteklof@us.ibm.com>
     2.9 +
    2.10 + This program is free software; you can redistribute it and/or modify
    2.11 + it under the terms of the GNU General Public License as published by
    2.12 + the Free Software Foundation; under version 2 of the License.
    2.13 +
    2.14 + This program is distributed in the hope that it will be useful,
    2.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.17 + GNU General Public License for more details.
    2.18 +
    2.19 + You should have received a copy of the GNU General Public License
    2.20 + along with this program; if not, write to the Free Software
    2.21 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.22 +
    2.23 +"""
    2.24 +
    2.25 +import sys
    2.26 +import commands
    2.27 +import os
    2.28 +import re
    2.29 +import time
    2.30 +import random
    2.31 +from xen.xend.sxp import Parser
    2.32 +
    2.33 +from Xm import *
    2.34 +from Test import *
    2.35 +from config import *
    2.36 +
    2.37 +class NetworkError(Exception):
    2.38 +    def __init__(self, msg):
    2.39 +        self.errMsg = msg
    2.40 +
    2.41 +    def __str__(self):
    2.42 +        return str(self.errMsg)
    2.43 +
    2.44 +def getXendNetConfig():
    2.45 +    # Find out what environment we're in: bridge, nat, or route
    2.46 +    xconfig = os.getenv("XEND_CONFIG")
    2.47 +    if not xconfig:
    2.48 +        xconfig = "/etc/xen/xend-config.sxp"
    2.49 +
    2.50 +    configfile = open(xconfig, 'r')
    2.51 +    S = configfile.read()
    2.52 +    pin = Parser()
    2.53 +    pin.input(S)
    2.54 +    pin.input_eof()
    2.55 +    val = pin.get_val()
    2.56 +    while val[0] != 'network-script':
    2.57 +        val = pin.get_val()
    2.58 +
    2.59 +    if val[1] == "network-bridge":
    2.60 +        netenv = "bridge"
    2.61 +    elif val[1] == "network-route":
    2.62 +        netenv = "route"
    2.63 +    elif val[1] == "network-nat":
    2.64 +        netenv = "nat"
    2.65 +    else:
    2.66 +        raise NetworkError("Failed to get network env from xend config")
    2.67 +
    2.68 +    configfile.close()
    2.69 +    return netenv
    2.70 +
    2.71 +def checkZeroconfAddresses():
    2.72 +    # Make sure there aren't existing zeroconf addresses.
    2.73 +    rc, out = traceCommand("ip addr show |grep \"inet 169.254\" | grep -v vif")
    2.74 +    if rc == 0:
    2.75 +        raise NetworkError("Zeroconf addresses already used: %s" % out)
    2.76 +
    2.77 +class NetConfig:
    2.78 +
    2.79 +    def __init__(self):
    2.80 +        self.netenv = getXendNetConfig()
    2.81 +        self.used_ips = {}
    2.82 +        self.free_oct_ips = [ 0, 0, 0, 0 ]
    2.83 +        self.total_ips = 0
    2.84 +
    2.85 +        if NETWORK_IP_RANGE == 'dhcp':
    2.86 +            self.netmask = NETWORK_IP_RANGE
    2.87 +            self.network = NETWORK_IP_RANGE
    2.88 +            self.max_ip = NETWORK_IP_RANGE
    2.89 +            self.min_ip = NETWORK_IP_RANGE
    2.90 +        else:
    2.91 +            self.netmask = NETMASK
    2.92 +            self.network = NETWORK
    2.93 +	    s_ip = ''
    2.94 +
    2.95 +            # Get starting ip and max ip from configured ip range
    2.96 +            s_ip = NETWORK_IP_RANGE
    2.97 +            ips = s_ip.split("-")
    2.98 +            self.max_ip = ips[1]
    2.99 +            self.min_ip = ips[0]
   2.100 +
   2.101 +            self.__setMaxNumberIPs()
   2.102 +
   2.103 +            if self.network == "169.254.0.0":
   2.104 +                checkZeroconfAddresses()
   2.105 +
   2.106 +            # Clean out any aliases in the network range for vif0.0. If
   2.107 +            # an alias exists, a test xendevice add command could fail.
   2.108 +            if NETWORK_IP_RANGE != "dhcp":
   2.109 +                self.__cleanDom0Aliases()
   2.110 +
   2.111 +    def __setMaxNumberIPs(self):
   2.112 +        # Count the number of IPs available, to help tests know whether they
   2.113 +        # have enough to run or not
   2.114 +        masko = self.netmask.split('.')
   2.115 +        maxo = self.max_ip.split('.')
   2.116 +        mino = self.min_ip.split('.')
   2.117 +        ips = 0
   2.118 +
   2.119 +        # Last octet
   2.120 +        self.free_oct_ips[3] = (int(maxo[3]) - int(mino[3])) + 1
   2.121 +
   2.122 +        # 3rd octet
   2.123 +        self.free_oct_ips[2] = (int(maxo[2]) - int(mino[2])) + 1
   2.124 +
   2.125 +        # 2nd octet
   2.126 +        self.free_oct_ips[1] = (int(maxo[1]) - int(mino[1])) + 1
   2.127 +
   2.128 +        # 1st octet
   2.129 +        self.free_oct_ips[0] = (int(maxo[0]) - int(mino[0])) + 1
   2.130 +
   2.131 +        self.total_ips = self.free_oct_ips[3]
   2.132 +        if self.free_oct_ips[2] > 1:
   2.133 +            self.total_ips = (self.total_ips * self.free_oct_ips[2])
   2.134 +        if self.free_oct_ips[1] > 1:
   2.135 +            self.total_ips = (self.total_ips * self.free_oct_ips[1])
   2.136 +        if self.free_oct_ips[0] > 1:
   2.137 +            self.total_ips = (self.total_ips * self.free_oct_ips[0])
   2.138 +
   2.139 +    def __cleanDom0Aliases(self):
   2.140 +        # Remove any aliases within the supplied network IP range on dom0
   2.141 +        scmd = 'ip addr show dev vif0.0'
   2.142 +
   2.143 +        status, output = traceCommand(scmd)
   2.144 +        if status:
   2.145 +            raise NetworkError("Failed to show vif0.0 aliases: %d" % status)
   2.146 +
   2.147 +        lines = output.split("\n")
   2.148 +        for line in lines:
   2.149 +            ip = re.search('(\d+\.\d+\.\d+\.\d+)', line)
   2.150 +            if ip and self.isIPInRange(ip.group(1)) == True:
   2.151 +                dcmd = 'ip addr del %s dev vif0.0' % ip.group(1)
   2.152 +                dstatus, doutput = traceCommand(dcmd)
   2.153 +                if dstatus:
   2.154 +                    raise NetworkError("Failed to remove vif0.0 aliases: %d" % status)
   2.155 +                
   2.156 +    def getNetEnv(self):
   2.157 +        return self.netenv
   2.158 + 
   2.159 +    def setUsedIP(self, domname, interface, ip):
   2.160 +        self.used_ips['%s:%s' % (domname, interface)] = ip
   2.161 +
   2.162 +    def __findFirstOctetIP(self, prefix, min, max):
   2.163 +        for i in range(min, max):
   2.164 +            ip = '%s%s' % (prefix, str(i))
   2.165 +            found = False
   2.166 +            for k in self.used_ips.keys():
   2.167 +                if self.used_ips[k] == ip:
   2.168 +                    found = True
   2.169 +            if found == False:
   2.170 +                return ip
   2.171 +
   2.172 +        if found == True:
   2.173 +            return None
   2.174 +
   2.175 +    def getFreeIP(self, domname, interface):
   2.176 +        # Get a free IP. It uses the starting ip octets and then the 
   2.177 +        # total number of allowed numbers for that octet. It only
   2.178 +        # calculates ips for the last two octets, we shouldn't need more
   2.179 +        start_octets = self.min_ip.split(".")
   2.180 +        ip = None
   2.181 +
   2.182 +        # Only working with ips from last two octets, shouldn't need more
   2.183 +        max = int(start_octets[2]) + self.free_oct_ips[2]
   2.184 +        for i in range(int(start_octets[2]), max):
   2.185 +            prefix = '%s.%s.%s.' % (start_octets[0], start_octets[1], str(i))
   2.186 +            ip = self.__findFirstOctetIP(prefix, int(start_octets[3]), self.free_oct_ips[3])
   2.187 +            if ip:
   2.188 +                break
   2.189 +
   2.190 +        if not ip:
   2.191 +            raise NetworkError("Ran out of configured addresses.")
   2.192 +
   2.193 +        self.setUsedIP(domname, interface, ip)
   2.194 +        return ip
   2.195 +
   2.196 +    def getNetMask(self):
   2.197 +        return self.netmask
   2.198 +
   2.199 +    def getNetwork(self):
   2.200 +        return self.network
   2.201 +
   2.202 +    def getIP(self, domname, interface):
   2.203 +        # Depending on environment, set an IP. Uses the configured range
   2.204 +        # of IPs, network address, and netmask
   2.205 +        if NETWORK_IP_RANGE == "dhcp":
   2.206 +            return None
   2.207 +
   2.208 +        # Make sure domain and interface aren't already assigned an IP
   2.209 +        if self.used_ips.has_key('%s:%s' % (domname, interface)):
   2.210 +            raise NetworkError("Domain %s interface %s is already has IP"
   2.211 +                               % (domname, interface))
   2.212 +
   2.213 +        return self.getFreeIP(domname, interface)
   2.214 +
   2.215 +    def setIP(self, domname, interface, ip):
   2.216 +        # Make sure domain and interface aren't already assigned an IP
   2.217 +        if self.used_ips.has_key('%s:%s' % (domname, interface)):
   2.218 +            raise NetworkError("Domain %s interface %s is already has IP"
   2.219 +                               % (domname, interface))
   2.220 +
   2.221 +        self.setUsedIP(domname, interface, ip)
   2.222 +
   2.223 +    def releaseIP(self, domname, interface, ip):
   2.224 +        if self.used_ips.has_key('%s:%s' % (domname, interface)):
   2.225 +            del self.used_ips['%s:%s' % (domname, interface)]
   2.226 +
   2.227 +    def getNumberAllowedIPs(self):
   2.228 +        return self.total_ips
   2.229 +
   2.230 +    def canRunNetTest(self, ips):
   2.231 +        # Check to see if a test can run, returns true or false. Input is
   2.232 +        # number of ips needed.
   2.233 +        if NETWORK_IP_RANGE == "dhcp":
   2.234 +            return True
   2.235 +
   2.236 +        if self.total_ips >= ips:
   2.237 +            return True
   2.238 +
   2.239 +        return False
   2.240 +
   2.241 +    def isIPInRange(self, ip):
   2.242 +        # Checks to see if supplied ip is in the range of allowed ips
   2.243 +        maxo = self.max_ip.split('.')
   2.244 +        mino = self.min_ip.split('.')
   2.245 +        ipo = ip.split('.')
   2.246 +
   2.247 +        if int(ipo[0]) < int(mino[0]):
   2.248 +            return False
   2.249 +        elif int(ipo[0]) > int(maxo[0]):
   2.250 +            return False
   2.251 +
   2.252 +        if int(ipo[1]) < int(mino[1]):
   2.253 +            return False
   2.254 +        elif int(ipo[1]) > int(maxo[1]):
   2.255 +            return False
   2.256 +
   2.257 +        if int(ipo[2]) < int(mino[2]):
   2.258 +            return False
   2.259 +        elif int(ipo[2]) > int(maxo[2]):
   2.260 +            return False
   2.261 +
   2.262 +        if int(ipo[3]) < int(mino[3]):
   2.263 +            return False
   2.264 +        elif int(ipo[3]) > int(maxo[3]):
   2.265 +            return False
   2.266 +
   2.267 +        return True
     3.1 --- a/tools/xm-test/lib/XmTestLib/Network.py	Thu May 04 14:22:17 2006 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,110 +0,0 @@
     3.4 -#!/usr/bin/python
     3.5 -"""
     3.6 - Network.py - Common utilities for network tests
     3.7 -
     3.8 - Copyright (C) International Business Machines Corp., 2005
     3.9 - Author: Jim Dykman <dykman@us.ibm.com>
    3.10 -
    3.11 - This program is free software; you can redistribute it and/or modify
    3.12 - it under the terms of the GNU General Public License as published by
    3.13 - the Free Software Foundation; under version 2 of the License.
    3.14 -
    3.15 - This program is distributed in the hope that it will be useful,
    3.16 - but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.17 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.18 - GNU General Public License for more details.
    3.19 -
    3.20 - You should have received a copy of the GNU General Public License
    3.21 - along with this program; if not, write to the Free Software
    3.22 - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.23 -
    3.24 -"""
    3.25 -import sys;
    3.26 -import os;
    3.27 -import atexit;
    3.28 -import random;
    3.29 -
    3.30 -from Test import *
    3.31 -from Xm import *
    3.32 -from config import *
    3.33 -
    3.34 -class NetworkError(Exception):
    3.35 -    def __init__(self, msg):
    3.36 -        self.errMsg = msg
    3.37 -
    3.38 -    def __str__(self):
    3.39 -        return str(self.errMsg)
    3.40 -
    3.41 -def undo_dom0_alias(eth, ip):
    3.42 -    traceCommand("ip addr del " + ip + " dev " + eth)
    3.43 -
    3.44 -def net_from_ip(ip):
    3.45 -    return ip[:ip.rfind(".")] + ".0/24"
    3.46 -    
    3.47 -class XmNetwork:
    3.48 -
    3.49 -    def __init__(self):
    3.50 -        # Check for existing zeroconf address. We are using the zeroconf 
    3.51 -        # address range as static IP addresses.... if someone is using 
    3.52 -        # real zeroconf addresses, then we're going to skip tests to 
    3.53 -        # avoid interfering with them.
    3.54 -        rc, out = traceCommand(
    3.55 -                  "ip addr show |grep \"inet 169.254\" | grep -v vif")
    3.56 -
    3.57 -        if rc == 0:
    3.58 -            SKIP("Zeroconf address found: " + out)
    3.59 -
    3.60 -        # Randomize one octet of the IP addresses we choose, so that
    3.61 -        # multiple machines running network tests don't interfere 
    3.62 -        # with each other. 
    3.63 -        self.subnet = random.randint(1,254)
    3.64 -
    3.65 -    def calc_ip_address(self, dom, interface):
    3.66 -        # Generate an IP address from the dom# and eth#:
    3.67 -        #      169.254.(self.subnet).(eth#)*16 + (dom# + 1)
    3.68 -        ethnum = int(interface[len("eth"):])
    3.69 -        if (ethnum > 15):
    3.70 -            raise NetworkError("ethnum > 15 : " + interface)
    3.71 -        domnum = int(dom[len("dom"):])
    3.72 -        if (domnum > 14):
    3.73 -            raise NetworkError("domnum > 14 : " + dom)
    3.74 -
    3.75 -        return "169.254."+ str(self.subnet) + "." + str(ethnum*16+domnum+1)
    3.76 -
    3.77 -    def ip(self, dom, interface, todomname=None, toeth=None, bridge=None):
    3.78 -        newip = self.calc_ip_address(dom, interface)
    3.79 -
    3.80 -        # If the testcase is going to talk to dom0, we need to add an 
    3.81 -        # IP address in the proper subnet
    3.82 -        if dom == "dom0":
    3.83 -	    if ENABLE_HVM_SUPPORT:
    3.84 -	        # HVM uses ioemu which uses a bridge
    3.85 -		if not bridge:
    3.86 -		    SKIP("no bridge supplied")
    3.87 -		else:
    3.88 -		    vifname = bridge
    3.89 -	    else:
    3.90 -                # The domain's vif is a convenient place to add to
    3.91 -                vifname = "vif" + str(domid(todomname)) + "." + toeth[3:]
    3.92 -
    3.93 -            # register the exit handler FIRST, just in case
    3.94 -            atexit.register(undo_dom0_alias, vifname, newip)
    3.95 -
    3.96 -            # add the alias
    3.97 -            status, output = traceCommand("ip addr add " + newip + 
    3.98 -                                              " dev " + vifname)
    3.99 -            if status:
   3.100 -                SKIP("\"ip addr add\" failed")
   3.101 -
   3.102 -	    if ENABLE_HVM_SUPPORT:
   3.103 -	        # We need to add a route to the bridge device
   3.104 -		network = net_from_ip(newip)
   3.105 -		status, output = traceCommand("ip route add " + network + " dev " + vifname + " scope link")
   3.106 -
   3.107 -                if status:
   3.108 -		    SKIP("\"ip route add\" failed")
   3.109 -
   3.110 -        return newip
   3.111 -
   3.112 -    def mask(self, dom, interface):
   3.113 -        return "255.255.255.240"
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/xm-test/lib/XmTestLib/XenDevice.py	Thu May 04 14:22:29 2006 +0100
     4.3 @@ -0,0 +1,271 @@
     4.4 +#!/usr/bin/python
     4.5 +"""
     4.6 + Copyright (C) International Business Machines Corp., 2005, 2006
     4.7 + Authors: Dan Smith <danms@us.ibm.com>
     4.8 +          Daniel Stekloff <dsteklof@us.ibm.com>
     4.9 +
    4.10 + This program is free software; you can redistribute it and/or modify
    4.11 + it under the terms of the GNU General Public License as published by
    4.12 + the Free Software Foundation; under version 2 of the License.
    4.13 +
    4.14 + This program is distributed in the hope that it will be useful,
    4.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.17 + GNU General Public License for more details.
    4.18 +
    4.19 + You should have received a copy of the GNU General Public License
    4.20 + along with this program; if not, write to the Free Software
    4.21 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.22 +
    4.23 +"""
    4.24 +
    4.25 +import sys
    4.26 +import commands
    4.27 +import os
    4.28 +import re
    4.29 +import time
    4.30 +
    4.31 +from Xm import *
    4.32 +from Test import *
    4.33 +from config import *
    4.34 +from XenDomain import *
    4.35 +from NetConfig import *
    4.36 +from XmTestLib import *
    4.37 +from __init__ import *
    4.38 +
    4.39 +class XenNetDevCmd:
    4.40 +
    4.41 +    def __init__(self, netDevice, addCmd, removeCmd):
    4.42 +        """Object representing a network device command"""
    4.43 +        self.addcmd = addCmd
    4.44 +        self.removecmd = removeCmd
    4.45 +        self.addhasrun = False
    4.46 +        self.rmvhasrun = False
    4.47 +        self.netdevice = netDevice
    4.48 +
    4.49 +    def getAddCmd(self):
    4.50 +        return self.addcmd
    4.51 +
    4.52 +    def getRemoveCmd(self):
    4.53 +        return self.removecmd
    4.54 +
    4.55 +    def hasAddRun(self):
    4.56 +        return self.addhasrun
    4.57 +
    4.58 +    def hasRemoveRun(self):
    4.59 +        self.rmvhasrun
    4.60 +
    4.61 +    def runAddCmd(self, runOnDom0=False):
    4.62 +        # Defaults running command on dom0, if console then will run there
    4.63 +        if runOnDom0 == False:
    4.64 +            dom = self.netdevice.getDomain()
    4.65 +            console = dom.getConsole()
    4.66 +            console.runCmd(self.addcmd)
    4.67 +        else:
    4.68 +            status, output = traceCommand(self.addcmd)
    4.69 +            if status:
    4.70 +                raise NetworkError("Device add cmd failed: %s Status: %d"
    4.71 +                                   % (self.addcmd, status))
    4.72 +        self.addhasrun = True
    4.73 +
    4.74 +    def runRemoveCmd(self, runOnDom0=False):
    4.75 +        # Defaults running command on dom0, if console then will run there
    4.76 +        if runOnDom0 == False:
    4.77 +            dom = self.netdevice.getDomain()
    4.78 +            console = dom.getConsole()
    4.79 +            console.runCmd(self.removecmd)
    4.80 +        else:
    4.81 +            status, output = traceCommand(self.removecmd)
    4.82 +            if status:
    4.83 +                raise NetworkError("Device remove cmd failed: %s Status: %d"
    4.84 +                                   % (self.removecmd, status))
    4.85 +        self.removehasrun = True
    4.86 +
    4.87 +class XenDevice:
    4.88 +
    4.89 +    def __init__(self, domain, id, devConfig=None):
    4.90 +        """An object to represent Xen Devices like network and block
    4.91 +        @param domain: Domain the device will be added to
    4.92 +        @param id: Device identifier
    4.93 +        @param devConfig: Initial configuration dictionary for XenDevice
    4.94 +        """
    4.95 +        if config:
    4.96 +            self.config = devConfig
    4.97 +        else:
    4.98 +            self.config = {}
    4.99 +
   4.100 +        self.id = id
   4.101 +        self.domain = domain
   4.102 +        self.configNode = None
   4.103 +        # Commands run when domain is started or devices added and removed.
   4.104 +	self.dom0_cmds = []
   4.105 +	self.domU_cmds = []
   4.106 +
   4.107 +    def __str__(self):
   4.108 +        """Convert device config to XenConfig node compatible string"""
   4.109 +        confstr = ''
   4.110 +        for k, v in self.config.items():
   4.111 +            if len(confstr) > 0:
   4.112 +                confstr += ', '
   4.113 +            if isinstance(v, int):
   4.114 +                confstr += "%s=%i" % (k, v)
   4.115 +            elif isinstance(v, list) and v:
   4.116 +                confstr += "%s=%s" % (k, v)
   4.117 +            elif isinstance(v, str) and v:
   4.118 +                confstr += "%s=%s" % (k, v)
   4.119 +
   4.120 +        return confstr
   4.121 +
   4.122 +    def execAddCmds(self):
   4.123 +        # Cmds for when a device is added to the system
   4.124 +        if len(self.dom0_cmds) > 0:
   4.125 +            for i in range(0, len(self.dom0_cmds)):
   4.126 +                if self.dom0_cmds[i].getAddCmd():
   4.127 +                    self.dom0_cmds[i].runAddCmd(runOnDom0=True)
   4.128 +
   4.129 +        if len(self.domU_cmds) > 0:
   4.130 +            for i in range(0, len(self.domU_cmds)):
   4.131 +                if self.domU_cmds[i].getAddCmd():
   4.132 +                    self.domU_cmds[i].runAddCmd()
   4.133 +
   4.134 +    def execRemoveCmds(self):
   4.135 +        # Cmds for when a device is removed from the system
   4.136 +        if len(self.dom0_cmds) > 0:
   4.137 +            for i in range(0, len(self.dom0_cmds)):
   4.138 +                if (self.dom0_cmds[i].getRemoveCmd() 
   4.139 +                    and self.dom0_cmds[i].hasAddRun() == True):
   4.140 +                    self.dom0_cmds[i].runRemoveCmd(runOnDom0=True)
   4.141 +
   4.142 +        if len(self.domU_cmds) > 0:
   4.143 +            for i in range(0, len(self.domU_cmds)):
   4.144 +                if (self.domU_cmds[i].getRemoveCmd()
   4.145 +                    and self.domU_cmds[i].hasAddRun() == True):
   4.146 +                    self.domU_cmds[i].runRemoveCmd()
   4.147 +
   4.148 +    def removeDevice(self):
   4.149 +        self.execRemoveCmds()
   4.150 +
   4.151 +    def getId(self):
   4.152 +        return self.id
   4.153 +
   4.154 +    def getConfigOpt(self):
   4.155 +        return self.configNode
   4.156 +
   4.157 +    def getDomain(self):
   4.158 +        return self.domain
   4.159 +
   4.160 +class XenNetDevice(XenDevice):
   4.161 +
   4.162 +    def __init__(self, domain, id, devConfig=None):
   4.163 +        """An object to represent Xen Network Device
   4.164 +        @param domain: Domain the device is being added to
   4.165 +        @param id: Network device identifier, interface name like eth0
   4.166 +        @param devConfig: Initial dictionary configuration for XenNetDevice
   4.167 +        """
   4.168 +        if devConfig:
   4.169 +            self.config = devConfig
   4.170 +        else:
   4.171 +            self.config = {}
   4.172 +
   4.173 +        self.id = id
   4.174 +        self.domain = domain
   4.175 +        self.configNode = "vif"
   4.176 +        self.dom0_cmds = []
   4.177 +        self.domU_cmds = []
   4.178 +        self.network = None
   4.179 +        self.netmask = None
   4.180 +        self.ip = None
   4.181 +        self.dom0_alias_ip = None
   4.182 +
   4.183 +        if domain.getDomainType() == "HVM":
   4.184 +	    self.config["type"] = "ioemu"
   4.185 +            if not self.config.has_key('bridge'):
   4.186 +                self.config["bridge"] = "xenbr0"
   4.187 +
   4.188 +        if self.config.has_key("ip"):
   4.189 +            self.setNetDevIP(ip=self.config["ip"])
   4.190 +        else:
   4.191 +            if NETWORK_IP_RANGE != "dhcp":
   4.192 +                self.setNetDevIP()
   4.193 +
   4.194 +    def __del__(self):
   4.195 +        # Make sure we clean up NetConfig's list of ips, so the ip can be
   4.196 +        # reused
   4.197 +        self.releaseNetDevIP()
   4.198 +
   4.199 +    def addIfconfigCmd(self, domU=True):
   4.200 +        # Method to add start and remove ifconfig functions
   4.201 +        if domU == True:
   4.202 +            locmd = XenNetDevCmd(self, addCmd="ifconfig lo 127.0.0.1", removeCmd=None)
   4.203 +        ifcmd = []
   4.204 +
   4.205 +
   4.206 +        # Start or Add cmd
   4.207 +        acmd = 'ifconfig %s inet %s netmask %s up' % (self.id, self.ip, self.netmask)
   4.208 +        rcmd = 'ifconfig %s down' % self.id
   4.209 +        ifcmd = XenNetDevCmd(self, addCmd=acmd, removeCmd=rcmd)
   4.210 +
   4.211 +        if domU == True:
   4.212 +            self.domU_cmds.append(locmd) 
   4.213 +            self.domU_cmds.append(ifcmd) 
   4.214 +        else:
   4.215 +            self.dom0_cmds.append(ifcmd) 
   4.216 +
   4.217 +    def removeDevice(self):
   4.218 +        self.releaseNetDevIP()
   4.219 +
   4.220 +    def addDom0AliasCmd(self, dev="vif0.0"):
   4.221 +        # Method to add start and remove dom0 alias cmds
   4.222 +        acmd = 'ip addr add %s dev %s' % (self.dom0_alias_ip, dev)
   4.223 +        rcmd = 'ip addr del %s dev %s' % (self.dom0_alias_ip, dev) 
   4.224 +        aliascmd = XenNetDevCmd(self, addCmd=acmd, removeCmd=rcmd)
   4.225 +
   4.226 +        self.dom0_cmds.append(aliascmd)
   4.227 +
   4.228 +    def releaseNetDevIP(self):
   4.229 +        # Must remove start cmds for ip configuration and then release from
   4.230 +        # NetConfig
   4.231 +        self.execRemoveCmds()
   4.232 +        self.dom0_cmds = []
   4.233 +        self.domU_cmds = []
   4.234 +        if self.config.has_key("ip"):
   4.235 +            del self.config["ip"]
   4.236 +
   4.237 +        if self.dom0_alias_ip:
   4.238 +                xmtest_netconf.releaseIP("domain0", self.domain.getName(), self.dom0_alias_ip)
   4.239 +        xmtest_netconf.releaseIP(self.domain.getName(), self.id, self.ip)
   4.240 +
   4.241 +    def getNetDevIP(self):
   4.242 +        return self.ip
   4.243 +
   4.244 +    def getDom0AliasIP(self):
   4.245 +        return self.dom0_alias_ip
   4.246 +
   4.247 +    def getNetwork(self):
   4.248 +        return self.network
   4.249 +
   4.250 +    def setNetDevIP(self, ip=None):
   4.251 +        # Function to set a new IP for NetDevice.
   4.252 +        if NETWORK_IP_RANGE == "dhcp":
   4.253 +            raise NetworkError("System configured for dhcp, cannot set new ip.")
   4.254 +
   4.255 +        if (self.ip and not ip) or ((self.ip and ip) and (self.ip != ip)): 
   4.256 +            self.releaseNetDevIP()
   4.257 +
   4.258 +	if not self.netmask:
   4.259 +            self.netmask = xmtest_netconf.getNetMask()
   4.260 +
   4.261 +        if not self.network:
   4.262 +            self.network = xmtest_netconf.getNetwork()
   4.263 +
   4.264 +        if ip:
   4.265 +            xmtest_netconf.setIP(self.domain.getName(), self.id, ip)
   4.266 +            self.ip = ip
   4.267 +        else:
   4.268 +            self.ip = xmtest_netconf.getIP(self.domain.getName(), self.id)
   4.269 +
   4.270 +        self.addIfconfigCmd()
   4.271 +
   4.272 +        # Setup an alias for Dom0
   4.273 +        self.dom0_alias_ip = xmtest_netconf.getIP("domain0", self.domain.getName())
   4.274 +        self.addDom0AliasCmd()
     5.1 --- a/tools/xm-test/lib/XmTestLib/XenDomain.py	Thu May 04 14:22:17 2006 +0100
     5.2 +++ b/tools/xm-test/lib/XmTestLib/XenDomain.py	Thu May 04 14:22:29 2006 +0100
     5.3 @@ -28,6 +28,7 @@ from Xm import *
     5.4  from Test import *
     5.5  from config import *
     5.6  from Console import *
     5.7 +from XenDevice import *
     5.8  
     5.9  BLOCK_ROOT_DEV = "hda"
    5.10  
    5.11 @@ -195,6 +196,8 @@ class XenDomain:
    5.12  
    5.13          self.config = config
    5.14          self.console = None
    5.15 +        self.devices = {}
    5.16 +        self.netEnv = "bridge"
    5.17  
    5.18          # Set domain type, either PV for ParaVirt domU or HVM for 
    5.19          # FullVirt domain
    5.20 @@ -216,6 +219,10 @@ class XenDomain:
    5.21          if self.getDomainType() == "HVM":
    5.22              waitForBoot()
    5.23  
    5.24 +        # Go through device list and run console cmds
    5.25 +        for dev in self.devices.keys():
    5.26 +            self.devices[dev].execAddCmds()
    5.27 +
    5.28          if self.console and noConsole == True:
    5.29              self.closeConsole()
    5.30  
    5.31 @@ -229,6 +236,8 @@ class XenDomain:
    5.32          prog = "xm"
    5.33          cmd = " shutdown "
    5.34  
    5.35 +        self.removeAllDevices()
    5.36 +
    5.37          if self.console:
    5.38              self.closeConsole()
    5.39  
    5.40 @@ -240,6 +249,8 @@ class XenDomain:
    5.41          prog = "xm"
    5.42          cmd = " destroy "
    5.43  
    5.44 +        self.removeAllDevices()
    5.45 +
    5.46          if self.console:
    5.47              self.closeConsole()
    5.48  
    5.49 @@ -274,6 +285,50 @@ class XenDomain:
    5.50  
    5.51          return self.console
    5.52  
    5.53 +    def newDevice(self, Device, *args):
    5.54 +        """Device Factory: Generic factory for creating new XenDevices.
    5.55 +           All device creation should be done through the XenDomain
    5.56 +           factory. Supply a XenDevice instance and its args and the
    5.57 +           constructor will be called."""
    5.58 +        # Make sure device with id hasn't already been added
    5.59 +        if self.devices.has_key(args[0]):
    5.60 +            raise DeviceError("Error: Domain already has device %s" % args[0])
    5.61 +
    5.62 +        # Call constructor for supplied Device instance
    5.63 +        dargs = (self,)
    5.64 +        dargs += args
    5.65 +        dev = apply(Device, dargs)
    5.66 +
    5.67 +        if self.isRunning():
    5.68 +            # Note: This needs to be done, XenDevice should have an attach
    5.69 +            #       method.
    5.70 +            print "Domain is running, need to attach new device to domain."
    5.71 +
    5.72 +        self.devices[dev.id] = dev
    5.73 +        self.config.appOpt(dev.configNode, str(dev))
    5.74 +        return dev
    5.75 +
    5.76 +    def removeDevice(self, id):
    5.77 +        if self.devices.has_key(id):
    5.78 +            self.devices[id].removeDevice()
    5.79 +
    5.80 +    def removeAllDevices(self):
    5.81 +        for k in self.devices.keys():
    5.82 +            self.removeDevice(k)
    5.83 +
    5.84 +    def isRunning(self):
    5.85 +        return isDomainRunning(self.name)
    5.86 +
    5.87 +    def getNetEnv(self):
    5.88 +        # We need to know the network environment: bridge, NAT, or routed.
    5.89 +        return self.netEnv
    5.90 +
    5.91 +    def getDevice(self, id):
    5.92 +        dev = self.devices[id]
    5.93 +        if dev:
    5.94 +            return dev
    5.95 +        print "Device %s not found for domain %s" % (id, self.getName())
    5.96 +
    5.97  
    5.98  class XmTestDomain(XenDomain):
    5.99  
   5.100 @@ -298,6 +353,30 @@ class XmTestDomain(XenDomain):
   5.101      def minSafeMem(self):
   5.102          return 32
   5.103  
   5.104 +class XmTestNetDomain(XmTestDomain):
   5.105 +
   5.106 +    def __init__(self, name=None, extraConfig=None, baseConfig=configDefaults):
   5.107 +        """Create a new xm-test domain with one network device
   5.108 +        @param name: The requested domain name
   5.109 +        @param extraConfig: Additional configuration options
   5.110 +        @param baseConfig: The initial configuration defaults to use
   5.111 +        """
   5.112 +        config = XenConfig()
   5.113 +        config.setOpts(baseConfig)
   5.114 +        if extraConfig:
   5.115 +            config.setOpts(extraConfig)
   5.116 +
   5.117 +        if name:
   5.118 +            config.setOpt("name", name)
   5.119 +        elif not config.getOpt("name"):
   5.120 +            config.setOpt("name", getUniqueName())
   5.121 +
   5.122 +        XenDomain.__init__(self, config.getOpt("name"), config=config)
   5.123 +
   5.124 +        # Add one network devices to domain
   5.125 +        self.newDevice(XenNetDevice, "eth0")
   5.126 +
   5.127 +
   5.128  if __name__ == "__main__":
   5.129  
   5.130      c = XenConfig()
     6.1 --- a/tools/xm-test/lib/XmTestLib/__init__.py	Thu May 04 14:22:17 2006 +0100
     6.2 +++ b/tools/xm-test/lib/XmTestLib/__init__.py	Thu May 04 14:22:29 2006 +0100
     6.3 @@ -4,11 +4,15 @@
     6.4  #
     6.5  
     6.6  from Console import *
     6.7 -from Network import *
     6.8  from Test import *
     6.9  from Xm import *
    6.10  from XenDomain import *
    6.11  from config import *
    6.12 +from XenDevice import *
    6.13 +from NetConfig import *
    6.14 +
    6.15 +# Make sure xen modules are in path
    6.16 +sys.path.append('/usr/lib/python')
    6.17  
    6.18  # Give this test a clean slate
    6.19  destroyAllDomUs();
    6.20 @@ -18,6 +22,8 @@ if os.environ.get("TEST_VERBOSE"):
    6.21  else:
    6.22      verbose = False
    6.23  
    6.24 -
    6.25  if verbose:
    6.26      timeStamp()
    6.27 +
    6.28 +# We need to track network configuration, like ips, etc.
    6.29 +xmtest_netconf = NetConfig()
     7.1 --- a/tools/xm-test/lib/XmTestLib/config.py.in	Thu May 04 14:22:17 2006 +0100
     7.2 +++ b/tools/xm-test/lib/XmTestLib/config.py.in	Thu May 04 14:22:29 2006 +0100
     7.3 @@ -1,4 +1,6 @@
     7.4  #!/usr/bin/python
     7.5  
     7.6  ENABLE_HVM_SUPPORT = @ENABLE_HVM@
     7.7 -
     7.8 +NETWORK_IP_RANGE = "@NET_IP_RANGE@"
     7.9 +NETWORK = "@NETWORK_ADDRESS@"
    7.10 +NETMASK = "@NETMASK@"
     8.1 --- a/tools/xm-test/tests/create/13_create_multinic_pos.py	Thu May 04 14:22:17 2006 +0100
     8.2 +++ b/tools/xm-test/tests/create/13_create_multinic_pos.py	Thu May 04 14:22:29 2006 +0100
     8.3 @@ -5,17 +5,14 @@
     8.4  
     8.5  from XmTestLib import *
     8.6  
     8.7 -# The current device model, qemu-dm, only supports 8 MAX_NICS currently.
     8.8 +# The device model, qemu-dm, only supports 8 MAX_NICS currently.
     8.9  if ENABLE_HVM_SUPPORT:
    8.10      MAX_NICS = 8
    8.11 -    nic = "type=ioemu, bridge=xenbr0"
    8.12  else:
    8.13      MAX_NICS = 10
    8.14 -    nic = ''
    8.15  
    8.16  for i in range(0,MAX_NICS):
    8.17 -    config = {"vif": [ nic ] * i}
    8.18 -    domain = XmTestDomain(extraConfig=config)
    8.19 +    domain = XmTestNetDomain()
    8.20  
    8.21      try:
    8.22          console = domain.start()
     9.1 --- a/tools/xm-test/tests/network/02_network_local_ping_pos.py	Thu May 04 14:22:17 2006 +0100
     9.2 +++ b/tools/xm-test/tests/network/02_network_local_ping_pos.py	Thu May 04 14:22:29 2006 +0100
     9.3 @@ -16,24 +16,17 @@
     9.4  pingsizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
     9.5                32767, 65507 ]
     9.6  
     9.7 -
     9.8 -
     9.9  from XmTestLib import *
    9.10  rc = 0
    9.11  
    9.12 -Net = XmNetwork()
    9.13 -
    9.14 -# read an IP address from the config
    9.15 -ip   = Net.ip("dom1", "eth0")
    9.16 -mask = Net.mask("dom1", "eth0")
    9.17 +# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
    9.18 +# aliases on dom0
    9.19 +if xmtest_netconf.canRunNetTest(2) == False:
    9.20 +    SKIP("Don't have enough free configured IPs to run this test")
    9.21  
    9.22 -# Fire up a guest domain w/1 nic
    9.23 -if ENABLE_HVM_SUPPORT:
    9.24 -    config = {"vif" : ['type=ioemu']}
    9.25 -else:
    9.26 -    config = {"vif" : ['ip=%s' % ip ]}
    9.27 +domain = XmTestDomain()
    9.28 +domain.newDevice(XenNetDevice, "eth0")
    9.29  
    9.30 -domain = XmTestDomain(extraConfig=config)
    9.31  try:
    9.32      console = domain.start()
    9.33  except DomainError, e:
    9.34 @@ -43,10 +36,7 @@ except DomainError, e:
    9.35      FAIL(str(e))
    9.36  
    9.37  try:
    9.38 -    # Bring up the "lo" interface.
    9.39 -    console.runCmd("ifconfig lo 127.0.0.1")
    9.40 -
    9.41 -    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
    9.42 +    console.setHistorySaveCmds(value=True)
    9.43  
    9.44      # First the loopback pings
    9.45      lofails=""
    9.46 @@ -57,6 +47,8 @@ try:
    9.47  
    9.48      # Next comes eth0
    9.49      eth0fails=""
    9.50 +    netdev = domain.getDevice("eth0")
    9.51 +    ip = netdev.getNetDevIP()
    9.52      for size in pingsizes:
    9.53          out = console.runCmd("ping -q -c 1 -s " + str(size) + " " + ip)
    9.54          if out["return"]:
    9.55 @@ -66,6 +58,7 @@ except ConsoleError, e:
    9.56  except NetworkError, e:
    9.57          FAIL(str(e))
    9.58  
    9.59 +domain.stop()
    9.60  
    9.61  # Tally up failures
    9.62  failures=""
    10.1 --- a/tools/xm-test/tests/network/03_network_local_tcp_pos.py	Thu May 04 14:22:17 2006 +0100
    10.2 +++ b/tools/xm-test/tests/network/03_network_local_tcp_pos.py	Thu May 04 14:22:29 2006 +0100
    10.3 @@ -17,28 +17,18 @@
    10.4  trysizes = [ 1, 48, 64, 512, 1440, 1448, 1500, 1505, 4096, 4192, 
    10.5                32767, 65495 ]
    10.6  
    10.7 -
    10.8  from XmTestLib import *
    10.9  rc = 0
   10.10  
   10.11 -Net = XmNetwork()
   10.12 -
   10.13 -try:
   10.14 -    # read an IP address from the config
   10.15 -    ip   = Net.ip("dom1", "eth0")
   10.16 -    mask = Net.mask("dom1", "eth0")
   10.17 -except NetworkError, e:
   10.18 -    FAIL(str(e))
   10.19 +# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
   10.20 +# aliases on dom0
   10.21 +if xmtest_netconf.canRunNetTest(2) == False:
   10.22 +    SKIP("Don't have enough free configured IPs to run this test")
   10.23  
   10.24  # Fire up a guest domain w/1 nic
   10.25 -if ENABLE_HVM_SUPPORT:
   10.26 -    brg = "xenbr0"
   10.27 -    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
   10.28 -else:
   10.29 -    brg = None
   10.30 -    config = {"vif" : ['ip=%s' % ip]}
   10.31 +domain = XmTestDomain()
   10.32 +domain.newDevice(XenNetDevice, "eth0")
   10.33  
   10.34 -domain = XmTestDomain(extraConfig=config)
   10.35  try:
   10.36      console = domain.start()
   10.37  except DomainError, e:
   10.38 @@ -48,10 +38,7 @@ except DomainError, e:
   10.39      FAIL(str(e))
   10.40  
   10.41  try:
   10.42 -    # Bring up the "lo" interface.
   10.43 -    console.runCmd("ifconfig lo 127.0.0.1")
   10.44 -
   10.45 -    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
   10.46 +    console.setHistorySaveCmds(value=True)
   10.47  
   10.48      # First do loopback 
   10.49      lofails=""
   10.50 @@ -63,6 +50,8 @@ try:
   10.51  
   10.52      # Next comes eth0
   10.53      eth0fails=""
   10.54 +    netdev = domain.getDevice("eth0")
   10.55 +    ip = netdev.getNetDevIP()
   10.56      for size in trysizes:
   10.57          out = console.runCmd("hping2 " + ip + " -E /dev/urandom -q -c 20 "
   10.58                + "--fast -d "+ str(size))
   10.59 @@ -73,6 +62,7 @@ except ConsoleError, e:
   10.60  except NetworkError, e:
   10.61          FAIL(str(e))
   10.62  
   10.63 +domain.stop()
   10.64  
   10.65  # Tally up failures
   10.66  failures=""
    11.1 --- a/tools/xm-test/tests/network/04_network_local_udp_pos.py	Thu May 04 14:22:17 2006 +0100
    11.2 +++ b/tools/xm-test/tests/network/04_network_local_udp_pos.py	Thu May 04 14:22:29 2006 +0100
    11.3 @@ -20,24 +20,14 @@ trysizes = [ 1, 48, 64, 512, 1440, 1448,
    11.4  from XmTestLib import *
    11.5  rc = 0
    11.6  
    11.7 -Net = XmNetwork()
    11.8 -
    11.9 -try:
   11.10 -    # read an IP address from the config
   11.11 -    ip   = Net.ip("dom1", "eth0")
   11.12 -    mask = Net.mask("dom1", "eth0")
   11.13 -except NetworkError, e:
   11.14 -    FAIL(str(e))
   11.15 +# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
   11.16 +# aliases on dom0
   11.17 +if xmtest_netconf.canRunNetTest(2) == False:
   11.18 +    SKIP("Don't have enough free configured IPs to run this test")
   11.19  
   11.20 -# Fire up a guest domain w/1 nic
   11.21 -if ENABLE_HVM_SUPPORT:
   11.22 -    brg = "xenbr0"
   11.23 -    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
   11.24 -else:
   11.25 -    brg = None
   11.26 -    config = {"vif" : ['ip=%s' % ip]}
   11.27 +domain = XmTestDomain()
   11.28 +domain.newDevice(XenNetDevice, "eth0")
   11.29  
   11.30 -domain = XmTestDomain(extraConfig=config)
   11.31  try:
   11.32      console = domain.start()
   11.33  except DomainError, e:
   11.34 @@ -47,10 +37,7 @@ except DomainError, e:
   11.35      FAIL(str(e))
   11.36  
   11.37  try:
   11.38 -    # Bring up the "lo" interface.
   11.39 -    console.runCmd("ifconfig lo 127.0.0.1")
   11.40 -
   11.41 -    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
   11.42 +    console.setHistorySaveCmds(value=True)
   11.43  
   11.44      # First do loopback 
   11.45      lofails=""
   11.46 @@ -63,6 +50,8 @@ try:
   11.47  
   11.48      # Next comes eth0
   11.49      eth0fails=""
   11.50 +    netdev = domain.getDevice("eth0")
   11.51 +    ip = netdev.getNetDevIP()
   11.52      for size in trysizes:
   11.53          out = console.runCmd("hping2 " + ip + " -E /dev/urandom -2 -q -c 20 "
   11.54                + "--fast -d " + str(size))
   11.55 @@ -74,6 +63,7 @@ except ConsoleError, e:
   11.56  except NetworkError, e:
   11.57          FAIL(str(e))
   11.58  
   11.59 +domain.stop()
   11.60  
   11.61  # Tally up failures
   11.62  failures=""
    12.1 --- a/tools/xm-test/tests/network/05_network_dom0_ping_pos.py	Thu May 04 14:22:17 2006 +0100
    12.2 +++ b/tools/xm-test/tests/network/05_network_dom0_ping_pos.py	Thu May 04 14:22:29 2006 +0100
    12.3 @@ -16,29 +16,18 @@
    12.4  pingsizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
    12.5                  32767, 65507 ]
    12.6  
    12.7 -
    12.8 -
    12.9  from XmTestLib import *
   12.10  rc = 0
   12.11  
   12.12 -Net = XmNetwork()
   12.13 -
   12.14 -try:
   12.15 -    # read an IP address from the config
   12.16 -    ip     = Net.ip("dom1", "eth0")
   12.17 -    mask   = Net.mask("dom1", "eth0")
   12.18 -except NetworkError, e:
   12.19 -        FAIL(str(e))
   12.20 +# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
   12.21 +# aliases on dom0
   12.22 +if xmtest_netconf.canRunNetTest(2) == False:
   12.23 +    SKIP("Don't have enough free configured IPs to run this test")
   12.24  
   12.25  # Fire up a guest domain w/1 nic
   12.26 -if ENABLE_HVM_SUPPORT:
   12.27 -    brg = "xenbr0"
   12.28 -    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
   12.29 -else:
   12.30 -    config = {"vif" : ['ip=%s' % ip ]}
   12.31 -    brg = None
   12.32 +domain = XmTestDomain()
   12.33 +domain.newDevice(XenNetDevice, "eth0")
   12.34  
   12.35 -domain = XmTestDomain(extraConfig=config)
   12.36  try:
   12.37      console = domain.start()
   12.38  except DomainError, e:
   12.39 @@ -48,16 +37,10 @@ except DomainError, e:
   12.40      FAIL(str(e))
   12.41  
   12.42  try:
   12.43 -    # Add a suitable dom0 IP address 
   12.44 -    dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", bridge=brg)
   12.45 -except NetworkError, e:
   12.46 -        FAIL(str(e))
   12.47 -
   12.48 -try:
   12.49 -    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
   12.50 -
   12.51      # Ping dom0
   12.52      fails=""
   12.53 +    netdev = domain.getDevice("eth0")
   12.54 +    dom0ip = netdev.getDom0AliasIP()
   12.55      for size in pingsizes:
   12.56          out = console.runCmd("ping -q -c 1 -s " + str(size) + " " + dom0ip)
   12.57          if out["return"]:
   12.58 @@ -65,6 +48,7 @@ try:
   12.59  except ConsoleError, e:
   12.60          FAIL(str(e))
   12.61  
   12.62 +domain.stop()
   12.63 +
   12.64  if len(fails):
   12.65      FAIL("Ping to dom0 failed for size" + fails + ".")
   12.66 -
    13.1 --- a/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py	Thu May 04 14:22:17 2006 +0100
    13.2 +++ b/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py	Thu May 04 14:22:29 2006 +0100
    13.3 @@ -16,31 +16,21 @@
    13.4  trysizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
    13.5                  32767, 65495 ]
    13.6  
    13.7 -
    13.8 -
    13.9  from XmTestLib import *
   13.10  rc = 0
   13.11  
   13.12 -Net = XmNetwork()
   13.13 -
   13.14 -try:
   13.15 -    # read an IP address from the config
   13.16 -    ip     = Net.ip("dom1", "eth0")
   13.17 -    mask   = Net.mask("dom1", "eth0")
   13.18 -except NetworkError, e:
   13.19 -        FAIL(str(e))
   13.20 +# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
   13.21 +# aliases on dom0
   13.22 +if xmtest_netconf.canRunNetTest(2) == False:
   13.23 +    SKIP("Don't have enough free configured IPs to run this test")
   13.24  
   13.25  # Fire up a guest domain w/1 nic
   13.26 -if ENABLE_HVM_SUPPORT:
   13.27 -    brg = "xenbr0"
   13.28 -    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
   13.29 -else:
   13.30 -    brg = None
   13.31 -    config = {"vif"  : ["ip=%s" % ip]}
   13.32 +domain = XmTestDomain()
   13.33 +domain.newDevice(XenNetDevice, "eth0")
   13.34  
   13.35 -domain = XmTestDomain(extraConfig=config)
   13.36  try:
   13.37      console = domain.start()
   13.38 +    console.setHistorySaveCmds(value=True)
   13.39  except DomainError, e:
   13.40      if verbose:
   13.41          print "Failed to create test domain because:"
   13.42 @@ -48,16 +38,10 @@ except DomainError, e:
   13.43      FAIL(str(e))
   13.44  
   13.45  try:
   13.46 -    # Add a suitable dom0 IP address 
   13.47 -    dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", bridge=brg)
   13.48 -except NetworkError, e:
   13.49 -        FAIL(str(e))
   13.50 -
   13.51 -try:
   13.52 -    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
   13.53 -
   13.54      # Ping dom0
   13.55      fails=""
   13.56 +    netdev = domain.getDevice("eth0")
   13.57 +    dom0ip = netdev.getDom0AliasIP()
   13.58      for size in trysizes:
   13.59          out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -q -c 20 "
   13.60                + "--fast -d " + str(size))
   13.61 @@ -67,6 +51,7 @@ try:
   13.62  except ConsoleError, e:
   13.63          FAIL(str(e))
   13.64  
   13.65 +domain.stop()
   13.66 +
   13.67  if len(fails):
   13.68      FAIL("TCP hping2 to dom0 failed for size" + fails + ".")
   13.69 -
    14.1 --- a/tools/xm-test/tests/network/07_network_dom0_udp_pos.py	Thu May 04 14:22:17 2006 +0100
    14.2 +++ b/tools/xm-test/tests/network/07_network_dom0_udp_pos.py	Thu May 04 14:22:29 2006 +0100
    14.3 @@ -16,29 +16,18 @@
    14.4  trysizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
    14.5                  32767, 65495 ]
    14.6  
    14.7 -
    14.8 -
    14.9  from XmTestLib import *
   14.10  rc = 0
   14.11  
   14.12 -Net = XmNetwork()
   14.13 -
   14.14 -try:
   14.15 -    # read an IP address from the config
   14.16 -    ip     = Net.ip("dom1", "eth0")
   14.17 -    mask   = Net.mask("dom1", "eth0")
   14.18 -except NetworkError, e:
   14.19 -        FAIL(str(e))
   14.20 +# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
   14.21 +# aliases on dom0
   14.22 +if xmtest_netconf.canRunNetTest(2) == False:
   14.23 +    SKIP("Don't have enough free configured IPs to run this test")
   14.24  
   14.25  # Fire up a guest domain w/1 nic
   14.26 -if ENABLE_HVM_SUPPORT:
   14.27 -    brg = "xenbr0"
   14.28 -    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
   14.29 -else:
   14.30 -    brg = None
   14.31 -    config = {"vif"  : ["ip=%s" % ip]}
   14.32 +domain = XmTestDomain()
   14.33 +domain.newDevice(XenNetDevice, "eth0")
   14.34  
   14.35 -domain = XmTestDomain(extraConfig=config)
   14.36  try:
   14.37      console = domain.start()
   14.38  except DomainError, e:
   14.39 @@ -48,16 +37,10 @@ except DomainError, e:
   14.40      FAIL(str(e))
   14.41  
   14.42  try:
   14.43 -    # Add a suitable dom0 IP address 
   14.44 -    dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", bridge=brg)
   14.45 -except NetworkError, e:
   14.46 -        FAIL(str(e))
   14.47 -
   14.48 -try:
   14.49 -    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
   14.50 -
   14.51      # Ping dom0
   14.52      fails=""
   14.53 +    netdev = domain.getDevice("eth0")
   14.54 +    dom0ip = netdev.getDom0AliasIP()
   14.55      for size in trysizes:
   14.56          out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -2 -q -c 20"
   14.57               + " --fast -d " + str(size))
   14.58 @@ -67,6 +50,7 @@ try:
   14.59  except ConsoleError, e:
   14.60          FAIL(str(e))
   14.61  
   14.62 +domain.stop()
   14.63 +
   14.64  if len(fails):
   14.65      FAIL("UDP hping2 to dom0 failed for size" + fails + ".")
   14.66 -
    15.1 --- a/tools/xm-test/tests/network/11_network_domU_ping_pos.py	Thu May 04 14:22:17 2006 +0100
    15.2 +++ b/tools/xm-test/tests/network/11_network_domU_ping_pos.py	Thu May 04 14:22:29 2006 +0100
    15.3 @@ -17,50 +17,37 @@ pingsizes = [ 1, 48, 64, 512, 1440, 1500
    15.4  
    15.5  from XmTestLib import *
    15.6  
    15.7 -def netDomain(ip):
    15.8 -    if ENABLE_HVM_SUPPORT:
    15.9 -        config = {"vif" : ['type=ioemu']}
   15.10 -    else:
   15.11 -        config = {"vif" : ['ip=%s' % ip ]}
   15.12 +def netDomain():
   15.13  
   15.14 -    dom = XmTestDomain(extraConfig=config)
   15.15 +    dom = XmTestDomain()
   15.16 +    dom.newDevice(XenNetDevice, "eth0")
   15.17      try:
   15.18          console = dom.start()
   15.19 +        console.setHistorySaveCmds(value=True)
   15.20      except DomainError, e:
   15.21          if verbose:
   15.22              print "Failed to create test domain because:"
   15.23              print e.extra
   15.24          FAIL(str(e))
   15.25 -    return console
   15.26 +    return dom
   15.27      
   15.28  rc = 0
   15.29  
   15.30 -Net = XmNetwork()
   15.31 +# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
   15.32 +# aliases on dom0
   15.33 +if xmtest_netconf.canRunNetTest(4) == False:
   15.34 +    SKIP("Don't have enough free configured IPs to run this test")
   15.35  
   15.36 -try:
   15.37 -    # pick an IP address 
   15.38 -    ip1   = Net.ip("dom1", "eth2")
   15.39 -    mask1 = Net.mask("dom1", "eth2")
   15.40 -except NetworkError, e:
   15.41 -    FAIL(str(e))
   15.42 +# Fire up a pair of guest domains w/1 nic each
   15.43 +pinger = netDomain()
   15.44 +pinger_console = pinger.getConsole()
   15.45 +victim = netDomain()
   15.46  
   15.47  try:
   15.48 -    # pick another IP address 
   15.49 -    ip2   = Net.ip("dom2", "eth2")
   15.50 -    mask2 = Net.mask("dom2", "eth2")
   15.51 -except NetworkError, e:
   15.52 -    FAIL(str(e))
   15.53 -
   15.54 -# Fire up a pair of guest domains w/1 nic each
   15.55 -pinger_console = netDomain(ip1)
   15.56 -victim_console = netDomain(ip2)
   15.57 -
   15.58 -try:
   15.59 -    pinger_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
   15.60 -    victim_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
   15.61 -
   15.62      # Ping the victim over eth0
   15.63      fails=""
   15.64 +    v_netdev = victim.getDevice("eth0")
   15.65 +    ip2 = v_netdev.getNetDevIP()
   15.66      for size in pingsizes:
   15.67          out = pinger_console.runCmd("ping -q -c 1 -s " + str(size) + " " + ip2)
   15.68          if out["return"]:
   15.69 @@ -68,6 +55,8 @@ try:
   15.70  except ConsoleError, e:
   15.71      FAIL(str(e))
   15.72  
   15.73 +pinger.stop()
   15.74 +victim.stop()
   15.75 +
   15.76  if len(fails):
   15.77      FAIL("Ping failed for size" + fails + ".")
   15.78 -
    16.1 --- a/tools/xm-test/tests/network/12_network_domU_tcp_pos.py	Thu May 04 14:22:17 2006 +0100
    16.2 +++ b/tools/xm-test/tests/network/12_network_domU_tcp_pos.py	Thu May 04 14:22:29 2006 +0100
    16.3 @@ -17,50 +17,37 @@ pingsizes = [ 1, 48, 64, 512, 1440, 1500
    16.4  
    16.5  from XmTestLib import *
    16.6  
    16.7 -def netDomain(ip):
    16.8 -    if ENABLE_HVM_SUPPORT:
    16.9 -        config = {"vif" : ['type=ioemu']}
   16.10 -    else:
   16.11 -        config = {"vif"  : ["ip=%s" % ip]}
   16.12 +def netDomain():
   16.13  
   16.14 -    dom = XmTestDomain(extraConfig=config)
   16.15 +    dom = XmTestDomain()
   16.16 +    dom.newDevice(XenNetDevice, "eth0")
   16.17      try:
   16.18          console = dom.start()
   16.19 +        console.setHistorySaveCmds(value=True)
   16.20      except DomainError, e:
   16.21          if verbose:
   16.22              print "Failed to create test domain because:"
   16.23              print e.extra
   16.24          FAIL(str(e))
   16.25 -    return console
   16.26 +    return dom
   16.27      
   16.28  rc = 0
   16.29  
   16.30 -Net = XmNetwork()
   16.31 +# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
   16.32 +# aliases on dom0
   16.33 +if xmtest_netconf.canRunNetTest(4) == False:
   16.34 +    SKIP("Don't have enough free configured IPs to run this test")
   16.35  
   16.36 -try:
   16.37 -    # pick an IP address 
   16.38 -    ip1   = Net.ip("dom1", "eth2")
   16.39 -    mask1 = Net.mask("dom1", "eth2")
   16.40 -except NetworkError, e:
   16.41 -    FAIL(str(e))
   16.42 +# Fire up a pair of guest domains w/1 nic each
   16.43 +src = netDomain()
   16.44 +src_console = src.getConsole()
   16.45 +dst = netDomain()
   16.46  
   16.47  try:
   16.48 -    # pick another IP address 
   16.49 -    ip2   = Net.ip("dom2", "eth2")
   16.50 -    mask2 = Net.mask("dom2", "eth2")
   16.51 -except NetworkError, e:
   16.52 -    FAIL(str(e))
   16.53 -
   16.54 -# Fire up a pair of guest domains w/1 nic each
   16.55 -src_console = netDomain(ip1)
   16.56 -dst_console = netDomain(ip2)
   16.57 -
   16.58 -try:
   16.59 -    src_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
   16.60 -    dst_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
   16.61 -
   16.62      # Ping the victim over eth0
   16.63      fails=""
   16.64 +    dst_netdev = dst.getDevice("eth0")
   16.65 +    ip2 = dst_netdev.getNetDevIP()
   16.66      for size in pingsizes:
   16.67          out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -q -c 20 "
   16.68                + "--fast -d " + str(size))
   16.69 @@ -70,6 +57,8 @@ try:
   16.70  except ConsoleError, e:
   16.71      FAIL(str(e))
   16.72  
   16.73 +src.stop()
   16.74 +dst.stop()
   16.75 +
   16.76  if len(fails):
   16.77      FAIL("TCP hping2 failed for size" + fails + ".")
   16.78 -
    17.1 --- a/tools/xm-test/tests/network/13_network_domU_udp_pos.py	Thu May 04 14:22:17 2006 +0100
    17.2 +++ b/tools/xm-test/tests/network/13_network_domU_udp_pos.py	Thu May 04 14:22:29 2006 +0100
    17.3 @@ -17,50 +17,37 @@ pingsizes = [ 1, 48, 64, 512, 1440, 1500
    17.4  
    17.5  from XmTestLib import *
    17.6  
    17.7 -def netDomain(ip):
    17.8 -    if ENABLE_HVM_SUPPORT:
    17.9 -        config = {"vif" : ['type=ioemu']}
   17.10 -    else:
   17.11 -        config = {"vif"  : ["ip=%s" % ip]}
   17.12 +def netDomain():
   17.13  
   17.14 -    dom = XmTestDomain(extraConfig=config)
   17.15 +    dom = XmTestDomain()
   17.16 +    dom.newDevice(XenNetDevice, "eth0")
   17.17      try:
   17.18          console = dom.start()
   17.19 +        console.setHistorySaveCmds(value=True)
   17.20      except DomainError, e:
   17.21          if verbose:
   17.22              print "Failed to create test domain because:"
   17.23              print e.extra
   17.24          FAIL(str(e))
   17.25 -    return console
   17.26 +    return dom
   17.27      
   17.28  rc = 0
   17.29  
   17.30 -Net = XmNetwork()
   17.31 +# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
   17.32 +# aliases on dom0
   17.33 +if xmtest_netconf.canRunNetTest(4) == False:
   17.34 +    SKIP("Don't have enough free configured IPs to run this test")
   17.35  
   17.36 -try:
   17.37 -    # pick an IP address 
   17.38 -    ip1   = Net.ip("dom1", "eth2")
   17.39 -    mask1 = Net.mask("dom1", "eth2")
   17.40 -except NetworkError, e:
   17.41 -    FAIL(str(e))
   17.42 +# Fire up a pair of guest domains w/1 nic each
   17.43 +src = netDomain()
   17.44 +src_console = src.getConsole()
   17.45 +dst = netDomain()
   17.46  
   17.47  try:
   17.48 -    # pick another IP address 
   17.49 -    ip2   = Net.ip("dom2", "eth2")
   17.50 -    mask2 = Net.mask("dom2", "eth2")
   17.51 -except NetworkError, e:
   17.52 -    FAIL(str(e))
   17.53 -
   17.54 -# Fire up a pair of guest domains w/1 nic each
   17.55 -src_console = netDomain(ip1)
   17.56 -dst_console = netDomain(ip2)
   17.57 -
   17.58 -try:
   17.59 -    src_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
   17.60 -    dst_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
   17.61 -
   17.62      # Ping the victim over eth0
   17.63      fails=""
   17.64 +    dst_netdev = dst.getDevice("eth0")
   17.65 +    ip2 = dst_netdev.getNetDevIP()
   17.66      for size in pingsizes:
   17.67          out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -2 -q "
   17.68                + "-c 20 --fast -d " + str(size))
   17.69 @@ -70,6 +57,8 @@ try:
   17.70  except ConsoleError, e:
   17.71      FAIL(str(e))
   17.72  
   17.73 +src.stop()
   17.74 +dst.stop()
   17.75 +
   17.76  if len(fails):
   17.77      FAIL("UDP hping2 failed for size" + fails + ".")
   17.78 -