blob: a11bc8b96c7c9a0f7e0671a5cf86c6b25cc803a4 [file] [log] [blame]
peusterm43485a22016-03-14 11:18:37 +01001import time
peusterm3055e702016-04-16 16:48:12 +02002import os
peusterm5c6475c2016-03-13 12:54:11 +01003from emuvim.test.base import SimpleTestTopology
peusterm43485a22016-03-14 11:18:37 +01004from emuvim.dcemulator.resourcemodel import BaseResourceModel, ResourceFlavor
peusterm279565d2016-03-19 10:36:52 +01005from emuvim.dcemulator.resourcemodel.upb.simple import UpbSimpleCloudDcRM
6from emuvim.dcemulator.resourcemodel import ResourceModelRegistrar
peusterm5c6475c2016-03-13 12:54:11 +01007
8
9class testResourceModel(SimpleTestTopology):
peustermbdcf2d22016-03-25 12:14:15 +010010 """
11 Test the general resource model API and functionality.
12 """
peusterm5c6475c2016-03-13 12:54:11 +010013
14 def testBaseResourceModelApi(self):
peustermbdcf2d22016-03-25 12:14:15 +010015 """
16 Tast bare API without real resource madel.
17 :return:
18 """
peusterm43485a22016-03-14 11:18:37 +010019 r = BaseResourceModel()
20 # check if default flavors are there
peustermbdcf2d22016-03-25 12:14:15 +010021 self.assertTrue(len(r._flavors) == 5)
peusterm43485a22016-03-14 11:18:37 +010022 # check addFlavor functionality
23 f = ResourceFlavor("test", {"testmetric": 42})
24 r.addFlavour(f)
peustermbdcf2d22016-03-25 12:14:15 +010025 self.assertTrue("test" in r._flavors)
26 self.assertTrue(r._flavors.get("test").get("testmetric") == 42)
peusterm5c6475c2016-03-13 12:54:11 +010027
28 def testAddRmToDc(self):
peustermbdcf2d22016-03-25 12:14:15 +010029 """
30 Test is allocate/free is called when a RM is added to a DC.
31 :return:
32 """
peusterm5c6475c2016-03-13 12:54:11 +010033 # create network
34 self.createNet(nswitches=0, ndatacenter=1, nhosts=2, ndockers=0)
35 # setup links
36 self.net.addLink(self.dc[0], self.h[0])
37 self.net.addLink(self.h[1], self.dc[0])
38 # add resource model
39 r = BaseResourceModel()
40 self.dc[0].assignResourceModel(r)
41 # start Mininet network
42 self.startNet()
43 # check number of running nodes
peustermbdcf2d22016-03-25 12:14:15 +010044 self.assertTrue(len(self.getDockernetContainers()) == 0)
45 self.assertTrue(len(self.net.hosts) == 2)
46 self.assertTrue(len(self.net.switches) == 1)
peusterm5c6475c2016-03-13 12:54:11 +010047 # check resource model and resource model registrar
peustermbdcf2d22016-03-25 12:14:15 +010048 self.assertTrue(self.dc[0]._resource_model is not None)
49 self.assertTrue(len(self.net.rm_registrar.resource_models) == 1)
peusterm43485a22016-03-14 11:18:37 +010050
51 # check if alloc was called during startCompute
peustermd18559d2016-04-16 04:59:23 +020052 self.assertTrue(len(r._allocated_compute_instances) == 0)
peusterm43485a22016-03-14 11:18:37 +010053 self.dc[0].startCompute("tc1")
54 time.sleep(1)
peustermd18559d2016-04-16 04:59:23 +020055 self.assertTrue(len(r._allocated_compute_instances) == 1)
peusterm43485a22016-03-14 11:18:37 +010056 # check if free was called during stopCompute
57 self.dc[0].stopCompute("tc1")
peustermd18559d2016-04-16 04:59:23 +020058 self.assertTrue(len(r._allocated_compute_instances) == 0)
peusterm5c6475c2016-03-13 12:54:11 +010059 # check connectivity by using ping
peustermbdcf2d22016-03-25 12:14:15 +010060 self.assertTrue(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
peusterm5c6475c2016-03-13 12:54:11 +010061 # stop Mininet network
62 self.stopNet()
peusterm279565d2016-03-19 10:36:52 +010063
64
peustermd18559d2016-04-16 04:59:23 +020065def createDummyContainerObject(name, flavor):
66
67 class DummyContainer(object):
68
69 def __init__(self):
70 self.cpu_period = -1
71 self.cpu_quota = -1
72 self.mem_limit = -1
73 self.memswap_limit = -1
74
75 def updateCpuLimit(self, cpu_period, cpu_quota):
76 self.cpu_period = cpu_period
77 self.cpu_quota = cpu_quota
78
79 def updateMemoryLimit(self, mem_limit):
80 self.mem_limit = mem_limit
81
82 d = DummyContainer()
83 d.name = name
84 d.flavor_name = flavor
85 return d
86
87
88
89
peusterm279565d2016-03-19 10:36:52 +010090class testUpbSimpleCloudDcRM(SimpleTestTopology):
91 """
92 Test the UpbSimpleCloudDc resource model.
93 """
peustermbdcf2d22016-03-25 12:14:15 +010094
peusterm279565d2016-03-19 10:36:52 +010095 def testAllocation(self):
peustermbdcf2d22016-03-25 12:14:15 +010096 """
97 Test the allocation procedures and correct calculations.
98 :return:
99 """
peusterm279565d2016-03-19 10:36:52 +0100100 # config
101 E_CPU = 1.0
102 MAX_CU = 100
peusterm972a9f02016-03-25 14:58:05 +0100103 E_MEM = 512
104 MAX_MU = 2048
peusterm279565d2016-03-19 10:36:52 +0100105 # create dummy resource model environment
peusterm972a9f02016-03-25 14:58:05 +0100106 reg = ResourceModelRegistrar(dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
107 rm = UpbSimpleCloudDcRM(max_cu=MAX_CU, max_mu=MAX_MU)
peusterm279565d2016-03-19 10:36:52 +0100108 reg.register("test_dc", rm)
109
peustermd18559d2016-04-16 04:59:23 +0200110 c1 = createDummyContainerObject("c1", flavor="tiny")
111 rm.allocate(c1) # calculate allocation
112 self.assertEqual(float(c1.cpu_quota) / c1.cpu_period, E_CPU / MAX_CU * 0.5) # validate compute result
113 self.assertEqual(float(c1.mem_limit/1024/1024), float(E_MEM) / MAX_MU * 32) # validate memory result
peusterm279565d2016-03-19 10:36:52 +0100114
peustermd18559d2016-04-16 04:59:23 +0200115 c2 = createDummyContainerObject("c2", flavor="small")
116 rm.allocate(c2) # calculate allocation
117 self.assertEqual(float(c2.cpu_quota) / c2.cpu_period, E_CPU / MAX_CU * 1) # validate compute result
118 self.assertEqual(float(c2.mem_limit/1024/1024), float(E_MEM) / MAX_MU * 128) # validate memory result
peusterm279565d2016-03-19 10:36:52 +0100119
peusterm279565d2016-03-19 10:36:52 +0100120
peustermd18559d2016-04-16 04:59:23 +0200121 c3 = createDummyContainerObject("c3", flavor="medium")
122 res = rm.allocate(c3) # calculate allocation
123 self.assertEqual(float(c3.cpu_quota) / c3.cpu_period, E_CPU / MAX_CU * 4) # validate compute result
124 self.assertEqual(float(c3.mem_limit/1024/1024), float(E_MEM) / MAX_MU * 256) # validate memory result
peusterm279565d2016-03-19 10:36:52 +0100125
peustermd18559d2016-04-16 04:59:23 +0200126
127 c4 = createDummyContainerObject("c4", flavor="large")
128 rm.allocate(c4) # calculate allocation
129 self.assertEqual(float(c4.cpu_quota) / c4.cpu_period, E_CPU / MAX_CU * 8) # validate compute result
130 self.assertEqual(float(c4.mem_limit/1024/1024), float(E_MEM) / MAX_MU * 512) # validate memory result
131
132
133 c5 = createDummyContainerObject("c5", flavor="xlarge")
134 rm.allocate(c5) # calculate allocation
135 self.assertEqual(float(c5.cpu_quota) / c5.cpu_period, E_CPU / MAX_CU * 16) # validate compute result
136 self.assertEqual(float(c5.mem_limit/1024/1024), float(E_MEM) / MAX_MU * 1024) # validate memory result
137
peusterm279565d2016-03-19 10:36:52 +0100138
peusterm972a9f02016-03-25 14:58:05 +0100139 def testAllocationCpuLimit(self):
140 """
141 Test CPU allocation limit
142 :return:
143 """
144 # config
145 E_CPU = 1.0
peusterm60bf8b82016-04-06 14:12:35 +0200146 MAX_CU = 40
peusterm972a9f02016-03-25 14:58:05 +0100147 E_MEM = 512
148 MAX_MU = 4096
149 # create dummy resource model environment
150 reg = ResourceModelRegistrar(dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
151 rm = UpbSimpleCloudDcRM(max_cu=MAX_CU, max_mu=MAX_MU)
152 reg.register("test_dc", rm)
153
peusterm279565d2016-03-19 10:36:52 +0100154 # test over provisioning exeption
155 exception = False
156 try:
peustermd18559d2016-04-16 04:59:23 +0200157 c6 = createDummyContainerObject("c6", flavor="xlarge")
158 c7 = createDummyContainerObject("c7", flavor="xlarge")
159 c8 = createDummyContainerObject("c8", flavor="xlarge")
160 c9 = createDummyContainerObject("c9", flavor="xlarge")
161 rm.allocate(c6) # calculate allocation
162 rm.allocate(c7) # calculate allocation
163 rm.allocate(c8) # calculate allocation
164 rm.allocate(c9) # calculate allocation
peusterm279565d2016-03-19 10:36:52 +0100165 except Exception as e:
peusterm972a9f02016-03-25 14:58:05 +0100166 self.assertIn("Not enough compute", e.message)
167 exception = True
168 self.assertTrue(exception)
169
170 def testAllocationMemLimit(self):
171 """
172 Test MEM allocation limit
173 :return:
174 """
175 # config
176 E_CPU = 1.0
177 MAX_CU = 500
178 E_MEM = 512
179 MAX_MU = 2048
180 # create dummy resource model environment
181 reg = ResourceModelRegistrar(dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
182 rm = UpbSimpleCloudDcRM(max_cu=MAX_CU, max_mu=MAX_MU)
183 reg.register("test_dc", rm)
184
185 # test over provisioning exeption
186 exception = False
187 try:
peustermd18559d2016-04-16 04:59:23 +0200188 c6 = createDummyContainerObject("c6", flavor="xlarge")
189 c7 = createDummyContainerObject("c7", flavor="xlarge")
190 c8 = createDummyContainerObject("c8", flavor="xlarge")
191 rm.allocate(c6) # calculate allocation
192 rm.allocate(c7) # calculate allocation
193 rm.allocate(c8) # calculate allocation
peusterm972a9f02016-03-25 14:58:05 +0100194 except Exception as e:
195 self.assertIn("Not enough memory", e.message)
peusterm279565d2016-03-19 10:36:52 +0100196 exception = True
peustermbdcf2d22016-03-25 12:14:15 +0100197 self.assertTrue(exception)
peusterm279565d2016-03-19 10:36:52 +0100198
199 def testFree(self):
peustermbdcf2d22016-03-25 12:14:15 +0100200 """
201 Test the free procedure.
202 :return:
203 """
peusterm279565d2016-03-19 10:36:52 +0100204 # config
205 E_CPU = 1.0
206 MAX_CU = 100
207 # create dummy resource model environment
peusterm972a9f02016-03-25 14:58:05 +0100208 reg = ResourceModelRegistrar(dc_emulation_max_cpu=1.0, dc_emulation_max_mem=512)
peusterm279565d2016-03-19 10:36:52 +0100209 rm = UpbSimpleCloudDcRM(max_cu=100, max_mu=100)
210 reg.register("test_dc", rm)
peustermd18559d2016-04-16 04:59:23 +0200211 c1 = createDummyContainerObject("c6", flavor="tiny")
212 rm.allocate(c1) # calculate allocation
peusterm60bf8b82016-04-06 14:12:35 +0200213 self.assertTrue(rm.dc_alloc_cu == 0.5)
peustermd18559d2016-04-16 04:59:23 +0200214 rm.free(c1)
peustermbdcf2d22016-03-25 12:14:15 +0100215 self.assertTrue(rm.dc_alloc_cu == 0)
216
217 def testInRealTopo(self):
218 """
219 Start a real container and check if limitations are really passed down to Dockernet.
220 :return:
221 """
peusterm3055e702016-04-16 16:48:12 +0200222 # ATTENTION: This test should only be executed if emu runs not inside a Docker container,
223 # because it manipulates cgroups.
224 if os.environ.get("SON_EMU_IN_DOCKER") is not None:
225 return
peustermbdcf2d22016-03-25 12:14:15 +0100226 # create network
227 self.createNet(nswitches=0, ndatacenter=1, nhosts=2, ndockers=0)
228 # setup links
229 self.net.addLink(self.dc[0], self.h[0])
230 self.net.addLink(self.h[1], self.dc[0])
231 # add resource model
232 r = UpbSimpleCloudDcRM(max_cu=100, max_mu=100)
233 self.dc[0].assignResourceModel(r)
234 # start Mininet network
235 self.startNet()
236 # check number of running nodes
237 self.assertTrue(len(self.getDockernetContainers()) == 0)
238 self.assertTrue(len(self.net.hosts) == 2)
239 self.assertTrue(len(self.net.switches) == 1)
240 # check resource model and resource model registrar
241 self.assertTrue(self.dc[0]._resource_model is not None)
242 self.assertTrue(len(self.net.rm_registrar.resource_models) == 1)
243
244 # check if alloc was called during startCompute
peustermd18559d2016-04-16 04:59:23 +0200245 self.assertTrue(len(r._allocated_compute_instances) == 0)
peustermbdcf2d22016-03-25 12:14:15 +0100246 tc1 = self.dc[0].startCompute("tc1", flavor_name="tiny")
247 time.sleep(1)
peustermd18559d2016-04-16 04:59:23 +0200248 self.assertTrue(len(r._allocated_compute_instances) == 1)
peustermbdcf2d22016-03-25 12:14:15 +0100249
250 # check if there is a real limitation set for containers cgroup
peusterm9349c872016-04-16 06:36:42 +0200251 # deactivated for now, seems not to work in docker-in-docker setup used in CI
peusterm3055e702016-04-16 16:48:12 +0200252 self.assertEqual(float(tc1.cpu_quota)/tc1.cpu_period, 0.005)
peustermbdcf2d22016-03-25 12:14:15 +0100253
254 # check if free was called during stopCompute
255 self.dc[0].stopCompute("tc1")
peustermd18559d2016-04-16 04:59:23 +0200256 self.assertTrue(len(r._allocated_compute_instances) == 0)
peustermbdcf2d22016-03-25 12:14:15 +0100257 # check connectivity by using ping
258 self.assertTrue(self.net.ping([self.h[0], self.h[1]]) <= 0.0)
259 # stop Mininet network
260 self.stopNet()
peusterm279565d2016-03-19 10:36:52 +0100261
262
263