fc06a69521357f6887b44b690ad4d6abac7da7f9
[osm/vim-emu.git] / src / emuvim / test / unittests / test_emulator.py
1 # Copyright (c) 2015 SONATA-NFV and Paderborn University
2 # ALL RIGHTS RESERVED.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16 # Neither the name of the SONATA-NFV, Paderborn University
17 # nor the names of its contributors may be used to endorse or promote
18 # products derived from this software without specific prior written
19 # permission.
20 #
21 # This work has been performed in the framework of the SONATA project,
22 # funded by the European Commission under Grant number 671517 through
23 # the Horizon 2020 and 5G-PPP programmes. The authors would like to
24 # acknowledge the contributions of their colleagues of the SONATA
25 # partner consortium (www.sonata-nfv.eu).
26 import unittest
27 from emuvim.dcemulator.node import EmulatorCompute
28 from emuvim.test.base import SimpleTestTopology
29 from mininet.node import RemoteController
30
31
32 # @unittest.skip("disabled topology tests for development")
33 class testEmulatorTopology(SimpleTestTopology):
34 """
35 Tests to check the topology API of the emulator.
36 """
37
38 def testSingleDatacenter(self):
39 """
40 Create a single data center and add check if its switch is up
41 by using manually added hosts. Tests especially the
42 data center specific addLink method.
43 """
44 # create network
45 self.createNet(nswitches=0, ndatacenter=1, nhosts=2, ndockers=0)
46 # setup links
47 self.net.addLink(self.dc[0], self.h[0])
48 self.net.addLink(self.h[1], self.dc[0])
49 # start Mininet network
50 self.startNet()
51 # check number of running nodes
52 self.assertTrue(len(self.getContainernetContainers()) == 0)
53 self.assertTrue(len(self.net.hosts) == 2)
54 self.assertTrue(len(self.net.switches) == 1)
55 # check connectivity by using ping
56 self.assertTrue(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
57 # stop Mininet network
58 self.stopNet()
59
60 # @unittest.skip("disabled to test if CI fails because this is the first test.")
61 def testMultipleDatacenterDirect(self):
62 """
63 Create a two data centers and interconnect them.
64 """
65 # create network
66 self.createNet(nswitches=0, ndatacenter=2, nhosts=2, ndockers=0)
67 # setup links
68 self.net.addLink(self.dc[0], self.h[0])
69 self.net.addLink(self.h[1], self.dc[1])
70 self.net.addLink(self.dc[0], self.dc[1])
71 # start Mininet network
72 self.startNet()
73 # check number of running nodes
74 self.assertTrue(len(self.getContainernetContainers()) == 0)
75 self.assertTrue(len(self.net.hosts) == 2)
76 self.assertTrue(len(self.net.switches) == 2)
77 # check connectivity by using ping
78 self.assertTrue(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
79 # stop Mininet network
80 self.stopNet()
81
82 def testMultipleDatacenterWithIntermediateSwitches(self):
83 """
84 Create a two data centers and interconnect them with additional
85 switches between them.
86 """
87 # create network
88 self.createNet(
89 nswitches=3, ndatacenter=2, nhosts=2, ndockers=0,
90 autolinkswitches=True)
91 # setup links
92 self.net.addLink(self.dc[0], self.h[0])
93 self.net.addLink(self.h[1], self.dc[1])
94 self.net.addLink(self.dc[0], self.s[0])
95 self.net.addLink(self.s[2], self.dc[1])
96 # start Mininet network
97 self.startNet()
98 # check number of running nodes
99 self.assertTrue(len(self.getContainernetContainers()) == 0)
100 self.assertTrue(len(self.net.hosts) == 2)
101 self.assertTrue(len(self.net.switches) == 5)
102 # check connectivity by using ping
103 self.assertTrue(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
104 # stop Mininet network
105 self.stopNet()
106
107
108 class testEmulatorNetworking(SimpleTestTopology):
109
110 def testSDNChainingSingleService_withLearning(self):
111 """
112 Create a two data centers and interconnect them with additional
113 switches between them.
114 Uses Ryu SDN controller.
115 Connect the Docker hosts to different datacenters and setup the links between.
116 """
117 # create network
118 self.createNet(
119 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
120 autolinkswitches=True,
121 controller=RemoteController,
122 enable_learning=True)
123 # setup links
124 self.net.addLink(self.dc[0], self.s[0])
125 self.net.addLink(self.s[2], self.dc[1])
126 # start Mininet network
127 self.startNet()
128
129 # add compute resources
130 vnf1 = self.dc[0].startCompute(
131 "vnf1", network=[{'id': 'intf1', 'ip': '10.0.10.1/24'}])
132 vnf2 = self.dc[1].startCompute(
133 "vnf2", network=[{'id': 'intf2', 'ip': '10.0.10.2/24'}])
134 # check number of running nodes
135 self.assertTrue(len(self.getContainernetContainers()) == 2)
136 self.assertTrue(len(self.net.hosts) == 2)
137 self.assertTrue(len(self.net.switches) == 5)
138 # check status
139 # check get status
140 s1 = self.dc[0].containers.get("vnf1").getStatus()
141 print s1
142 self.assertTrue(s1["name"] == "vnf1")
143 self.assertTrue(s1["state"]["Running"])
144 self.assertTrue(s1["network"][0]['intf_name'] == 'intf1')
145 self.assertTrue(s1["network"][0]['ip'] == '10.0.10.1/24')
146
147 s2 = self.dc[1].containers.get("vnf2").getStatus()
148 print s2
149 self.assertTrue(s2["name"] == "vnf2")
150 self.assertTrue(s2["state"]["Running"])
151 self.assertTrue(s2["network"][0]['intf_name'] == 'intf2')
152 self.assertTrue(s2["network"][0]['ip'] == '10.0.10.2/24')
153
154 # should be connected because learning = True
155 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
156 # setup links
157 self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
158 bidirectional=True, cmd='add-flow')
159 # should still be connected
160 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
161 # stop Mininet network
162 self.stopNet()
163
164 def testSDNChainingSingleService(self):
165 """
166 Create a two data centers and interconnect them with additional
167 switches between them.
168 Uses Ryu SDN controller.
169 Connect the Docker hosts to different datacenters and setup the links between.
170 """
171 # create network
172 self.createNet(
173 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
174 autolinkswitches=True,
175 controller=RemoteController,
176 enable_learning=False)
177 # setup links
178 self.net.addLink(self.dc[0], self.s[0])
179 self.net.addLink(self.s[2], self.dc[1])
180 # start Mininet network
181 self.startNet()
182
183 # add compute resources
184 vnf1 = self.dc[0].startCompute(
185 "vnf1", network=[{'id': 'intf1', 'ip': '10.0.10.1/24'}])
186 vnf2 = self.dc[1].startCompute(
187 "vnf2", network=[{'id': 'intf2', 'ip': '10.0.10.2/24'}])
188 # check number of running nodes
189 self.assertTrue(len(self.getContainernetContainers()) == 2)
190 self.assertTrue(len(self.net.hosts) == 2)
191 self.assertTrue(len(self.net.switches) == 5)
192 # check status
193 # check get status
194 s1 = self.dc[0].containers.get("vnf1").getStatus()
195 print s1
196 self.assertTrue(s1["name"] == "vnf1")
197 self.assertTrue(s1["state"]["Running"])
198 self.assertTrue(s1["network"][0]['intf_name'] == 'intf1')
199 self.assertTrue(s1["network"][0]['ip'] == '10.0.10.1/24')
200
201 s2 = self.dc[1].containers.get("vnf2").getStatus()
202 print s2
203 self.assertTrue(s2["name"] == "vnf2")
204 self.assertTrue(s2["state"]["Running"])
205 self.assertTrue(s2["network"][0]['intf_name'] == 'intf2')
206 self.assertTrue(s2["network"][0]['ip'] == '10.0.10.2/24')
207
208 # should be not not yet connected
209 self.assertTrue(self.net.ping([vnf1, vnf2]) > 0.0)
210 # setup links
211 self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
212 bidirectional=True, cmd='add-flow')
213 # check connectivity by using ping
214 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
215 # stop Mininet network
216 self.stopNet()
217
218 def testSDNChainingMultiService(self):
219 """
220 Create a two data centers and interconnect them with additional
221 switches between them.
222 Uses Ryu SDN controller.
223 Setup 2 services and setup isolated paths between them
224 Delete only the first service, and check that other one still works
225 """
226 # create network
227 self.createNet(
228 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
229 autolinkswitches=True,
230 controller=RemoteController,
231 enable_learning=False)
232 # setup links
233 self.net.addLink(self.dc[0], self.s[0])
234 self.net.addLink(self.s[2], self.dc[1])
235 # start Mininet network
236 self.startNet()
237
238 # First Service
239 # add compute resources
240 vnf1 = self.dc[0].startCompute(
241 "vnf1", network=[{'id': 'intf1', 'ip': '10.0.10.1/24'}])
242 vnf2 = self.dc[1].startCompute(
243 "vnf2", network=[{'id': 'intf2', 'ip': '10.0.10.2/24'}])
244 # setup links
245 self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
246 bidirectional=True, cmd='add-flow', cookie=1)
247 # check connectivity by using ping
248 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
249
250 # Second Service
251 # add compute resources
252 vnf11 = self.dc[0].startCompute(
253 "vnf11", network=[{'id': 'intf1', 'ip': '10.0.20.1/24'}])
254 vnf22 = self.dc[1].startCompute(
255 "vnf22", network=[{'id': 'intf2', 'ip': '10.0.20.2/24'}])
256
257 # check number of running nodes
258 self.assertTrue(len(self.getContainernetContainers()) == 4)
259 self.assertTrue(len(self.net.hosts) == 4)
260 self.assertTrue(len(self.net.switches) == 5)
261
262 # setup links
263 self.net.setChain('vnf11', 'vnf22', 'intf1', 'intf2',
264 bidirectional=True, cmd='add-flow', cookie=2)
265 # check connectivity by using ping
266 self.assertTrue(self.net.ping([vnf11, vnf22]) <= 0.0)
267 # check first service cannot ping second service
268 self.assertTrue(self.net.ping([vnf1, vnf22]) > 0.0)
269 self.assertTrue(self.net.ping([vnf2, vnf11]) > 0.0)
270
271 # delete the first service chain
272 self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
273 bidirectional=True, cmd='del-flows', cookie=1)
274 # check connectivity of first service is down
275 self.assertTrue(self.net.ping([vnf1, vnf2]) > 0.0)
276 # time.sleep(100)
277 # check connectivity of second service is still up
278 self.assertTrue(self.net.ping([vnf11, vnf22]) <= 0.0)
279
280 # stop Mininet network
281 self.stopNet()
282
283 # @unittest.skip("disabled compute tests for development")
284
285
286 class testEmulatorCompute(SimpleTestTopology):
287 """
288 Tests to check the emulator's API to add and remove
289 compute resources at runtime.
290 """
291
292 def testAddSingleComputeSingleDC(self):
293 """
294 Adds a single compute instance to
295 a single DC and checks its connectivity with a
296 manually added host.
297 """
298 # create network
299 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
300 # setup links
301 self.net.addLink(self.dc[0], self.h[0])
302 # start Mininet network
303 self.startNet()
304 # add compute resources
305 vnf1 = self.dc[0].startCompute("vnf1")
306 # check number of running nodes
307 self.assertTrue(len(self.getContainernetContainers()) == 1)
308 self.assertTrue(len(self.net.hosts) == 2)
309 self.assertTrue(len(self.net.switches) == 1)
310 # check compute list result
311 self.assertTrue(len(self.dc[0].listCompute()) == 1)
312 self.assertTrue(isinstance(
313 self.dc[0].listCompute()[0], EmulatorCompute))
314 self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
315 # check connectivity by using ping
316 self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
317 # stop Mininet network
318 self.stopNet()
319
320 def testRemoveSingleComputeSingleDC(self):
321 """
322 Test stop method for compute instances.
323 Check that the instance is really removed.
324 """
325 # create network
326 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
327 # setup links
328 self.net.addLink(self.dc[0], self.h[0])
329 # start Mininet network
330 self.startNet()
331 # add compute resources
332 vnf1 = self.dc[0].startCompute("vnf1")
333 # check number of running nodes
334 self.assertTrue(len(self.getContainernetContainers()) == 1)
335 self.assertTrue(len(self.net.hosts) == 2)
336 self.assertTrue(len(self.net.switches) == 1)
337 # check compute list result
338 self.assertTrue(len(self.dc[0].listCompute()) == 1)
339 # check connectivity by using ping
340 self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
341 # remove compute resources
342 self.dc[0].stopCompute("vnf1")
343 # check number of running nodes
344 self.assertTrue(len(self.getContainernetContainers()) == 0)
345 self.assertTrue(len(self.net.hosts) == 1)
346 self.assertTrue(len(self.net.switches) == 1)
347 # check compute list result
348 self.assertTrue(len(self.dc[0].listCompute()) == 0)
349 # stop Mininet network
350 self.stopNet()
351
352 def testGetStatusSingleComputeSingleDC(self):
353 """
354 Check if the getStatus functionality of EmulatorCompute
355 objects works well.
356 """
357 # create network
358 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
359 # setup links
360 self.net.addLink(self.dc[0], self.h[0])
361 # start Mininet network
362 self.startNet()
363 # add compute resources
364 vnf1 = self.dc[0].startCompute("vnf1")
365 # check number of running nodes
366 self.assertTrue(len(self.getContainernetContainers()) == 1)
367 self.assertTrue(len(self.net.hosts) == 2)
368 self.assertTrue(len(self.net.switches) == 1)
369 # check compute list result
370 self.assertTrue(len(self.dc[0].listCompute()) == 1)
371 self.assertTrue(isinstance(
372 self.dc[0].listCompute()[0], EmulatorCompute))
373 self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
374 # check connectivity by using ping
375 self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
376 # check get status
377 s = self.dc[0].containers.get("vnf1").getStatus()
378 self.assertTrue(s["name"] == "vnf1")
379 self.assertTrue(s["state"]["Running"])
380 # stop Mininet network
381 self.stopNet()
382
383 def testConnectivityMultiDC(self):
384 """
385 Test if compute instances started in different data centers
386 are able to talk to each other.
387 """
388 # create network
389 self.createNet(
390 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
391 autolinkswitches=True)
392 # setup links
393 self.net.addLink(self.dc[0], self.s[0])
394 self.net.addLink(self.dc[1], self.s[2])
395 # start Mininet network
396 self.startNet()
397 # add compute resources
398 vnf1 = self.dc[0].startCompute("vnf1")
399 vnf2 = self.dc[1].startCompute("vnf2")
400 # check number of running nodes
401 self.assertTrue(len(self.getContainernetContainers()) == 2)
402 self.assertTrue(len(self.net.hosts) == 2)
403 self.assertTrue(len(self.net.switches) == 5)
404 # check compute list result
405 self.assertTrue(len(self.dc[0].listCompute()) == 1)
406 self.assertTrue(len(self.dc[1].listCompute()) == 1)
407 # check connectivity by using ping
408 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
409 # stop Mininet network
410 self.stopNet()
411
412 def testInterleavedAddRemoveMultiDC(self):
413 """
414 Test multiple, interleaved add and remove operations and ensure
415 that always all expected compute instances are reachable.
416 """
417 # create network
418 self.createNet(
419 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
420 autolinkswitches=True)
421 # setup links
422 self.net.addLink(self.dc[0], self.s[0])
423 self.net.addLink(self.dc[1], self.s[2])
424 # start Mininet network
425 self.startNet()
426 # add compute resources
427 vnf1 = self.dc[0].startCompute("vnf1")
428 vnf2 = self.dc[1].startCompute("vnf2")
429 # check number of running nodes
430 self.assertTrue(len(self.getContainernetContainers()) == 2)
431 self.assertTrue(len(self.net.hosts) == 2)
432 self.assertTrue(len(self.net.switches) == 5)
433 # check compute list result
434 self.assertTrue(len(self.dc[0].listCompute()) == 1)
435 self.assertTrue(len(self.dc[1].listCompute()) == 1)
436 # check connectivity by using ping
437 self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
438 # remove compute resources
439 self.dc[0].stopCompute("vnf1")
440 # check number of running nodes
441 self.assertTrue(len(self.getContainernetContainers()) == 1)
442 self.assertTrue(len(self.net.hosts) == 1)
443 self.assertTrue(len(self.net.switches) == 5)
444 # check compute list result
445 self.assertTrue(len(self.dc[0].listCompute()) == 0)
446 self.assertTrue(len(self.dc[1].listCompute()) == 1)
447 # add compute resources
448 vnf3 = self.dc[0].startCompute("vnf3")
449 vnf4 = self.dc[0].startCompute("vnf4")
450 # check compute list result
451 self.assertTrue(len(self.dc[0].listCompute()) == 2)
452 self.assertTrue(len(self.dc[1].listCompute()) == 1)
453 self.assertTrue(self.net.ping([vnf3, vnf2]) <= 0.0)
454 self.assertTrue(self.net.ping([vnf4, vnf2]) <= 0.0)
455 # remove compute resources
456 self.dc[0].stopCompute("vnf3")
457 self.dc[0].stopCompute("vnf4")
458 self.dc[1].stopCompute("vnf2")
459 # check compute list result
460 self.assertTrue(len(self.dc[0].listCompute()) == 0)
461 self.assertTrue(len(self.dc[1].listCompute()) == 0)
462 # stop Mininet network
463 self.stopNet()
464
465
466 if __name__ == '__main__':
467 unittest.main()