blob: 06e2da31acfa8560facf20cdb5dad8607ec27e7f [file] [log] [blame]
peusterm94f53ae2016-01-15 12:32:53 +01001"""
2Test suite to automatically test emulator functionalities.
3Directly interacts with the emulator through the Mininet-like
4Python API.
5
6Does not test API endpoints. This is done in separated test suites.
7"""
8
9import unittest
10import os
11import time
12import subprocess
13import docker
cgeoffroy9524ad32016-03-03 18:24:15 +010014from emuvim.dcemulator.net import DCNetwork
15from emuvim.dcemulator.node import EmulatorCompute
peusterm94f53ae2016-01-15 12:32:53 +010016from mininet.node import Host, Controller, OVSSwitch, Docker
17from mininet.link import TCLink
18from mininet.topo import SingleSwitchTopo, LinearTopo
19from mininet.log import setLogLevel
20from mininet.util import quietRun
21from mininet.clean import cleanup
22
23
24class simpleTestTopology( unittest.TestCase ):
25 """
26 Helper class to do basic test setups.
27 s1 -- s2 -- s3 -- ... -- sN
28 """
29
30 def __init__(self, *args, **kwargs):
31 self.net = None
32 self.s = [] # list of switches
33 self.h = [] # list of hosts
34 self.d = [] # list of docker containers
35 self.dc = [] # list of data centers
36 self.docker_cli = None
37 super(simpleTestTopology, self).__init__(*args, **kwargs)
38
39 def createNet(
40 self,
41 nswitches=0, ndatacenter=0, nhosts=0, ndockers=0,
42 autolinkswitches=False):
43 """
44 Creates a Mininet instance and automatically adds some
45 nodes to it.
46 """
47 self.net = net = DCNetwork()
48
49 # add some switches
50 for i in range(0, nswitches):
51 self.s.append(self.net.addSwitch('s%d' % i))
52 # if specified, chain all switches
53 if autolinkswitches:
54 for i in range(0, len(self.s) - 1):
55 self.net.addLink(self.s[i], self.s[i + 1])
56 # add some data centers
57 for i in range(0, ndatacenter):
peusterm53504942016-02-04 16:09:28 +010058 self.dc.append(
59 self.net.addDatacenter(
60 'datacenter%d' % i,
61 metadata={"unittest_dc": i}))
peusterm94f53ae2016-01-15 12:32:53 +010062 # add some hosts
63 for i in range(0, nhosts):
64 self.h.append(self.net.addHost('h%d' % i))
65 # add some dockers
66 for i in range(0, ndockers):
67 self.d.append(self.net.addDocker('d%d' % i, dimage="ubuntu"))
68
69 def startNet(self):
70 self.net.start()
71
72 def stopNet(self):
73 self.net.stop()
74
75 def getDockerCli(self):
76 """
77 Helper to interact with local docker instance.
78 """
79 if self.docker_cli is None:
80 self.docker_cli = docker.Client(
81 base_url='unix://var/run/docker.sock')
82 return self.docker_cli
83
cgeoffroycf350382016-03-02 16:39:58 +010084 def getDockernetContainers(self):
85 """
86 List the containers managed by dockernet
87 """
88 return self.getDockerCli().containers(filters={"label": "com.dockernet"})
89
peusterm94f53ae2016-01-15 12:32:53 +010090 @staticmethod
91 def setUp():
92 pass
93
94 @staticmethod
95 def tearDown():
96 cleanup()
97 # make sure that all pending docker containers are killed
98 with open(os.devnull, 'w') as devnull:
99 subprocess.call(
cgeoffroycf350382016-03-02 16:39:58 +0100100 "sudo docker rm -f $(sudo docker ps --filter 'label=com.dockernet' -a -q)",
peusterm94f53ae2016-01-15 12:32:53 +0100101 stdout=devnull,
102 stderr=devnull,
103 shell=True)
104
105
106#@unittest.skip("disabled topology tests for development")
107class testEmulatorTopology( simpleTestTopology ):
108 """
109 Tests to check the topology API of the emulator.
110 """
111
112 def testSingleDatacenter(self):
113 """
114 Create a single data center and add check if its switch is up
115 by using manually added hosts. Tests especially the
116 data center specific addLink method.
117 """
118 # create network
119 self.createNet(nswitches=0, ndatacenter=1, nhosts=2, ndockers=0)
120 # setup links
121 self.net.addLink(self.dc[0], self.h[0])
122 self.net.addLink(self.h[1], self.dc[0])
123 # start Mininet network
124 self.startNet()
125 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100126 assert(len(self.getDockernetContainers()) == 0)
peusterm94f53ae2016-01-15 12:32:53 +0100127 assert(len(self.net.hosts) == 2)
128 assert(len(self.net.switches) == 1)
129 # check connectivity by using ping
130 assert(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
131 # stop Mininet network
132 self.stopNet()
133
134 def testMultipleDatacenterDirect(self):
135 """
136 Create a two data centers and interconnect them.
137 """
138 # create network
139 self.createNet(nswitches=0, ndatacenter=2, nhosts=2, ndockers=0)
140 # setup links
141 self.net.addLink(self.dc[0], self.h[0])
142 self.net.addLink(self.h[1], self.dc[1])
143 self.net.addLink(self.dc[0], self.dc[1])
144 # start Mininet network
145 self.startNet()
146 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100147 assert(len(self.getDockernetContainers()) == 0)
peusterm94f53ae2016-01-15 12:32:53 +0100148 assert(len(self.net.hosts) == 2)
149 assert(len(self.net.switches) == 2)
150 # check connectivity by using ping
151 assert(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
152 # stop Mininet network
153 self.stopNet()
154
155 def testMultipleDatacenterWithIntermediateSwitches(self):
156 """
157 Create a two data centers and interconnect them with additional
158 switches between them.
159 """
160 # create network
161 self.createNet(
162 nswitches=3, ndatacenter=2, nhosts=2, ndockers=0,
163 autolinkswitches=True)
164 # setup links
165 self.net.addLink(self.dc[0], self.h[0])
166 self.net.addLink(self.h[1], self.dc[1])
167 self.net.addLink(self.dc[0], self.s[0])
168 self.net.addLink(self.s[2], self.dc[1])
169 # start Mininet network
170 self.startNet()
171 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100172 assert(len(self.getDockernetContainers()) == 0)
peusterm94f53ae2016-01-15 12:32:53 +0100173 assert(len(self.net.hosts) == 2)
174 assert(len(self.net.switches) == 5)
175 # check connectivity by using ping
176 assert(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
177 # stop Mininet network
178 self.stopNet()
179
180
181#@unittest.skip("disabled compute tests for development")
182class testEmulatorCompute( simpleTestTopology ):
183 """
184 Tests to check the emulator's API to add and remove
185 compute resources at runtime.
186 """
187
188 def testAddSingleComputeSingleDC(self):
189 """
190 Adds a single compute instance to
191 a single DC and checks its connectivity with a
192 manually added host.
193 """
194 # create network
195 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
196 # setup links
197 self.net.addLink(self.dc[0], self.h[0])
198 # start Mininet network
199 self.startNet()
200 # add compute resources
201 vnf1 = self.dc[0].startCompute("vnf1")
202 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100203 assert(len(self.getDockernetContainers()) == 1)
peusterm94f53ae2016-01-15 12:32:53 +0100204 assert(len(self.net.hosts) == 2)
205 assert(len(self.net.switches) == 1)
206 # check compute list result
207 assert(len(self.dc[0].listCompute()) == 1)
208 assert(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
209 assert(self.dc[0].listCompute()[0].name == "vnf1")
210 # check connectivity by using ping
211 assert(self.net.ping([self.h[0], vnf1]) <= 0.0)
212 # stop Mininet network
213 self.stopNet()
214
215 def testRemoveSingleComputeSingleDC(self):
216 """
217 Test stop method for compute instances.
218 Check that the instance is really removed.
219 """
220 # create network
221 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
222 # setup links
223 self.net.addLink(self.dc[0], self.h[0])
224 # start Mininet network
225 self.startNet()
226 # add compute resources
227 vnf1 = self.dc[0].startCompute("vnf1")
228 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100229 assert(len(self.getDockernetContainers()) == 1)
peusterm94f53ae2016-01-15 12:32:53 +0100230 assert(len(self.net.hosts) == 2)
231 assert(len(self.net.switches) == 1)
232 # check compute list result
233 assert(len(self.dc[0].listCompute()) == 1)
234 # check connectivity by using ping
235 assert(self.net.ping([self.h[0], vnf1]) <= 0.0)
236 # remove compute resources
237 self.dc[0].stopCompute("vnf1")
238 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100239 assert(len(self.getDockernetContainers()) == 0)
peusterm94f53ae2016-01-15 12:32:53 +0100240 assert(len(self.net.hosts) == 1)
241 assert(len(self.net.switches) == 1)
242 # check compute list result
243 assert(len(self.dc[0].listCompute()) == 0)
244 # stop Mininet network
245 self.stopNet()
246
247 def testGetStatusSingleComputeSingleDC(self):
248 """
249 Check if the getStatus functionality of EmulatorCompute
250 objects works well.
251 """
252 # create network
253 self.createNet(nswitches=0, ndatacenter=1, nhosts=1, ndockers=0)
254 # setup links
255 self.net.addLink(self.dc[0], self.h[0])
256 # start Mininet network
257 self.startNet()
258 # add compute resources
259 vnf1 = self.dc[0].startCompute("vnf1")
260 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100261 assert(len(self.getDockernetContainers()) == 1)
peusterm94f53ae2016-01-15 12:32:53 +0100262 assert(len(self.net.hosts) == 2)
263 assert(len(self.net.switches) == 1)
264 # check compute list result
265 assert(len(self.dc[0].listCompute()) == 1)
266 assert(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
267 assert(self.dc[0].listCompute()[0].name == "vnf1")
268 # check connectivity by using ping
269 assert(self.net.ping([self.h[0], vnf1]) <= 0.0)
270 # check get status
271 s = self.dc[0].containers.get("vnf1").getStatus()
272 assert(s["name"] == "vnf1")
273 assert(s["state"]["Running"])
274 # stop Mininet network
275 self.stopNet()
276
277 def testConnectivityMultiDC(self):
278 """
279 Test if compute instances started in different data centers
280 are able to talk to each other.
281 """
282 # create network
283 self.createNet(
284 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
285 autolinkswitches=True)
286 # setup links
287 self.net.addLink(self.dc[0], self.s[0])
288 self.net.addLink(self.dc[1], self.s[2])
289 # start Mininet network
290 self.startNet()
291 # add compute resources
292 vnf1 = self.dc[0].startCompute("vnf1")
293 vnf2 = self.dc[1].startCompute("vnf2")
294 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100295 assert(len(self.getDockernetContainers()) == 2)
peusterm94f53ae2016-01-15 12:32:53 +0100296 assert(len(self.net.hosts) == 2)
297 assert(len(self.net.switches) == 5)
298 # check compute list result
299 assert(len(self.dc[0].listCompute()) == 1)
300 assert(len(self.dc[1].listCompute()) == 1)
301 # check connectivity by using ping
302 assert(self.net.ping([vnf1, vnf2]) <= 0.0)
303 # stop Mininet network
304 self.stopNet()
305
306 def testInterleavedAddRemoveMultiDC(self):
307 """
308 Test multiple, interleaved add and remove operations and ensure
309 that always all expected compute instances are reachable.
310 """
311 # create network
312 self.createNet(
313 nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
314 autolinkswitches=True)
315 # setup links
316 self.net.addLink(self.dc[0], self.s[0])
317 self.net.addLink(self.dc[1], self.s[2])
318 # start Mininet network
319 self.startNet()
320 # add compute resources
321 vnf1 = self.dc[0].startCompute("vnf1")
322 vnf2 = self.dc[1].startCompute("vnf2")
323 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100324 assert(len(self.getDockernetContainers()) == 2)
peusterm94f53ae2016-01-15 12:32:53 +0100325 assert(len(self.net.hosts) == 2)
326 assert(len(self.net.switches) == 5)
327 # check compute list result
328 assert(len(self.dc[0].listCompute()) == 1)
329 assert(len(self.dc[1].listCompute()) == 1)
330 # check connectivity by using ping
331 assert(self.net.ping([vnf1, vnf2]) <= 0.0)
332 # remove compute resources
333 self.dc[0].stopCompute("vnf1")
334 # check number of running nodes
cgeoffroycf350382016-03-02 16:39:58 +0100335 assert(len(self.getDockernetContainers()) == 1)
peusterm94f53ae2016-01-15 12:32:53 +0100336 assert(len(self.net.hosts) == 1)
337 assert(len(self.net.switches) == 5)
338 # check compute list result
339 assert(len(self.dc[0].listCompute()) == 0)
340 assert(len(self.dc[1].listCompute()) == 1)
341 # add compute resources
342 vnf3 = self.dc[0].startCompute("vnf3")
343 vnf4 = self.dc[0].startCompute("vnf4")
344 # check compute list result
345 assert(len(self.dc[0].listCompute()) == 2)
346 assert(len(self.dc[1].listCompute()) == 1)
347 assert(self.net.ping([vnf3, vnf2]) <= 0.0)
348 assert(self.net.ping([vnf4, vnf2]) <= 0.0)
349 # remove compute resources
350 self.dc[0].stopCompute("vnf3")
351 self.dc[0].stopCompute("vnf4")
352 self.dc[1].stopCompute("vnf2")
353 # check compute list result
354 assert(len(self.dc[0].listCompute()) == 0)
355 assert(len(self.dc[1].listCompute()) == 0)
356 # stop Mininet network
357 self.stopNet()
358
359if __name__ == '__main__':
360 unittest.main()