From 4758420a2ad96f5857abcdf53f9a2f7e2a79ee8c Mon Sep 17 00:00:00 2001 From: hifzasakhi Date: Tue, 20 Feb 2018 22:44:54 +0000 Subject: [PATCH] Add unit tests for Tiller handler Change-Id: Ic10b26618d8bcec1c4b89387834de4944f099461 --- armada/handlers/tiller.py | 8 +- armada/tests/unit/handlers/test_tiller.py | 243 ++++++++++++++++++++-- 2 files changed, 234 insertions(+), 17 deletions(-) diff --git a/armada/handlers/tiller.py b/armada/handlers/tiller.py index 58734464..7a18ba7f 100644 --- a/armada/handlers/tiller.py +++ b/armada/handlers/tiller.py @@ -217,9 +217,8 @@ class Tiller(object): self.delete_resources( release_name, name, action_type, labels, namespace) except Exception: - raise ex.PreUpdateJobDeleteException(name, namespace) - LOG.debug("PRE: Could not delete anything, please check yaml") + raise ex.PreUpdateJobDeleteException(name, namespace) try: for action in actions.get('create', []): @@ -230,9 +229,8 @@ class Tiller(object): self.k8s.create_job_action(name, action_type) continue except Exception: - raise ex.PreUpdateJobCreateException(name, namespace) - LOG.debug("PRE: Could not create anything, please check yaml") + raise ex.PreUpdateJobCreateException(name, namespace) def _post_update_actions(self, actions, namespace): try: @@ -244,8 +242,8 @@ class Tiller(object): self.k8s.create_job_action(name, action_type) continue except Exception: - raise ex.PreUpdateJobCreateException() LOG.debug("POST: Could not create anything, please check yaml") + raise ex.PreUpdateJobCreateException(name, namespace) def list_charts(self): ''' diff --git a/armada/tests/unit/handlers/test_tiller.py b/armada/tests/unit/handlers/test_tiller.py index bea18c5f..cac5d93b 100644 --- a/armada/tests/unit/handlers/test_tiller.py +++ b/armada/tests/unit/handlers/test_tiller.py @@ -13,14 +13,15 @@ # limitations under the License. import mock -import unittest -from armada.handlers.tiller import Tiller +from armada.exceptions import tiller_exceptions as ex +from armada.handlers import tiller +from armada.tests.unit import base -class TillerTestCase(unittest.TestCase): +class TillerTestCase(base.ArmadaTestCase): - @mock.patch.object(Tiller, '_get_tiller_ip') + @mock.patch.object(tiller.Tiller, '_get_tiller_ip') @mock.patch('armada.handlers.tiller.K8s') @mock.patch('armada.handlers.tiller.grpc') @mock.patch('armada.handlers.tiller.Config') @@ -31,8 +32,8 @@ class TillerTestCase(unittest.TestCase): # instantiate Tiller object mock_grpc.insecure_channel.return_value = None mock_ip.return_value = '0.0.0.0' - tiller = Tiller() - assert tiller._get_tiller_ip() == '0.0.0.0' + tiller_obj = tiller.Tiller() + assert tiller_obj._get_tiller_ip() == '0.0.0.0' # set params chart = mock.Mock() @@ -44,11 +45,11 @@ class TillerTestCase(unittest.TestCase): wait = False timeout = 3600 - tiller.install_release(chart, name, namespace, - dry_run=dry_run, values=initial_values, - wait=wait, timeout=timeout) + tiller_obj.install_release(chart, name, namespace, + dry_run=dry_run, values=initial_values, + wait=wait, timeout=timeout) - mock_stub.assert_called_with(tiller.channel) + mock_stub.assert_called_with(tiller_obj.channel) release_request = mock_install_request( chart=chart, dry_run=dry_run, @@ -58,7 +59,225 @@ class TillerTestCase(unittest.TestCase): wait=wait, timeout=timeout ) - (mock_stub(tiller.channel).InstallRelease + (mock_stub(tiller_obj.channel).InstallRelease .assert_called_with(release_request, timeout + 60, - metadata=tiller.metadata)) + metadata=tiller_obj.metadata)) + + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch.object(tiller.Tiller, '_get_tiller_ip', autospec=True) + @mock.patch.object(tiller.Tiller, '_get_tiller_port', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_get_channel(self, mock_grpc, mock_port, mock_ip, _): + mock_port.return_value = mock.sentinel.port + mock_ip.return_value = mock.sentinel.ip + + # instantiate Tiller object + mock_grpc.insecure_channel.return_value = 'connected' + tiller_obj = tiller.Tiller() + + self.assertIsNotNone(tiller_obj.channel) + self.assertEqual('connected', tiller_obj.channel) + + mock_grpc.insecure_channel.assert_called_once_with( + '%s:%s' % (str(mock.sentinel.ip), str(mock.sentinel.port)), + options=[('grpc.max_send_message_length', + tiller.MAX_MESSAGE_LENGTH), + ('grpc.max_receive_message_length', + tiller.MAX_MESSAGE_LENGTH)] + ) + + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_get_tiller_ip_with_host_provided(self, mock_grpc, _): + tiller_obj = tiller.Tiller('1.1.1.1') + self.assertIsNotNone(tiller_obj._get_tiller_ip()) + self.assertEqual('1.1.1.1', tiller_obj._get_tiller_ip()) + + @mock.patch.object(tiller.Tiller, '_get_tiller_pod', autospec=True) + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_get_tiller_ip_with_mocked_pod(self, mock_grpc, mock_k8s, + mock_pod): + status = mock.Mock(pod_ip='1.1.1.1') + mock_pod.return_value.status = status + tiller_obj = tiller.Tiller() + self.assertEqual('1.1.1.1', tiller_obj._get_tiller_ip()) + + @mock.patch.object(tiller.Tiller, '_get_tiller_ip', autospec=True) + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_get_tiller_pod_throws_exception(self, mock_grpc, mock_k8s, + mock_ip): + + mock_k8s.get_namespace_pod.return_value.items = [] + tiller_obj = tiller.Tiller() + mock_grpc.insecure_channel.side_effect = ex.ChannelException() + self.assertRaises(ex.TillerPodNotRunningException, + tiller_obj._get_tiller_pod) + + @mock.patch.object(tiller.Tiller, '_get_tiller_ip', autospec=True) + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_get_tiller_port(self, mock_grpc, _, mock_ip): + # instantiate Tiller object + tiller_obj = tiller.Tiller(None, '8080', None) + self.assertEqual('8080', tiller_obj._get_tiller_port()) + + @mock.patch.object(tiller.Tiller, '_get_tiller_ip', autospec=True) + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_get_tiller_namespace(self, mock_grpc, _, mock_ip): + # verifies namespace set via instantiation + tiller_obj = tiller.Tiller(None, None, 'test_namespace2') + self.assertEqual('test_namespace2', + tiller_obj._get_tiller_namespace()) + + @mock.patch.object(tiller.Tiller, '_get_tiller_ip', autospec=True) + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_get_tiller_status_with_ip_provided(self, mock_grpc, _, mock_ip): + # instantiate Tiller object + tiller_obj = tiller.Tiller(None, '8080', None) + self.assertTrue(tiller_obj.tiller_status()) + + @mock.patch.object(tiller.Tiller, '_get_tiller_ip', autospec=True) + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_get_tiller_status_no_ip(self, mock_grpc, _, mock_ip): + mock_ip.return_value = '' + # instantiate Tiller object + tiller_obj = tiller.Tiller() + self.assertFalse(tiller_obj.tiller_status()) + + @mock.patch.object(tiller.Tiller, '_get_tiller_ip', autospec=True) + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_list_releases_empty(self, mock_grpc, _, mock_ip): + # instantiate Tiller object + tiller_obj = tiller.Tiller() + self.assertEqual([], tiller_obj.list_releases()) + + @mock.patch.object(tiller.Tiller, '_get_tiller_ip', autospec=True) + @mock.patch('armada.handlers.tiller.K8s', autospec=True) + @mock.patch('armada.handlers.tiller.grpc', autospec=True) + def test_list_charts_empty(self, mock_grpc, _, mock_ip): + # instantiate Tiller object + tiller_obj = tiller.Tiller() + self.assertEqual([], tiller_obj.list_charts()) + + @mock.patch('armada.handlers.tiller.K8s') + @mock.patch('armada.handlers.tiller.grpc') + @mock.patch.object(tiller, 'ListReleasesRequest') + @mock.patch.object(tiller, 'ReleaseServiceStub') + def test_list_releases(self, mock_release_service_stub, + mock_list_releases_request, mock_grpc, _): + mock_release_service_stub.return_value.ListReleases. \ + return_value = [mock.Mock(releases=['foo', 'bar'])] + + tiller_obj = tiller.Tiller('host', '8080', None) + self.assertEqual(['foo', 'bar'], tiller_obj.list_releases()) + + mock_release_service_stub.assert_called_once_with( + tiller_obj.channel) + list_releases_stub = mock_release_service_stub.return_value. \ + ListReleases + list_releases_stub.assert_called_once_with( + mock_list_releases_request.return_value, tiller_obj.timeout, + metadata=tiller_obj.metadata) + + mock_list_releases_request.assert_called_once_with( + limit=tiller.RELEASE_LIMIT, + status_codes=[tiller.STATUS_DEPLOYED, + tiller.STATUS_FAILED], + sort_by='LAST_RELEASED', + sort_order='DESC') + + @mock.patch('armada.handlers.tiller.K8s') + @mock.patch('armada.handlers.tiller.grpc') + @mock.patch.object(tiller, 'GetReleaseContentRequest') + @mock.patch.object(tiller, 'ReleaseServiceStub') + def test_get_release_content(self, mock_release_service_stub, + mock_release_content_request, + mock_grpc, _): + mock_release_service_stub.return_value.GetReleaseContent\ + .return_value = {} + + tiller_obj = tiller.Tiller('host', '8080', None) + + self.assertEqual({}, tiller_obj.get_release_content('release')) + get_release_content_stub = mock_release_service_stub. \ + return_value.GetReleaseContent + get_release_content_stub.assert_called_once_with( + mock_release_content_request.return_value, tiller_obj.timeout, + metadata=tiller_obj.metadata) + + @mock.patch('armada.handlers.tiller.K8s') + @mock.patch('armada.handlers.tiller.grpc') + @mock.patch.object(tiller, 'GetVersionRequest') + @mock.patch.object(tiller, 'ReleaseServiceStub') + def test_tiller_version(self, mock_release_service_stub, + mock_version_request, + mock_grpc, _): + + mock_version = mock.Mock() + mock_version.Version.sem_ver = mock.sentinel.sem_ver + mock_release_service_stub.return_value.GetVersion\ + .return_value = mock_version + + tiller_obj = tiller.Tiller('host', '8080', None) + + self.assertEqual(mock.sentinel.sem_ver, tiller_obj.tiller_version()) + + mock_release_service_stub.assert_called_once_with( + tiller_obj.channel) + + get_version_stub = mock_release_service_stub.return_value.GetVersion + get_version_stub.assert_called_once_with( + mock_version_request.return_value, tiller_obj.timeout, + metadata=tiller_obj.metadata) + + @mock.patch('armada.handlers.tiller.K8s') + @mock.patch('armada.handlers.tiller.grpc') + @mock.patch.object(tiller, 'GetVersionRequest') + @mock.patch.object(tiller, 'GetReleaseStatusRequest') + @mock.patch.object(tiller, 'ReleaseServiceStub') + def test_get_release_status(self, mock_release_service_stub, + mock_rel_status_request, mock_version_request, + mock_grpc, _): + mock_release_service_stub.return_value.GetReleaseStatus. \ + return_value = {} + + tiller_obj = tiller.Tiller('host', '8080', None) + self.assertEqual({}, tiller_obj.get_release_status('release')) + + mock_release_service_stub.assert_called_once_with( + tiller_obj.channel) + get_release_status_stub = mock_release_service_stub.return_value. \ + GetReleaseStatus + get_release_status_stub.assert_called_once_with( + mock_rel_status_request.return_value, tiller_obj.timeout, + metadata=tiller_obj.metadata) + + @mock.patch('armada.handlers.tiller.K8s') + @mock.patch('armada.handlers.tiller.grpc') + @mock.patch.object(tiller, 'UninstallReleaseRequest') + @mock.patch.object(tiller, 'ReleaseServiceStub') + def test_uninstall_release(self, mock_release_service_stub, + mock_uninstall_release_request, + mock_grpc, _): + mock_release_service_stub.return_value.UninstallRelease\ + .return_value = {} + + tiller_obj = tiller.Tiller('host', '8080', None) + + self.assertEqual({}, tiller_obj.uninstall_release('release')) + + mock_release_service_stub.assert_called_once_with( + tiller_obj.channel) + uninstall_release_stub = mock_release_service_stub.return_value. \ + UninstallRelease + + uninstall_release_stub.assert_called_once_with( + mock_uninstall_release_request.return_value, tiller_obj.timeout, + metadata=tiller_obj.metadata)