X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Flinux%2Fudptest.py;fp=src%2Fnepi%2Fresources%2Flinux%2Fudptest.py;h=dbb081378cb072ba86dbd05a96974bbfd5541c00;hb=fc4dfc014dad45142f3dd63fdd0be57616cf2796;hp=0000000000000000000000000000000000000000;hpb=0f1f8b4831f892fa82407dd7d1ab07b3927cd92c;p=nepi.git diff --git a/src/nepi/resources/linux/udptest.py b/src/nepi/resources/linux/udptest.py new file mode 100644 index 00000000..dbb08137 --- /dev/null +++ b/src/nepi/resources/linux/udptest.py @@ -0,0 +1,376 @@ +# +# 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 ResourceManager, clsinit_copy, ResourceState, \ + reschedule_delay +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 LinuxUdpTest(LinuxApplication): + """ Uses the hpcbench udptest tool to gather UDP measurements. + Measurements require two ends, a server and a client RM. + + http://hpcbench.sourceforge.net/ + """ + _rtype = "LinuxUdpTest" + + @classmethod + def _register_attributes(cls): + s = Attribute("s", + "Runs in server mode. ", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + p = Attribute("p", + "Port to listen to in server mode, or to connect to in client mode. " + "Defaults to 5678. ", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + a = Attribute("a", + "Client option. Perform UDP Round Trip Time (latency) ", + type = Types.Bool, + flags = Flags.ExecReadOnly) + + A = Attribute("A", + "Client option. " + "Message size for UDP RTT test. " + "UDP RTT (latency) test with specified message size.", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + b = Attribute("b", + "Client option. " + "Client UDP buffer size in bytes. Using system default " + "value if not defined.", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + B = Attribute("B", + "Client option. " + "Server UDP buffer size in bytes. The same as cleint's by default.", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + c = Attribute("c", + "Client option. " + "CPU log option. Tracing system info during the test. " + "Only available when output is defined. ", + type = Types.Bool, + flags = Flags.ExecReadOnly) + + d = Attribute("d", + "Client option. " + "Data size of each read/write in bytes. The same as packet size " + "by default.", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + e = Attribute("e", + "Client option. " + "Exponential test (data size of each sending increasing from 1 " + "byte to packet size). ", + type = Types.Bool, + flags = Flags.ExecReadOnly) + + g = Attribute("g", + "Client option. " + "UDP traffic generator (Keep sending data to a host). " + "Work without server's support.", + type = Types.Bool, + flags = Flags.ExecReadOnly) + + target = Attribute("target", + "Client option. " + "Hostname or IP address of UDP server. Must be specified.", + flags = Flags.ExecReadOnly) + + i = Attribute("i", + "Client option. " + "Bidirectional UDP throuhgput test. Default is unidirection " + "stream test. ", + type = Types.Bool, + flags = Flags.ExecReadOnly) + + l = Attribute("l", + "Client option. " + "UDP datagram (packet) size in bytes ( < udp-buffer-szie ). " + "1460 by default.", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + m = Attribute("m", + "Client option. " + "Total message size in bytes. 1048576 by default.", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + o = Attribute("o", + "Client option. " + "Output file name. ", + flags = Flags.ExecReadOnly) + + P = Attribute("P", + "Client option. " + "Write the plot file for gnuplot. Only enable when the output " + "is specified. ", + type = Types.Bool, + flags = Flags.ExecReadOnly) + + q = Attribute("q", + "Client option. " + "Define the TOS field of IP packets. " + "Six values can be used for this setting:\n" + " 1:(IPTOS)-Minimize delay\n" + " 2:(IPTOS)-Maximize throughput\n" + " 3:(DiffServ)-Class1 with low drop probability\n" + " 4:(DiffServ)-class1 with high drop probability\n" + " 5:(DiffServ)-Class4 with low drop probabiltiy\n" + " 6:(DiffServ)-Class4 with high drop probabiltiy\n" + "Write the plot file for gnuplot. Only enable when the output " + "is specified. ", + type = Types.Enumerate, + allowed = ["1", "2", "3", "4", "5", "6"], + flags = Flags.ExecReadOnly) + + r = Attribute("r", + "Client option. " + "Repetition of tests. 10 by default. ", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + t = Attribute("t", + "Client option. " + "Test time constraint in seconds. 5 by default. ", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + T = Attribute("T", + "Client option. " + "Throughput constraint for UDP generator or throughput " + "test. Unlimited by default. ", + type = Types.Integer, + flags = Flags.ExecReadOnly) + + continuous = Attribute("continuous", + "Run nping in a while loop", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + print_timestamp = Attribute("printTimestamp", + "Print timestamp before running nping", + type = Types.Bool, + default = False, + flags = Flags.ExecReadOnly) + + cls._register_attribute(s) + cls._register_attribute(p) + cls._register_attribute(a) + cls._register_attribute(A) + cls._register_attribute(b) + cls._register_attribute(B) + cls._register_attribute(c) + cls._register_attribute(d) + cls._register_attribute(e) + cls._register_attribute(g) + cls._register_attribute(target) + cls._register_attribute(g) + cls._register_attribute(i) + cls._register_attribute(l) + cls._register_attribute(m) + cls._register_attribute(o) + cls._register_attribute(P) + cls._register_attribute(q) + cls._register_attribute(r) + cls._register_attribute(t) + cls._register_attribute(T) + cls._register_attribute(continuous) + cls._register_attribute(print_timestamp) + + def __init__(self, ec, guid): + super(LinuxUdpTest, self).__init__(ec, guid) + self._home = "udptest-%s" % self.guid + + def deploy(self): + if not self.get("command"): + self.set("command", self._start_command) + + if not self.get("sources"): + self.set("sources", self._sources) + + if not self.get("install"): + self.set("install", self._install) + + if not self.get("build"): + self.set("build", self._build) + + if not self.get("env"): + self.set("env", self._environment) + + if not self.get("depends"): + self.set("depends", self._depends) + + super(LinuxUdpTest, self).deploy() + + def upload_start_command(self): + + super(LinuxUdpTest, self).upload_start_command() + + if self.get("s") == True: + # We want to make sure the server is running + # before the client starts. + # Run the command as a bash script in background, + # in the host ( but wait until the command has + # finished to continue ) + self._run_in_background() + + def start(self): + if self.get("s") == True: + # Server is already running + if self._state == ResourceState.READY: + command = self.get("command") + self.info("Starting command '%s'" % command) + + self._start_time = tnow() + self._state = ResourceState.STARTED + else: + msg = " Failed to execute command '%s'" % command + self.error(msg, out, err) + self._state = ResourceState.FAILED + raise RuntimeError, msg + else: + super(LinuxUdpTest, self).start() + + @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'`";""") + + if self.get("s") == True: + args.append("udpserver") + else: + args.append("udptest") + + if self.get("p"): + args.append("-p %d" % self.get("p")) + if self.get("a") == True: + args.append("-a") + if self.get("A"): + args.append("-A %d" % self.get("A")) + if self.get("b"): + args.append("-b %d" % self.get("b")) + if self.get("B"): + args.append("-B %d" % self.get("B")) + if self.get("c") == True: + args.append("-c") + if self.get("d"): + args.append("-d %d" % self.get("d")) + if self.get("e") == True: + args.append("-e") + if self.get("g") == True: + args.append("-g") + if self.get("target"): + args.append("-h %s" % self.get("target")) + if self.get("i") == True: + args.append("-i") + if self.get("l"): + args.append("-l %d" % self.get("l")) + if self.get("m"): + args.append("-m %d" % self.get("m")) + if self.get("o"): + args.append("-o %d" % self.get("o")) + if self.get("P"): + args.append("-P %d" % self.get("P")) + if self.get("q"): + args.append("-q %s" % self.get("q")) + if self.get("r"): + args.append("-r %d" % self.get("r")) + if self.get("t"): + args.append("-t %d" % self.get("t")) + if self.get("T"): + args.append("-T %d" % self.get("T")) + + if self.get("continuous") == True: + args.append("; done ") + + command = " ".join(args) + + return command + + @property + def _sources(self): + return "http://hpcbench.sourceforge.net/udp.tar.gz" + + @property + def _depends(self): + return "gcc make" + + @property + def _build(self): + sources = self.get("sources").split(" ")[0] + sources = os.path.basename(sources) + + return ( + # Evaluate if ccnx binaries are already installed + " ( " + " test -f ${BIN}/udptest && " + " echo 'binaries found, nothing to do' " + " ) || ( " + # If not, untar and build + " ( " + " mkdir -p ${SRC}/udptest && " + " tar xf ${SRC}/%(sources)s --strip-components=1 -C ${SRC}/udptest " + " ) && " + "cd ${SRC}/udptest && " + # Just execute and silence warnings... + " ( make ) " + " )") % ({ 'sources': sources, + }) + + @property + def _install(self): + return ( + # Evaluate if ccnx binaries are already installed + " ( " + " test -f ${BIN}/udptest && " + " echo 'binaries found, nothing to do' " + " ) || ( " + # If not, install + " mv ${SRC}/udptest ${BIN} " + " )") + + @property + def _environment(self): + return "PATH=$PATH:${BIN}/udptest" + + def valid_connection(self, guid): + # TODO: Validate! + return True +