Added factroy method to the ns-3 wrapper
[nepi.git] / test / resources / ns3 / ns3wrapper.py
1 #!/usr/bin/env python
2 #
3 #    NEPI, a framework to manage network experiments
4 #    Copyright (C) 2013 INRIA
5 #
6 #    This program is free software: you can redistribute it and/or modify
7 #    it under the terms of the GNU General Public License as published by
8 #    the Free Software Foundation, either version 3 of the License, or
9 #    (at your option) any later version.
10 #
11 #    This program is distributed in the hope that it will be useful,
12 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #    GNU General Public License for more details.
15 #
16 #    You should have received a copy of the GNU General Public License
17 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
20
21
22 # Test based on ns-3 csma/examples/csma-ping.cc file
23 #
24 # Network topology
25 #
26 #       n0    n1   n2   n3
27 #       |     |    |    |
28 #       -----------------
29 #
30 #  node n0 sends IGMP traffic to node n3
31
32
33 from nepi.resources.ns3.ns3wrapper import NS3Wrapper
34
35 import subprocess
36 import time
37 import unittest
38
39 class NS3WrapperTest(unittest.TestCase):
40     def setUp(self):
41         pass
42
43     def test_csma_ping(self):
44         wrapper = NS3Wrapper()
45
46         ### create 4  nodes
47         # NodeContainer c;
48         c = wrapper.create("NodeContainer")
49
50         # c.Create (4);
51         wrapper.invoke(c, "Create", 4)
52
53         ### connect the nodes to a shared channel
54         # CsmaHelper csma;
55         csma = wrapper.create("CsmaHelper")
56
57         # csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
58         dr = wrapper.create("DataRate", 5000000)
59         drv = wrapper.create("DataRateValue", dr)
60         wrapper.invoke(csma, "SetChannelAttribute", "DataRate", drv)
61
62         # csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
63         ms = wrapper.create("MilliSeconds", 2)
64         delay = wrapper.create("TimeValue", ms)
65         wrapper.invoke(csma, "SetChannelAttribute", "Delay", delay)
66
67         # csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
68         encap = wrapper.create("StringValue", "Llc")
69         wrapper.invoke(csma, "SetDeviceAttribute", "EncapsulationMode", encap)
70
71         # NetDeviceContainer devs = csma.Install (c);
72         devs = wrapper.invoke(csma, "Install", c)
73
74         ### add IP stack to all nodes
75         # InternetStackHelper ipStack;
76         ipStack = wrapper.create("InternetStackHelper")
77         
78         # ipStack.Install (c);
79         wrapper.invoke(ipStack, "Install", c)
80
81         ### assign ip addresses
82         #Ipv4AddressHelper ip;
83         ip = wrapper.create("Ipv4AddressHelper")
84
85         # ip.SetBase ("192.168.1.0", "255.255.255.0");
86         ip4 = wrapper.create("Ipv4Address", "192.168.1.0")
87         mask4 = wrapper.create("Ipv4Mask", "255.255.255.0")
88         wrapper.invoke(ip, "SetBase", ip4, mask4)
89
90         # Ipv4InterfaceContainer addresses = ip.Assign (devs);
91         addresses = wrapper.invoke(ip, "Assign", devs)
92
93         ### Create source
94         # Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
95         proto = wrapper.create("StringValue", "2")
96         wrapper.invoke("singleton::Config", "SetDefault", 
97                 "ns3::Ipv4RawSocketImpl::Protocol", proto)
98
99         # InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
100         addr3 = wrapper.invoke(addresses, "GetAddress", 3)
101         dst = wrapper.create("InetSocketAddress", addr3)
102
103         # OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
104         onoff = wrapper.create("OnOffHelper", "ns3::Ipv4RawSocketFactory", dst)
105
106         # onoff.SetAttribute ("DataRate", DataRateValue (DataRate (15000)));
107         dr2 = wrapper.create("DataRate", 15000)
108         drv2 = wrapper.create("DataRateValue", dr2)
109         wrapper.invoke(onoff, "SetAttribute", "DataRate", drv2)
110
111         # onoff.SetAttribute ("PacketSize", UintegerValue (1200));
112         uiv = wrapper.create("UintegerValue", 1200)
113         wrapper.invoke(onoff, "SetAttribute", "PacketSize", uiv)
114
115         # ApplicationContainer apps = onoff.Install (c.Get (0));
116         n1 = wrapper.invoke(c, "Get", 0)
117         apps = wrapper.invoke(onoff, "Install", n1)
118         
119         # apps.Start (Seconds (1.0));
120         s1 = wrapper.create("Seconds", 1.0)
121         wrapper.invoke(apps, "Start", s1)
122         
123         # apps.Stop (Seconds (10.0));
124         s2 = wrapper.create("Seconds", 10.0)
125         wrapper.invoke(apps, "Stop", s2)
126
127         ### create sink
128         # PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
129         sink = wrapper.create("PacketSinkHelper", "ns3::Ipv4RawSocketFactory", dst)
130         
131         # apps = sink.Install (c.Get (3));
132         n3 = wrapper.invoke(c, "Get", 3)
133         apps = wrapper.invoke (sink, "Install", n3)
134         
135         # apps.Start (Seconds (0.0));
136         s3 = wrapper.create ("Seconds", 0.0)
137         wrapper.invoke (apps, "Start", s3)
138         
139         # apps.Stop (Seconds (11.0));
140         s4 = wrapper.create ("Seconds", 11.0)
141         wrapper.invoke (apps, "Stop", s4)
142
143         ### create pinger
144         #V4PingHelper ping = V4PingHelper (addresses.GetAddress (2));
145         addr2 = wrapper.invoke(addresses, "GetAddress", 2)
146         ping = wrapper.create("V4PingHelper", addr2)
147         
148         #NodeContainer pingers;
149         pingers = wrapper.create("NodeContainer")
150         
151         #pingers.Add (c.Get (0));
152         n0 = wrapper.invoke(c, "Get", 0)
153         wrapper.invoke(pingers, "Add", n0)
154         
155         #pingers.Add (c.Get (1));
156         n1 = wrapper.invoke(c, "Get", 1)
157         wrapper.invoke(pingers, "Add", n1)
158         
159         #pingers.Add (c.Get (3));
160         n3 = wrapper.invoke(c, "Get", 3)
161         wrapper.invoke(pingers, "Add", n3)
162         
163         #apps = ping.Install (pingers);
164         apps = wrapper.invoke(ping, "Install", pingers)
165         
166         #apps.Start (Seconds (2.0));
167         s5 = wrapper.create ("Seconds", 2.0)
168         wrapper.invoke (apps, "Start", s5)
169         
170         #apps.Stop (Seconds (5.0));
171         s6 = wrapper.create ("Seconds", 5.0)
172         wrapper.invoke (apps, "Stop", s6)
173
174         ### configure tracing
175         #csma.EnablePcapAll ("csma-ping", false);
176         wrapper.invoke(csma, "EnablePcapAll", "/tmp/csma-ping-pcap", False)
177  
178         #csma.EnableAsciiAll ("csma-ping", false);
179         wrapper.invoke(csma, "EnableAsciiAll", "/tmp/csma-ping-ascii")
180  
181         def SinkRx(packet, address):
182             print packet
183
184         def PingRtt(context, rtt):
185             print context, rtt
186       
187         # XXX: No biding for MakeCallback
188         #Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", 
189         # MakeCallback (&SinkRx));
190         #cb = wrapper.create("MakeCallback", SinkRx)
191         #wrapper.invoke("singleton::Config", "ConnectWithoutContext", 
192         #        "/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", cb)
193
194         # Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt", 
195         # MakeCallback (&PingRtt));
196         #cb2 = wrapper.create("MakeCallback", PingRtt)
197         #wrapper.invoke("singleton::Config", "ConnectWithoutContext", 
198         #        "/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt", 
199         #        cb2)
200
201         # Packet::EnablePrinting ();
202         wrapper.invoke("singleton::Packet", "EnablePrinting")
203
204         ### run Simulation
205         # Simulator::Run ();
206         wrapper.invoke("singleton::Simulator", "Run")
207
208         # Simulator::Destroy ();
209         wrapper.invoke("singleton::Simulator", "Destroy")
210
211         p = subprocess.Popen("ls /tmp/csma-ping-* | wc -w", stdout = subprocess.PIPE, 
212                 stderr = subprocess.PIPE, shell = True)
213         (out, err) = p.communicate()
214
215         self.assertEquals(int(out), 8)
216
217         p = subprocess.Popen("rm /tmp/csma-ping-*",  shell = True)
218         p.communicate()
219
220     def test_start(self):
221         wrapper = NS3Wrapper()
222
223         ### create 2  nodes
224         c = wrapper.create("NodeContainer")
225
226         # c.Create (2);
227         wrapper.invoke(c, "Create", 2)
228
229         ### connect the nodes to a shared channel
230         # CsmaHelper csma;
231         csma = wrapper.create("CsmaHelper")
232
233         # csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
234         dr = wrapper.create("DataRate", 5000000)
235         drv = wrapper.create("DataRateValue", dr)
236         wrapper.invoke(csma, "SetChannelAttribute", "DataRate", drv)
237
238         # csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
239         ms = wrapper.create("MilliSeconds", 2)
240         delay = wrapper.create("TimeValue", ms)
241         wrapper.invoke(csma, "SetChannelAttribute", "Delay", delay)
242
243         # NetDeviceContainer devs = csma.Install (c);
244         devs = wrapper.invoke(csma, "Install", c)
245
246         ### add IP stack to all nodes
247         # InternetStackHelper ipStack;
248         ipStack = wrapper.create("InternetStackHelper")
249         
250         # ipStack.Install (c);
251         wrapper.invoke(ipStack, "Install", c)
252
253         ### assign ip addresses
254         #Ipv4AddressHelper ip;
255         ip = wrapper.create("Ipv4AddressHelper")
256
257         # ip.SetBase ("192.168.1.0", "255.255.255.0");
258         ip4 = wrapper.create("Ipv4Address", "192.168.1.0")
259         mask4 = wrapper.create("Ipv4Mask", "255.255.255.0")
260         wrapper.invoke(ip, "SetBase", ip4, mask4)
261
262         # Ipv4InterfaceContainer addresses = ip.Assign (devs);
263         addresses = wrapper.invoke(ip, "Assign", devs)
264
265         ### create pinger
266         #V4PingHelper ping = V4PingHelper (addresses.GetAddress (1));
267         addr1 = wrapper.invoke(addresses, "GetAddress", 1)
268         ping = wrapper.create("V4PingHelper", addr1)
269         btrue = wrapper.create("BooleanValue", True)
270         wrapper.invoke(ping, "SetAttribute", "Verbose", btrue)
271         
272         #apps = ping.Install (pingers);
273         n0 = wrapper.invoke(c, "Get", 0)
274         apps = wrapper.invoke(ping, "Install", n0)
275         
276         #apps.Start (Seconds (0.0));
277         s = wrapper.create ("Seconds", 0.0)
278         wrapper.invoke (apps, "Start", s)
279         
280         #apps.Stop (Seconds (5.0));
281         s = wrapper.create ("Seconds", 5.0)
282         wrapper.invoke (apps, "Stop", s)
283
284         ### run Simulation
285         # Simulator::Stop (6.0);
286         wrapper.stop(time = "6s")
287
288         # Simulator::Run ();
289         wrapper.start()
290
291         # wait until simulation is over
292         wrapper.shutdown()
293
294     def test_runtime_attr_modify(self):
295         wrapper = NS3Wrapper()
296        
297         # Define a real time simulation 
298         stype = wrapper.create("StringValue", "ns3::RealtimeSimulatorImpl")
299         wrapper.invoke("singleton::GlobalValue", "Bind", "SimulatorImplementationType", stype)
300         btrue = wrapper.create("BooleanValue", True)
301         wrapper.invoke("singleton::GlobalValue", "Bind", "ChecksumEnabled", btrue)
302
303         ### create 2  nodes
304         ## NODE 1
305         n1 = wrapper.create("Node")
306
307         ## Install internet stack
308         ipv41 = wrapper.create("Ipv4L3Protocol")
309         wrapper.invoke(n1, "AggregateObject", ipv41)
310
311         arp1 = wrapper.create("ArpL3Protocol")
312         wrapper.invoke(n1, "AggregateObject", arp1)
313         
314         icmp1 = wrapper.create("Icmpv4L4Protocol")
315         wrapper.invoke(n1, "AggregateObject", icmp1)
316
317         ## Add IPv4 routing
318         lr1 = wrapper.create("Ipv4ListRouting")
319         wrapper.invoke(ipv41, "SetRoutingProtocol", lr1)
320         sr1 = wrapper.create("Ipv4StaticRouting")
321         wrapper.invoke(lr1, "AddRoutingProtocol", sr1, 1)
322
323         ## NODE 2
324         n2 = wrapper.create("Node")
325
326         ## Install internet stack
327         ipv42 = wrapper.create("Ipv4L3Protocol")
328         wrapper.invoke(n2, "AggregateObject", ipv42)
329
330         arp2 = wrapper.create("ArpL3Protocol")
331         wrapper.invoke(n2, "AggregateObject", arp2)
332         
333         icmp2 = wrapper.create("Icmpv4L4Protocol")
334         wrapper.invoke(n2, "AggregateObject", icmp2)
335
336         ## Add IPv4 routing
337         lr2 = wrapper.create("Ipv4ListRouting")
338         wrapper.invoke(ipv42, "SetRoutingProtocol", lr2)
339         sr2 = wrapper.create("Ipv4StaticRouting")
340         wrapper.invoke(lr2, "AddRoutingProtocol", sr2, 1)
341
342         ##### Create p2p device and enable ascii tracing
343
344         p2pHelper = wrapper.create("PointToPointHelper")
345         asciiHelper = wrapper.create("AsciiTraceHelper")
346
347         # Iface for node1
348         p1 = wrapper.create("PointToPointNetDevice")
349         wrapper.invoke(n1, "AddDevice", p1)
350         q1 = wrapper.create("DropTailQueue")
351         wrapper.invoke(p1, "SetQueue", q1)
352       
353         # Add IPv4 address
354         ifindex1 = wrapper.invoke(ipv41, "AddInterface", p1)
355         mask1 = wrapper.create("Ipv4Mask", "/30")
356         addr1 = wrapper.create("Ipv4Address", "10.0.0.1")
357         inaddr1 = wrapper.create("Ipv4InterfaceAddress", addr1, mask1)
358         wrapper.invoke(ipv41, "AddAddress", ifindex1, inaddr1)
359         wrapper.invoke(ipv41, "SetMetric", ifindex1, 1)
360         wrapper.invoke(ipv41, "SetUp", ifindex1)
361
362         # Enable collection of Ascii format to a specific file
363         filepath1 = "/tmp/trace-p2p-1.tr"
364         stream1 = wrapper.invoke(asciiHelper, "CreateFileStream", filepath1)
365         wrapper.invoke(p2pHelper, "EnableAscii", stream1, p1)
366        
367         # Iface for node2
368         p2 = wrapper.create("PointToPointNetDevice")
369         wrapper.invoke(n2, "AddDevice", p2)
370         q2 = wrapper.create("DropTailQueue")
371         wrapper.invoke(p2, "SetQueue", q2)
372
373         # Add IPv4 address
374         ifindex2 = wrapper.invoke(ipv42, "AddInterface", p2)
375         mask2 = wrapper.create("Ipv4Mask", "/30")
376         addr2 = wrapper.create("Ipv4Address", "10.0.0.2")
377         inaddr2 = wrapper.create("Ipv4InterfaceAddress", addr2, mask2)
378         wrapper.invoke(ipv42, "AddAddress", ifindex2, inaddr2)
379         wrapper.invoke(ipv42, "SetMetric", ifindex2, 1)
380         wrapper.invoke(ipv42, "SetUp", ifindex2)
381
382         # Enable collection of Ascii format to a specific file
383         filepath2 = "/tmp/trace-p2p-2.tr"
384         stream2 = wrapper.invoke(asciiHelper, "CreateFileStream", filepath2)
385         wrapper.invoke(p2pHelper, "EnableAscii", stream2, p2)
386
387         # Create channel
388         chan = wrapper.create("PointToPointChannel")
389         wrapper.set(chan, "Delay", "0s")
390         wrapper.invoke(p1, "Attach", chan)
391         wrapper.invoke(p2, "Attach", chan)
392
393         ### create pinger
394         ping = wrapper.create("V4Ping")
395         wrapper.invoke(n1, "AddApplication", ping)
396         wrapper.set (ping, "Remote", "10.0.0.2")
397         wrapper.set (ping, "Interval", "1s")
398         wrapper.set (ping, "Verbose", True)
399         wrapper.set (ping, "StartTime", "0s")
400         wrapper.set (ping, "StopTime", "20s")
401
402         ### run Simulation
403         wrapper.stop(time = "21s")
404         wrapper.start()
405
406         time.sleep(1)
407
408         wrapper.set(chan, "Delay", "5s")
409
410         time.sleep(5)
411
412         wrapper.set(chan, "Delay", "0s")
413
414         # wait until simulation is over
415         wrapper.shutdown()
416
417         p = subprocess.Popen("rm /tmp/trace-p2p-*",  shell = True)
418         p.communicate()
419
420 if __name__ == '__main__':
421     unittest.main()
422