2 Copyright (c) 2015 SONATA-NFV
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
17 Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
18 nor the names of its contributors may be used to endorse or promote
19 products derived from this software without specific prior written
22 This work has been performed in the framework of the SONATA project,
23 funded by the European Commission under Grant number 671517 through
24 the Horizon 2020 and 5G-PPP programmes. The authors would like to
25 acknowledge the contributions of their colleagues of the SONATA
26 partner consortium (www.sonata-nfv.eu).
29 Test suite to automatically test emulator functionalities.
30 Directly interacts with the emulator through the Mininet-like
33 Does not test API endpoints. This is done in separated test suites.
38 from emuvim
.dcemulator
.node
import EmulatorCompute
39 from emuvim
.test
.base
import SimpleTestTopology
40 from mininet
.node
import RemoteController
43 #@unittest.skip("disabled topology tests for development")
44 class testEmulatorTopology( SimpleTestTopology
):
46 Tests to check the topology API of the emulator.
49 def testSingleDatacenter(self
):
51 Create a single data center and add check if its switch is up
52 by using manually added hosts. Tests especially the
53 data center specific addLink method.
56 self
.createNet(nswitches
=0, ndatacenter
=1, nhosts
=2, ndockers
=0)
58 self
.net
.addLink(self
.dc
[0], self
.h
[0])
59 self
.net
.addLink(self
.h
[1], self
.dc
[0])
60 # start Mininet network
62 # check number of running nodes
63 self
.assertTrue(len(self
.getContainernetContainers()) == 0)
64 self
.assertTrue(len(self
.net
.hosts
) == 2)
65 self
.assertTrue(len(self
.net
.switches
) == 1)
66 # check connectivity by using ping
67 self
.assertTrue(self
.net
.ping([self
.h
[0], self
.h
[1]]) <= 0.0)
68 # stop Mininet network
71 #@unittest.skip("disabled to test if CI fails because this is the first test.")
72 def testMultipleDatacenterDirect(self
):
74 Create a two data centers and interconnect them.
77 self
.createNet(nswitches
=0, ndatacenter
=2, nhosts
=2, ndockers
=0)
79 self
.net
.addLink(self
.dc
[0], self
.h
[0])
80 self
.net
.addLink(self
.h
[1], self
.dc
[1])
81 self
.net
.addLink(self
.dc
[0], self
.dc
[1])
82 # start Mininet network
84 # check number of running nodes
85 self
.assertTrue(len(self
.getContainernetContainers()) == 0)
86 self
.assertTrue(len(self
.net
.hosts
) == 2)
87 self
.assertTrue(len(self
.net
.switches
) == 2)
88 # check connectivity by using ping
89 self
.assertTrue(self
.net
.ping([self
.h
[0], self
.h
[1]]) <= 0.0)
90 # stop Mininet network
93 def testMultipleDatacenterWithIntermediateSwitches(self
):
95 Create a two data centers and interconnect them with additional
96 switches between them.
100 nswitches
=3, ndatacenter
=2, nhosts
=2, ndockers
=0,
101 autolinkswitches
=True)
103 self
.net
.addLink(self
.dc
[0], self
.h
[0])
104 self
.net
.addLink(self
.h
[1], self
.dc
[1])
105 self
.net
.addLink(self
.dc
[0], self
.s
[0])
106 self
.net
.addLink(self
.s
[2], self
.dc
[1])
107 # start Mininet network
109 # check number of running nodes
110 self
.assertTrue(len(self
.getContainernetContainers()) == 0)
111 self
.assertTrue(len(self
.net
.hosts
) == 2)
112 self
.assertTrue(len(self
.net
.switches
) == 5)
113 # check connectivity by using ping
114 self
.assertTrue(self
.net
.ping([self
.h
[0], self
.h
[1]]) <= 0.0)
115 # stop Mininet network
118 class testEmulatorNetworking( SimpleTestTopology
):
120 def testSDNChainingSingleService_withLearning(self
):
122 Create a two data centers and interconnect them with additional
123 switches between them.
124 Uses Ryu SDN controller.
125 Connect the Docker hosts to different datacenters and setup the links between.
129 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
130 autolinkswitches
=True,
131 controller
=RemoteController
,
132 enable_learning
=True)
134 self
.net
.addLink(self
.dc
[0], self
.s
[0])
135 self
.net
.addLink(self
.s
[2], self
.dc
[1])
136 # start Mininet network
139 # add compute resources
140 vnf1
= self
.dc
[0].startCompute("vnf1", network
=[{'id':'intf1', 'ip':'10.0.10.1/24'}])
141 vnf2
= self
.dc
[1].startCompute("vnf2", network
=[{'id':'intf2', 'ip':'10.0.10.2/24'}])
142 # check number of running nodes
143 self
.assertTrue(len(self
.getContainernetContainers()) == 2)
144 self
.assertTrue(len(self
.net
.hosts
) == 2)
145 self
.assertTrue(len(self
.net
.switches
) == 5)
148 s1
= self
.dc
[0].containers
.get("vnf1").getStatus()
150 self
.assertTrue(s1
["name"] == "vnf1")
151 self
.assertTrue(s1
["state"]["Running"])
152 self
.assertTrue(s1
["network"][0]['intf_name'] == 'intf1')
153 self
.assertTrue(s1
["network"][0]['ip'] == '10.0.10.1/24')
155 s2
= self
.dc
[1].containers
.get("vnf2").getStatus()
157 self
.assertTrue(s2
["name"] == "vnf2")
158 self
.assertTrue(s2
["state"]["Running"])
159 self
.assertTrue(s2
["network"][0]['intf_name'] == 'intf2')
160 self
.assertTrue(s2
["network"][0]['ip'] == '10.0.10.2/24')
162 # should be connected because learning = True
163 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) <= 0.0)
165 self
.net
.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional
=True, cmd
='add-flow')
166 # should still be connected
167 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) <= 0.0)
168 # stop Mininet network
171 def testSDNChainingSingleService(self
):
173 Create a two data centers and interconnect them with additional
174 switches between them.
175 Uses Ryu SDN controller.
176 Connect the Docker hosts to different datacenters and setup the links between.
180 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
181 autolinkswitches
=True,
182 controller
=RemoteController
,
183 enable_learning
=False)
185 self
.net
.addLink(self
.dc
[0], self
.s
[0])
186 self
.net
.addLink(self
.s
[2], self
.dc
[1])
187 # start Mininet network
190 # add compute resources
191 vnf1
= self
.dc
[0].startCompute("vnf1", network
=[{'id':'intf1', 'ip':'10.0.10.1/24'}])
192 vnf2
= self
.dc
[1].startCompute("vnf2", network
=[{'id':'intf2', 'ip':'10.0.10.2/24'}])
193 # check number of running nodes
194 self
.assertTrue(len(self
.getContainernetContainers()) == 2)
195 self
.assertTrue(len(self
.net
.hosts
) == 2)
196 self
.assertTrue(len(self
.net
.switches
) == 5)
199 s1
= self
.dc
[0].containers
.get("vnf1").getStatus()
201 self
.assertTrue(s1
["name"] == "vnf1")
202 self
.assertTrue(s1
["state"]["Running"])
203 self
.assertTrue(s1
["network"][0]['intf_name'] == 'intf1')
204 self
.assertTrue(s1
["network"][0]['ip'] == '10.0.10.1/24')
206 s2
= self
.dc
[1].containers
.get("vnf2").getStatus()
208 self
.assertTrue(s2
["name"] == "vnf2")
209 self
.assertTrue(s2
["state"]["Running"])
210 self
.assertTrue(s2
["network"][0]['intf_name'] == 'intf2')
211 self
.assertTrue(s2
["network"][0]['ip'] == '10.0.10.2/24')
213 # should be not not yet connected
214 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) > 0.0)
216 self
.net
.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional
=True, cmd
='add-flow')
217 # check connectivity by using ping
218 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) <= 0.0)
219 # stop Mininet network
222 def testSDNChainingMultiService(self
):
224 Create a two data centers and interconnect them with additional
225 switches between them.
226 Uses Ryu SDN controller.
227 Setup 2 services and setup isolated paths between them
228 Delete only the first service, and check that other one still works
232 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
233 autolinkswitches
=True,
234 controller
=RemoteController
,
235 enable_learning
=False)
237 self
.net
.addLink(self
.dc
[0], self
.s
[0])
238 self
.net
.addLink(self
.s
[2], self
.dc
[1])
239 # start Mininet network
243 # add compute resources
244 vnf1
= self
.dc
[0].startCompute("vnf1", network
=[{'id': 'intf1', 'ip': '10.0.10.1/24'}])
245 vnf2
= self
.dc
[1].startCompute("vnf2", network
=[{'id': 'intf2', 'ip': '10.0.10.2/24'}])
247 self
.net
.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional
=True, cmd
='add-flow', cookie
=1)
248 # check connectivity by using ping
249 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) <= 0.0)
252 # add compute resources
253 vnf11
= self
.dc
[0].startCompute("vnf11", network
=[{'id': 'intf1', 'ip': '10.0.20.1/24'}])
254 vnf22
= self
.dc
[1].startCompute("vnf22", network
=[{'id': 'intf2', 'ip': '10.0.20.2/24'}])
256 # check number of running nodes
257 self
.assertTrue(len(self
.getContainernetContainers()) == 4)
258 self
.assertTrue(len(self
.net
.hosts
) == 4)
259 self
.assertTrue(len(self
.net
.switches
) == 5)
262 self
.net
.setChain('vnf11', 'vnf22', 'intf1', 'intf2', bidirectional
=True, cmd
='add-flow', cookie
=2)
263 # check connectivity by using ping
264 self
.assertTrue(self
.net
.ping([vnf11
, vnf22
]) <= 0.0)
265 # check first service cannot ping second service
266 self
.assertTrue(self
.net
.ping([vnf1
, vnf22
]) > 0.0)
267 self
.assertTrue(self
.net
.ping([vnf2
, vnf11
]) > 0.0)
269 # delete the first service chain
270 self
.net
.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional
=True, cmd
='del-flows', cookie
=1)
271 # check connectivity of first service is down
272 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) > 0.0)
274 # check connectivity of second service is still up
275 self
.assertTrue(self
.net
.ping([vnf11
, vnf22
]) <= 0.0)
277 # stop Mininet network
280 #@unittest.skip("disabled compute tests for development")
281 class testEmulatorCompute( SimpleTestTopology
):
283 Tests to check the emulator's API to add and remove
284 compute resources at runtime.
287 def testAddSingleComputeSingleDC(self
):
289 Adds a single compute instance to
290 a single DC and checks its connectivity with a
294 self
.createNet(nswitches
=0, ndatacenter
=1, nhosts
=1, ndockers
=0)
296 self
.net
.addLink(self
.dc
[0], self
.h
[0])
297 # start Mininet network
299 # add compute resources
300 vnf1
= self
.dc
[0].startCompute("vnf1")
301 # check number of running nodes
302 self
.assertTrue(len(self
.getContainernetContainers()) == 1)
303 self
.assertTrue(len(self
.net
.hosts
) == 2)
304 self
.assertTrue(len(self
.net
.switches
) == 1)
305 # check compute list result
306 self
.assertTrue(len(self
.dc
[0].listCompute()) == 1)
307 self
.assertTrue(isinstance(self
.dc
[0].listCompute()[0], EmulatorCompute
))
308 self
.assertTrue(self
.dc
[0].listCompute()[0].name
== "vnf1")
309 # check connectivity by using ping
310 self
.assertTrue(self
.net
.ping([self
.h
[0], vnf1
]) <= 0.0)
311 # stop Mininet network
314 def testRemoveSingleComputeSingleDC(self
):
316 Test stop method for compute instances.
317 Check that the instance is really removed.
320 self
.createNet(nswitches
=0, ndatacenter
=1, nhosts
=1, ndockers
=0)
322 self
.net
.addLink(self
.dc
[0], self
.h
[0])
323 # start Mininet network
325 # add compute resources
326 vnf1
= self
.dc
[0].startCompute("vnf1")
327 # check number of running nodes
328 self
.assertTrue(len(self
.getContainernetContainers()) == 1)
329 self
.assertTrue(len(self
.net
.hosts
) == 2)
330 self
.assertTrue(len(self
.net
.switches
) == 1)
331 # check compute list result
332 self
.assertTrue(len(self
.dc
[0].listCompute()) == 1)
333 # check connectivity by using ping
334 self
.assertTrue(self
.net
.ping([self
.h
[0], vnf1
]) <= 0.0)
335 # remove compute resources
336 self
.dc
[0].stopCompute("vnf1")
337 # check number of running nodes
338 self
.assertTrue(len(self
.getContainernetContainers()) == 0)
339 self
.assertTrue(len(self
.net
.hosts
) == 1)
340 self
.assertTrue(len(self
.net
.switches
) == 1)
341 # check compute list result
342 self
.assertTrue(len(self
.dc
[0].listCompute()) == 0)
343 # stop Mininet network
346 def testGetStatusSingleComputeSingleDC(self
):
348 Check if the getStatus functionality of EmulatorCompute
352 self
.createNet(nswitches
=0, ndatacenter
=1, nhosts
=1, ndockers
=0)
354 self
.net
.addLink(self
.dc
[0], self
.h
[0])
355 # start Mininet network
357 # add compute resources
358 vnf1
= self
.dc
[0].startCompute("vnf1")
359 # check number of running nodes
360 self
.assertTrue(len(self
.getContainernetContainers()) == 1)
361 self
.assertTrue(len(self
.net
.hosts
) == 2)
362 self
.assertTrue(len(self
.net
.switches
) == 1)
363 # check compute list result
364 self
.assertTrue(len(self
.dc
[0].listCompute()) == 1)
365 self
.assertTrue(isinstance(self
.dc
[0].listCompute()[0], EmulatorCompute
))
366 self
.assertTrue(self
.dc
[0].listCompute()[0].name
== "vnf1")
367 # check connectivity by using ping
368 self
.assertTrue(self
.net
.ping([self
.h
[0], vnf1
]) <= 0.0)
370 s
= self
.dc
[0].containers
.get("vnf1").getStatus()
371 self
.assertTrue(s
["name"] == "vnf1")
372 self
.assertTrue(s
["state"]["Running"])
373 # stop Mininet network
376 def testConnectivityMultiDC(self
):
378 Test if compute instances started in different data centers
379 are able to talk to each other.
383 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
384 autolinkswitches
=True)
386 self
.net
.addLink(self
.dc
[0], self
.s
[0])
387 self
.net
.addLink(self
.dc
[1], self
.s
[2])
388 # start Mininet network
390 # add compute resources
391 vnf1
= self
.dc
[0].startCompute("vnf1")
392 vnf2
= self
.dc
[1].startCompute("vnf2")
393 # check number of running nodes
394 self
.assertTrue(len(self
.getContainernetContainers()) == 2)
395 self
.assertTrue(len(self
.net
.hosts
) == 2)
396 self
.assertTrue(len(self
.net
.switches
) == 5)
397 # check compute list result
398 self
.assertTrue(len(self
.dc
[0].listCompute()) == 1)
399 self
.assertTrue(len(self
.dc
[1].listCompute()) == 1)
400 # check connectivity by using ping
401 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) <= 0.0)
402 # stop Mininet network
405 def testInterleavedAddRemoveMultiDC(self
):
407 Test multiple, interleaved add and remove operations and ensure
408 that always all expected compute instances are reachable.
412 nswitches
=3, ndatacenter
=2, nhosts
=0, ndockers
=0,
413 autolinkswitches
=True)
415 self
.net
.addLink(self
.dc
[0], self
.s
[0])
416 self
.net
.addLink(self
.dc
[1], self
.s
[2])
417 # start Mininet network
419 # add compute resources
420 vnf1
= self
.dc
[0].startCompute("vnf1")
421 vnf2
= self
.dc
[1].startCompute("vnf2")
422 # check number of running nodes
423 self
.assertTrue(len(self
.getContainernetContainers()) == 2)
424 self
.assertTrue(len(self
.net
.hosts
) == 2)
425 self
.assertTrue(len(self
.net
.switches
) == 5)
426 # check compute list result
427 self
.assertTrue(len(self
.dc
[0].listCompute()) == 1)
428 self
.assertTrue(len(self
.dc
[1].listCompute()) == 1)
429 # check connectivity by using ping
430 self
.assertTrue(self
.net
.ping([vnf1
, vnf2
]) <= 0.0)
431 # remove compute resources
432 self
.dc
[0].stopCompute("vnf1")
433 # check number of running nodes
434 self
.assertTrue(len(self
.getContainernetContainers()) == 1)
435 self
.assertTrue(len(self
.net
.hosts
) == 1)
436 self
.assertTrue(len(self
.net
.switches
) == 5)
437 # check compute list result
438 self
.assertTrue(len(self
.dc
[0].listCompute()) == 0)
439 self
.assertTrue(len(self
.dc
[1].listCompute()) == 1)
440 # add compute resources
441 vnf3
= self
.dc
[0].startCompute("vnf3")
442 vnf4
= self
.dc
[0].startCompute("vnf4")
443 # check compute list result
444 self
.assertTrue(len(self
.dc
[0].listCompute()) == 2)
445 self
.assertTrue(len(self
.dc
[1].listCompute()) == 1)
446 self
.assertTrue(self
.net
.ping([vnf3
, vnf2
]) <= 0.0)
447 self
.assertTrue(self
.net
.ping([vnf4
, vnf2
]) <= 0.0)
448 # remove compute resources
449 self
.dc
[0].stopCompute("vnf3")
450 self
.dc
[0].stopCompute("vnf4")
451 self
.dc
[1].stopCompute("vnf2")
452 # check compute list result
453 self
.assertTrue(len(self
.dc
[0].listCompute()) == 0)
454 self
.assertTrue(len(self
.dc
[1].listCompute()) == 0)
455 # stop Mininet network
458 if __name__
== '__main__':