From 5bf45c1e55bf9637611c3d2dfa9c8de0504269a4 Mon Sep 17 00:00:00 2001 From: Alina Quereilhac Date: Thu, 11 Jul 2013 18:44:39 -0700 Subject: [PATCH] Added LinuxTcpdump --- src/nepi/execution/ec.py | 2 +- src/nepi/resources/linux/ccn/fibentry.py | 82 ++--- src/nepi/resources/linux/mtr.py | 26 +- src/nepi/resources/linux/ping.py | 12 +- src/nepi/resources/linux/tcpdump.py | 406 +++++++++++++++++++++++ test/resources/linux/ccn/fibentry.py | 94 ++++++ test/resources/linux/tcpdump.py | 76 +++++ 7 files changed, 649 insertions(+), 49 deletions(-) create mode 100644 src/nepi/resources/linux/tcpdump.py create mode 100644 test/resources/linux/ccn/fibentry.py create mode 100755 test/resources/linux/tcpdump.py diff --git a/src/nepi/execution/ec.py b/src/nepi/execution/ec.py index abcb88df..645d6678 100644 --- a/src/nepi/execution/ec.py +++ b/src/nepi/execution/ec.py @@ -537,7 +537,7 @@ class ExperimentController(object): """ rm = self.get_resource(guid) - return rm.start_with_condition() + return rm.start_with_conditions() def deploy(self, group = None, wait_all_ready = True): """ Deploy all resource manager in group diff --git a/src/nepi/resources/linux/ccn/fibentry.py b/src/nepi/resources/linux/ccn/fibentry.py index 83fbe9c7..ace4f524 100644 --- a/src/nepi/resources/linux/ccn/fibentry.py +++ b/src/nepi/resources/linux/ccn/fibentry.py @@ -67,12 +67,16 @@ class LinuxFIBEntry(LinuxApplication): @classmethod def _register_traces(cls): ping = Trace("ping", "Continuous ping to the peer end") + mtr = Trace("mtr", "Continuous mtr to the peer end") cls._register_trace(ping) + cls._register_trace(mtr) def __init__(self, ec, guid): super(LinuxFIBEntry, self).__init__(ec, guid) self._home = "fib-%s" % self.guid + self._ping = None + self._mtr = None @property def ccnd(self): @@ -85,6 +89,14 @@ class LinuxFIBEntry(LinuxApplication): if self.ccnd: return self.ccnd.node return None + def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0): + if name == "ping": + return self.ec.trace(self._ping, "stdout", attr, block, offset) + if name == "mtr": + return self.ec.trace(self._mtr, "stdout", attr, block, offset) + + return super(LinuxFIBEntry, self).trace(name, attr, block, offset) + def deploy(self): # Wait until associated ccnd is provisioned if not self.ccnd or self.ccnd.state < ResourceState.READY: @@ -135,41 +147,36 @@ class LinuxFIBEntry(LinuxApplication): raise RuntimeError, msg def configure(self): - if not self.trace_enabled("ping"): - return - - ping_script = """echo "Staring PING %(host)s at date `date +'%Y%m%d%H%M%S'`"; ping %(host)s""" % ({ - "host": self.get("host")}) - ping_file = os.path.join(self.run_home, "ping.sh") - self.node.upload(ping_script, - ping_file, - text = True, - overwrite = False) - - command = """bash %s""" % ping_file - (out, err), proc = self.node.run(command, self.run_home, - stdout = "ping", - stderr = "ping_stderr", - pidfile = "ping_pidfile") - - # Wait for pid file to be generated - pid, ppid = self.node.wait_pid(self.run_home, "ping_pidfile") - - # If the process is not running, check for error information - # on the remote machine - if not pid or not ppid: - (out, err), proc = self.node.check_errors(self.run_home, - stderr = "ping_pidfile") - - # Out is what was written in the stderr file - if err: - self.fail() - msg = " Failed to deploy ping trace command '%s' " % command - self.error(msg, out, err) - raise RuntimeError, msg - - #while true; do echo `date +'%Y%m%d%H%M%S'`; mtr --no-dns --report -c 1 roseval.pl.sophia.inria.fr;sleep 2;done - + if self.trace_enabled("ping"): + self.info("Configuring PING trace") + self._ping = self.ec.register_resource("LinuxPing") + self.ec.set(self._ping, "printTimestamp", True) + self.ec.set(self._ping, "target", self.get("host")) + self.ec.register_connection(self._ping, self.node.guid) + # force waiting until ping is READY before we starting the FIB + self.ec.register_condition(self.guid, ResourceAction.START, + self._ping, ResourceState.READY) + # schedule ping deploy and start + self.ec.deploy(group=[self._ping]) + self.ec.start_with_conditions(self._ping) + + if self.trace_enabled("mtr"): + self.info("Configuring TRACE trace") + self._mtr = self.ec.register_resource("LinuxMtr") + self.ec.set(self._mtr, "noDns", True) + self.ec.set(self._mtr, "printTimestamp", True) + self.ec.set(self._mtr, "continuous", True) + self.ec.set(self._mtr, "target", self.get("host")) + self.ec.register_connection(self._mtr, self.node.guid) + self.ec.deploy(group=[self._mtr]) + # force waiting until mtr is READY before we starting the FIB + self.ec.register_condition(self.guid, ResourceAction.START, + self._mtr, ResourceState.READY) + # schedule mtr deploy and start + self.ec.deploy(group=[self._mtr]) + self.ec.start_with_conditions(self._mtr) + + def start(self): if self._state in [ResourceState.READY, ResourceState.STARTED]: command = self.get("command") @@ -196,11 +203,6 @@ class LinuxFIBEntry(LinuxApplication): if proc.poll(): pass - # now stop the ping trace - if self.trace_enabled("ping"): - pid, ppid = self.node.wait_pid(self.run_home, "ping_pidfile") - (out, err), proc = self.node.kill(pid, ppid) - self._stop_time = tnow() self._state = ResourceState.STOPPED diff --git a/src/nepi/resources/linux/mtr.py b/src/nepi/resources/linux/mtr.py index 0bf5fae2..9de7ca17 100644 --- a/src/nepi/resources/linux/mtr.py +++ b/src/nepi/resources/linux/mtr.py @@ -54,6 +54,18 @@ class LinuxMtr(LinuxApplication): "between ICMP ECHO requests. Default value is one second ", flags = Flags.ExecReadOnly) + countinuous = Attribute("continuous", + "Run mtr in a while loop", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + print_timestamp = Attribute("printTimestamp", + "Print timestamp before running mtr", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + target = Attribute("target", "mtr target host (host that will be pinged)", flags = Flags.ExecReadOnly) @@ -62,11 +74,14 @@ class LinuxMtr(LinuxApplication): cls._register_attribute(no_dns) cls._register_attribute(address) cls._register_attribute(interval) + cls._register_attribute(countinuous) + cls._register_attribute(print_timestamp) cls._register_attribute(target) def __init__(self, ec, guid): super(LinuxMtr, self).__init__(ec, guid) self._home = "mtr-%s" % self.guid + self._sudo_kill = True def deploy(self): if not self.get("command"): @@ -80,6 +95,11 @@ class LinuxMtr(LinuxApplication): @property def _start_command(self): args = [] + if self.get("continuous") == True: + args.append("while true; do ") + if self.get("printTimestamp") == True: + args.append("""echo "`date +'%Y%m%d%H%M%S'`";""") + args.append("sudo -S mtr --report") if self.get("reportCycles"): args.append("-c %s" % self.get("reportCycles")) if self.get("noDns") == True: @@ -87,10 +107,10 @@ class LinuxMtr(LinuxApplication): if self.get("address"): args.append("-a %s" % self.get("address")) args.append(self.get("target")) + if self.get("continuous") == True: + args.append("; done ") - command = """echo "Starting mtr `date +'%Y%m%d%H%M%S'`"; """ - command += " sudo -S mtr --report " - command += " ".join(args) + command = " ".join(args) return command diff --git a/src/nepi/resources/linux/ping.py b/src/nepi/resources/linux/ping.py index 0a5796a0..a80397bf 100644 --- a/src/nepi/resources/linux/ping.py +++ b/src/nepi/resources/linux/ping.py @@ -56,7 +56,7 @@ class LinuxPing(LinuxApplication): numeric = Attribute("numeric", "Sets ping -n option. Disables resolution of host addresses into " - "symbolic names ", + "symbolic names. ", type = Types.Bool, default = False, flags = Flags.ExecReadOnly) @@ -193,6 +193,11 @@ class LinuxPing(LinuxApplication): def _start_command(self): args = [] + if self.get("printTimestamp") == True: + args.append("""echo "`date +'%Y%m%d%H%M%S'`";""") + + args.append("ping ") + if self.get("count"): args.append("-c %s" % self.get("count")) if self.get("mark"): @@ -207,8 +212,6 @@ class LinuxPing(LinuxApplication): args.append("-n") if self.get("pattern"): args.append("-p %s" % self.get("pattern")) - if self.get("printTimestamp") == True: - args.append("-D") if self.get("tos"): args.append("-Q %s" % self.get("tos")) if self.get("quiet"): @@ -239,8 +242,7 @@ class LinuxPing(LinuxApplication): args.append("-W %s" % self.get("timeout")) args.append(self.get("target")) - command = " sudo -S ping " - command += " ".join(args) + command = " ".join(args) return command diff --git a/src/nepi/resources/linux/tcpdump.py b/src/nepi/resources/linux/tcpdump.py new file mode 100644 index 00000000..06357de4 --- /dev/null +++ b/src/nepi/resources/linux/tcpdump.py @@ -0,0 +1,406 @@ +# +# NEPI, a framework to manage network experiments +# Copyright (C) 2013 INRIA +# +# 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 3 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, see . +# +# Author: Alina Quereilhac + +from nepi.execution.attribute import Attribute, Flags, Types +from nepi.execution.resource import clsinit_copy +from nepi.resources.linux.application import LinuxApplication +from nepi.util.timefuncs import tnow + +import os + +@clsinit_copy +class LinuxTcpdump(LinuxApplication): + _rtype = "LinuxTcpdump" + + @classmethod + def _register_attributes(cls): + A = Attribute("A", + "Sets tcpdump -A option. " + "Prints each packet (minus its link level header) in ASCII.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + b = Attribute("b", + "Sets tcpdump -b option. " + "Prints the AS number in BGP packets in ASDOT notation. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + B = Attribute("B", + "Sets tcpdump -B option. " + "Sets the operaing system capture buffer size in untils of " + "KiB (1024 bytes).", + flags = Flags.ExecReadOnly) + + c = Attribute("c", + "Sets tcpdump -c option. " + "Exists after receiving count packets.", + flags = Flags.ExecReadOnly) + + C = Attribute("C", + "Sets tcpdump -C option. " + "Before writing a raw packet to a savefile, check whether the " + "file is currently larger than file_size and, if so, close the " + "current savefile and open a new one. " + "Savefiles after the first savefile will have the name specified " + "with the -w with a number after it, starting at 1 and continuing " + "upward. ", + flags = Flags.ExecReadOnly) + + d = Attribute("d", + "Sets tcpdump -d option. " + "Dump the compiled packet-matching code in a human readable form " + "to standard output and stop.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + dd = Attribute("dd", + "Sets tcpdump -dd option. " + "Dump packet-matching code as a C program fragment. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + ddd = Attribute("ddd", + "Sets tcpdump -ddd option. " + "Dump packet-matching code as decimal numbers " + "(preceded with a count).", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + D = Attribute("D", + "Sets tcpdump -D option. " + "Print the list of the network interfaces available on the system " + "and on which tcpdump can capture packets. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + e = Attribute("e", + "Sets tcpdump -e option. " + "Print the link-level header on each dump line.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + F = Attribute("F", + "Sets tcpdump -F option. " + "Use file as input for the filter expression.", + flags = Flags.ExecReadOnly) + + G = Attribute("G", + "Sets tcpdump -G option. " + "If specified, rotates the dump file specified with the -w " + "option every rotate_seconds seconds. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + i = Attribute("i", + "Sets tcpdump -i option. " + "Listen on interface. If unspecified, tcpdump searches the " + "system interface list for the lowest numbered, configured " + "up interface (excluding loopback). ", + flags = Flags.ExecReadOnly) + + I = Attribute("I", + "Sets tcpdump -I option. " + "Put the interface in 'monitor mode'; this is supported only " + "on IEEE 802.11 Wi-Fi interfaces, and supported only on some " + "operating systems. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + j = Attribute("j", + "Sets tcpdump -j option. " + "Sets the time stamp type for the capture to tstamp_type. " + "The names to use for the time stamp types are given in " + "pcap-tstamp-type(7); not all the types listed there will " + "necessarily be valid for any given interface.", + flags = Flags.ExecReadOnly) + + K = Attribute("K", + "Sets tcpdump -K option. " + "Don't attempt to verify IP, TCP, or UDP checksums. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + l = Attribute("l", + "Sets tcpdump -l option. " + "Make stdout line buffered. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + U = Attribute("U", + "Sets tcpdump -U option. " + "Similar to -l in its behavior, but it will cause output to be " + "``packet-buffered'', so that the output is written to stdout " + "at the end of each packet. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + n = Attribute("n", + "Sets tcpdump -n option. " + "Don't convert addresses (i.e., host addresses, port numbers, " + "etc.) to names.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + N = Attribute("N", + "Sets tcpdump -N option. " + "Don't print domain name qualification of host names. " + "E.g., if you give this flag then tcpdump will print ``nic'' " + "instead of ``nic.ddn.mil''.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + S = Attribute("S", + "Sets tcpdump -S option. " + "Print absolute, rather than relative, TCP sequence numbers.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + s = Attribute("s", + "Sets tcpdump -s option. " + "Snarf snaplen bytes of data from each packet rather than " + "the default of 65535 bytes. ", + flags = Flags.ExecReadOnly) + + T = Attribute("T", + "Sets tcpdump -T option. " + "Force packets selected by 'expression' to be interpreted the " + "specified type. Currently known types are aodv (Ad-hoc " + "On-demand Distance Vector protocol), cnfp (Cisco NetFlow " + "protocol), rpc (Remote Procedure Call), rtp (Real-Time " + "Applications protocol), rtcp (Real-Time Applications control " + "protocol), snmp (Simple Network Management Protocol), tftp " + "(Trivial File Transfer Protocol), vat (Visual Audio Tool), " + "and wb (distributed White Board).", + flags = Flags.ExecReadOnly) + + t = Attribute("t", + "Sets tcpdump -t option. " + "Don't print a timestamp on each dump line.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + tt = Attribute("tt", + "Sets tcpdump -tt option. " + "Print an unformatted timestamp on each dump line. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + ttt = Attribute("ttt", + "Sets tcpdump -ttt option. " + "Print a delta (micro-second resolution) between current " + "and previous line on each dump line.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + tttt = Attribute("tttt", + "Sets tcpdump -tttt option. " + "Print a timestamp in default format proceeded by date on " + "each dump line. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + ttttt = Attribute("ttttt", + "Sets tcpdump -ttttt option. " + "Print a delta (micro-second resolution) between current and " + "first line on each dump line.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + v = Attribute("v", + "Sets tcpdump -v option. " + "When parsing and printing, produce (slightly more) " + "verbose output. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + vv = Attribute("vv", + "Sets tcpdump -vv option. " + "Even more verbose output. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + vvv = Attribute("vvv", + "Sets tcpdump -vv option. " + "Even more verbose output. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + w = Attribute("w", + "Sets tcpdump -w option. " + "Write the raw packets to file rather than parsing " + "and printing them out.", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + expression = Attribute("expression", + "selects which packets will be dumped.", + flags = Flags.ExecReadOnly) + + cls._register_attribute(A) + cls._register_attribute(b) + cls._register_attribute(B) + cls._register_attribute(c) + cls._register_attribute(C) + cls._register_attribute(d) + cls._register_attribute(dd) + cls._register_attribute(ddd) + cls._register_attribute(D) + cls._register_attribute(e) + cls._register_attribute(F) + cls._register_attribute(G) + cls._register_attribute(i) + cls._register_attribute(I) + cls._register_attribute(j) + cls._register_attribute(K) + cls._register_attribute(l) + cls._register_attribute(U) + cls._register_attribute(n) + cls._register_attribute(N) + cls._register_attribute(S) + cls._register_attribute(s) + cls._register_attribute(T) + cls._register_attribute(t) + cls._register_attribute(tt) + cls._register_attribute(ttt) + cls._register_attribute(tttt) + cls._register_attribute(ttttt) + cls._register_attribute(v) + cls._register_attribute(vv) + cls._register_attribute(vvv) + cls._register_attribute(w) + cls._register_attribute(expression) + + def __init__(self, ec, guid): + super(LinuxTcpdump, self).__init__(ec, guid) + self._home = "tcpdump-%s" % self.guid + self._sudo_kill = True + + def deploy(self): + if not self.get("command"): + self.set("command", self._start_command) + + if not self.get("depends"): + self.set("depends", "tcpdump") + + super(LinuxTcpdump, self).deploy() + + @property + def _start_command(self): + args = [] + args.append("sudo -S tcpdump") + if self.get("A") == True: + args.append("-A") + if self.get("b") == True: + args.append("-b") + if self.get("B"): + args.append("-B %s" % self.get("B")) + if self.get("c"): + args.append("-c %s" % self.get("c")) + if self.get("C"): + args.append("-C %s" % self.get("C")) + if self.get("d") == True: + args.append("-d") + if self.get("dd") == True: + args.append("-dd") + if self.get("ddd") == True: + args.append("-ddd") + if self.get("D") == True: + args.append("-D") + if self.get("e") == True: + args.append("-e") + if self.get("F"): + args.append("-F %s" % self.get("F")) + if self.get("G") == True: + args.append("-G") + if self.get("i"): + args.append("-i %s" % self.get("i")) + if self.get("I") == True: + args.append("-I") + if self.get("j"): + args.append("-j %s" % self.get("j")) + if self.get("K") == True: + args.append("-K") + if self.get("l") == True: + args.append("-l") + if self.get("U") == True: + args.append("-U") + if self.get("n") == True: + args.append("-n") + if self.get("N") == True: + args.append("-N") + if self.get("S") == True: + args.append("-S") + if self.get("s"): + args.append("-s %s" % self.get("s")) + if self.get("T"): + args.append("-T %s" % self.get("T")) + if self.get("t") == True: + args.append("-t") + if self.get("tt") == True: + args.append("-tt") + if self.get("ttt") == True: + args.append("-ttt") + if self.get("tttt") == True: + args.append("-tttt") + if self.get("ttttt") == True: + args.append("-ttttt") + if self.get("v") == True: + args.append("-v") + if self.get("vv") == True: + args.append("-vv") + if self.get("vvv") == True: + args.append("-vvv") + if self.get("w"): + args.append("-w %s" % self.get("w")) + if self.get("expression"): + args.append(self.get("expression")) + + command = " ".join(args) + + return command + + def valid_connection(self, guid): + # TODO: Validate! + return True + diff --git a/test/resources/linux/ccn/fibentry.py b/test/resources/linux/ccn/fibentry.py new file mode 100644 index 00000000..cf2f8bba --- /dev/null +++ b/test/resources/linux/ccn/fibentry.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# +# NEPI, a framework to manage network experiments +# Copyright (C) 2013 INRIA +# +# 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 3 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, see . +# +# Author: Alina Quereilhac + +from nepi.execution.ec import ExperimentController +from test_utils import skipIfNotAlive, skipInteractive + +import os +import time +import tempfile +import unittest + +class LinuxFIBEntryTestCase(unittest.TestCase): + def setUp(self): + self.fedora_host = "nepi2.pl.sophia.inria.fr" + self.fedora_user = "inria_nepi" + + self.ubuntu_host = "roseval.pl.sophia.inria.fr" + self.ubuntu_user = "alina" + + self.target = "nepi5.pl.sophia.inria.fr" + + @skipIfNotAlive + def t_traces(self, host, user): + + ec = ExperimentController(exp_id = "test-fib-traces") + + node1 = ec.register_resource("LinuxNode") + ec.set(node1, "hostname", host) + ec.set(node1, "username", user) + #ec.set(node1, "cleanHome", True) + ec.set(node1, "cleanProcesses", True) + + ccnd1 = ec.register_resource("LinuxCCND") + ec.register_connection(ccnd1, node1) + + entry1 = ec.register_resource("LinuxFIBEntry") + ec.set(entry1, "host", self.target) + ec.enable_trace(entry1, "ping") + ec.enable_trace(entry1, "mtr") + ec.register_connection(entry1, ccnd1) + + node2 = ec.register_resource("LinuxNode") + ec.set(node2, "hostname", self.target) + ec.set(node2, "username", self.fedora_user) + ec.set(node2, "cleanHome", True) + ec.set(node2, "cleanProcesses", True) + + ccnd2 = ec.register_resource("LinuxCCND") + ec.register_connection(ccnd2, node2) + + entry2 = ec.register_resource("LinuxFIBEntry") + ec.set(entry2, "host", host) + ec.register_connection(entry2, ccnd2) + + ec.deploy() + + ec.wait_started([ccnd1, ccnd2]) + + stdout = ec.trace(entry1, "ping") + expected = "icmp_seq=1" + self.assertTrue(stdout.find(expected) > -1) + + stdout = ec.trace(entry1, "mtr") + expected = "1." + self.assertTrue(stdout.find(expected) > -1) + + ec.shutdown() + + def test_traces_fedora(self): + self.t_traces(self.fedora_host, self.fedora_user) + + def test_traces_ubuntu(self): + self.t_traces(self.ubuntu_host, self.ubuntu_user) + +if __name__ == '__main__': + unittest.main() + diff --git a/test/resources/linux/tcpdump.py b/test/resources/linux/tcpdump.py new file mode 100755 index 00000000..6ba73753 --- /dev/null +++ b/test/resources/linux/tcpdump.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# NEPI, a framework to manage network experiments +# Copyright (C) 2013 INRIA +# +# 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 3 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, see . +# +# Author: Alina Quereilhac + +from nepi.execution.ec import ExperimentController +from test_utils import skipIfNotAlive, skipInteractive + +import os +import time +import tempfile +import unittest + +class LinuxTcpdumpTestCase(unittest.TestCase): + def setUp(self): + self.fedora_host = "nepi2.pl.sophia.inria.fr" + self.fedora_user = "inria_nepi" + + self.ubuntu_host = "roseval.pl.sophia.inria.fr" + self.ubuntu_user = "alina" + + self.target = "nepi5.pl.sophia.inria.fr" + + @skipIfNotAlive + def t_tofile(self, host, user): + ec = ExperimentController(exp_id = "test-to-file") + + node = ec.register_resource("LinuxNode") + ec.set(node, "hostname", host) + ec.set(node, "username", user) + ec.set(node, "cleanHome", True) + ec.set(node, "cleanProcesses", True) + + pcap = ec.register_resource("LinuxTcpdump") + ec.set(pcap, "i", "eth0") + ec.set(pcap, "w", "custom_output") + ec.register_connection(pcap, node) + + app = ec.register_resource("LinuxPing") + ec.set(app, "count", "20") + ec.set(app, "target", self.target) + ec.register_connection(app, node) + + ec.deploy() + + ec.wait_finished(app) + + output = ec.trace(pcap, "custom_output") + self.assertTrue(len(output) > 0) + + ec.shutdown() + + def test_tofile_fedora(self): + self.t_tofile(self.fedora_host, self.fedora_user) + + def test_tofile_ubuntu(self): + self.t_tofile(self.ubuntu_host, self.ubuntu_user) + +if __name__ == '__main__': + unittest.main() + -- 2.47.0