80ac1d1a24fc2a23890eb5d3e16de38f9c72d54c
[osm/vim-emu.git] / src / emuvim / test / unittests / test_emulator.py
1 """
2 Test suite to automatically test emulator functionalities.
3 Directly interacts with the emulator through the Mininet-like
4 Python API.
5
6 Does not test API endpoints. This is done in separated test suites.
7 """
8
9 import time
10 import unittest
11 from emuvim.dcemulator.node import EmulatorCompute
12 from emuvim.test.base import SimpleTestTopology
13 from mininet.node import RemoteController
14
15
16 #@unittest.skip("disabled topology tests for development")
17 class testEmulatorTopology( SimpleTestTopology ):
18 """
19 Tests to check the topology API of the emulator.
20 """
21
22 def testSingleDatacenter(self):
23 """
24 Create a single data center and add check if its switch is up
25 by using manually added hosts. Tests especially the
26 data center specific addLink method.
27 """
28 # create network
29 self.createNet(nswitches=0, ndatacenter=1, nhosts=2, ndockers=0)
30 # setup links
31 self.net.addLink(self.dc[0], self.h[0])
32 self.net.addLink(self.h[1], self.dc[0])
33 # start Mininet network
34 self.startNet()
35 # check number of running nodes
36 self.assertTrue(len(self.getContainernetContainers()) == 0)
37 self.assertTrue(len(self.net.hosts) == 2)
38 self.assertTrue(len(self.net.switches) == 1)
39 # check connectivity by using ping
40 self.assertTrue(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
41 # stop Mininet network
42 self.stopNet()
43
44 #@unittest.skip("disabled to test if CI fails because this is the first test.")
45 def testMultipleDatacenterDirect(self):
46 """
47 Create a two data centers and interconnect them.
48 """
49 # create network
50 self.createNet(nswitches=0, ndatacenter=2, nhosts=2, ndockers=0)
51 # setup links
52 self.net.addLink(self.dc[0], self.h[0])
53 self.net.addLink(self.h[1], self.dc[1])
54 self.net.addLink(self.dc[0], self.dc[1])
55 # start Mininet network
56 self.startNet()
57 # check number of running nodes
58 self.assertTrue(len(self.getContainernetContainers()) == 0)
59 self.assertTrue(len(self.net.hosts) == 2)
60 self.assertTrue(len(self.net.switches) == 2)
61 # check connectivity by using ping
62 self.assertTrue(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
63 # stop Mininet network
64 self.stopNet()
65
66 def testMultipleDatacenterWithIntermediateSwitches(self):
67 """
68 Create a two data centers and interconnect them with additional
69 switches between them.
70 """
71 # create network
72 self.createNet(
73 nswitches=3, ndatacenter=2, nhosts=2, ndockers=0,
74 autolinkswitches=True)
75 # setup links
76 self.net.addLink(self.dc[0], self.h[0])
77 self.net.addLink(self.h[1], self.dc[1])
78 self.net.addLink(self.dc[0], self.s[0])
79 self.net.addLink(self.s[2], self.dc[1])
80 # start Mininet network
81 self.startNet()
82 # check number of running nodes
83 self.assertTrue(len(self.getContainernetContainers()) == 0)
84 self.assertTrue(len(self.net.hosts) == 2)
85 self.assertTrue(len(self.net.switches) == 5)
86 # check connectivity by using ping
87 self.assertTrue(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
88 # stop Mininet network
89 self.stopNet()
90
91 class testEmulatorNetworking( SimpleTestTopology ):
92
93 def testSDNChainingSingleService(self):
94 """
95 Create a two data centers and interconnect them with additional
96 switches between them.
97 Uses Ryu SDN controller.
98 Connect the Docker hosts to different datacenters and setup the links between.
99 """
100 # create network
101 self.createNet(
102 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
103 autolinkswitches=True,
104 controller=RemoteController,
105 enable_learning=False)
106 # setup links
107 self.net.addLink(self.dc[0], self.s[0])
108 self.net.addLink(self.s[2], self.dc[1])
109 # start Mininet network
110 self.startNet()
111
112 # add compute resources
113 vnf1 = self.dc[0].startCompute("vnf1", network=[{'id':'intf1', 'ip':'10.0.10.1/24'}])
114 vnf2 = self.dc[1].startCompute("vnf2", network=[{'id':'intf2', 'ip':'10.0.10.2/24'}])
115 # check number of running nodes
116 self.assertTrue(len(self.getContainernetContainers()) == 2)
117 self.assertTrue(len(self.net.hosts) == 2)
118 self.assertTrue(len(self.net.switches) == 5)
119 # check status
120 # check get status
121 s1 = self.dc[0].containers.get("vnf1").getStatus()
122 self.assertTrue(s1["name"] == "vnf1")
123 self.assertTrue(s1["state"]["Running"])
124 self.assertTrue(s1["network"][0]['intf_name'] == 'intf1')
125 self.assertTrue(s1["network"][0]['ip'] == '10.0.10.1')
126
127 s2 = self.dc[1].containers.get("vnf2").getStatus()
128 self.assertTrue(s2["name"] == "vnf2")
129 self.assertTrue(s2["state"]["Running"])
130 self.assertTrue(s2["network"][0]['intf_name'] == 'intf2')
131 self.assertTrue(s2["network"][0]['ip'] == '10.0.10.2')
132
133 # setup links
134 self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='add-flow')
135 # check connectivity by using ping
136 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
137 # stop Mininet network
138 self.stopNet()
139
140 def testSDNChainingMultiService(self):
141 """
142 Create a two data centers and interconnect them with additional
143 switches between them.
144 Uses Ryu SDN controller.
145 Setup 2 services and setup isolated paths between them
146 Delete only the first service, and check that other one still works
147 """
148 # create network
149 self.createNet(
150 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
151 autolinkswitches=True,
152 controller=RemoteController,
153 enable_learning=False)
154 # setup links
155 self.net.addLink(self.dc[0], self.s[0])
156 self.net.addLink(self.s[2], self.dc[1])
157 # start Mininet network
158 self.startNet()
159
160 ## First Service
161 # add compute resources
162 vnf1 = self.dc[0].startCompute("vnf1", network=[{'id': 'intf1', 'ip': '10.0.10.1/24'}])
163 vnf2 = self.dc[1].startCompute("vnf2", network=[{'id': 'intf2', 'ip': '10.0.10.2/24'}])
164 # setup links
165 self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='add-flow', cookie=1)
166 # check connectivity by using ping
167 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
168
169 ## Second Service
170 # add compute resources
171 vnf11 = self.dc[0].startCompute("vnf11", network=[{'id': 'intf1', 'ip': '10.0.20.1/24'}])
172 vnf22 = self.dc[1].startCompute("vnf22", network=[{'id': 'intf2', 'ip': '10.0.20.2/24'}])
173
174 # check number of running nodes
175 self.assertTrue(len(self.getContainernetContainers()) == 4)
176 self.assertTrue(len(self.net.hosts) == 4)
177 self.assertTrue(len(self.net.switches) == 5)
178
179 # setup links
180 self.net.setChain('vnf11', 'vnf22', 'intf1', 'intf2', bidirectional=True, cmd='add-flow', cookie=2)
181 # check connectivity by using ping
182 self.assertTrue(self.net.ping([vnf11, vnf22]) <= 0.0)
183 # check first service cannot ping second service
184 self.assertTrue(self.net.ping([vnf1, vnf22]) > 0.0)
185 self.assertTrue(self.net.ping([vnf2, vnf11]) > 0.0)
186
187 # delete the first service chain
188 self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='del-flows', cookie=1)
189 # check connectivity of first service is down
190 self.assertTrue(self.net.ping([vnf1, vnf2]) > 0.0)
191 #time.sleep(100)
192 # check connectivity of second service is still up
193 self.assertTrue(self.net.ping([vnf11, vnf22]) <= 0.0)
194
195 # stop Mininet network
196 self.stopNet()
197
198 #@unittest.skip("disabled compute tests for development")
199 class testEmulatorCompute( SimpleTestTopology ):
200 """
201 Tests to check the emulator's API to add and remove
202 compute resources at runtime.
203 """
204
205 def testAddSingleComputeSingleDC(self):
206 """
207 Adds a single compute instance to
208 a single DC and checks its connectivity with a
209 manually added host.
210 """
211 # create network
212 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
213 # setup links
214 self.net.addLink(self.dc[0], self.h[0])
215 # start Mininet network
216 self.startNet()
217 # add compute resources
218 vnf1 = self.dc[0].startCompute("vnf1")
219 # check number of running nodes
220 self.assertTrue(len(self.getContainernetContainers()) == 1)
221 self.assertTrue(len(self.net.hosts) == 2)
222 self.assertTrue(len(self.net.switches) == 1)
223 # check compute list result
224 self.assertTrue(len(self.dc[0].listCompute()) == 1)
225 self.assertTrue(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
226 self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
227 # check connectivity by using ping
228 self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
229 # stop Mininet network
230 self.stopNet()
231
232 def testRemoveSingleComputeSingleDC(self):
233 """
234 Test stop method for compute instances.
235 Check that the instance is really removed.
236 """
237 # create network
238 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
239 # setup links
240 self.net.addLink(self.dc[0], self.h[0])
241 # start Mininet network
242 self.startNet()
243 # add compute resources
244 vnf1 = self.dc[0].startCompute("vnf1")
245 # check number of running nodes
246 self.assertTrue(len(self.getContainernetContainers()) == 1)
247 self.assertTrue(len(self.net.hosts) == 2)
248 self.assertTrue(len(self.net.switches) == 1)
249 # check compute list result
250 self.assertTrue(len(self.dc[0].listCompute()) == 1)
251 # check connectivity by using ping
252 self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
253 # remove compute resources
254 self.dc[0].stopCompute("vnf1")
255 # check number of running nodes
256 self.assertTrue(len(self.getContainernetContainers()) == 0)
257 self.assertTrue(len(self.net.hosts) == 1)
258 self.assertTrue(len(self.net.switches) == 1)
259 # check compute list result
260 self.assertTrue(len(self.dc[0].listCompute()) == 0)
261 # stop Mininet network
262 self.stopNet()
263
264 def testGetStatusSingleComputeSingleDC(self):
265 """
266 Check if the getStatus functionality of EmulatorCompute
267 objects works well.
268 """
269 # create network
270 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
271 # setup links
272 self.net.addLink(self.dc[0], self.h[0])
273 # start Mininet network
274 self.startNet()
275 # add compute resources
276 vnf1 = self.dc[0].startCompute("vnf1")
277 # check number of running nodes
278 self.assertTrue(len(self.getContainernetContainers()) == 1)
279 self.assertTrue(len(self.net.hosts) == 2)
280 self.assertTrue(len(self.net.switches) == 1)
281 # check compute list result
282 self.assertTrue(len(self.dc[0].listCompute()) == 1)
283 self.assertTrue(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
284 self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
285 # check connectivity by using ping
286 self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
287 # check get status
288 s = self.dc[0].containers.get("vnf1").getStatus()
289 self.assertTrue(s["name"] == "vnf1")
290 self.assertTrue(s["state"]["Running"])
291 # stop Mininet network
292 self.stopNet()
293
294 def testConnectivityMultiDC(self):
295 """
296 Test if compute instances started in different data centers
297 are able to talk to each other.
298 """
299 # create network
300 self.createNet(
301 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
302 autolinkswitches=True)
303 # setup links
304 self.net.addLink(self.dc[0], self.s[0])
305 self.net.addLink(self.dc[1], self.s[2])
306 # start Mininet network
307 self.startNet()
308 # add compute resources
309 vnf1 = self.dc[0].startCompute("vnf1")
310 vnf2 = self.dc[1].startCompute("vnf2")
311 # check number of running nodes
312 self.assertTrue(len(self.getContainernetContainers()) == 2)
313 self.assertTrue(len(self.net.hosts) == 2)
314 self.assertTrue(len(self.net.switches) == 5)
315 # check compute list result
316 self.assertTrue(len(self.dc[0].listCompute()) == 1)
317 self.assertTrue(len(self.dc[1].listCompute()) == 1)
318 # check connectivity by using ping
319 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
320 # stop Mininet network
321 self.stopNet()
322
323 def testInterleavedAddRemoveMultiDC(self):
324 """
325 Test multiple, interleaved add and remove operations and ensure
326 that always all expected compute instances are reachable.
327 """
328 # create network
329 self.createNet(
330 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
331 autolinkswitches=True)
332 # setup links
333 self.net.addLink(self.dc[0], self.s[0])
334 self.net.addLink(self.dc[1], self.s[2])
335 # start Mininet network
336 self.startNet()
337 # add compute resources
338 vnf1 = self.dc[0].startCompute("vnf1")
339 vnf2 = self.dc[1].startCompute("vnf2")
340 # check number of running nodes
341 self.assertTrue(len(self.getContainernetContainers()) == 2)
342 self.assertTrue(len(self.net.hosts) == 2)
343 self.assertTrue(len(self.net.switches) == 5)
344 # check compute list result
345 self.assertTrue(len(self.dc[0].listCompute()) == 1)
346 self.assertTrue(len(self.dc[1].listCompute()) == 1)
347 # check connectivity by using ping
348 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
349 # remove compute resources
350 self.dc[0].stopCompute("vnf1")
351 # check number of running nodes
352 self.assertTrue(len(self.getContainernetContainers()) == 1)
353 self.assertTrue(len(self.net.hosts) == 1)
354 self.assertTrue(len(self.net.switches) == 5)
355 # check compute list result
356 self.assertTrue(len(self.dc[0].listCompute()) == 0)
357 self.assertTrue(len(self.dc[1].listCompute()) == 1)
358 # add compute resources
359 vnf3 = self.dc[0].startCompute("vnf3")
360 vnf4 = self.dc[0].startCompute("vnf4")
361 # check compute list result
362 self.assertTrue(len(self.dc[0].listCompute()) == 2)
363 self.assertTrue(len(self.dc[1].listCompute()) == 1)
364 self.assertTrue(self.net.ping([vnf3, vnf2]) <= 0.0)
365 self.assertTrue(self.net.ping([vnf4, vnf2]) <= 0.0)
366 # remove compute resources
367 self.dc[0].stopCompute("vnf3")
368 self.dc[0].stopCompute("vnf4")
369 self.dc[1].stopCompute("vnf2")
370 # check compute list result
371 self.assertTrue(len(self.dc[0].listCompute()) == 0)
372 self.assertTrue(len(self.dc[1].listCompute()) == 0)
373 # stop Mininet network
374 self.stopNet()
375
376 if __name__ == '__main__':
377 unittest.main()