bace37653dc7a0a531de4510604714de1f07a2b1
[yardstick.git] / yardstick / tests / unit / benchmark / contexts / test_kubernetes.py
1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd and others.
3 #
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 ##############################################################################
9
10 import collections
11 import time
12
13 import mock
14 import unittest
15
16 from yardstick.benchmark import contexts
17 from yardstick.benchmark.contexts import base
18 from yardstick.benchmark.contexts import kubernetes
19 from yardstick.common import constants
20 from yardstick.common import exceptions
21 from yardstick.common import kubernetes_utils as k8s_utils
22 from yardstick.orchestrator import kubernetes as orchestrator_kubernetes
23
24
25 CONTEXT_CFG = {
26     'type': contexts.CONTEXT_KUBERNETES,
27     'name': 'k8s',
28     'task_id': '1234567890',
29     'servers': {
30         'host': {
31             'image': 'openretriever/yardstick',
32             'command': '/bin/bash',
33             'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; '
34                      'service ssh restart;while true ; do sleep 10000; done']
35         },
36         'target': {
37             'image': 'openretriever/yardstick',
38             'command': '/bin/bash',
39             'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; '
40                      'service ssh restart;while true ; do sleep 10000; done']
41         }
42     },
43     'networks': {
44         'flannel': {
45             'args': 'flannel_args',
46             'plugin': 'flannel'
47         },
48         'sriov01': {
49             'args': 'sriov_args',
50             'plugin': 'sriov'
51         },
52     }
53 }
54
55
56 class NodePort(object):
57     def __init__(self):
58         self.node_port = 30000
59         self.port = constants.SSH_PORT
60
61
62 class Service(object):
63     def __init__(self):
64         self.ports = [NodePort()]
65
66
67 class Status(object):
68     def __init__(self):
69         self.pod_ip = '172.16.10.131'
70
71
72 class Pod(object):
73     def __init__(self):
74         self.status = Status()
75
76
77 class KubernetesTestCase(unittest.TestCase):
78
79     def setUp(self):
80         self.k8s_context = kubernetes.KubernetesContext()
81         self.addCleanup(self._remove_contexts)
82         self.k8s_context.init(CONTEXT_CFG)
83
84     @staticmethod
85     def _remove_contexts():
86         for context in base.Context.list:
87             context._delete_context()
88         base.Context.list = []
89
90     @mock.patch.object(kubernetes.KubernetesContext, '_delete_services')
91     @mock.patch.object(kubernetes.KubernetesContext, '_delete_ssh_key')
92     @mock.patch.object(kubernetes.KubernetesContext, '_delete_rcs')
93     @mock.patch.object(kubernetes.KubernetesContext, '_delete_pods')
94     @mock.patch.object(kubernetes.KubernetesContext, '_delete_networks')
95     @mock.patch.object(kubernetes.KubernetesContext, '_delete_crd')
96     def test_undeploy(self, mock_delete_pods, mock_delete_rcs,
97                       mock_delete_ssh, mock_delete_services,
98                       mock_delete_networks, mock_delete_crd):
99
100         self.k8s_context.undeploy()
101         mock_delete_ssh.assert_called_once()
102         mock_delete_rcs.assert_called_once()
103         mock_delete_pods.assert_called_once()
104         mock_delete_services.assert_called_once()
105         mock_delete_networks.assert_called_once()
106         mock_delete_crd.assert_called_once()
107
108     @mock.patch.object(kubernetes.KubernetesContext, '_create_services')
109     @mock.patch.object(kubernetes.KubernetesContext, '_wait_until_running')
110     @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
111                        'get_rc_pods')
112     @mock.patch.object(kubernetes.KubernetesContext, '_create_rcs')
113     @mock.patch.object(kubernetes.KubernetesContext, '_set_ssh_key')
114     @mock.patch.object(kubernetes.KubernetesContext, '_create_networks')
115     @mock.patch.object(kubernetes.KubernetesContext, '_create_crd')
116     def test_deploy(self, mock_set_ssh_key, mock_create_rcs, mock_get_rc_pods,
117                     mock_wait_until_running, mock_create_services,
118                     mock_create_networks, mock_create_crd):
119
120         with mock.patch.object(time, 'sleep'):
121             self.k8s_context.deploy()
122         mock_set_ssh_key.assert_called_once()
123         mock_create_rcs.assert_called_once()
124         mock_create_services.assert_called_once()
125         mock_get_rc_pods.assert_called_once()
126         mock_wait_until_running.assert_called_once()
127         mock_create_networks.assert_called_once()
128         mock_create_crd.assert_called_once()
129
130     @mock.patch.object(kubernetes, 'paramiko', **{"resource_filename.return_value": ""})
131     @mock.patch.object(kubernetes, 'pkg_resources', **{"resource_filename.return_value": ""})
132     @mock.patch.object(kubernetes, 'utils')
133     @mock.patch.object(kubernetes, 'open', create=True)
134     @mock.patch.object(k8s_utils, 'delete_config_map')
135     @mock.patch.object(k8s_utils, 'create_config_map')
136     def test_ssh_key(self, mock_create, mock_delete, *args):
137         self.k8s_context._set_ssh_key()
138         self.k8s_context._delete_ssh_key()
139
140         mock_create.assert_called_once()
141         mock_delete.assert_called_once()
142
143     @mock.patch.object(k8s_utils, 'read_pod_status')
144     def test_wait_until_running(self, mock_read_pod_status):
145
146         self.k8s_context.template.pods = ['server']
147         mock_read_pod_status.return_value = 'Running'
148         self.k8s_context._wait_until_running()
149
150     @mock.patch.object(k8s_utils, 'get_pod_by_name')
151     @mock.patch.object(kubernetes.KubernetesContext, '_get_node_ip')
152     def test_get_server(self, mock_get_node_ip, mock_get_pod_by_name):
153         mock_get_pod_by_name.return_value = Pod()
154         mock_get_node_ip.return_value = '172.16.10.131'
155         with mock.patch.object(self.k8s_context, '_get_service_ports',
156                                return_value=[NodePort()]):
157             server = self.k8s_context._get_server('server_name')
158         self.assertEqual('server_name', server['name'])
159         self.assertEqual(30000, server['ssh_port'])
160
161     @mock.patch.object(kubernetes.KubernetesContext, '_create_rc')
162     def test_create_rcs(self, mock_create_rc):
163         self.k8s_context._create_rcs()
164         mock_create_rc.assert_called()
165
166     @mock.patch.object(k8s_utils, 'create_replication_controller')
167     def test_create_rc(self, mock_create_replication_controller):
168         self.k8s_context._create_rc({})
169         mock_create_replication_controller.assert_called_once()
170
171     @mock.patch.object(kubernetes.KubernetesContext, '_delete_rc')
172     def test_delete_rcs(self, mock_delete_rc):
173         self.k8s_context._delete_rcs()
174         mock_delete_rc.assert_called()
175
176     @mock.patch.object(k8s_utils, 'delete_replication_controller')
177     def test_delete_rc(self, mock_delete_replication_controller):
178         self.k8s_context._delete_rc({})
179         mock_delete_replication_controller.assert_called_once()
180
181     @mock.patch.object(k8s_utils, 'get_node_list')
182     def test_get_node_ip(self, mock_get_node_list):
183         self.k8s_context._get_node_ip()
184         mock_get_node_list.assert_called_once()
185
186     @mock.patch.object(orchestrator_kubernetes.ServiceNodePortObject, 'create')
187     def test_create_services(self, mock_create):
188         self.k8s_context._create_services()
189         mock_create.assert_called()
190
191     @mock.patch.object(orchestrator_kubernetes.ServiceNodePortObject, 'delete')
192     def test_delete_services(self, mock_delete):
193         self.k8s_context._delete_services()
194         mock_delete.assert_called()
195
196     def test_init(self):
197         self.k8s_context._delete_context()
198         with mock.patch.object(orchestrator_kubernetes, 'KubernetesTemplate',
199                 return_value='fake_template') as mock_k8stemplate:
200             self.k8s_context = kubernetes.KubernetesContext()
201             self.k8s_context.init(CONTEXT_CFG)
202         mock_k8stemplate.assert_called_once_with(self.k8s_context.name,
203                                                  CONTEXT_CFG)
204         self.assertEqual('fake_template', self.k8s_context.template)
205         self.assertEqual(2, len(self.k8s_context._networks))
206         self.assertIn('flannel', self.k8s_context._networks.keys())
207         self.assertIn('sriov01', self.k8s_context._networks.keys())
208
209     def test__get_physical_nodes(self):
210         result = self.k8s_context._get_physical_nodes()
211         self.assertIsNone(result)
212
213     def test__get_physical_node_for_server(self):
214         result = self.k8s_context._get_physical_node_for_server("fake")
215         self.assertIsNone(result)
216
217     def test__get_network(self):
218         networks = collections.OrderedDict([('n1', 'data1'), ('n2', 'data2')])
219         self.k8s_context._networks = networks
220         self.assertEqual({'name': 'n1'}, self.k8s_context._get_network('n1'))
221         self.assertEqual({'name': 'n2'}, self.k8s_context._get_network('n2'))
222         self.assertIsNone(self.k8s_context._get_network('n3'))
223
224     @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
225                        'get_rc_by_name')
226     def test__get_interfaces(self, mock_get_rc):
227         rc = orchestrator_kubernetes.ReplicationControllerObject('rc_name')
228         rc._networks = ['net1', 'net2']
229         mock_get_rc.return_value = rc
230         expected = {'net1': {'network_name': 'net1',
231                              'local_mac': None,
232                              'local_ip': None},
233                     'net2': {'network_name': 'net2',
234                              'local_mac': None,
235                              'local_ip': None}}
236         self.assertEqual(expected, self.k8s_context._get_interfaces('rc_name'))
237
238     @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
239                        'get_rc_by_name')
240     def test__get_interfaces_no_networks(self, mock_get_rc):
241         rc = orchestrator_kubernetes.ReplicationControllerObject('rc_name')
242         mock_get_rc.return_value = rc
243         self.assertEqual({}, self.k8s_context._get_interfaces('rc_name'))
244
245     @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
246                        'get_rc_by_name', return_value=None)
247     def test__get_interfaces_no_rc(self, *args):
248         self.assertEqual({}, self.k8s_context._get_interfaces('rc_name'))
249
250     @mock.patch.object(k8s_utils, 'get_service_by_name',
251                        return_value=Service())
252     def test__get_service_ports(self, mock_get_service_by_name):
253         name = 'rc_name'
254         service_ports = self.k8s_context._get_service_ports(name)
255         mock_get_service_by_name.assert_called_once_with(name + '-service')
256         self.assertEqual(30000, service_ports[0].node_port)
257
258     @mock.patch.object(k8s_utils, 'get_service_by_name',
259                        return_value=None)
260     def test__get_service_ports_exception(self, *args):
261         name = 'rc_name'
262         with self.assertRaises(exceptions.KubernetesServiceObjectNotDefined):
263             self.k8s_context._get_service_ports(name)