Fix #128 - [NS3] Test ns-3 with localhost
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Tue, 18 Feb 2014 16:51:41 +0000 (17:51 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Tue, 18 Feb 2014 16:51:41 +0000 (17:51 +0100)
src/nepi/resources/linux/ccn/ccnd.py
src/nepi/resources/linux/ccn/ccnr.py
src/nepi/resources/linux/node.py
src/nepi/resources/linux/ns3/ns3simulation.py
src/nepi/resources/ns3/ns3application.py
src/nepi/util/execfuncs.py
src/nepi/util/sshfuncs.py
test/resources/linux/ns3/ns3simulation.py

index 95ac92f..ffaee50 100644 (file)
@@ -194,8 +194,7 @@ class LinuxCCND(LinuxApplication):
         self.node.run_and_wait(command, self.run_home,
                 shfile = shfile,
                 overwrite = False,
         self.node.run_and_wait(command, self.run_home,
                 shfile = shfile,
                 overwrite = False,
-                env = env,
-                raise_on_error = True)
+                env = env)
 
     def do_start(self):
         if self.state == ResourceState.READY:
 
     def do_start(self):
         if self.state == ResourceState.READY:
index 69a8437..9ac5cce 100644 (file)
@@ -247,8 +247,7 @@ class LinuxCCNR(LinuxApplication):
         self.node.run_and_wait(command, self.run_home,
                 shfile = shfile,
                 overwrite = False,
         self.node.run_and_wait(command, self.run_home,
                 shfile = shfile,
                 overwrite = False,
-                env = env,
-                raise_on_error = True)
+                env = env)
 
     def do_start(self):
         if self.state == ResourceState.READY:
 
     def do_start(self):
         if self.state == ResourceState.READY:
index f9ae091..214c4ef 100644 (file)
@@ -274,7 +274,8 @@ class LinuxNode(ResourceManager):
         if self._os:
             return self._os
 
         if self._os:
             return self._os
 
-        if (not self.get("hostname") or not self.get("username")):
+        if self.get("hostname") not in ["localhost", "127.0.0.1"] and \
+                not self.get("username"):
             msg = "Can't resolve OS, insufficient data "
             self.error(msg)
             raise RuntimeError, msg
             msg = "Can't resolve OS, insufficient data "
             self.error(msg)
             raise RuntimeError, msg
@@ -400,6 +401,9 @@ class LinuxNode(ResourceManager):
     def clean_processes(self):
         self.info("Cleaning up processes")
  
     def clean_processes(self):
         self.info("Cleaning up processes")
  
+        if self.get("hostname") in ["localhost", "127.0.0.2"]:
+            return 
+        
         if self.get("username") != 'root':
             cmd = ("sudo -S killall tcpdump || /bin/true ; " +
                 "sudo -S kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; " +
         if self.get("username") != 'root':
             cmd = ("sudo -S killall tcpdump || /bin/true ; " +
                 "sudo -S kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; " +
@@ -424,7 +428,6 @@ class LinuxNode(ResourceManager):
                 cmd = ("killall tcpdump || /bin/true ; " +
                     "kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; ")
 
                 cmd = ("killall tcpdump || /bin/true ; " +
                     "kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; ")
 
-        out = err = ""
         (out, err), proc = self.execute(cmd, retry = 1, with_lock = True)
 
     def clean_home(self):
         (out, err), proc = self.execute(cmd, retry = 1, with_lock = True)
 
     def clean_home(self):
@@ -534,14 +537,13 @@ class LinuxNode(ResourceManager):
         self.debug("Running command '%s'" % command)
         
         if self.localhost:
         self.debug("Running command '%s'" % command)
         
         if self.localhost:
-            (out, err), proc = execfuncs.lspawn(command, pidfile, 
-                    stdout = stdout, 
-                    stderr = stderr, 
-                    stdin = stdin, 
+            (out, err), proc = execfuncs.lspawn(command, pidfile,
                     home = home, 
                     create_home = create_home, 
                     home = home, 
                     create_home = create_home, 
-                    sudo = sudo,
-                    user = user) 
+                    stdin = stdin or '/dev/null',
+                    stdout = stdout or '/dev/null',
+                    stderr = stderr or '/dev/null',
+                    sudo = sudo) 
         else:
             with self._node_lock:
                 (out, err), proc = sshfuncs.rspawn(
         else:
             with self._node_lock:
                 (out, err), proc = sshfuncs.rspawn(
@@ -549,9 +551,9 @@ class LinuxNode(ResourceManager):
                     pidfile = pidfile,
                     home = home,
                     create_home = create_home,
                     pidfile = pidfile,
                     home = home,
                     create_home = create_home,
-                    stdin = stdin if stdin is not None else '/dev/null',
-                    stdout = stdout if stdout else '/dev/null',
-                    stderr = stderr if stderr else '/dev/null',
+                    stdin = stdin or '/dev/null',
+                    stdout = stdout or '/dev/null',
+                    stderr = stderr or '/dev/null',
                     sudo = sudo,
                     host = self.get("hostname"),
                     user = self.get("username"),
                     sudo = sudo,
                     host = self.get("hostname"),
                     user = self.get("username"),
@@ -631,9 +633,8 @@ class LinuxNode(ResourceManager):
 
     def copy(self, src, dst):
         if self.localhost:
 
     def copy(self, src, dst):
         if self.localhost:
-            (out, err), proc = execfuncs.lcopy(source, dest, 
-                    recursive = True,
-                    strict_host_checking = False)
+            (out, err), proc = execfuncs.lcopy(src, dst, 
+                    recursive = True)
         else:
             with self._node_lock:
                 (out, err), proc = sshfuncs.rcopy(
         else:
             with self._node_lock:
                 (out, err), proc = sshfuncs.rcopy(
@@ -648,7 +649,8 @@ class LinuxNode(ResourceManager):
 
         return (out, err), proc
 
 
         return (out, err), proc
 
-    def upload(self, src, dst, text = False, overwrite = True):
+    def upload(self, src, dst, text = False, overwrite = True,
+            raise_on_error = True):
         """ Copy content to destination
 
         src  string with the content to copy. Can be:
         """ Copy content to destination
 
         src  string with the content to copy. Can be:
@@ -687,19 +689,36 @@ class LinuxNode(ResourceManager):
             # Build destination as <user>@<server>:<path>
             dst = "%s@%s:%s" % (self.get("username"), self.get("hostname"), dst)
 
             # Build destination as <user>@<server>:<path>
             dst = "%s@%s:%s" % (self.get("username"), self.get("hostname"), dst)
 
-        result = self.copy(src, dst)
+        ((out, err), proc) = self.copy(src, dst)
 
         # clean up temp file
         if f:
             os.remove(f.name)
 
 
         # clean up temp file
         if f:
             os.remove(f.name)
 
-        return result
+        if err:
+            msg = " Failed to upload files - src: %s dst: %s" %  (";".join(src), dst) 
+            self.error(msg, out, err)
+
+            if raise_on_error:
+                raise RuntimeError, msg
 
 
-    def download(self, src, dst):
+        return ((out, err), proc)
+
+    def download(self, src, dst, raise_on_error = True):
         if not self.localhost:
             # Build destination as <user>@<server>:<path>
             src = "%s@%s:%s" % (self.get("username"), self.get("hostname"), src)
         if not self.localhost:
             # Build destination as <user>@<server>:<path>
             src = "%s@%s:%s" % (self.get("username"), self.get("hostname"), src)
-        return self.copy(src, dst)
+
+        ((out, err), proc) = self.copy(src, dst)
+
+        if err:
+            msg = " Failed to download files - src: %s dst: %s" %  (";".join(src), dst) 
+            self.error(msg, out, err)
+
+            if raise_on_error:
+                raise RuntimeError, msg
+
+        return ((out, err), proc)
 
     def install_packages_command(self, packages):
         command = ""
 
     def install_packages_command(self, packages):
         command = ""
@@ -714,7 +733,8 @@ class LinuxNode(ResourceManager):
 
         return command
 
 
         return command
 
-    def install_packages(self, packages, home, run_home = None):
+    def install_packages(self, packages, home, run_home = None,
+            raise_on_error = True):
         """ Install packages in the Linux host.
 
         'home' is the directory to upload the package installation script.
         """ Install packages in the Linux host.
 
         'home' is the directory to upload the package installation script.
@@ -731,11 +751,12 @@ class LinuxNode(ResourceManager):
             stdout = "instpkg_stdout", 
             stderr = "instpkg_stderr",
             overwrite = False,
             stdout = "instpkg_stdout", 
             stderr = "instpkg_stderr",
             overwrite = False,
-            raise_on_error = True)
+            raise_on_error = raise_on_error)
 
         return (out, err), proc 
 
 
         return (out, err), proc 
 
-    def remove_packages(self, packages, home, run_home = None):
+    def remove_packages(self, packages, home, run_home = None,
+            raise_on_error = True):
         """ Uninstall packages from the Linux host.
 
         'home' is the directory to upload the package un-installation script.
         """ Uninstall packages from the Linux host.
 
         'home' is the directory to upload the package un-installation script.
@@ -759,7 +780,7 @@ class LinuxNode(ResourceManager):
             stdout = "rmpkg_stdout", 
             stderr = "rmpkg_stderr",
             overwrite = False,
             stdout = "rmpkg_stdout", 
             stderr = "rmpkg_stderr",
             overwrite = False,
-            raise_on_error = True)
+            raise_on_error = raise_on_error)
          
         return (out, err), proc 
 
          
         return (out, err), proc 
 
@@ -783,7 +804,7 @@ class LinuxNode(ResourceManager):
             stderr = "stderr", 
             sudo = False,
             tty = False,
             stderr = "stderr", 
             sudo = False,
             tty = False,
-            raise_on_error = False):
+            raise_on_error = True):
         """
         Uploads the 'command' to a bash script in the host.
         Then runs the script detached in background in the host, and
         """
         Uploads the 'command' to a bash script in the host.
         Then runs the script detached in background in the host, and
index a7780b0..9ce8291 100644 (file)
@@ -376,6 +376,7 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
                 "     ( "
                 "       tar xf ${SRC}/%(pygccxml_version)s.tar.gz -C ${SRC} && "
                 "       cd ${SRC}/%(pygccxml_version)s && "
                 "     ( "
                 "       tar xf ${SRC}/%(pygccxml_version)s.tar.gz -C ${SRC} && "
                 "       cd ${SRC}/%(pygccxml_version)s && "
+                "       python setup.py build && "
                 "       sudo -S python setup.py install "
                 "     ) "
                 "   ) " 
                 "       sudo -S python setup.py install "
                 "     ) "
                 "   ) " 
index db6096b..302e128 100644 (file)
@@ -62,6 +62,7 @@ class NS3BaseApplication(NS3Base):
             self.ec.schedule(reschedule_delay, self.start)
         else:
             super(NS3BaseApplication, self).do_start()
             self.ec.schedule(reschedule_delay, self.start)
         else:
             super(NS3BaseApplication, self).do_start()
+            self._start_time = self.simulation.start_time
 
     @property
     def state(self):
 
     @property
     def state(self):
index d2da3ac..c998038 100644 (file)
 #
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
 #
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
-from nepi.util.sshfuncs import ProcStatus, STDOUT
+from nepi.util.sshfuncs import ProcStatus, STDOUT, log, shell_escape
 
 
+import logging
+import shlex
 import subprocess
 
 def lexec(command, 
 import subprocess
 
 def lexec(command, 
@@ -39,12 +41,21 @@ def lexec(command,
     elif user:
         command = "su %s ; %s " % (user, command)
 
     elif user:
         command = "su %s ; %s " % (user, command)
 
+    proc = subprocess.Popen(command,
+                shell = True, 
+                stdout = subprocess.PIPE, 
+                stderr = subprocess.PIPE)
 
 
-    proc = subprocess.Popen(command, shell=True, 
-            stdout = subprocess.PIPE, 
-            stderr = subprocess.PIPE)
+    out = err = ""
+    log_msg = "lexec - command %s " % command
+
+    try:
+        out, err = proc.communicate()
+        log(log_msg, logging.DEBUG, out, err)
+    except:
+        log(log_msg, logging.ERROR, out, err)
+        raise
 
 
-    out, err = proc.communicate()
     return ((out, err), proc)
 
 def lcopy(source, dest, recursive = False):
     return ((out, err), proc)
 
 def lcopy(source, dest, recursive = False):
@@ -52,28 +63,35 @@ def lcopy(source, dest, recursive = False):
     Copies from/to localy.
     """
     
     Copies from/to localy.
     """
     
-    if TRACE:
-        print "scp", source, dest
-    
-    command = ["cp"]
+    args = ["cp"]
     if recursive:
     if recursive:
-        command.append("-R")
+        args.append("-r")
   
   
-    if isinstance(dest, str):
-        dest = dest.split(";")
-
-    if isinstance(src, str):
-        src = src.split(";")
-           
-    args.extend(src)
+    if isinstance(source, list):
+        args.extend(source)
+    else:
+        args.append(source)
 
 
-    args.extend(dest)
+    if isinstance(dest, list):
+        args.extend(dest)
+    else:
+        args.append(dest)
 
 
-    proc = subprocess.Popen(command
+    proc = subprocess.Popen(args
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE)
 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE)
 
-    out, err = proc.communicate()
+    out = err = ""
+    command = " ".join(args)
+    log_msg = " lcopy - command %s " % command
+
+    try:
+        out, err = proc.communicate()
+        log(log_msg, logging.DEBUG, out, err)
+    except:
+        log(log_msg, logging.ERROR, out, err)
+        raise
+
     return ((out, err), proc)
    
 def lspawn(command, pidfile, 
     return ((out, err), proc)
    
 def lspawn(command, pidfile, 
@@ -125,7 +143,7 @@ def lspawn(command, pidfile,
         'stdin' : stdin,
     }
     
         'stdin' : stdin,
     }
     
-    cmd = "%(create)s%(gohome)s rm -f %(pidfile)s ; %(sudo)s nohup bash -c %(command)s " % {
+    cmd = "%(create)s%(gohome)s rm -f %(pidfile)s ; %(sudo)s bash -c %(command)s " % {
             'command' : shell_escape(daemon_command),
             'sudo' : 'sudo -S' if sudo else '',
             'pidfile' : shell_escape(pidfile),
             'command' : shell_escape(daemon_command),
             'sudo' : 'sudo -S' if sudo else '',
             'pidfile' : shell_escape(pidfile),
index b9b5342..d1952bc 100644 (file)
@@ -46,7 +46,6 @@ def log(msg, level, out = None, err = None):
 
     logger.log(level, msg)
 
 
     logger.log(level, msg)
 
-
 if hasattr(os, "devnull"):
     DEV_NULL = os.devnull
 else:
 if hasattr(os, "devnull"):
     DEV_NULL = os.devnull
 else:
@@ -304,7 +303,6 @@ def rcopy(source, dest,
         port = None,
         gwuser = None,
         gw = None,
         port = None,
         gwuser = None,
         gw = None,
-        agent = True, 
         recursive = False,
         identity = None,
         server_key = None,
         recursive = False,
         identity = None,
         server_key = None,
@@ -377,11 +375,14 @@ def rcopy(source, dest,
         if openssh_has_persist():
             args.extend([
                 '-o', 'ControlMaster=auto',
         if openssh_has_persist():
             args.extend([
                 '-o', 'ControlMaster=auto',
-                '-o', 'ControlPath=%s' % (make_control_path(agent, False),)
+                '-o', 'ControlPath=%s' % (make_control_path(False, False),)
                 ])
         args.append(source)
 
                 ])
         args.append(source)
 
-    args.append(dest)
+    if isinstance(dest, list):
+        args.extend(dest)
+    else:
+        args.append(dest)
 
     log_msg = " rcopy - host %s - command %s " % (host, " ".join(args))
     
 
     log_msg = " rcopy - host %s - command %s " % (host, " ".join(args))
     
index 25a11b2..e632bcf 100644 (file)
@@ -146,6 +146,47 @@ class LinuxNS3ClientTest(unittest.TestCase):
         self.fedora_user = "inria_nepi"
         self.fedora_identity = "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])
 
         self.fedora_user = "inria_nepi"
         self.fedora_identity = "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])
 
+    def test_local_p2p_ping(self):
+        ec = ExperimentController(exp_id = "test-ns3-local-p2p")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", "localhost")
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        ec.register_connection(simu, node)
+
+        nsnode1 = add_ns3_node(ec, simu)
+        dev1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        dev2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
+
+        # Create channel
+        chan = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(chan, "Delay", "0s")
+        ec.register_connection(chan, dev1)
+        ec.register_connection(chan, dev2)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.0.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "0s")
+        ec.set (ping, "StopTime", "20s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+        
+        stdout = ec.trace(simu, "stdout") 
+
+        expected = "20 packets transmitted, 20 received, 0% packet loss"
+        self.assertTrue(stdout.find(expected) > -1)
+
+        ec.shutdown()
+
     def test_simple_p2p_ping(self):
         ec = ExperimentController(exp_id = "test-ns3-p2p-ping")
         
     def test_simple_p2p_ping(self):
         ec = ExperimentController(exp_id = "test-ns3-p2p-ping")
         
@@ -385,15 +426,15 @@ class LinuxNS3ClientTest(unittest.TestCase):
         rm = ec.get_resource(ping)
         start_time = rm.start_time
         stop_time = rm.stop_time
         rm = ec.get_resource(ping)
         start_time = rm.start_time
         stop_time = rm.stop_time
-        delta =  stop_time - start_time
+        delta = stop_time - start_time
 
 
-        self.assertTrue(delta.seconds >= 20)
-        self.assertTrue(delta.seconds < 25)
+        self.assertTrue(delta.seconds >= 20, "Time elapsed %d" % delta.seconds)
+        self.assertTrue(delta.seconds < 25, "Time elapsed %d" % delta.seconds)
 
         ec.shutdown()
 
 
         ec.shutdown()
 
-    def test_dev2p_traces(self):
-        ec = ExperimentController(exp_id = "test-ns3-dev2p-traces")
+    def test_traces(self):
+        ec = ExperimentController(exp_id = "test-ns3-traces")
         
         node = ec.register_resource("LinuxNode")
         ec.set(node, "hostname", self.fedora_host)
         
         node = ec.register_resource("LinuxNode")
         ec.set(node, "hostname", self.fedora_host)