From: Alina Quereilhac Date: Mon, 12 Nov 2012 17:39:47 +0000 (+0100) Subject: Unit tests for linux_node.py X-Git-Tag: nepi-3.0.0~122^2~38 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=98d5e132b2f38082409d525b58f80bf4e72c1f01;p=nepi.git Unit tests for linux_node.py --- diff --git a/src/neco/resources/base/linux_node.py b/src/neco/resources/base/linux_node.py index e0ec18b6..b763b953 100644 --- a/src/neco/resources/base/linux_node.py +++ b/src/neco/resources/base/linux_node.py @@ -36,60 +36,31 @@ class LinuxNode(Resource): out = self.execute("cat /etc/issue") if out.find("Fedora") == 0: - self._pm = "yum -y " + self._pm = "yum" elif out.find("Debian") == 0 or out.find("Ubuntu") ==0: - self._pm = "apt-get -y " + self._pm = "apt-get" else: msg = "Can't resolve package management system. Unknown OS." self._logger.error(msg) raise RuntimeError(msg) return self._pm - - def execute(self, command, - agent = True, - sudo = False, - stdin = "", - tty = False, - timeout = None, - retry = 0, - err_on_timeout = True, - connect_timeout = 30, - persistent = True): - """ Notice that this invocation will block until the - execution finishes. If this is not the desired behavior, - use 'run' instead.""" - (out, err), proc = eintr_retry(rexec)( - command, - self.host or self.ip, - self.user, - port = self.port, - agent = agent, - sudo = sudo, - stdin = stdin, - identity_file = self.identity_file, - tty = tty, - timeout = timeout, - retry = retry, - err_on_timeout = err_on_timeout, - connect_timeout = connect_timeout, - persistent = persistent) - if proc.wait(): - msg = "Failed to execute command %s at node %s: %s %s" % \ - (command, self.host or self.ip, out, err,) - self._logger.warn(msg) - raise RuntimeError(msg) + def install(self, packages): + if not isinstance(packages, list): + packages = [packages] - return out + for p in packages: + self.execute("%s -y install %s" % (self.pm, p), sudo = True, + tty = True) - def package_install(self, dependencies): - if not isinstance(dependencies, list): - dependencies = [dependencies] + def uninstall(self, packages): + if not isinstance(packages, list): + packages = [packages] - for d in dependencies: - self.execute("%s install %s" % (self.pm, d), sudo = True, - tty2 = True) + for p in packages: + self.execute("%s -y remove %s" % (self.pm, p), sudo = True, + tty = True) def upload(self, src, dst): if not os.path.isfile(src): @@ -130,11 +101,7 @@ class LinuxNode(Resource): def mkdir(self, path, clean = True): if clean: - self.execute( - "rm -rf %s" % path, - timeout = 120, - retry = 3 - ) + self.rmdir(path) self.execute( "mkdir -p %s" % path, @@ -142,6 +109,50 @@ class LinuxNode(Resource): retry = 3 ) + def rmdir(self, path): + self.execute( + "rm -rf %s" % path, + timeout = 120, + retry = 3 + ) + + def execute(self, command, + agent = True, + sudo = False, + stdin = "", + tty = False, + timeout = None, + retry = 0, + err_on_timeout = True, + connect_timeout = 30, + persistent = True): + """ Notice that this invocation will block until the + execution finishes. If this is not the desired behavior, + use 'run' instead.""" + (out, err), proc = eintr_retry(rexec)( + command, + self.host or self.ip, + self.user, + port = self.port, + agent = agent, + sudo = sudo, + stdin = stdin, + identity_file = self.identity_file, + tty = tty, + timeout = timeout, + retry = retry, + err_on_timeout = err_on_timeout, + connect_timeout = connect_timeout, + persistent = persistent) + + if proc.wait(): + msg = "Failed to execute command %s at node %s: %s %s" % \ + (command, self.host or self.ip, out, err,) + self._logger.warn(msg) + raise RuntimeError(msg) + + return out + def run(self, command, home, stdin = None, stdout = 'stdout', diff --git a/src/neco/util/sshfuncs.py b/src/neco/util/sshfuncs.py index 347056f2..872143dc 100644 --- a/src/neco/util/sshfuncs.py +++ b/src/neco/util/sshfuncs.py @@ -118,7 +118,6 @@ def rexec(command, host, user, stdin = "", identity_file = None, tty = False, - tty2 = False, timeout = None, retry = 0, err_on_timeout = True, @@ -153,9 +152,9 @@ def rexec(command, host, user, args.extend(('-i', identity_file)) if tty: args.append('-t') - elif tty2: - args.append('-t') - args.append('-t') + if sudo: + args.append('-t') + if sudo: command = "sudo " + command args.append(command) @@ -582,10 +581,7 @@ def rkill(pid, ppid, Nothing, should have killed the process """ - if sudo: - subkill = "$(ps --ppid %(pid)d -o pid h)" % { 'pid' : pid } - else: - subkill = "" + subkill = "$(ps --ppid %(pid)d -o pid h)" % { 'pid' : pid } cmd = """ SUBKILL="%(subkill)s" ; %(sudo)s kill -- -%(pid)d $SUBKILL || /bin/true diff --git a/test/resources/base/linux_node.py b/test/resources/base/linux_node.py new file mode 100644 index 00000000..159c9f4f --- /dev/null +++ b/test/resources/base/linux_node.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +from neco.resources.base.linux_node import LinuxNode +from neco.design.box import Box +from neco.util.sshfuncs import RUNNING, FINISHED + +import os.path +import time +import unittest + +class DummyEC(object): + pass + +class LinuxBoxTestCase(unittest.TestCase): + def test_execute(self): + box = Box() + ec = DummyEC() + + node = LinuxNode(box, ec) + node.host = 'nepi2.pl.sophia.inria.fr' + node.user = 'inria_nepi' + + self.assertEquals(node.pm, "yum") + self.assertTrue(node.is_alive()) + + command = "ping -qc3 nepi5.pl.sophia.inria.fr" + out = node.execute(command) + + expected = """3 packets transmitted, 3 received, 0% packet loss""" + + self.assertTrue(out.find(expected) > 0) + + def test_run(self): + box = Box() + ec = DummyEC() + + node = LinuxNode(box, ec) + node.host = 'nepi2.pl.sophia.inria.fr' + node.user = 'inria_nepi' + + home = '${HOME}/test-app' + node.mkdir(home, clean = True) + + command = "ping nepi5.pl.sophia.inria.fr" + dst = os.path.join(home, "app.sh") + node.upload(command, dst) + + cmd = "bash ./app.sh" + node.run(cmd, home) + pid, ppid = node.checkpid(home) + + status = node.status(pid, ppid) + self.assertTrue(status, RUNNING) + + node.kill(pid, ppid) + status = node.status(pid, ppid) + self.assertTrue(status, FINISHED) + + node.rmdir(home) + + def test_install(self): + box = Box() + ec = DummyEC() + + node = LinuxNode(box, ec) + node.host = 'nepi2.pl.sophia.inria.fr' + node.user = 'inria_nepi' + + self.assertEquals(node.pm, "yum") + self.assertTrue(node.is_alive()) + + home = '${HOME}/test-app' + node.mkdir(home, clean = True) + + prog = """#include + +int +main (void) +{ + printf ("Hello, world!\\n"); + return 0; +} +""" + dst = os.path.join(home, "hello.c") + node.upload(prog, dst) + + node.install('gcc') + + command = "cd ${HOME}/test-app; gcc -Wall hello.c -o hello" + out = node.execute(command) + + command = "${HOME}/test-app/hello" + out = node.execute(command) + + self.assertEquals(out, "Hello, world!\n") + + node.uninstall('gcc') + node.rmdir(home) + +if __name__ == '__main__': + unittest.main() + diff --git a/test/util/plot.py b/test/util/plot.py index 6c20da6b..20ae5110 100755 --- a/test/util/plot.py +++ b/test/util/plot.py @@ -8,6 +8,8 @@ import unittest class BoxPlotTestCase(unittest.TestCase): def xtest_plot(self): + """ XXX: This test is interactive, it will open an evince instance, + so it should not run automatically """ node1 = Box(label="node1") ping1 = Box(label="ping") mobility1 = Box(label="mob1")