3 # NEPI, a framework to manage network experiments
4 # Copyright (C) 2013 INRIA
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 2 as
8 # published by the Free Software Foundation;
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
21 # Test based on ns-3 csma/examples/csma-ping.cc file
29 # node n0 sends IGMP traffic to node n3
31 from __future__ import print_function
33 from nepi.resources.ns3.ns3wrapper import NS3Wrapper
41 class NS3WrapperTest(unittest.TestCase):
45 def test_csma_ping(self):
46 wrapper = NS3Wrapper()
50 c = wrapper.create("NodeContainer")
53 wrapper.invoke(c, "Create", 4)
55 ### connect the nodes to a shared channel
57 csma = wrapper.create("CsmaHelper")
59 # csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
60 dr = wrapper.create("DataRate", 5000000)
61 drv = wrapper.create("DataRateValue", dr)
62 wrapper.invoke(csma, "SetChannelAttribute", "DataRate", drv)
64 # csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
65 ms = wrapper.create("MilliSeconds", 2)
66 delay = wrapper.create("TimeValue", ms)
67 wrapper.invoke(csma, "SetChannelAttribute", "Delay", delay)
69 # csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
70 encap = wrapper.create("StringValue", "Llc")
71 wrapper.invoke(csma, "SetDeviceAttribute", "EncapsulationMode", encap)
73 # NetDeviceContainer devs = csma.Install (c);
74 devs = wrapper.invoke(csma, "Install", c)
76 ### add IP stack to all nodes
77 # InternetStackHelper ipStack;
78 ipStack = wrapper.create("InternetStackHelper")
80 # ipStack.Install (c);
81 wrapper.invoke(ipStack, "Install", c)
83 ### assign ip addresses
84 #Ipv4AddressHelper ip;
85 ip = wrapper.create("Ipv4AddressHelper")
87 # ip.SetBase ("192.168.1.0", "255.255.255.0");
88 ip4 = wrapper.create("Ipv4Address", "192.168.1.0")
89 mask4 = wrapper.create("Ipv4Mask", "255.255.255.0")
90 wrapper.invoke(ip, "SetBase", ip4, mask4)
92 # Ipv4InterfaceContainer addresses = ip.Assign (devs);
93 addresses = wrapper.invoke(ip, "Assign", devs)
96 # Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
97 proto = wrapper.create("StringValue", "2")
98 wrapper.invoke("singleton::Config", "SetDefault",
99 "ns3::Ipv4RawSocketImpl::Protocol", proto)
101 # InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
102 addr3 = wrapper.invoke(addresses, "GetAddress", 3)
103 dst = wrapper.create("InetSocketAddress", addr3)
105 # OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
106 onoff = wrapper.create("OnOffHelper", "ns3::Ipv4RawSocketFactory", dst)
108 # onoff.SetAttribute ("DataRate", DataRateValue (DataRate (15000)));
109 dr2 = wrapper.create("DataRate", 15000)
110 drv2 = wrapper.create("DataRateValue", dr2)
111 wrapper.invoke(onoff, "SetAttribute", "DataRate", drv2)
113 # onoff.SetAttribute ("PacketSize", UintegerValue (1200));
114 uiv = wrapper.create("UintegerValue", 1200)
115 wrapper.invoke(onoff, "SetAttribute", "PacketSize", uiv)
117 # ApplicationContainer apps = onoff.Install (c.Get (0));
118 n1 = wrapper.invoke(c, "Get", 0)
119 apps = wrapper.invoke(onoff, "Install", n1)
121 # apps.Start (Seconds (1.0));
122 s1 = wrapper.create("Seconds", 1.0)
123 wrapper.invoke(apps, "Start", s1)
125 # apps.Stop (Seconds (10.0));
126 s2 = wrapper.create("Seconds", 10.0)
127 wrapper.invoke(apps, "Stop", s2)
130 # PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
131 sink = wrapper.create("PacketSinkHelper", "ns3::Ipv4RawSocketFactory", dst)
133 # apps = sink.Install (c.Get (3));
134 n3 = wrapper.invoke(c, "Get", 3)
135 apps = wrapper.invoke (sink, "Install", n3)
137 # apps.Start (Seconds (0.0));
138 s3 = wrapper.create ("Seconds", 0.0)
139 wrapper.invoke (apps, "Start", s3)
141 # apps.Stop (Seconds (11.0));
142 s4 = wrapper.create ("Seconds", 11.0)
143 wrapper.invoke (apps, "Stop", s4)
146 #V4PingHelper ping = V4PingHelper (addresses.GetAddress (2));
147 addr2 = wrapper.invoke(addresses, "GetAddress", 2)
148 ping = wrapper.create("V4PingHelper", addr2)
150 #NodeContainer pingers;
151 pingers = wrapper.create("NodeContainer")
153 #pingers.Add (c.Get (0));
154 n0 = wrapper.invoke(c, "Get", 0)
155 wrapper.invoke(pingers, "Add", n0)
157 #pingers.Add (c.Get (1));
158 n1 = wrapper.invoke(c, "Get", 1)
159 wrapper.invoke(pingers, "Add", n1)
161 #pingers.Add (c.Get (3));
162 n3 = wrapper.invoke(c, "Get", 3)
163 wrapper.invoke(pingers, "Add", n3)
165 #apps = ping.Install (pingers);
166 apps = wrapper.invoke(ping, "Install", pingers)
168 #apps.Start (Seconds (2.0));
169 s5 = wrapper.create ("Seconds", 2.0)
170 wrapper.invoke (apps, "Start", s5)
172 #apps.Stop (Seconds (5.0));
173 s6 = wrapper.create ("Seconds", 5.0)
174 wrapper.invoke (apps, "Stop", s6)
176 ### configure tracing
177 #csma.EnablePcapAll ("csma-ping", false);
178 wrapper.invoke(csma, "EnablePcapAll", "/tmp/csma-ping-pcap", False)
180 #csma.EnableAsciiAll ("csma-ping", false);
181 wrapper.invoke(csma, "EnableAsciiAll", "/tmp/csma-ping-ascii")
183 def SinkRx(packet, address):
186 def PingRtt(context, rtt):
189 # XXX: No biding for MakeCallback
190 #Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx",
191 # MakeCallback (&SinkRx));
192 #cb = wrapper.create("MakeCallback", SinkRx)
193 #wrapper.invoke("singleton::Config", "ConnectWithoutContext",
194 # "/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", cb)
196 # Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt",
197 # MakeCallback (&PingRtt));
198 #cb2 = wrapper.create("MakeCallback", PingRtt)
199 #wrapper.invoke("singleton::Config", "ConnectWithoutContext",
200 # "/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt",
203 # Packet::EnablePrinting ();
204 wrapper.invoke("singleton::Packet", "EnablePrinting")
208 wrapper.invoke("singleton::Simulator", "Run")
210 # Simulator::Destroy ();
211 wrapper.invoke("singleton::Simulator", "Destroy")
213 p = subprocess.Popen("ls /tmp/csma-ping-* | wc -w", stdout = subprocess.PIPE,
214 stderr = subprocess.PIPE, shell = True)
215 (out, err) = p.communicate()
217 self.assertEqual(int(out), 8)
219 p = subprocess.Popen("rm /tmp/csma-ping-*", shell = True)
222 def test_start(self):
224 wrapper = NS3Wrapper()
227 c = wrapper.create("NodeContainer")
230 wrapper.invoke(c, "Create", 2)
232 ### connect the nodes to a shared channel
234 csma = wrapper.create("CsmaHelper")
236 # csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
237 dr = wrapper.create("DataRate", 5000000)
238 drv = wrapper.create("DataRateValue", dr)
239 wrapper.invoke(csma, "SetChannelAttribute", "DataRate", drv)
241 # csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
242 ms = wrapper.create("MilliSeconds", 2)
243 delay = wrapper.create("TimeValue", ms)
244 wrapper.invoke(csma, "SetChannelAttribute", "Delay", delay)
246 # NetDeviceContainer devs = csma.Install (c);
247 devs = wrapper.invoke(csma, "Install", c)
249 ### add IP stack to all nodes
250 # InternetStackHelper ipStack;
251 ipStack = wrapper.create("InternetStackHelper")
253 # ipStack.Install (c);
254 wrapper.invoke(ipStack, "Install", c)
256 ### assign ip addresses
257 #Ipv4AddressHelper ip;
258 ip = wrapper.create("Ipv4AddressHelper")
260 # ip.SetBase ("192.168.1.0", "255.255.255.0");
261 ip4 = wrapper.create("Ipv4Address", "192.168.1.0")
262 mask4 = wrapper.create("Ipv4Mask", "255.255.255.0")
263 wrapper.invoke(ip, "SetBase", ip4, mask4)
265 # Ipv4InterfaceContainer addresses = ip.Assign (devs);
266 addresses = wrapper.invoke(ip, "Assign", devs)
269 #V4PingHelper ping = V4PingHelper (addresses.GetAddress (1));
270 addr1 = wrapper.invoke(addresses, "GetAddress", 1)
271 ping = wrapper.create("V4PingHelper", addr1)
272 btrue = wrapper.create("BooleanValue", True)
273 wrapper.invoke(ping, "SetAttribute", "Verbose", btrue)
275 #apps = ping.Install (pingers);
276 n0 = wrapper.invoke(c, "Get", 0)
277 apps = wrapper.invoke(ping, "Install", n0)
279 #apps.Start (Seconds (0.0));
280 s = wrapper.create ("Seconds", 0.0)
281 wrapper.invoke (apps, "Start", s)
283 #apps.Stop (Seconds (5.0));
284 s = wrapper.create ("Seconds", 5.0)
285 wrapper.invoke (apps, "Stop", s)
288 # Simulator::Stop (6.0);
289 wrapper.stop(time = "6s")
294 # wait until simulation is over
297 # TODO: Add assertions !!
299 def test_runtime_attr_modify(self):
300 wrapper = NS3Wrapper()
302 # Define a real time simulation
303 stype = wrapper.create("StringValue", "ns3::RealtimeSimulatorImpl")
304 wrapper.invoke("singleton::GlobalValue", "Bind", "SimulatorImplementationType", stype)
305 btrue = wrapper.create("BooleanValue", True)
306 wrapper.invoke("singleton::GlobalValue", "Bind", "ChecksumEnabled", btrue)
310 n1 = wrapper.create("Node")
312 ## Install internet stack
313 ipv41 = wrapper.create("Ipv4L3Protocol")
314 wrapper.invoke(n1, "AggregateObject", ipv41)
316 arp1 = wrapper.create("ArpL3Protocol")
317 wrapper.invoke(n1, "AggregateObject", arp1)
319 icmp1 = wrapper.create("Icmpv4L4Protocol")
320 wrapper.invoke(n1, "AggregateObject", icmp1)
323 lr1 = wrapper.create("Ipv4ListRouting")
324 wrapper.invoke(ipv41, "SetRoutingProtocol", lr1)
325 sr1 = wrapper.create("Ipv4StaticRouting")
326 wrapper.invoke(lr1, "AddRoutingProtocol", sr1, 1)
329 n2 = wrapper.create("Node")
331 ## Install internet stack
332 ipv42 = wrapper.create("Ipv4L3Protocol")
333 wrapper.invoke(n2, "AggregateObject", ipv42)
335 arp2 = wrapper.create("ArpL3Protocol")
336 wrapper.invoke(n2, "AggregateObject", arp2)
338 icmp2 = wrapper.create("Icmpv4L4Protocol")
339 wrapper.invoke(n2, "AggregateObject", icmp2)
342 lr2 = wrapper.create("Ipv4ListRouting")
343 wrapper.invoke(ipv42, "SetRoutingProtocol", lr2)
344 sr2 = wrapper.create("Ipv4StaticRouting")
345 wrapper.invoke(lr2, "AddRoutingProtocol", sr2, 1)
347 ##### Create p2p device and enable ascii tracing
349 p2pHelper = wrapper.create("PointToPointHelper")
350 asciiHelper = wrapper.create("AsciiTraceHelper")
353 p1 = wrapper.create("PointToPointNetDevice")
354 wrapper.invoke(n1, "AddDevice", p1)
355 q1 = wrapper.create("DropTailQueue")
356 wrapper.invoke(p1, "SetQueue", q1)
359 ifindex1 = wrapper.invoke(ipv41, "AddInterface", p1)
360 mask1 = wrapper.create("Ipv4Mask", "/30")
361 addr1 = wrapper.create("Ipv4Address", "10.0.0.1")
362 inaddr1 = wrapper.create("Ipv4InterfaceAddress", addr1, mask1)
363 wrapper.invoke(ipv41, "AddAddress", ifindex1, inaddr1)
364 wrapper.invoke(ipv41, "SetMetric", ifindex1, 1)
365 wrapper.invoke(ipv41, "SetUp", ifindex1)
367 # Enable collection of Ascii format to a specific file
368 filepath1 = "/tmp/trace-p2p-1.tr"
369 stream1 = wrapper.invoke(asciiHelper, "CreateFileStream", filepath1)
370 wrapper.invoke(p2pHelper, "EnableAscii", stream1, p1)
373 p2 = wrapper.create("PointToPointNetDevice")
374 wrapper.invoke(n2, "AddDevice", p2)
375 q2 = wrapper.create("DropTailQueue")
376 wrapper.invoke(p2, "SetQueue", q2)
379 ifindex2 = wrapper.invoke(ipv42, "AddInterface", p2)
380 mask2 = wrapper.create("Ipv4Mask", "/30")
381 addr2 = wrapper.create("Ipv4Address", "10.0.0.2")
382 inaddr2 = wrapper.create("Ipv4InterfaceAddress", addr2, mask2)
383 wrapper.invoke(ipv42, "AddAddress", ifindex2, inaddr2)
384 wrapper.invoke(ipv42, "SetMetric", ifindex2, 1)
385 wrapper.invoke(ipv42, "SetUp", ifindex2)
387 # Enable collection of Ascii format to a specific file
388 filepath2 = "/tmp/trace-p2p-2.tr"
389 stream2 = wrapper.invoke(asciiHelper, "CreateFileStream", filepath2)
390 wrapper.invoke(p2pHelper, "EnableAscii", stream2, p2)
393 chan = wrapper.create("PointToPointChannel")
394 wrapper.set(chan, "Delay", "0s")
395 wrapper.invoke(p1, "Attach", chan)
396 wrapper.invoke(p2, "Attach", chan)
399 ping = wrapper.create("V4Ping")
400 wrapper.invoke(n1, "AddApplication", ping)
401 wrapper.set (ping, "Remote", "10.0.0.2")
402 wrapper.set (ping, "Interval", "1s")
403 wrapper.set (ping, "Verbose", True)
404 wrapper.set (ping, "StartTime", "0s")
405 wrapper.set (ping, "StopTime", "20s")
408 wrapper.stop(time = "21s")
413 wrapper.set(chan, "Delay", "5s")
417 wrapper.set(chan, "Delay", "0s")
419 # wait until simulation is over
422 p = subprocess.Popen("rm /tmp/trace-p2p-*", shell = True)
425 # TODO: Add assertions !!
427 if __name__ == '__main__':