Merge "Modify install.yaml to support Ubuntu 18"
[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         self.name = 'port_name'
61         self.protocol = 'TCP'
62         self.target_port = constants.SSH_PORT
63
64
65 class Service(object):
66     def __init__(self):
67         self.ports = [NodePort()]
68
69
70 class Status(object):
71     def __init__(self):
72         self.pod_ip = '172.16.10.131'
73
74
75 class Pod(object):
76     def __init__(self):
77         self.status = Status()
78
79
80 class KubernetesTestCase(unittest.TestCase):
81
82     def setUp(self):
83         self.k8s_context = kubernetes.KubernetesContext()
84         self.addCleanup(self._remove_contexts)
85         self.k8s_context.init(CONTEXT_CFG)
86
87     @staticmethod
88     def _remove_contexts():
89         for context in base.Context.list:
90             context._delete_context()
91         base.Context.list = []
92
93     @mock.patch.object(kubernetes.KubernetesContext, '_delete_services')
94     @mock.patch.object(kubernetes.KubernetesContext, '_delete_ssh_key')
95     @mock.patch.object(kubernetes.KubernetesContext, '_delete_rcs')
96     @mock.patch.object(kubernetes.KubernetesContext, '_delete_pods')
97     @mock.patch.object(kubernetes.KubernetesContext, '_delete_networks')
98     @mock.patch.object(kubernetes.KubernetesContext, '_delete_crd')
99     def test_undeploy(self, mock_delete_pods, mock_delete_rcs,
100                       mock_delete_ssh, mock_delete_services,
101                       mock_delete_networks, mock_delete_crd):
102
103         self.k8s_context.undeploy()
104         mock_delete_ssh.assert_called_once()
105         mock_delete_rcs.assert_called_once()
106         mock_delete_pods.assert_called_once()
107         mock_delete_services.assert_called_once()
108         mock_delete_networks.assert_called_once()
109         mock_delete_crd.assert_called_once()
110
111     @mock.patch.object(kubernetes.KubernetesContext, '_create_services')
112     @mock.patch.object(kubernetes.KubernetesContext, '_wait_until_running')
113     @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
114                        'get_rc_pods')
115     @mock.patch.object(kubernetes.KubernetesContext, '_create_rcs')
116     @mock.patch.object(kubernetes.KubernetesContext, '_set_ssh_key')
117     @mock.patch.object(kubernetes.KubernetesContext, '_create_networks')
118     @mock.patch.object(kubernetes.KubernetesContext, '_create_crd')
119     def test_deploy(self, mock_set_ssh_key, mock_create_rcs, mock_get_rc_pods,
120                     mock_wait_until_running, mock_create_services,
121                     mock_create_networks, mock_create_crd):
122
123         with mock.patch.object(time, 'sleep'):
124             self.k8s_context.deploy()
125         mock_set_ssh_key.assert_called_once()
126         mock_create_rcs.assert_called_once()
127         mock_create_services.assert_called_once()
128         mock_get_rc_pods.assert_called_once()
129         mock_wait_until_running.assert_called_once()
130         mock_create_networks.assert_called_once()
131         mock_create_crd.assert_called_once()
132
133     @mock.patch.object(kubernetes, 'paramiko', **{"resource_filename.return_value": ""})
134     @mock.patch.object(kubernetes, 'pkg_resources', **{"resource_filename.return_value": ""})
135     @mock.patch.object(kubernetes, 'utils')
136     @mock.patch.object(kubernetes, 'open', create=True)
137     @mock.patch.object(k8s_utils, 'delete_config_map')
138     @mock.patch.object(k8s_utils, 'create_config_map')
139     def test_ssh_key(self, mock_create, mock_delete, *args):
140         self.k8s_context._set_ssh_key()
141         self.k8s_context._delete_ssh_key()
142
143         mock_create.assert_called_once()
144         mock_delete.assert_called_once()
145
146     @mock.patch.object(k8s_utils, 'read_pod_status')
147     def test_wait_until_running(self, mock_read_pod_status):
148
149         self.k8s_context.template.pods = ['server']
150         mock_read_pod_status.return_value = 'Running'
151         self.k8s_context._wait_until_running()
152
153     @mock.patch.object(k8s_utils, 'get_pod_by_name')
154     @mock.patch.object(kubernetes.KubernetesContext, '_get_node_ip')
155     def test_get_server(self, mock_get_node_ip, mock_get_pod_by_name):
156         mock_get_pod_by_name.return_value = Pod()
157         mock_get_node_ip.return_value = '172.16.10.131'
158         with mock.patch.object(self.k8s_context, '_get_service_ports') as \
159                 mock_get_sports:
160             mock_get_sports.return_value = [
161                 {'port': constants.SSH_PORT, 'node_port': 30000}]
162             server = self.k8s_context._get_server('server_name')
163         self.assertEqual('server_name', server['name'])
164         self.assertEqual(30000, server['ssh_port'])
165
166     @mock.patch.object(kubernetes.KubernetesContext, '_create_rc')
167     def test_create_rcs(self, mock_create_rc):
168         self.k8s_context._create_rcs()
169         mock_create_rc.assert_called()
170
171     @mock.patch.object(k8s_utils, 'create_replication_controller')
172     def test_create_rc(self, mock_create_replication_controller):
173         self.k8s_context._create_rc({})
174         mock_create_replication_controller.assert_called_once()
175
176     @mock.patch.object(kubernetes.KubernetesContext, '_delete_rc')
177     def test_delete_rcs(self, mock_delete_rc):
178         self.k8s_context._delete_rcs()
179         mock_delete_rc.assert_called()
180
181     @mock.patch.object(k8s_utils, 'delete_replication_controller')
182     def test_delete_rc(self, mock_delete_replication_controller):
183         self.k8s_context._delete_rc({})
184         mock_delete_replication_controller.assert_called_once()
185
186     @mock.patch.object(k8s_utils, 'get_node_list')
187     def test_get_node_ip(self, mock_get_node_list):
188         self.k8s_context._get_node_ip()
189         mock_get_node_list.assert_called_once()
190
191     @mock.patch.object(orchestrator_kubernetes.ServiceNodePortObject, 'create')
192     def test_create_services(self, mock_create):
193         self.k8s_context._create_services()
194         mock_create.assert_called()
195
196     @mock.patch.object(orchestrator_kubernetes.ServiceNodePortObject, 'delete')
197     def test_delete_services(self, mock_delete):
198         self.k8s_context._delete_services()
199         mock_delete.assert_called()
200
201     def test_init(self):
202         self.k8s_context._delete_context()
203         with mock.patch.object(orchestrator_kubernetes, 'KubernetesTemplate',
204                 return_value='fake_template') as mock_k8stemplate:
205             self.k8s_context = kubernetes.KubernetesContext()
206             self.k8s_context.init(CONTEXT_CFG)
207         mock_k8stemplate.assert_called_once_with(self.k8s_context.name,
208                                                  CONTEXT_CFG)
209         self.assertEqual('fake_template', self.k8s_context.template)
210         self.assertEqual(2, len(self.k8s_context._networks))
211         self.assertIn('flannel', self.k8s_context._networks.keys())
212         self.assertIn('sriov01', self.k8s_context._networks.keys())
213
214     def test__get_physical_nodes(self):
215         result = self.k8s_context._get_physical_nodes()
216         self.assertIsNone(result)
217
218     def test__get_physical_node_for_server(self):
219         result = self.k8s_context._get_physical_node_for_server("fake")
220         self.assertIsNone(result)
221
222     def test__get_network(self):
223         networks = collections.OrderedDict([('n1', 'data1'), ('n2', 'data2')])
224         self.k8s_context._networks = networks
225         self.assertEqual({'name': 'n1'}, self.k8s_context._get_network('n1'))
226         self.assertEqual({'name': 'n2'}, self.k8s_context._get_network('n2'))
227         self.assertIsNone(self.k8s_context._get_network('n3'))
228
229     @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
230                        'get_rc_by_name')
231     def test__get_interfaces(self, mock_get_rc):
232         rc = orchestrator_kubernetes.ReplicationControllerObject('rc_name')
233         rc._networks = ['net1', 'net2']
234         mock_get_rc.return_value = rc
235         expected = {'net1': {'network_name': 'net1',
236                              'local_mac': None,
237                              'local_ip': None},
238                     'net2': {'network_name': 'net2',
239                              'local_mac': None,
240                              'local_ip': None}}
241         self.assertEqual(expected, self.k8s_context._get_interfaces('rc_name'))
242
243     @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
244                        'get_rc_by_name')
245     def test__get_interfaces_no_networks(self, mock_get_rc):
246         rc = orchestrator_kubernetes.ReplicationControllerObject('rc_name')
247         mock_get_rc.return_value = rc
248         self.assertEqual({}, self.k8s_context._get_interfaces('rc_name'))
249
250     @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
251                        'get_rc_by_name', return_value=None)
252     def test__get_interfaces_no_rc(self, *args):
253         self.assertEqual({}, self.k8s_context._get_interfaces('rc_name'))
254
255     @mock.patch.object(k8s_utils, 'get_service_by_name',
256                        return_value=Service())
257     def test__get_service_ports(self, mock_get_service_by_name):
258         name = 'rc_name'
259         service_ports = self.k8s_context._get_service_ports(name)
260         mock_get_service_by_name.assert_called_once_with(name + '-service')
261         expected = {'node_port': 30000,
262                     'port': constants.SSH_PORT,
263                     'name': 'port_name',
264                     'protocol': 'TCP',
265                     'target_port': constants.SSH_PORT}
266         self.assertEqual(expected, service_ports[0])
267
268     @mock.patch.object(k8s_utils, 'get_service_by_name',
269                        return_value=None)
270     def test__get_service_ports_exception(self, *args):
271         name = 'rc_name'
272         with self.assertRaises(exceptions.KubernetesServiceObjectNotDefined):
273             self.k8s_context._get_service_ports(name)