Changing ResourceManager naming for platform::ResourceName
[nepi.git] / test / resources / linux / ns3 / serialization.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 from nepi.execution.ec import ExperimentController 
22 from nepi.execution.trace import TraceAttr
23
24 from test_utils import skipIfNotAlive
25
26 import os
27 import shutil
28 import time
29 import tempfile
30 import unittest
31
32 def add_ns3_node(ec, simu):
33     node = ec.register_resource("ns3::Node")
34     ec.register_connection(node, simu)
35
36     ipv4 = ec.register_resource("ns3::Ipv4L3Protocol")
37     ec.register_connection(node, ipv4)
38
39     arp = ec.register_resource("ns3::ArpL3Protocol")
40     ec.register_connection(node, arp)
41     
42     icmp = ec.register_resource("ns3::Icmpv4L4Protocol")
43     ec.register_connection(node, icmp)
44
45     udp = ec.register_resource("ns3::UdpL4Protocol")
46     ec.register_connection(node, udp)
47
48     return node
49
50 def add_point2point_device(ec, node, ip, prefix):
51     dev = ec.register_resource("ns3::PointToPointNetDevice")
52     ec.set(dev, "ip", ip)
53     ec.set(dev, "prefix", prefix)
54     ec.register_connection(node, dev)
55
56     queue = ec.register_resource("ns3::DropTailQueue")
57     ec.register_connection(dev, queue)
58
59     return dev
60
61 def add_csma_device(ec, node, ip, prefix):
62     dev = ec.register_resource("ns3::CsmaNetDevice")
63     ec.set(dev, "ip", ip)
64     ec.set(dev, "prefix", prefix)
65     ec.register_connection(node, dev)
66
67     queue = ec.register_resource("ns3::DropTailQueue")
68     ec.register_connection(dev, queue)
69
70     return dev
71
72 def add_wifi_device(ec, node, ip, prefix, 
73         access_point = False):
74     dev = ec.register_resource("ns3::WifiNetDevice")
75     ec.set(dev, "ip", ip)
76     ec.set(dev, "prefix", prefix)
77     ec.register_connection(node, dev)
78
79     phy = ec.register_resource("ns3::YansWifiPhy")
80     ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a")
81     ec.register_connection(dev, phy)
82
83     error = ec.register_resource("ns3::NistErrorRateModel")
84     ec.register_connection(phy, error)
85
86     manager = ec.register_resource("ns3::ArfWifiManager")
87     ec.register_connection(dev, manager)
88
89     if access_point:
90         mac = ec.register_resource("ns3::ApWifiMac")
91     else:
92         mac = ec.register_resource("ns3::StaWifiMac")
93
94     ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a")
95     ec.register_connection(dev, mac)
96
97     return dev, phy
98
99 def add_random_mobility(ec, node, x, y, z, speed, bounds_width, 
100         bounds_height):
101     position = "%d:%d:%d" % (x, y, z)
102     bounds = "0|%d|0|%d" % (bounds_width, bounds_height) 
103     speed = "ns3::UniformRandomVariable[Min=%d|Max=%s]" % (speed, speed)
104     pause = "ns3::ConstantRandomVariable[Constant=1.0]"
105     
106     mobility = ec.register_resource("ns3::RandomDirection2dMobilityModel")
107     ec.set(mobility, "Position", position)
108     ec.set(mobility, "Bounds", bounds)
109     ec.set(mobility, "Speed", speed)
110     ec.set(mobility, "Pause",  pause)
111     ec.register_connection(node, mobility)
112     return mobility
113
114 def add_constant_mobility(ec, node, x, y, z):
115     mobility = ec.register_resource("ns3::ConstantPositionMobilityModel") 
116     position = "%d:%d:%d" % (x, y, z)
117     ec.set(mobility, "Position", position)
118     ec.register_connection(node, mobility)
119     return mobility
120
121 def add_wifi_channel(ec):
122     channel = ec.register_resource("ns3::YansWifiChannel")
123     delay = ec.register_resource("ns3::ConstantSpeedPropagationDelayModel")
124     ec.register_connection(channel, delay)
125
126     loss  = ec.register_resource("ns3::LogDistancePropagationLossModel")
127     ec.register_connection(channel, loss)
128
129     return channel
130
131 class LinuxNS3SimulationSerializationTest(unittest.TestCase):
132     def setUp(self):
133         #self.fedora_host = "nepi2.pl.sophia.inria.fr"
134         self.fedora_host = "planetlab1.informatik.uni-erlangen.de"
135         self.fedora_user = "inria_nepi"
136         self.fedora_identity = "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])
137
138     @skipIfNotAlive
139     def t_wifi_serialize(self, host, user = None, identity = None):
140         bounds_width = bounds_height = 200
141         x = y = 100
142         speed = 1
143
144         dirpath = tempfile.mkdtemp()
145         
146         ec = ExperimentController(exp_id = "test-ns3-wifi-ping")
147         
148         node = ec.register_resource("linux::Node")
149         if host == "localhost":
150             ec.set(node, "hostname", "localhost")
151         else:
152             ec.set(node, "hostname", host)
153             ec.set(node, "username", user)
154             ec.set(node, "identity", identity)
155
156         ec.set(node, "cleanProcesses", True)
157         #ec.set(node, "cleanHome", True)
158
159         simu = ec.register_resource("linux::ns3::Simulation")
160         ec.set(simu, "verbose", True)
161         ec.register_connection(simu, node)
162
163         nsnode1 = add_ns3_node(ec, simu)
164         dev1, phy1 = add_wifi_device(ec, nsnode1, "10.0.0.1", "24", access_point = True)
165         mobility1 = add_constant_mobility(ec, nsnode1, x, y, 0)
166
167         nsnode2 = add_ns3_node(ec, simu)
168         dev2, phy2 = add_wifi_device(ec, nsnode2, "10.0.0.2", "24", access_point = False)
169         mobility1 = add_constant_mobility(ec, nsnode2, x, y, 0)
170         #mobility2 = add_random_mobility(ec, nsnode2, x, y, 0, speed, bounds_width, bounds_height)
171
172         # Create channel
173         chan = add_wifi_channel(ec)
174         ec.register_connection(chan, phy1)
175         ec.register_connection(chan, phy2)
176
177         ### create pinger
178         ping = ec.register_resource("ns3::V4Ping")
179         ec.set (ping, "Remote", "10.0.0.1")
180         ec.set (ping, "Interval", "1s")
181         ec.set (ping, "Verbose", True)
182         ec.set (ping, "StartTime", "1s")
183         ec.set (ping, "StopTime", "21s")
184         ec.register_connection(ping, nsnode2)
185
186         filepath = ec.save(dirpath)
187         print filepath
188         
189         ec.deploy()
190
191         ec.wait_finished([ping])
192         
193         stdout = ec.trace(simu, "stdout")
194
195         expected = "20 packets transmitted, 20 received, 0% packet loss"
196         self.assertTrue(stdout.find(expected) > -1)
197
198         ec.shutdown()
199
200         # Load serialized experiment
201         ec2 = ExperimentController.load(filepath)
202         
203         ec2.deploy()
204
205         ec2.wait_finished([ping])
206         
207         self.assertEquals(len(ec.resources), len(ec2.resources))
208         
209         stdout = ec2.trace(simu, "stdout")
210  
211         expected = "20 packets transmitted, 20 received, 0% packet loss"
212         self.assertTrue(stdout.find(expected) > -1)
213         
214         ec2.shutdown()
215
216         shutil.rmtree(dirpath)
217
218     @skipIfNotAlive
219     def t_routing_serialize(self, host, user = None, identity = None):
220         """ 
221         network topology:
222                                 n4
223                                 |
224            n1 -- p2p -- n2 -- csma -- n5 -- p2p -- n6
225            |                    | 
226            ping n6              n3
227            
228
229         """
230         dirpath = tempfile.mkdtemp()
231         
232         ec = ExperimentController(exp_id = "test-ns3-routes")
233         
234         node = ec.register_resource("linux::Node")
235         if host == "localhost":
236             ec.set(node, "hostname", host)
237         else:
238             ec.set(node, "hostname", host)
239             ec.set(node, "username", user)
240             ec.set(node, "identity", identity)
241
242         ec.set(node, "cleanProcesses", True)
243         #ec.set(node, "cleanHome", True)
244
245         simu = ec.register_resource("linux::ns3::Simulation")
246         ec.set(simu, "verbose", True)
247         ec.register_connection(simu, node)
248
249         nsnode1 = add_ns3_node(ec, simu)
250         p2p12 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
251
252         nsnode2 = add_ns3_node(ec, simu)
253         p2p21 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
254         csma2 = add_csma_device(ec, nsnode2, "10.0.1.1", "24")
255
256         nsnode3 = add_ns3_node(ec, simu)
257         csma3 = add_csma_device(ec, nsnode3, "10.0.1.2", "24")
258
259         nsnode4 = add_ns3_node(ec, simu)
260         csma4 = add_csma_device(ec, nsnode4, "10.0.1.3", "24")
261
262         nsnode5 = add_ns3_node(ec, simu)
263         p2p56 = add_point2point_device(ec, nsnode5, "10.0.2.1", "30")
264         csma5 = add_csma_device(ec, nsnode5, "10.0.1.4", "24")
265
266         nsnode6 = add_ns3_node(ec, simu)
267         p2p65 = add_point2point_device(ec, nsnode6, "10.0.2.2", "30")
268
269         # P2P chan1
270         p2p_chan1 = ec.register_resource("ns3::PointToPointChannel")
271         ec.set(p2p_chan1, "Delay", "0s")
272         ec.register_connection(p2p_chan1, p2p12)
273         ec.register_connection(p2p_chan1, p2p21)
274
275         # CSMA chan
276         csma_chan = ec.register_resource("ns3::CsmaChannel")
277         ec.set(csma_chan, "Delay", "0s")
278         ec.register_connection(csma_chan, csma2)
279         ec.register_connection(csma_chan, csma3)
280         ec.register_connection(csma_chan, csma4)
281         ec.register_connection(csma_chan, csma5)
282
283         # P2P chan2
284         p2p_chan2 = ec.register_resource("ns3::PointToPointChannel")
285         ec.set(p2p_chan2, "Delay", "0s")
286         ec.register_connection(p2p_chan2, p2p56)
287         ec.register_connection(p2p_chan2, p2p65)
288
289         # Add routes - n1 - n6
290         r1 = ec.register_resource("ns3::Route")
291         ec.set(r1, "network", "10.0.2.0")
292         ec.set(r1, "prefix", "30")
293         ec.set(r1, "nexthop", "10.0.0.2")
294         ec.register_connection(r1, nsnode1)
295
296         # Add routes - n2 - n6
297         r2 = ec.register_resource("ns3::Route")
298         ec.set(r2, "network", "10.0.2.0")
299         ec.set(r2, "prefix", "30")
300         ec.set(r2, "nexthop", "10.0.1.4")
301         ec.register_connection(r2, nsnode2)
302
303         # Add routes - n5 - n1
304         r5 = ec.register_resource("ns3::Route")
305         ec.set(r5, "network", "10.0.0.0")
306         ec.set(r5, "prefix", "30")
307         ec.set(r5, "nexthop", "10.0.1.1")
308         ec.register_connection(r5, nsnode5)
309
310         # Add routes - n6 - n1
311         r6 = ec.register_resource("ns3::Route")
312         ec.set(r6, "network", "10.0.0.0")
313         ec.set(r6, "prefix", "30")
314         ec.set(r6, "nexthop", "10.0.2.1")
315         ec.register_connection(r6, nsnode6)
316
317         ### create pinger
318         ping = ec.register_resource("ns3::V4Ping")
319         ec.set (ping, "Remote", "10.0.2.2")
320         ec.set (ping, "Interval", "1s")
321         ec.set (ping, "Verbose", True)
322         ec.set (ping, "StartTime", "1s")
323         ec.set (ping, "StopTime", "21s")
324         ec.register_connection(ping, nsnode1)
325
326         filepath = ec.save(dirpath)
327         print filepath
328         
329         ec.deploy()
330
331         ec.wait_finished([ping])
332         
333         stdout = ec.trace(simu, "stdout")
334
335         expected = "20 packets transmitted, 20 received, 0% packet loss"
336         self.assertTrue(stdout.find(expected) > -1)
337
338         ec.shutdown()
339
340         # Load serialized experiment
341         ec2 = ExperimentController.load(filepath)
342         
343         ec2.deploy()
344
345         ec2.wait_finished([ping])
346         
347         self.assertEquals(len(ec.resources), len(ec2.resources))
348         
349         stdout = ec2.trace(simu, "stdout")
350  
351         expected = "20 packets transmitted, 20 received, 0% packet loss"
352         self.assertTrue(stdout.find(expected) > -1)
353         
354         ec2.shutdown()
355
356         shutil.rmtree(dirpath)
357
358     @skipIfNotAlive
359     def t_dce_serialize(self, host, user = None, identity = None):
360         dirpath = tempfile.mkdtemp()
361         
362         ec = ExperimentController(exp_id = "test-ns3-dce")
363         
364         node = ec.register_resource("linux::Node")
365         if host == "localhost":
366             ec.set(node, "hostname", host)
367         else:
368             ec.set(node, "hostname", host)
369             ec.set(node, "username", user)
370             ec.set(node, "identity", identity)
371
372         ec.set(node, "cleanProcesses", True)
373         #ec.set(node, "cleanHome", True)
374
375         simu = ec.register_resource("linux::ns3::Simulation")
376         ec.set(simu, "verbose", True)
377         ec.register_connection(simu, node)
378
379         nsnode1 = add_ns3_node(ec, simu)
380         p2p1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
381         ec.set(p2p1, "DataRate", "5Mbps")
382
383         nsnode2 = add_ns3_node(ec, simu)
384         p2p2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
385         ec.set(p2p2, "DataRate", "5Mbps")
386
387         # Create channel
388         chan = ec.register_resource("ns3::PointToPointChannel")
389         ec.set(chan, "Delay", "2ms")
390
391         ec.register_connection(chan, p2p1)
392         ec.register_connection(chan, p2p2)
393
394         ### create applications
395         udp_perf = ec.register_resource("linux::ns3::dce::Application")
396         ec.set (udp_perf, "binary", "udp-perf")
397         ec.set (udp_perf, "stackSize", 1<<20)
398         ec.set (udp_perf, "arguments", "--duration=10;--nodes=2")
399         ec.set (udp_perf, "StartTime", "1s")
400         ec.set (udp_perf, "StopTime", "20s")
401         ec.register_connection(udp_perf, nsnode1)
402
403         udp_perf_client = ec.register_resource("linux::ns3::dce::Application")
404         ec.set (udp_perf_client, "binary", "udp-perf")
405         ec.set (udp_perf_client, "stackSize", 1<<20)
406         ec.set (udp_perf_client, "arguments", "--client;--nodes=2;--host=10.0.0.1;--duration=10")
407         ec.set (udp_perf_client, "StartTime", "2s")
408         ec.set (udp_perf_client, "StopTime", "20s")
409         ec.register_connection(udp_perf_client, nsnode2)
410
411         filepath = ec.save(dirpath)
412         
413         ec.deploy()
414
415         ec.wait_finished([udp_perf_client])
416
417         # Give time to flush the streams
418         import time
419         time.sleep(5) 
420
421         expected = "udp-perf --duration=10 --nodes=2"
422         cmdline = ec.trace(udp_perf, "cmdline")
423         self.assertTrue(cmdline.find(expected) > -1, cmdline)
424
425         expected = "Start Time: NS3 Time:          1s ("
426         status = ec.trace(udp_perf, "status")
427         self.assertTrue(status.find(expected) > -1, status)
428
429         expected = "received=1500 bytes, 1 reads (@1500 bytes) 1500"
430         stdout = ec.trace(udp_perf, "stdout")
431         self.assertTrue(stdout.find(expected) > -1, stdout)
432
433         ec.shutdown()
434
435         # Load serialized experiment
436         ec2 = ExperimentController.load(filepath)
437         
438         ec2.deploy()
439         ec2.wait_finished([udp_perf_client])
440
441         # Give time to flush the streams
442         time.sleep(5) 
443        
444         self.assertEquals(len(ec.resources), len(ec2.resources))
445  
446         expected = "udp-perf --duration=10 --nodes=2"
447         cmdline = ec2.trace(udp_perf, "cmdline")
448         self.assertTrue(cmdline.find(expected) > -1, cmdline)
449
450         expected = "Start Time: NS3 Time:          1s ("
451         status = ec2.trace(udp_perf, "status")
452         self.assertTrue(status.find(expected) > -1, status)
453
454         expected = "received=1500 bytes, 1 reads (@1500 bytes) 1500"
455         stdout = ec2.trace(udp_perf, "stdout")
456         self.assertTrue(stdout.find(expected) > -1, stdout)
457
458         ec2.shutdown()
459
460         shutil.rmtree(dirpath)
461     
462     def test_wifi_serialize_fedora(self):
463         self.t_wifi_serialize(self.fedora_host, self.fedora_user, self.fedora_identity)
464
465     def test_wifi_serialize_local(self):
466         self.t_wifi_serialize("localhost")
467
468     def test_routing_serialize_fedora(self):
469         self.t_routing_serialize(self.fedora_host, self.fedora_user, self.fedora_identity)
470
471     def test_routing_serialize_local(self):
472         self.t_routing_serialize("localhost")
473
474     def test_dce_serialize_fedora(self):
475         self.t_dce_serialize(self.fedora_host, self.fedora_user, self.fedora_identity)
476
477     def test_dce_serialize_local(self):
478         self.t_dce_serialize("localhost")
479
480
481 if __name__ == '__main__':
482     unittest.main()
483