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