Petr Benas has uploaded a new change for review.

Change subject: <tests>: Add NetworkTest.testAddDelNetworkDhcp
......................................................................

<tests>: Add NetworkTest.testAddDelNetworkDhcp

Tests adding and deletion of network with dynamically
assigned address. The dhcp package is required for this
test, otherwise the test is skipped.

Change-Id: I9dbb59f3cd420b2071eb0ec42f9816ab52151bce
Signed-off-by: Petr Benas <pbe...@redhat.com>
---
M lib/vdsm/config.py.in
M tests/functional/Makefile.am
A tests/functional/dhcpd.py
M tests/functional/networkTests.py
A tests/functional/veth.py
M tests/testValidation.py
6 files changed, 190 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/13/21113/1

diff --git a/lib/vdsm/config.py.in b/lib/vdsm/config.py.in
index c0bdd53..dee435c 100644
--- a/lib/vdsm/config.py.in
+++ b/lib/vdsm/config.py.in
@@ -38,7 +38,7 @@
         ('extra_mem_reserve', '65',
             'Memory reserved for non-vds-administered programs.'),
 
-        ('fake_nics', 'dummy_*',
+        ('fake_nics', 'dummy_*,veth_*',
             'Comma-separated list of fnmatch-patterns for dummy hosts nics to '
             'be shown to vdsm.'),
 
diff --git a/tests/functional/Makefile.am b/tests/functional/Makefile.am
index 3d23e89..1c97feb 100644
--- a/tests/functional/Makefile.am
+++ b/tests/functional/Makefile.am
@@ -29,6 +29,8 @@
        utils.py \
        virtTests.py \
        storageTests.py \
+       veth.py \
+       dhcpd.py \
        $(NULL)
 
 dist_vdsmfunctests_DATA = \
diff --git a/tests/functional/dhcpd.py b/tests/functional/dhcpd.py
new file mode 100644
index 0000000..f00cd98
--- /dev/null
+++ b/tests/functional/dhcpd.py
@@ -0,0 +1,62 @@
+# Copyright 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import tempfile
+import os
+
+from nose.plugins.skip import SkipTest
+
+from vdsm.utils import CommandPath
+from vdsm.utils import execCmd
+
+_DHCPD_BINARY = CommandPath('dhcpd', '/sbin/dhcpd')
+
+dhcpdConfig = '''# minimalistic dhcpd configuration file
+authoritative;
+
+subnet 240.0.0.0 netmask 255.255.255.0 {
+   range 240.0.0.10 240.0.0.100;
+}
+'''
+
+
+class Dhcpd():
+    def __init__(self):
+        self.configDir = ''
+        self.proc = ''
+
+    def start(self, interface):
+        self._checkDhcpdInstalled()
+        self._writeConfigFile()
+        self.proc = execCmd([_DHCPD_BINARY.cmd, '-f', '-cf', self.configDir +
+                             '/dhcpd.conf', interface], sync=False)
+
+    def stop(self):
+        self.proc.kill()
+        execCmd(['rm', '-rf', self.configDir])
+
+    def _writeConfigFile(self):
+        self.configDir = tempfile.mkdtemp()
+        f = open(self.configDir + '/dhcpd.conf', 'w')
+        f.write(dhcpdConfig)
+        f.close()
+
+    def _checkDhcpdInstalled(self):
+        if not os.path.exists('/sbin/dhcpd'):
+            raise SkipTest('Dhcpd does not seem to be installed')
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index 4b3a53f..3cbaaaf 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -26,9 +26,12 @@
 from hookValidation import ValidatesHook
 from testrunner import (VdsmTestCase as TestCaseBase,
                         expandPermutations, permutations)
-from testValidation import RequireDummyMod, ValidateRunningAsRoot
+from testValidation import (RequireDummyMod, RequireVethMod,
+                            ValidateRunningAsRoot)
 
 import dummy
+import veth
+import dhcpd
 from utils import SUCCESS, VdsProxy, cleanupRules
 
 from vdsm.ipwrapper import (ruleAdd, ruleDel, routeAdd, routeDel, routeExists,
@@ -1494,3 +1497,33 @@
                     delete = {network: {'remove': True}}
                     status, msg = self.vdsm_net.setupNetworks(delete, {}, {})
                     self.assertEqual(status, SUCCESS, msg)
+
+    @cleanupNet
+    @permutations([[True], [False]])
+    @RequireVethMod
+    @ValidateRunningAsRoot
+    def testAddDelNetworkDhcp(self, bridged):
+        (right, left) = veth.create()
+        veth.setIP(right, IP_ADDRESS, IP_CIDR)
+        veth.setLinkUp(right)
+
+        dhcpServer = dhcpd.Dhcpd()
+        dhcpServer.start(right)
+
+        nics = [left]
+        status, msg = self.vdsm_net.addNetwork(NETWORK_NAME,
+                                               nics=nics,
+                                               opts={'bridged': bridged,
+                                                     'bootproto': 'dhcp'})
+        self.assertEqual(status, SUCCESS, msg)
+        self.assertNetworkExists(NETWORK_NAME)
+
+        status, msg = self.vdsm_net.delNetwork(NETWORK_NAME,
+                                               nics=nics,
+                                               opts={'bridged': bridged,
+                                                     'bootproto': 'dhcp'})
+        self.assertEqual(status, SUCCESS, msg)
+        self.assertNetworkDoesntExist(NETWORK_NAME)
+
+        dhcpServer.stop()
+        veth.remove(right)
diff --git a/tests/functional/veth.py b/tests/functional/veth.py
new file mode 100644
index 0000000..dbe233a
--- /dev/null
+++ b/tests/functional/veth.py
@@ -0,0 +1,77 @@
+#
+# Copyright 2013 Red Hat, Inc.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+import random
+
+from nose.plugins.skip import SkipTest
+
+from vdsm.ipwrapper import linkAdd, linkDel, addrAdd, linkSet, IPRoute2Error
+
+
+def create():
+    """
+    Creates a veth interface with a pseudo-random name for both endpoints (e.g.
+    veth_85 and veth_31 in the format veth_Number). Assumes root privileges.
+    """
+
+    deviceNumbers = random.sample(range(100), 2)
+    rightPoint = 'veth_%s' % deviceNumbers[0]
+    leftPoint = 'veth_%s' % deviceNumbers[1]
+    try:
+        linkAdd(rightPoint, linkType='veth', args=('peer', 'name', leftPoint))
+    except IPRoute2Error:
+        pass
+    else:
+        return (rightPoint, leftPoint)
+
+    raise SkipTest('Failed to create a veth interface')
+
+
+def remove(vethName):
+    """
+    Removes veth interface vethName. The pair device is removed automatically.
+    Assumes root privileges.
+    """
+
+    try:
+        linkDel(vethName)
+    except IPRoute2Error as e:
+        raise SkipTest("Unable to delete veth interface %s because %s" %
+                       (vethName, e))
+
+
+def setIP(vethName, ipaddr, netmask):
+    try:
+        addrAdd(vethName, ipaddr, netmask)
+    except IPRoute2Error:
+        raise SkipTest('Failed to set device ip')
+
+
+def setLinkUp(vethName):
+    _setLinkState(vethName, 'up')
+
+
+def setLinkDown(vethName):
+    _setLinkState(vethName, 'down')
+
+
+def _setLinkState(vethName, state):
+    try:
+        linkSet(vethName, [state])
+    except IPRoute2Error:
+        raise SkipTest('Failed to bring %s to state %s' % (vethName, state))
diff --git a/tests/testValidation.py b/tests/testValidation.py
index d370971..dbe5c8e 100644
--- a/tests/testValidation.py
+++ b/tests/testValidation.py
@@ -115,6 +115,20 @@
     return wrapper
 
 
+def RequireVethMod(f):
+    """
+    Assumes root privileges to be used after
+    ValidateRunningAsRoot decoration.
+    """
+    @wraps(f)
+    def wrapper(*args, **kwargs):
+        if not os.path.exists('/sys/module/veth'):
+            cmd_modprobe = [modprobe.cmd, "veth"]
+            rc, out, err = utils.execCmd(cmd_modprobe, sudo=True)
+        return f(*args, **kwargs)
+    return wrapper
+
+
 def slowtest(f):
     @wraps(f)
     def wrapper(*args, **kwargs):


-- 
To view, visit http://gerrit.ovirt.org/21113
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9dbb59f3cd420b2071eb0ec42f9816ab52151bce
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Petr Benas <pbe...@redhat.com>
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to