1 # Copyright (c) 2015 SONATA-NFV and Paderborn University
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
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
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).
27 from emuvim
.dcemulator
.node
import EmulatorCompute
28 from emuvim
.test
.base
import SimpleTestTopology
29 from mininet
.node
import RemoteController
32 # @unittest.skip("disabled topology tests for development")
33 class testEmulatorTopology(SimpleTestTopology
):
35 Tests to check the topology API of the emulator.
38 def testSingleDatacenter(self
):
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.
45 self
.createNet(nswitches
=0, ndatacenter
=1, nhosts
=2, ndockers
=0)
47 self
.net
.addLink(self
.dc
[0], self
.h
[0])
48 self
.net
.addLink(self
.h
[1], self
.dc
[0])
49 # start Mininet network
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
60 # @unittest.skip("disabled to test if CI fails because this is the first test.")
61 def testMultipleDatacenterDirect(self
):
63 Create a two data centers and interconnect them.
66 self
.createNet(nswitches
=0, ndatacenter
=2, nhosts
=2, ndockers
=0)
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
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
82 def testMultipleDatacenterWithIntermediateSwitches(self
):
84 Create a two data centers and interconnect them with additional
85 switches between them.
89 nswitches
=3, ndatacenter
=2, nhosts
=2, ndockers
=0,
90 autolinkswitches
=True)
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
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
108 class testEmulatorNetworking(SimpleTestTopology
):
110 def testSDNChainingSingleService_withLearning(self
):
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.
119 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
120 autolinkswitches
=True,
121 controller
=RemoteController
,
122 enable_learning
=True)
124 self
.net
.addLink(self
.dc
[0], self
.s
[0])
125 self
.net
.addLink(self
.s
[2], self
.dc
[1])
126 # start Mininet network
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)
140 s1
= self
.dc
[0].containers
.get("vnf1").getStatus()
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')
147 s2
= self
.dc
[1].containers
.get("vnf2").getStatus()
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')
154 # should be connected because learning = True
155 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) <= 0.0)
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
164 def testSDNChainingSingleService(self
):
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.
173 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
174 autolinkswitches
=True,
175 controller
=RemoteController
,
176 enable_learning
=False)
178 self
.net
.addLink(self
.dc
[0], self
.s
[0])
179 self
.net
.addLink(self
.s
[2], self
.dc
[1])
180 # start Mininet network
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)
194 s1
= self
.dc
[0].containers
.get("vnf1").getStatus()
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')
201 s2
= self
.dc
[1].containers
.get("vnf2").getStatus()
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')
208 # should be not not yet connected
209 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) > 0.0)
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
218 def testSDNChainingMultiService(self
):
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
228 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
229 autolinkswitches
=True,
230 controller
=RemoteController
,
231 enable_learning
=False)
233 self
.net
.addLink(self
.dc
[0], self
.s
[0])
234 self
.net
.addLink(self
.s
[2], self
.dc
[1])
235 # start Mininet network
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'}])
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)
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'}])
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)
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)
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)
277 # check connectivity of second service is still up
278 self
.assertTrue(self
.net
.ping([vnf11
, vnf22
]) <= 0.0)
280 # stop Mininet network
283 # @unittest.skip("disabled compute tests for development")
286 class testEmulatorCompute(SimpleTestTopology
):
288 Tests to check the emulator's API to add and remove
289 compute resources at runtime.
292 def testAddSingleComputeSingleDC(self
):
294 Adds a single compute instance to
295 a single DC and checks its connectivity with a
299 self
.createNet(nswitches
=0, ndatacenter
=1, nhosts
=1, ndockers
=0)
301 self
.net
.addLink(self
.dc
[0], self
.h
[0])
302 # start Mininet network
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
320 def testRemoveSingleComputeSingleDC(self
):
322 Test stop method for compute instances.
323 Check that the instance is really removed.
326 self
.createNet(nswitches
=0, ndatacenter
=1, nhosts
=1, ndockers
=0)
328 self
.net
.addLink(self
.dc
[0], self
.h
[0])
329 # start Mininet network
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
352 def testGetStatusSingleComputeSingleDC(self
):
354 Check if the getStatus functionality of EmulatorCompute
358 self
.createNet(nswitches
=0, ndatacenter
=1, nhosts
=1, ndockers
=0)
360 self
.net
.addLink(self
.dc
[0], self
.h
[0])
361 # start Mininet network
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)
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
383 def testConnectivityMultiDC(self
):
385 Test if compute instances started in different data centers
386 are able to talk to each other.
390 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
391 autolinkswitches
=True)
393 self
.net
.addLink(self
.dc
[0], self
.s
[0])
394 self
.net
.addLink(self
.dc
[1], self
.s
[2])
395 # start Mininet network
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
412 def testInterleavedAddRemoveMultiDC(self
):
414 Test multiple, interleaved add and remove operations and ensure
415 that always all expected compute instances are reachable.
419 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
420 autolinkswitches
=True)
422 self
.net
.addLink(self
.dc
[0], self
.s
[0])
423 self
.net
.addLink(self
.dc
[1], self
.s
[2])
424 # start Mininet network
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
466 if __name__
== '__main__':