1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/utils/flowmon/bench-all.py Mon May 04 18:35:43 2009 +0100
1.3 @@ -0,0 +1,116 @@
1.4 +import subprocess
1.5 +import sys
1.6 +import resource
1.7 +from optparse import OptionParser
1.8 +import time
1.9 +import re
1.10 +import tempfile
1.11 +import os
1.12 +from xml.dom import minidom
1.13 +
1.14 +DATA_LIMIT = None
1.15 +CPU_LIMIT = None
1.16 +
1.17 +
1.18 +
1.19 +def run_sim(args):
1.20 + argv = ['python', 'flowmon-bench.py'] + args
1.21 +
1.22 + results_fname = tempfile.mktemp(prefix='results', suffix='.xml')
1.23 + argv.append("--Results=%s" % results_fname)
1.24 +
1.25 + print >> sys.stderr, "popen ", repr(argv)
1.26 + start_time = time.time()
1.27 +
1.28 + def preexec_fn(*dummy_args):
1.29 + resource.setrlimit(resource.RLIMIT_DATA, (DATA_LIMIT, -1))
1.30 + resource.setrlimit(resource.RLIMIT_AS, (DATA_LIMIT, -1))
1.31 + resource.setrlimit(resource.RLIMIT_CPU, (CPU_LIMIT, -1))
1.32 + proc = subprocess.Popen(argv, preexec_fn=preexec_fn)
1.33 + max_mem = 0
1.34 + while 1:
1.35 + if proc.poll() is not None:
1.36 + break
1.37 + time.sleep(1.0)
1.38 + mem = int(open("/proc/%i/statm" % proc.pid, "rt").read().split()[0])*4
1.39 + if mem > max_mem:
1.40 + max_mem = mem
1.41 + retval = proc.wait()
1.42 + end_time = time.time()
1.43 +
1.44 + if retval:
1.45 + raise RuntimeError("Simulation exited with code %i.\t" % (retval,))
1.46 +
1.47 + if os.path.exists(results_fname):
1.48 + results = minidom.parse(results_fname)
1.49 + os.unlink(results_fname)
1.50 + else:
1.51 + results = None
1.52 +
1.53 + return max_mem, (end_time - start_time), results
1.54 +
1.55 +
1.56 +def main():
1.57 +
1.58 + parser = OptionParser()
1.59 + parser.add_option("-j", None, dest="concurrency", default="2",
1.60 + help="Number of tasks to run in parallel")
1.61 + parser.add_option("-c", "--cpu-limit", dest="cpu_limit", default="5",
1.62 + help="CPU limit, in hours")
1.63 + parser.add_option("-m", "--memory-limit", dest="mem_limit", default="detect",
1.64 + help="Memory limit, total, in GigaBytes. "
1.65 + "Actual per-process memory limit will be this value divided"
1.66 + " by the concurrency level setting.")
1.67 + parser.add_option("-s", "--stop-time", dest="stop_time", default="300",
1.68 + help="Simulation stop time (s)")
1.69 + (options, args) = parser.parse_args()
1.70 +
1.71 + global CPU_LIMIT, DATA_LIMIT
1.72 + CPU_LIMIT = long(float(options.cpu_limit)*60*60)
1.73 +
1.74 + if options.mem_limit == 'detect':
1.75 + for line in file("/proc/meminfo"):
1.76 + m = re.match("MemTotal:\s+(\d+) kB", line)
1.77 + if m:
1.78 + DATA_LIMIT = 1024*long(m.group(1))
1.79 + print >> sys.stderr, "Detected DATA_LIMIT = ", DATA_LIMIT, "(%s GiB)" % (DATA_LIMIT/1024.0/1024.0/1024.0)
1.80 + break
1.81 + else:
1.82 + print >> sys.stderr, "Could not detect DATA_LIMIT => fallback to 512 MB."
1.83 + DATA_LIMIT = long(float(0.5)*1024*1024*1024)
1.84 + else:
1.85 + DATA_LIMIT = long(float(options.mem_limit)*1024*1024*1024)
1.86 + DATA_LIMIT /= int(int(options.concurrency)*1.25)
1.87 + print >> sys.stderr, "Per-process data limit: %.3f GiB (%r)" % (DATA_LIMIT/1024.0/1024.0/1024.0, DATA_LIMIT)
1.88 +
1.89 + newdoc = minidom.getDOMImplementation().createDocument(None, "flowmon-bench-results", None)
1.90 + results_root_el = newdoc.documentElement
1.91 +
1.92 + for num_nodes_side in range(2,11):
1.93 + for run_number in range(10):
1.94 + for enable_monitor in [False, True]:
1.95 + args = ["--NumNodesSide=%i" % num_nodes_side,
1.96 + "--RunNumber=%i" % run_number,
1.97 + "--EnableMonitor=%i" % enable_monitor,
1.98 + "--StopTime=%s" % options.stop_time,
1.99 + ]
1.100 + max_mem, duration, results = run_sim(args)
1.101 + simulation_el = results_root_el.appendChild(newdoc.createElement('simulation'))
1.102 +
1.103 + simulation_el.setAttribute("num-nodes-side", str(num_nodes_side))
1.104 + simulation_el.setAttribute("run-number", str(run_number))
1.105 + simulation_el.setAttribute("enable-monitor", str(enable_monitor))
1.106 + simulation_el.setAttribute("max-memory", str(max_mem))
1.107 + simulation_el.setAttribute("cpu-time", str(duration))
1.108 +
1.109 + if enable_monitor:
1.110 + simulation_el.appendChild(results.documentElement.cloneNode(True))
1.111 +
1.112 + out = open("results.xml", "wt")
1.113 + newdoc.writexml(out, addindent=' ', newl='\n', encoding='utf-8')
1.114 + out.close()
1.115 +
1.116 +
1.117 +
1.118 +if __name__ == '__main__':
1.119 + main()
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/utils/flowmon/flowmon-bench.py Mon May 04 18:35:43 2009 +0100
2.3 @@ -0,0 +1,212 @@
2.4 +# -*- Mode: Python; -*-
2.5 +# Copyright (c) 2009 INESC Porto
2.6 +#
2.7 +# This program is free software; you can redistribute it and/or modify
2.8 +# it under the terms of the GNU General Public License version 2 as
2.9 +# published by the Free Software Foundation;
2.10 +#
2.11 +# This program is distributed in the hope that it will be useful,
2.12 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
2.13 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.14 +# GNU General Public License for more details.
2.15 +#
2.16 +# You should have received a copy of the GNU General Public License
2.17 +# along with this program; if not, write to the Free Software
2.18 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.19 +#
2.20 +# Authors: Gustavo Carneiro <gjc@inescporto.pt>
2.21 +
2.22 +import sys
2.23 +import ns3
2.24 +from xml.dom import minidom
2.25 +
2.26 +DISTANCE = 150 # (m)
2.27 +NUM_NODES_SIDE = 3
2.28 +
2.29 +
2.30 +def write_flowmon_results_to_file(file_name, flow_monitor, flow_classifier):
2.31 + results_file = open(file_name, "wb")
2.32 + domimpl = minidom.getDOMImplementation()
2.33 + doc = domimpl.createDocument(None, "flow-monitor", None)
2.34 + results = doc.documentElement
2.35 +
2.36 + flows_el = results.appendChild(doc.createElement('flows'))
2.37 +
2.38 + for flow_id, stats in flow_monitor.GetFlowStats():
2.39 + flow_el = flows_el.appendChild(doc.createElement('flow'))
2.40 + flow_el.setAttribute('flow-id', str(flow_id))
2.41 +
2.42 + #Time timeFirstTxPacket;
2.43 + flow_el.setAttribute("time-first-tx-packet", str(stats.timeFirstTxPacket))
2.44 +
2.45 + #Time timeFirstRxPacket;
2.46 + flow_el.setAttribute("time-first-rx-packet", str(stats.timeFirstRxPacket))
2.47 +
2.48 + #Time timeLastTxPacket;
2.49 + flow_el.setAttribute("time-last-tx-packet", str(stats.timeLastTxPacket))
2.50 +
2.51 + #Time timeLastRxPacket;
2.52 + flow_el.setAttribute("time-last-rx-packet", str(stats.timeLastRxPacket))
2.53 +
2.54 + #Time delaySum;
2.55 + flow_el.setAttribute("delay-sum", str(stats.delaySum))
2.56 +
2.57 + #uint64_t txBytes;
2.58 + flow_el.setAttribute("tx-bytes", str(stats.txBytes))
2.59 +
2.60 + #uint64_t rxBytes;
2.61 + flow_el.setAttribute("rx-bytes", str(stats.rxBytes))
2.62 +
2.63 + #uint32_t txPackets;
2.64 + flow_el.setAttribute("tx-packets", str(stats.txPackets))
2.65 +
2.66 + #uint32_t rxPackets;
2.67 + flow_el.setAttribute("rx-packets", str(stats.rxPackets))
2.68 +
2.69 + #uint32_t lostPackets;
2.70 + flow_el.setAttribute("lost-packets", str(stats.lostPackets))
2.71 +
2.72 + #uint32_t timesForwarded;
2.73 + flow_el.setAttribute("times-forwarded", str(stats.timesForwarded))
2.74 +
2.75 + # -- add ipv4 flow filtering information
2.76 + five_tuple = flow_classifier.FindFlow(flow_id)
2.77 + five_tuple_el = flow_el.appendChild(doc.createElement('five-tuple'))
2.78 + five_tuple_el.setAttribute("protocol", str(five_tuple.protocol))
2.79 + five_tuple_el.setAttribute("source-address", str(five_tuple.sourceAddress))
2.80 + five_tuple_el.setAttribute("destination-address", str(five_tuple.destinationAddress))
2.81 + five_tuple_el.setAttribute("source-port", str(five_tuple.sourcePort))
2.82 + five_tuple_el.setAttribute("destination-port", str(five_tuple.destinationPort))
2.83 +
2.84 + doc.writexml(results_file, addindent=' ', newl='\n', encoding='utf-8')
2.85 + results_file.close()
2.86 +
2.87 +
2.88 +def main(argv):
2.89 +
2.90 + cmd = ns3.CommandLine()
2.91 +
2.92 + cmd.Viz = None
2.93 + cmd.AddValue("Viz", "Enable visualizer")
2.94 +
2.95 + cmd.NumNodesSide = None
2.96 + cmd.AddValue("NumNodesSide", "Grid side number of nodes (total number of nodes will be this number squared)")
2.97 + cmd.AddValue("EnableMonitor", "Set to 0 or 1 to disable/enable flow monitoring")
2.98 + cmd.AddValue("RunNumber", "Run number (statistics)")
2.99 + cmd.AddValue("Results", "Write results to the given file")
2.100 + cmd.AddValue("StopTime", "Simulation stop time")
2.101 +
2.102 + cmd.Parse(argv)
2.103 +
2.104 + enable_monitor = int(cmd.EnableMonitor)
2.105 + run_number = int(cmd.RunNumber)
2.106 + if cmd.NumNodesSide is None:
2.107 + num_nodes_side = NUM_NODES_SIDE
2.108 + else:
2.109 + num_nodes_side = int(cmd.NumNodesSide)
2.110 +
2.111 +
2.112 + ns3.RandomVariable.UseGlobalSeed(1, 1, 2, 3, 5, 8)
2.113 + ns3.RandomVariable.SetRunNumber(run_number)
2.114 +
2.115 + p2p = ns3.PointToPointHelper()
2.116 + p2p.SetDeviceAttribute("DataRate", ns3.StringValue("5Mbps"))
2.117 + p2p.SetChannelAttribute("Delay", ns3.StringValue("2ms"))
2.118 +
2.119 + internet = ns3.InternetStackHelper()
2.120 + ipv4Addresses = ns3.Ipv4AddressHelper()
2.121 + ipv4Addresses.SetBase(ns3.Ipv4Address("10.0.0.0"), ns3.Ipv4Mask("255.255.255.255"))
2.122 +
2.123 + olsrHelper = ns3.OlsrHelper()
2.124 +
2.125 + port = 9 # Discard port(RFC 863)
2.126 + onOffHelper = ns3.OnOffHelper("ns3::UdpSocketFactory",
2.127 + ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address("10.0.0.1"), port)))
2.128 + onOffHelper.SetAttribute("DataRate", ns3.DataRateValue(ns3.DataRate("100kbps")))
2.129 + onOffHelper.SetAttribute("OnTime", ns3.RandomVariableValue(ns3.ConstantVariable(1)))
2.130 + onOffHelper.SetAttribute("OffTime", ns3.RandomVariableValue(ns3.ConstantVariable(0)))
2.131 +
2.132 + nodes = []
2.133 + for yi in range(num_nodes_side):
2.134 + nodes_row = []
2.135 + nodes.append(nodes_row)
2.136 + for xi in range(num_nodes_side):
2.137 +
2.138 + node = ns3.Node()
2.139 + nodes_row.append(node)
2.140 +
2.141 + internet.Install(ns3.NodeContainer(node))
2.142 +
2.143 + mobility = ns3.StaticMobilityModel()
2.144 + mobility.SetPosition(ns3.Vector(xi*DISTANCE, yi*DISTANCE, 0))
2.145 + node.AggregateObject(mobility)
2.146 +
2.147 + node_main_address = None
2.148 +
2.149 + if xi > 0:
2.150 + node_left = nodes[yi][xi-1]
2.151 + devices = p2p.Install(ns3.NodeContainer(ns3.NodeContainer(node), ns3.NodeContainer(node_left)))
2.152 + ipv4Addresses.Assign(devices)
2.153 +
2.154 + if yi > 0:
2.155 + node_above = nodes[yi-1][xi]
2.156 + devices = p2p.Install(ns3.NodeContainer(ns3.NodeContainer(node), ns3.NodeContainer(node_above)))
2.157 + ipv4Addresses.Assign(devices)
2.158 +
2.159 + def get_node_address(node):
2.160 + return node.GetObject(ns3.Ipv4.GetTypeId()).GetAddress(1)
2.161 +
2.162 +
2.163 + for yi, nodes_row in enumerate(nodes):
2.164 + for xi, node in enumerate(nodes_row):
2.165 + olsrHelper.Install(ns3.NodeContainer(node))
2.166 + destaddr = get_node_address(nodes[(yi-1)%num_nodes_side][(xi-1)%num_nodes_side])
2.167 + onOffHelper.SetAttribute("Remote", ns3.AddressValue(ns3.InetSocketAddress(destaddr, port)))
2.168 + app = onOffHelper.Install(ns3.NodeContainer(node))
2.169 + app.Start(ns3.Seconds(ns3.UniformVariable(20, 30).GetValue()))
2.170 +
2.171 +
2.172 + if enable_monitor:
2.173 + flowmon_helper = ns3.FlowMonitorHelper()
2.174 + flowmon_helper.SetMonitorAttribute("StartTime", ns3.TimeValue(ns3.Seconds(31)))
2.175 + monitor = flowmon_helper.InstallAll()
2.176 + classifier = flowmon_helper.GetClassifier()
2.177 +
2.178 + ns3.Simulator.Stop(ns3.Seconds(float(getattr(cmd, "StopTime", "100"))))
2.179 + if cmd.Viz is not None:
2.180 + import visualizer
2.181 + visualizer.start()
2.182 + else:
2.183 + ns3.Simulator.Run()
2.184 +
2.185 + def print_stats(os, monitor, classifier):
2.186 + def print_flow_stats(os, st):
2.187 + print >> os, " Tx Bytes: ", st.txBytes
2.188 + print >> os, " Rx Bytes: ", st.rxBytes
2.189 + print >> os, " Tx Packets: ", st.txPackets
2.190 + print >> os, " Rx Packets: ", st.rxPackets
2.191 + print >> os, " Lost Packets: ", st.lostPackets
2.192 + if st.rxPackets > 0:
2.193 + print >> os, " Mean{Delay}: ", (st.delaySum.GetSeconds() / st.rxPackets)
2.194 + print >> os, " Mean{Hop Count}: ", float(st.timesForwarded) / st.rxPackets + 1
2.195 +
2.196 + monitor.CheckForLostPackets()
2.197 + for flow_id, flow_stats in monitor.GetFlowStats():
2.198 + t = classifier.FindFlow(flow_id)
2.199 + proto = {6: 'TCP', 17: 'UDP'} [t.protocol]
2.200 + print "FlowID: %i (%s %s/%s --> %s/%i)" % \
2.201 + (flow_id, proto, t.sourceAddress, t.sourcePort, t.destinationAddress, t.destinationPort)
2.202 + print_flow_stats(sys.stdout, flow_stats)
2.203 +
2.204 + if enable_monitor:
2.205 + if hasattr(cmd, "Results"):
2.206 + write_flowmon_results_to_file(cmd.Results, monitor, classifier)
2.207 + else:
2.208 + print_stats(sys.stdout, monitor, classifier)
2.209 +
2.210 + return 0
2.211 +
2.212 +
2.213 +if __name__ == '__main__':
2.214 + sys.exit(main(sys.argv))
2.215 +