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