1 ##############################################################################
2 # Copyright (c) 2017 Intel Corporation
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
14 from yardstick.common import exceptions
15 from yardstick.common import kubernetes_utils
16 from yardstick.orchestrator import kubernetes
17 from yardstick.tests.unit import base
20 class GetTemplateTestCase(base.BaseUnitTestCase):
22 def test_get_template(self):
25 "kind": "ReplicationController",
27 "name": "host-k8s-86096c30"
34 "app": "host-k8s-86096c30"
42 "chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; \
43 service ssh restart;while true ; do sleep 10000; done"
48 "image": "openretriever/yardstick",
49 "name": "host-k8s-86096c30-container",
52 "mountPath": "/tmp/.ssh/",
53 "name": "k8s-86096c30-key",
62 "name": "k8s-86096c30-key"
64 "name": "k8s-86096c30-key"
68 "kubernetes.io/hostname": "node-01"
70 "restartPolicy": "Always"
76 'command': '/bin/bash',
77 'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; \
78 service ssh restart;while true ; do sleep 10000; done'],
79 'ssh_key': 'k8s-86096c30-key',
80 'nodeSelector': {'kubernetes.io/hostname': 'node-01'},
82 'restartPolicy': 'Always'
84 name = 'host-k8s-86096c30'
85 output_r = kubernetes.ReplicationControllerObject(
86 name, **input_s).get_template()
87 self.assertEqual(output_r, output_t)
89 def test_get_template_invalid_restart_policy(self):
90 input_s = {'restartPolicy': 'invalid_option'}
91 name = 'host-k8s-86096c30'
92 with self.assertRaises(exceptions.KubernetesWrongRestartPolicy):
93 kubernetes.ReplicationControllerObject(
94 name, **input_s).get_template()
97 class GetRcPodsTestCase(base.BaseUnitTestCase):
99 @mock.patch('yardstick.orchestrator.kubernetes.k8s_utils.get_pod_list')
100 def test_get_rc_pods(self, mock_get_pod_list):
103 'image': 'openretriever/yardstick',
104 'command': '/bin/bash',
105 'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; \
106 service ssh restart;while true ; do sleep 10000; done']
109 'image': 'openretriever/yardstick',
110 'command': '/bin/bash',
111 'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; \
112 service ssh restart;while true ; do sleep 10000; done']
115 k8s_template = kubernetes.KubernetesTemplate('k8s-86096c30', servers)
116 mock_get_pod_list.return_value.items = []
117 pods = k8s_template.get_rc_pods()
118 self.assertEqual(pods, [])
121 class ReplicationControllerObjectTestCase(base.BaseUnitTestCase):
123 def test__init_one_container(self):
124 pod_name = 'pod_name'
125 _kwargs = {'args': ['arg1', 'arg2'],
126 'image': 'fake_image',
127 'command': 'fake_command'}
128 k8s_obj = kubernetes.ReplicationControllerObject(pod_name, **_kwargs)
129 self.assertEqual(1, len(k8s_obj._containers))
130 container = k8s_obj._containers[0]
131 self.assertEqual(['arg1', 'arg2'], container._args)
132 self.assertEqual('fake_image', container._image)
133 self.assertEqual(['fake_command'], container._command)
134 self.assertEqual([], container._volume_mounts)
136 def test__init_multipe_containers(self):
137 pod_name = 'pod_name'
140 containers.append({'args': ['arg1', 'arg2'],
141 'image': 'fake_image_%s' % i,
142 'command': 'fake_command_%s' % i})
143 _kwargs = {'containers': containers}
144 k8s_obj = kubernetes.ReplicationControllerObject(pod_name, **_kwargs)
145 self.assertEqual(5, len(k8s_obj._containers))
147 container = k8s_obj._containers[i]
148 self.assertEqual(['arg1', 'arg2'], container._args)
149 self.assertEqual('fake_image_%s' % i, container._image)
150 self.assertEqual(['fake_command_%s' % i], container._command)
151 self.assertEqual([], container._volume_mounts)
153 def test__add_volumes(self):
154 volume1 = {'name': 'fake_sshkey',
155 'configMap': {'name': 'fake_sshkey'}}
156 volume2 = {'name': 'volume2',
158 k8s_obj = kubernetes.ReplicationControllerObject(
159 'name', ssh_key='fake_sshkey', volumes=[volume2])
160 k8s_obj._add_volumes()
161 volumes = k8s_obj.template['spec']['template']['spec']['volumes']
162 self.assertEqual(sorted([volume1, volume2], key=lambda k: k['name']),
163 sorted(volumes, key=lambda k: k['name']))
165 def test__add_volumes_no_volumes(self):
166 volume1 = {'name': 'fake_sshkey',
167 'configMap': {'name': 'fake_sshkey'}}
168 k8s_obj = kubernetes.ReplicationControllerObject(
169 'name', ssh_key='fake_sshkey')
170 k8s_obj._add_volumes()
171 volumes = k8s_obj.template['spec']['template']['spec']['volumes']
172 self.assertEqual([volume1], volumes)
174 def test__create_ssh_key_volume(self):
175 expected = {'name': 'fake_sshkey',
176 'configMap': {'name': 'fake_sshkey'}}
177 k8s_obj = kubernetes.ReplicationControllerObject(
178 'name', ssh_key='fake_sshkey')
179 self.assertEqual(expected, k8s_obj._create_ssh_key_volume())
181 def test__create_volume_item(self):
182 for vol_type in kubernetes_utils.get_volume_types():
183 volume = {'name': 'vol_name',
187 kubernetes.ReplicationControllerObject.
188 _create_volume_item(volume))
190 def test__create_volume_item_invalid_type(self):
191 volume = {'name': 'vol_name',
192 'invalid_type': 'data'}
193 with self.assertRaises(exceptions.KubernetesTemplateInvalidVolumeType):
194 kubernetes.ReplicationControllerObject._create_volume_item(volume)
196 def test__add_security_context(self):
197 k8s_obj = kubernetes.ReplicationControllerObject('pod_name')
198 self.assertNotIn('securityContext',
199 k8s_obj.template['spec']['template']['spec'])
201 k8s_obj._security_context = {'key_pod': 'value_pod'}
202 k8s_obj._add_security_context()
204 {'key_pod': 'value_pod'},
205 k8s_obj.template['spec']['template']['spec']['securityContext'])
207 def test__add_security_context_by_init(self):
211 {'securityContext': {'key%s' % i: 'value%s' % i}})
212 _kwargs = {'containers': containers,
213 'securityContext': {'key_pod': 'value_pod'}}
214 k8s_obj = kubernetes.ReplicationControllerObject('pod_name', **_kwargs)
216 {'key_pod': 'value_pod'},
217 k8s_obj.template['spec']['template']['spec']['securityContext'])
220 k8s_obj.template['spec']['template']['spec']['containers'][i])
221 self.assertEqual({'key%s' % i: 'value%s' % i},
222 container['securityContext'])
224 def test__add_networks(self):
225 k8s_obj = kubernetes.ReplicationControllerObject(
226 'name', networks=['network1', 'network2', 'network3'])
227 k8s_obj._add_networks()
229 template['spec']['template']['metadata']['annotations']['networks']
230 expected = ('[{"name": "network1"}, {"name": "network2"}, '
231 '{"name": "network3"}]')
232 self.assertEqual(expected, networks)
235 class ContainerObjectTestCase(base.BaseUnitTestCase):
237 def test__create_volume_mounts(self):
238 volume_mount = {'name': 'fake_name',
239 'mountPath': 'fake_path'}
240 ssh_vol = {'name': 'fake_ssh_key',
241 'mountPath': kubernetes.ContainerObject.SSH_MOUNT_PATH,
243 expected = copy.deepcopy(volume_mount)
244 expected['readOnly'] = False
245 expected = [expected, ssh_vol]
246 container_obj = kubernetes.ContainerObject(
247 'cname', 'fake_ssh_key', volumeMounts=[volume_mount])
248 output = container_obj._create_volume_mounts()
249 self.assertEqual(expected, output)
251 def test__create_volume_mounts_no_volume_mounts(self):
252 ssh_vol = {'name': 'fake_ssh_key2',
253 'mountPath': kubernetes.ContainerObject.SSH_MOUNT_PATH,
255 container_obj = kubernetes.ContainerObject('name', 'fake_ssh_key2')
256 output = container_obj._create_volume_mounts()
257 self.assertEqual([ssh_vol], output)
259 def test__create_volume_mounts_item(self):
260 volume_mount = {'name': 'fake_name',
261 'mountPath': 'fake_path'}
262 expected = copy.deepcopy(volume_mount)
263 expected['readOnly'] = False
264 output = kubernetes.ContainerObject._create_volume_mounts_item(
266 self.assertEqual(expected, output)
268 def test_get_container_item(self):
269 volume_mount = {'name': 'fake_name',
270 'mountPath': 'fake_path'}
271 args = ['arg1', 'arg2']
272 container_obj = kubernetes.ContainerObject(
273 'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount],
275 expected = {'args': args,
276 'command': [kubernetes.ContainerObject.COMMAND_DEFAULT],
277 'image': kubernetes.ContainerObject.IMAGE_DEFAULT,
278 'name': 'cname-container',
279 'volumeMounts': container_obj._create_volume_mounts()}
280 self.assertEqual(expected, container_obj.get_container_item())
282 def test_get_container_item_with_security_context(self):
283 volume_mount = {'name': 'fake_name',
284 'mountPath': 'fake_path'}
285 args = ['arg1', 'arg2']
286 container_obj = kubernetes.ContainerObject(
287 'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount],
288 args=args, securityContext={'key': 'value'})
289 expected = {'args': args,
290 'command': [kubernetes.ContainerObject.COMMAND_DEFAULT],
291 'image': kubernetes.ContainerObject.IMAGE_DEFAULT,
292 'name': 'cname-container',
293 'volumeMounts': container_obj._create_volume_mounts(),
294 'securityContext': {'key': 'value'}}
295 self.assertEqual(expected, container_obj.get_container_item())
297 def test_get_container_item_with_env(self):
298 volume_mount = {'name': 'fake_name',
299 'mountPath': 'fake_path'}
300 args = ['arg1', 'arg2']
301 container_obj = kubernetes.ContainerObject(
302 'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount],
303 args=args, env=[{'name': 'fake_var_name',
304 'value': 'fake_var_value'}])
305 expected = {'args': args,
306 'command': [kubernetes.ContainerObject.COMMAND_DEFAULT],
307 'image': kubernetes.ContainerObject.IMAGE_DEFAULT,
308 'name': 'cname-container',
309 'volumeMounts': container_obj._create_volume_mounts(),
310 'env': [{'name': 'fake_var_name',
311 'value': 'fake_var_value'}]}
312 self.assertEqual(expected, container_obj.get_container_item())
314 def test_get_container_item_with_ports_multi_parameter(self):
315 volume_mount = {'name': 'fake_name',
316 'mountPath': 'fake_path'}
317 args = ['arg1', 'arg2']
318 container_obj = kubernetes.ContainerObject(
319 'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount],
320 args=args, ports=[{'containerPort': 'fake_port_name',
321 'hostPort': 'fake_host_port',
323 'protocol': 'fake_protocol',
324 'invalid_varible': 'fakeinvalid_varible',
325 'hostIP': 'fake_port_number'}])
326 expected = {'args': args,
328 kubernetes.ContainerObject.COMMAND_DEFAULT],
329 'image': kubernetes.ContainerObject.IMAGE_DEFAULT,
330 'name': 'cname-container',
331 'volumeMounts': container_obj._create_volume_mounts(),
332 'ports': [{'containerPort': 'fake_port_name',
333 'hostPort': 'fake_host_port',
335 'protocol': 'fake_protocol',
336 'hostIP': 'fake_port_number'}]}
337 self.assertEqual(expected, container_obj.get_container_item())
339 def test_get_container_item_with_ports_no_container_port(self):
340 with self.assertRaises(exceptions.KubernetesContainerPortNotDefined):
341 volume_mount = {'name': 'fake_name',
342 'mountPath': 'fake_path'}
343 args = ['arg1', 'arg2']
344 container_obj = kubernetes.ContainerObject(
345 'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount],
346 args=args, ports=[{'hostPort': 'fake_host_port',
348 'protocol': 'fake_protocol',
349 'hostIP': 'fake_port_number'}])
350 container_obj.get_container_item()
352 def test_get_container_item_with_resources(self):
353 volume_mount = {'name': 'fake_name',
354 'mountPath': 'fake_path'}
355 args = ['arg1', 'arg2']
356 resources = {'requests': {'key1': 'val1'},
357 'limits': {'key2': 'val2'},
358 'other_key': {'key3': 'val3'}}
359 container_obj = kubernetes.ContainerObject(
360 'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount],
361 args=args, resources=resources)
362 expected = {'args': args,
363 'command': [kubernetes.ContainerObject.COMMAND_DEFAULT],
364 'image': kubernetes.ContainerObject.IMAGE_DEFAULT,
365 'name': 'cname-container',
366 'volumeMounts': container_obj._create_volume_mounts(),
367 'resources': {'requests': {'key1': 'val1'},
368 'limits': {'key2': 'val2'}}}
369 self.assertEqual(expected, container_obj.get_container_item())
372 class CustomResourceDefinitionObjectTestCase(base.BaseUnitTestCase):
374 def test__init(self):
377 'name': 'newcrds.ctx_name.com'
380 'group': 'ctx_name.com',
383 'names': {'plural': 'newcrds',
384 'singular': 'newcrd',
388 crd_obj = kubernetes.CustomResourceDefinitionObject(
389 'ctx_name', name='newcrd', version='v2', scope='scope')
390 self.assertEqual('newcrds.ctx_name.com', crd_obj._name)
391 self.assertEqual(template, crd_obj._template)
393 def test__init_missing_parameter(self):
394 with self.assertRaises(exceptions.KubernetesCRDObjectDefinitionError):
395 kubernetes.CustomResourceDefinitionObject('ctx_name',
399 class NetworkObjectTestCase(base.BaseUnitTestCase):
402 self.net_obj = kubernetes.NetworkObject(name='fake_name',
403 plugin='fake_plugin',
406 def test__init_missing_parameter(self):
407 with self.assertRaises(
408 exceptions.KubernetesNetworkObjectDefinitionError):
409 kubernetes.NetworkObject(name='name', plugin='plugin')
410 with self.assertRaises(
411 exceptions.KubernetesNetworkObjectDefinitionError):
412 kubernetes.NetworkObject(name='name', args='args')
413 with self.assertRaises(
414 exceptions.KubernetesNetworkObjectDefinitionError):
415 kubernetes.NetworkObject(args='args', plugin='plugin')
417 @mock.patch.object(kubernetes_utils, 'get_custom_resource_definition')
418 def test_crd(self, mock_get_crd):
419 mock_crd = mock.Mock()
420 mock_get_crd.return_value = mock_crd
421 net_obj = copy.deepcopy(self.net_obj)
422 self.assertEqual(mock_crd, net_obj.crd)
424 def test_template(self):
425 net_obj = copy.deepcopy(self.net_obj)
426 expected = {'apiVersion': 'group.com/v2',
427 'kind': kubernetes.NetworkObject.KIND,
429 'name': 'fake_name'},
430 'plugin': 'fake_plugin',
433 crd.spec.group = 'group.com'
434 crd.spec.version = 'v2'
436 self.assertEqual(expected, net_obj.template)
438 def test_group(self):
439 net_obj = copy.deepcopy(self.net_obj)
440 net_obj._crd = mock.Mock()
441 net_obj._crd.spec.group = 'fake_group'
442 self.assertEqual('fake_group', net_obj.group)
444 def test_version(self):
445 net_obj = copy.deepcopy(self.net_obj)
446 net_obj._crd = mock.Mock()
447 net_obj._crd.spec.version = 'version_4'
448 self.assertEqual('version_4', net_obj.version)
450 def test_plural(self):
451 net_obj = copy.deepcopy(self.net_obj)
452 net_obj._crd = mock.Mock()
453 net_obj._crd.spec.names.plural = 'name_ending_in_s'
454 self.assertEqual('name_ending_in_s', net_obj.plural)
456 def test_scope(self):
457 net_obj = copy.deepcopy(self.net_obj)
458 net_obj._crd = mock.Mock()
459 net_obj._crd.spec.scope = 'Cluster'
460 self.assertEqual('Cluster', net_obj.scope)
462 @mock.patch.object(kubernetes_utils, 'create_network')
463 def test_create(self, mock_create_network):
464 net_obj = copy.deepcopy(self.net_obj)
465 net_obj._scope = 'scope'
466 net_obj._group = 'group'
467 net_obj._version = 'version'
468 net_obj._plural = 'plural'
469 net_obj._template = 'template'
471 mock_create_network.assert_called_once_with(
472 'scope', 'group', 'version', 'plural', 'template')
474 @mock.patch.object(kubernetes_utils, 'delete_network')
475 def test_delete(self, mock_delete_network):
476 net_obj = copy.deepcopy(self.net_obj)
477 net_obj._scope = 'scope'
478 net_obj._group = 'group'
479 net_obj._version = 'version'
480 net_obj._plural = 'plural'
481 net_obj._name = 'name'
483 mock_delete_network.assert_called_once_with(
484 'scope', 'group', 'version', 'plural', 'name')
487 class ServiceNodePortObjectTestCase(base.BaseUnitTestCase):
489 def test__init(self):
490 with mock.patch.object(kubernetes.ServiceNodePortObject, '_add_port') \
492 kubernetes.ServiceNodePortObject('fake_name',
493 node_ports=[{'port': 80}])
495 mock_add_port.assert_has_calls([mock.call(22, protocol='TCP'),
498 def test__add_port(self):
499 nodeport_object = kubernetes.ServiceNodePortObject('fake_name')
500 port_ssh = {'port': 22,
502 port_definition = {'port': 80,
507 port = copy.deepcopy(port_definition)
509 nodeport_object._add_port(80, **port)
510 self.assertEqual([port_ssh, port_definition],
511 nodeport_object.template['spec']['ports'])
513 @mock.patch.object(kubernetes_utils, 'create_service')
514 def test_create(self, mock_create_service):
515 nodeport_object = kubernetes.ServiceNodePortObject('fake_name')
516 nodeport_object.template = 'fake_template'
517 nodeport_object.create()
518 mock_create_service.assert_called_once_with('fake_template')
520 @mock.patch.object(kubernetes_utils, 'delete_service')
521 def test_delete(self, mock_delete_service):
522 nodeport_object = kubernetes.ServiceNodePortObject('fake_name')
523 nodeport_object.delete()
524 mock_delete_service.assert_called_once_with('fake_name-service')