8fad928c854f505eb1b9567853d43693ce332598
[nepi.git] / test / resources / linux / ns3 / ns3client.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.ns3server import run_server
34 from nepi.resources.linux.ns3.ns3client import LinuxNS3Client
35
36 import os
37 import threading
38 import time
39 import unittest
40
41 class DummySimulation(object):
42     def __init__(self, socket_name):
43         self.socket_name = socket_name
44         self.node = dict({'hostname': 'localhost'})
45
46     @property
47     def remote_socket(self):
48         return self.socket_name
49
50 class LinuxNS3ClientTest(unittest.TestCase):
51     def setUp(self):
52         self.socket_name = os.path.join("/", "tmp", "NS3WrapperServer.sock")
53         if os.path.exists(self.socket_name):
54             os.remove(self.socket_name) 
55
56     def tearDown(self):
57         os.remove(self.socket_name) 
58
59     def test_runtime_attr_modify(self):
60         thread = threading.Thread(target = run_server,
61                 args = [self.socket_name])
62
63         thread.setDaemon(True)
64         thread.start()
65
66         time.sleep(3)
67
68         # Verify that the communication socket was created
69         self.assertTrue(os.path.exists(self.socket_name))
70
71         # Create a dummy simulation object
72         simulation = DummySimulation(self.socket_name) 
73
74         # Instantiate the NS3 client
75         client = LinuxNS3Client(simulation)
76  
77         # Define a real time simulation 
78         stype = client.create("StringValue", "ns3::RealtimeSimulatorImpl")
79         client.invoke("singleton::GlobalValue", "Bind", "SimulatorImplementationType", stype)
80         btrue = client.create("BooleanValue", True)
81         client.invoke("singleton::GlobalValue", "Bind", "ChecksumEnabled", btrue)
82         
83         # Create Node
84         n1 = client.create("Node")
85         self.assertTrue(n1.startswith("uuid"))
86
87         ## Install internet stack
88         ipv41 = client.create("Ipv4L3Protocol")
89         client.invoke(n1, "AggregateObject", ipv41)
90
91         arp1 = client.create("ArpL3Protocol")
92         client.invoke(n1, "AggregateObject", arp1)
93         
94         icmp1 = client.create("Icmpv4L4Protocol")
95         client.invoke(n1, "AggregateObject", icmp1)
96
97         ## Add IPv4 routing
98         lr1 = client.create("Ipv4ListRouting")
99         client.invoke(ipv41, "SetRoutingProtocol", lr1)
100         sr1 = client.create("Ipv4StaticRouting")
101         client.invoke(lr1, "AddRoutingProtocol", sr1, 1)
102
103         ## NODE 2
104         n2 = client.create("Node")
105
106         ## Install internet stack
107         ipv42 = client.create("Ipv4L3Protocol")
108         client.invoke(n2, "AggregateObject", ipv42)
109
110         arp2 = client.create("ArpL3Protocol")
111         client.invoke(n2, "AggregateObject", arp2)
112         
113         icmp2 = client.create("Icmpv4L4Protocol")
114         client.invoke(n2, "AggregateObject", icmp2)
115
116         ## Add IPv4 routing
117         lr2 = client.create("Ipv4ListRouting")
118         client.invoke(ipv42, "SetRoutingProtocol", lr2)
119         sr2 = client.create("Ipv4StaticRouting")
120         client.invoke(lr2, "AddRoutingProtocol", sr2, 1)
121
122         ##### Create p2p device and enable ascii tracing
123         p2pHelper = client.create("PointToPointHelper")
124         asciiHelper = client.create("AsciiTraceHelper")
125
126         # Iface for node1
127         p1 = client.create("PointToPointNetDevice")
128         client.invoke(n1, "AddDevice", p1)
129         q1 = client.create("DropTailQueue")
130         client.invoke(p1, "SetQueue", q1)
131       
132         # Add IPv4 address
133         ifindex1 = client.invoke(ipv41, "AddInterface", p1)
134         mask1 = client.create("Ipv4Mask", "/30")
135         addr1 = client.create("Ipv4Address", "10.0.0.1")
136         inaddr1 = client.create("Ipv4InterfaceAddress", addr1, mask1)
137         client.invoke(ipv41, "AddAddress", ifindex1, inaddr1)
138         client.invoke(ipv41, "SetMetric", ifindex1, 1)
139         client.invoke(ipv41, "SetUp", ifindex1)
140
141         # Enable collection of Ascii format to a specific file
142         filepath1 = "trace-p2p-1.tr"
143         stream1 = client.invoke(asciiHelper, "CreateFileStream", filepath1)
144         client.invoke(p2pHelper, "EnableAscii", stream1, p1)
145        
146         # Iface for node2
147         p2 = client.create("PointToPointNetDevice")
148         client.invoke(n2, "AddDevice", p2)
149         q2 = client.create("DropTailQueue")
150         client.invoke(p2, "SetQueue", q2)
151
152         # Add IPv4 address
153         ifindex2 = client.invoke(ipv42, "AddInterface", p2)
154         mask2 = client.create("Ipv4Mask", "/30")
155         addr2 = client.create("Ipv4Address", "10.0.0.2")
156         inaddr2 = client.create("Ipv4InterfaceAddress", addr2, mask2)
157         client.invoke(ipv42, "AddAddress", ifindex2, inaddr2)
158         client.invoke(ipv42, "SetMetric", ifindex2, 1)
159         client.invoke(ipv42, "SetUp", ifindex2)
160
161         # Enable collection of Ascii format to a specific file
162         filepath2 = "trace-p2p-2.tr"
163         stream2 = client.invoke(asciiHelper, "CreateFileStream", filepath2)
164         client.invoke(p2pHelper, "EnableAscii", stream2, p2)
165
166         # Create channel
167         chan = client.create("PointToPointChannel")
168         client.set(chan, "Delay", "0s")
169         client.invoke(p1, "Attach", chan)
170         client.invoke(p2, "Attach", chan)
171
172         ### create pinger
173         ping = client.create("V4Ping")
174         client.invoke(n1, "AddApplication", ping)
175         client.set (ping, "Remote", "10.0.0.2")
176         client.set (ping, "Interval", "1s")
177         client.set (ping, "Verbose", True)
178         client.set (ping, "StartTime", "0s")
179         client.set (ping, "StopTime", "20s")
180
181         ### run Simulation
182         client.stop(time = "21s")
183         client.start()
184
185         time.sleep(1)
186
187         client.set(chan, "Delay", "5s")
188
189         time.sleep(5)
190
191         client.set(chan, "Delay", "0s")
192
193         # wait until simulation is over
194         client.shutdown()
195
196         ## TODO: Add assertions !!
197
198 if __name__ == '__main__':
199     unittest.main()
200