NodePort information returned in context should be a dictionary
[yardstick.git] / yardstick / tests / unit / benchmark / contexts / test_kubernetes.py
index 73c59c1..b526e7c 100644 (file)
@@ -7,33 +7,74 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
+import collections
+import time
+
 import mock
 import unittest
 
+from yardstick.benchmark import contexts
+from yardstick.benchmark.contexts import base
 from yardstick.benchmark.contexts import kubernetes
+from yardstick.common import constants
+from yardstick.common import exceptions
+from yardstick.common import kubernetes_utils as k8s_utils
+from yardstick.orchestrator import kubernetes as orchestrator_kubernetes
 
 
-context_cfg = {
-    'type': 'Kubernetes',
+CONTEXT_CFG = {
+    'type': contexts.CONTEXT_KUBERNETES,
     'name': 'k8s',
     'task_id': '1234567890',
     'servers': {
         'host': {
             'image': 'openretriever/yardstick',
             'command': '/bin/bash',
-            'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; \
-service ssh restart;while true ; do sleep 10000; done']
+            'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; '
+                     'service ssh restart;while true ; do sleep 10000; done']
         },
         'target': {
             'image': 'openretriever/yardstick',
             'command': '/bin/bash',
-            'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; \
-service ssh restart;while true ; do sleep 10000; done']
+            'args': ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; '
+                     'service ssh restart;while true ; do sleep 10000; done']
         }
+    },
+    'networks': {
+        'flannel': {
+            'args': 'flannel_args',
+            'plugin': 'flannel'
+        },
+        'sriov01': {
+            'args': 'sriov_args',
+            'plugin': 'sriov'
+        },
     }
 }
 
-prefix = 'yardstick.benchmark.contexts.kubernetes'
+
+class NodePort(object):
+    def __init__(self):
+        self.node_port = 30000
+        self.port = constants.SSH_PORT
+        self.name = 'port_name'
+        self.protocol = 'TCP'
+        self.target_port = constants.SSH_PORT
+
+
+class Service(object):
+    def __init__(self):
+        self.ports = [NodePort()]
+
+
+class Status(object):
+    def __init__(self):
+        self.pod_ip = '172.16.10.131'
+
+
+class Pod(object):
+    def __init__(self):
+        self.status = Status()
 
 
 class KubernetesTestCase(unittest.TestCase):
@@ -41,137 +82,192 @@ class KubernetesTestCase(unittest.TestCase):
     def setUp(self):
         self.k8s_context = kubernetes.KubernetesContext()
         self.addCleanup(self._remove_contexts)
-        self.k8s_context.init(context_cfg)
+        self.k8s_context.init(CONTEXT_CFG)
 
-    def _remove_contexts(self):
-        if self.k8s_context in self.k8s_context.list:
-            self.k8s_context._delete_context()
+    @staticmethod
+    def _remove_contexts():
+        for context in base.Context.list:
+            context._delete_context()
+        base.Context.list = []
 
     @mock.patch.object(kubernetes.KubernetesContext, '_delete_services')
     @mock.patch.object(kubernetes.KubernetesContext, '_delete_ssh_key')
     @mock.patch.object(kubernetes.KubernetesContext, '_delete_rcs')
     @mock.patch.object(kubernetes.KubernetesContext, '_delete_pods')
-    def test_undeploy(self,
-                      mock_delete_pods,
-                      mock_delete_rcs,
-                      mock_delete_ssh,
-                      mock_delete_services):
+    @mock.patch.object(kubernetes.KubernetesContext, '_delete_networks')
+    @mock.patch.object(kubernetes.KubernetesContext, '_delete_crd')
+    def test_undeploy(self, mock_delete_pods, mock_delete_rcs,
+                      mock_delete_ssh, mock_delete_services,
+                      mock_delete_networks, mock_delete_crd):
 
         self.k8s_context.undeploy()
-        self.assertTrue(mock_delete_ssh.called)
-        self.assertTrue(mock_delete_rcs.called)
-        self.assertTrue(mock_delete_pods.called)
-        self.assertTrue(mock_delete_services.called)
+        mock_delete_ssh.assert_called_once()
+        mock_delete_rcs.assert_called_once()
+        mock_delete_pods.assert_called_once()
+        mock_delete_services.assert_called_once()
+        mock_delete_networks.assert_called_once()
+        mock_delete_crd.assert_called_once()
 
     @mock.patch.object(kubernetes.KubernetesContext, '_create_services')
     @mock.patch.object(kubernetes.KubernetesContext, '_wait_until_running')
-    @mock.patch.object(kubernetes.KubernetesTemplate, 'get_rc_pods')
+    @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
+                       'get_rc_pods')
     @mock.patch.object(kubernetes.KubernetesContext, '_create_rcs')
     @mock.patch.object(kubernetes.KubernetesContext, '_set_ssh_key')
-    def test_deploy(self,
-                    mock_set_ssh_key,
-                    mock_create_rcs,
-                    mock_get_rc_pods,
-                    mock_wait_until_running,
-                    mock_create_services):
-
-        with mock.patch("yardstick.benchmark.contexts.kubernetes.time"):
+    @mock.patch.object(kubernetes.KubernetesContext, '_create_networks')
+    @mock.patch.object(kubernetes.KubernetesContext, '_create_crd')
+    def test_deploy(self, mock_set_ssh_key, mock_create_rcs, mock_get_rc_pods,
+                    mock_wait_until_running, mock_create_services,
+                    mock_create_networks, mock_create_crd):
+
+        with mock.patch.object(time, 'sleep'):
             self.k8s_context.deploy()
-        self.assertTrue(mock_set_ssh_key.called)
-        self.assertTrue(mock_create_rcs.called)
-        self.assertTrue(mock_create_services.called)
-        self.assertTrue(mock_get_rc_pods.called)
-        self.assertTrue(mock_wait_until_running.called)
+        mock_set_ssh_key.assert_called_once()
+        mock_create_rcs.assert_called_once()
+        mock_create_services.assert_called_once()
+        mock_get_rc_pods.assert_called_once()
+        mock_wait_until_running.assert_called_once()
+        mock_create_networks.assert_called_once()
+        mock_create_crd.assert_called_once()
 
     @mock.patch.object(kubernetes, 'paramiko', **{"resource_filename.return_value": ""})
     @mock.patch.object(kubernetes, 'pkg_resources', **{"resource_filename.return_value": ""})
     @mock.patch.object(kubernetes, 'utils')
     @mock.patch.object(kubernetes, 'open', create=True)
-    @mock.patch.object(kubernetes.k8s_utils, 'delete_config_map')
-    @mock.patch.object(kubernetes.k8s_utils, 'create_config_map')
+    @mock.patch.object(k8s_utils, 'delete_config_map')
+    @mock.patch.object(k8s_utils, 'create_config_map')
     def test_ssh_key(self, mock_create, mock_delete, *args):
         self.k8s_context._set_ssh_key()
         self.k8s_context._delete_ssh_key()
 
-        self.assertTrue(mock_create.called)
-        self.assertTrue(mock_delete.called)
+        mock_create.assert_called_once()
+        mock_delete.assert_called_once()
 
-    @mock.patch.object(kubernetes.k8s_utils, 'read_pod_status')
+    @mock.patch.object(k8s_utils, 'read_pod_status')
     def test_wait_until_running(self, mock_read_pod_status):
 
         self.k8s_context.template.pods = ['server']
         mock_read_pod_status.return_value = 'Running'
         self.k8s_context._wait_until_running()
 
-    @mock.patch.object(kubernetes.k8s_utils, 'get_pod_by_name')
+    @mock.patch.object(k8s_utils, 'get_pod_by_name')
     @mock.patch.object(kubernetes.KubernetesContext, '_get_node_ip')
-    @mock.patch.object(kubernetes.k8s_utils, 'get_service_by_name')
-    def test_get_server(self,
-                        mock_get_service_by_name,
-                        mock_get_node_ip,
-                        mock_get_pod_by_name):
-        class Service(object):
-            def __init__(self):
-                self.name = 'yardstick'
-                self.node_port = 30000
-
-        class Services(object):
-            def __init__(self):
-                self.ports = [Service()]
-
-        class Status(object):
-            def __init__(self):
-                self.pod_ip = '172.16.10.131'
-
-        class Pod(object):
-            def __init__(self):
-                self.status = Status()
-
-        mock_get_service_by_name.return_value = Services()
+    def test_get_server(self, mock_get_node_ip, mock_get_pod_by_name):
         mock_get_pod_by_name.return_value = Pod()
         mock_get_node_ip.return_value = '172.16.10.131'
-
-        self.assertIsNotNone(self.k8s_context._get_server('server'))
+        with mock.patch.object(self.k8s_context, '_get_service_ports') as \
+                mock_get_sports:
+            mock_get_sports.return_value = [
+                {'port': constants.SSH_PORT, 'node_port': 30000}]
+            server = self.k8s_context._get_server('server_name')
+        self.assertEqual('server_name', server['name'])
+        self.assertEqual(30000, server['ssh_port'])
 
     @mock.patch.object(kubernetes.KubernetesContext, '_create_rc')
     def test_create_rcs(self, mock_create_rc):
         self.k8s_context._create_rcs()
-        self.assertTrue(mock_create_rc.called)
+        mock_create_rc.assert_called()
 
-    @mock.patch.object(kubernetes.k8s_utils, 'create_replication_controller')
+    @mock.patch.object(k8s_utils, 'create_replication_controller')
     def test_create_rc(self, mock_create_replication_controller):
         self.k8s_context._create_rc({})
-        self.assertTrue(mock_create_replication_controller.called)
+        mock_create_replication_controller.assert_called_once()
 
     @mock.patch.object(kubernetes.KubernetesContext, '_delete_rc')
     def test_delete_rcs(self, mock_delete_rc):
         self.k8s_context._delete_rcs()
-        self.assertTrue(mock_delete_rc.called)
+        mock_delete_rc.assert_called()
 
-    @mock.patch.object(kubernetes.k8s_utils, 'delete_replication_controller')
+    @mock.patch.object(k8s_utils, 'delete_replication_controller')
     def test_delete_rc(self, mock_delete_replication_controller):
         self.k8s_context._delete_rc({})
-        self.assertTrue(mock_delete_replication_controller.called)
+        mock_delete_replication_controller.assert_called_once()
 
-    @mock.patch.object(kubernetes.k8s_utils, 'get_node_list')
+    @mock.patch.object(k8s_utils, 'get_node_list')
     def test_get_node_ip(self, mock_get_node_list):
         self.k8s_context._get_node_ip()
-        self.assertTrue(mock_get_node_list.called)
+        mock_get_node_list.assert_called_once()
 
-    @mock.patch('yardstick.orchestrator.kubernetes.ServiceObject.create')
+    @mock.patch.object(orchestrator_kubernetes.ServiceNodePortObject, 'create')
     def test_create_services(self, mock_create):
         self.k8s_context._create_services()
-        self.assertTrue(mock_create.called)
+        mock_create.assert_called()
 
-    @mock.patch('yardstick.orchestrator.kubernetes.ServiceObject.delete')
+    @mock.patch.object(orchestrator_kubernetes.ServiceNodePortObject, 'delete')
     def test_delete_services(self, mock_delete):
         self.k8s_context._delete_services()
-        self.assertTrue(mock_delete.called)
-
-
-def main():
-    unittest.main()
-
-
-if __name__ == '__main__':
-    main()
+        mock_delete.assert_called()
+
+    def test_init(self):
+        self.k8s_context._delete_context()
+        with mock.patch.object(orchestrator_kubernetes, 'KubernetesTemplate',
+                return_value='fake_template') as mock_k8stemplate:
+            self.k8s_context = kubernetes.KubernetesContext()
+            self.k8s_context.init(CONTEXT_CFG)
+        mock_k8stemplate.assert_called_once_with(self.k8s_context.name,
+                                                 CONTEXT_CFG)
+        self.assertEqual('fake_template', self.k8s_context.template)
+        self.assertEqual(2, len(self.k8s_context._networks))
+        self.assertIn('flannel', self.k8s_context._networks.keys())
+        self.assertIn('sriov01', self.k8s_context._networks.keys())
+
+    def test__get_physical_nodes(self):
+        result = self.k8s_context._get_physical_nodes()
+        self.assertIsNone(result)
+
+    def test__get_physical_node_for_server(self):
+        result = self.k8s_context._get_physical_node_for_server("fake")
+        self.assertIsNone(result)
+
+    def test__get_network(self):
+        networks = collections.OrderedDict([('n1', 'data1'), ('n2', 'data2')])
+        self.k8s_context._networks = networks
+        self.assertEqual({'name': 'n1'}, self.k8s_context._get_network('n1'))
+        self.assertEqual({'name': 'n2'}, self.k8s_context._get_network('n2'))
+        self.assertIsNone(self.k8s_context._get_network('n3'))
+
+    @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
+                       'get_rc_by_name')
+    def test__get_interfaces(self, mock_get_rc):
+        rc = orchestrator_kubernetes.ReplicationControllerObject('rc_name')
+        rc._networks = ['net1', 'net2']
+        mock_get_rc.return_value = rc
+        expected = {'net1': {'network_name': 'net1',
+                             'local_mac': None,
+                             'local_ip': None},
+                    'net2': {'network_name': 'net2',
+                             'local_mac': None,
+                             'local_ip': None}}
+        self.assertEqual(expected, self.k8s_context._get_interfaces('rc_name'))
+
+    @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
+                       'get_rc_by_name')
+    def test__get_interfaces_no_networks(self, mock_get_rc):
+        rc = orchestrator_kubernetes.ReplicationControllerObject('rc_name')
+        mock_get_rc.return_value = rc
+        self.assertEqual({}, self.k8s_context._get_interfaces('rc_name'))
+
+    @mock.patch.object(orchestrator_kubernetes.KubernetesTemplate,
+                       'get_rc_by_name', return_value=None)
+    def test__get_interfaces_no_rc(self, *args):
+        self.assertEqual({}, self.k8s_context._get_interfaces('rc_name'))
+
+    @mock.patch.object(k8s_utils, 'get_service_by_name',
+                       return_value=Service())
+    def test__get_service_ports(self, mock_get_service_by_name):
+        name = 'rc_name'
+        service_ports = self.k8s_context._get_service_ports(name)
+        mock_get_service_by_name.assert_called_once_with(name + '-service')
+        expected = {'node_port': 30000,
+                    'port': constants.SSH_PORT,
+                    'name': 'port_name',
+                    'protocol': 'TCP',
+                    'target_port': constants.SSH_PORT}
+        self.assertEqual(expected, service_ports[0])
+
+    @mock.patch.object(k8s_utils, 'get_service_by_name',
+                       return_value=None)
+    def test__get_service_ports_exception(self, *args):
+        name = 'rc_name'
+        with self.assertRaises(exceptions.KubernetesServiceObjectNotDefined):
+            self.k8s_context._get_service_ports(name)