From 9a5bf82fae8ed0e3929a06f0a5eb70f033d4aa48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Beraud?= Date: Mon, 8 Jun 2020 22:59:13 +0200 Subject: [PATCH] Use unittest.mock instead of mock The mock third party library was needed for mock support in py2 runtimes. Since we now only support py36 and later, we can use the standard lib unittest.mock module instead. Note that https://github.com/openstack/charms.openstack is used during tests and he need `mock`, unfortunatelly it doesn't declare `mock` in its requirements so it retrieve mock from other charm project (cross dependency). So we depend on charms.openstack first and when Ib1ed5b598a52375e29e247db9ab4786df5b6d142 will be merged then CI will pass without errors. Drop Python 3.5 testing. Rework some unit tests that use unittest.mock features not introduced until Python 3.7. Depends-On: Ib1ed5b598a52375e29e247db9ab4786df5b6d142 Change-Id: I029c77ed697620725dc040d1849a691eb10c9351 --- .zuul.yaml | 1 - unit_tests/test_actions.py | 4 +- unit_tests/test_actions_openstack_upgrade.py | 2 +- unit_tests/test_keystone_contexts.py | 37 ++++++++++++++++--- unit_tests/test_keystone_hooks.py | 2 +- unit_tests/test_keystone_utils.py | 2 +- .../test_scripts_fernet_rotate_and_sync.py | 2 +- unit_tests/test_utils.py | 2 +- 8 files changed, 38 insertions(+), 14 deletions(-) diff --git a/.zuul.yaml b/.zuul.yaml index b3037e94..0eed1965 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -1,5 +1,4 @@ - project: templates: - - python35-charm-jobs - openstack-python3-ussuri-jobs - openstack-cover-jobs diff --git a/unit_tests/test_actions.py b/unit_tests/test_actions.py index 40933538..842f8396 100644 --- a/unit_tests/test_actions.py +++ b/unit_tests/test_actions.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -import mock -from mock import patch +from unittest import mock +from unittest.mock import patch from test_utils import CharmTestCase diff --git a/unit_tests/test_actions_openstack_upgrade.py b/unit_tests/test_actions_openstack_upgrade.py index 4475393a..bca61104 100644 --- a/unit_tests/test_actions_openstack_upgrade.py +++ b/unit_tests/test_actions_openstack_upgrade.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from mock import patch +from unittest.mock import patch import os os.environ['JUJU_UNIT_NAME'] = 'keystone' diff --git a/unit_tests/test_keystone_contexts.py b/unit_tests/test_keystone_contexts.py index 8a75cd4a..60fc129f 100644 --- a/unit_tests/test_keystone_contexts.py +++ b/unit_tests/test_keystone_contexts.py @@ -16,7 +16,7 @@ import collections import importlib import os -from mock import patch, MagicMock, ANY +from unittest.mock import patch, MagicMock, ANY with patch('charmhelpers.contrib.openstack.' 'utils.snap_install_requested') as snap_install_requested: snap_install_requested.return_value = False @@ -549,39 +549,59 @@ class TestKeystoneContexts(CharmTestCase): @patch.object(context, 'log') def test__decode_password_security_compliance_string_pre_newton( self, mock_log): + self.log_message = None + + def _mock_log(message, level=None): + self.log_message = message + mock_log.side_effect = _mock_log self.os_release.return_value = 'mitaka' self.assertIsNone( context. KeystoneContext. _decode_password_security_compliance_string("")) mock_log.assert_called_once_with(ANY, level='ERROR') - self.assertIn("Newton", mock_log.call_args.args[0]) + self.assertIn("Newton", self.log_message) @patch.object(context, 'log') def test__decode_password_security_compliance_string_invalid_yaml( self, mock_log): + self.log_message = None + + def _mock_log(message, level=None): + self.log_message = message + mock_log.side_effect = _mock_log self.os_release.return_value = 'ocata' self.assertIsNone( context. KeystoneContext. _decode_password_security_compliance_string("hello: this: one")) mock_log.assert_called_once_with(ANY, level='ERROR') - self.assertIn("Invalid YAML", mock_log.call_args.args[0]) + self.assertIn("Invalid YAML", self.log_message) @patch.object(context, 'log') def test__decode_password_security_compliance_string_yaml_not_dict( self, mock_log): + self.log_message = None + + def _mock_log(message, level=None): + self.log_message = message + mock_log.side_effect = _mock_log self.os_release.return_value = 'pike' self.assertIsNone( context. KeystoneContext. _decode_password_security_compliance_string("hello")) mock_log.assert_called_once_with(ANY, level='ERROR') - self.assertIn("dictionary", mock_log.call_args.args[0]) + self.assertIn("dictionary", self.log_message) @patch.object(context, 'log') def test__decode_password_security_compliance_string_invalid_key( self, mock_log): + self.log_message = None + + def _mock_log(message, level=None): + self.log_message = message + mock_log.side_effect = _mock_log self.os_release.return_value = 'queens' self.assertIsNone( context. @@ -589,11 +609,16 @@ class TestKeystoneContexts(CharmTestCase): _decode_password_security_compliance_string( "lockout_failure_attempts: 5\nlookout_duration: 180\n")) mock_log.assert_called_once_with(ANY, level='ERROR') - self.assertIn("Invalid config key(s)", mock_log.call_args.args[0]) + self.assertIn("Invalid config key(s)", self.log_message) @patch.object(context, 'log') def test__decode_password_security_compliance_string_invalid_type( self, mock_log): + self.log_message = None + + def _mock_log(message, level=None): + self.log_message = message + mock_log.side_effect = _mock_log self.os_release.return_value = 'rocky' self.assertIsNone( context. @@ -601,7 +626,7 @@ class TestKeystoneContexts(CharmTestCase): _decode_password_security_compliance_string( "lockout_failure_attempts: hello")) mock_log.assert_called_once_with(ANY, level='ERROR') - self.assertIn("Invalid config value", mock_log.call_args.args[0]) + self.assertIn("Invalid config value", self.log_message) @patch.object(context, 'log') def test__decode_password_security_compliance_string_valid( diff --git a/unit_tests/test_keystone_hooks.py b/unit_tests/test_keystone_hooks.py index 33ba52f9..4934fbd3 100644 --- a/unit_tests/test_keystone_hooks.py +++ b/unit_tests/test_keystone_hooks.py @@ -18,7 +18,7 @@ import sys import charmhelpers.contrib.openstack.utils as os_utils -from mock import call, patch, MagicMock, ANY +from unittest.mock import call, patch, MagicMock, ANY from test_utils import CharmTestCase # python-apt is not installed as part of test-requirements but is imported by diff --git a/unit_tests/test_keystone_utils.py b/unit_tests/test_keystone_utils.py index e1f79717..7fa82421 100644 --- a/unit_tests/test_keystone_utils.py +++ b/unit_tests/test_keystone_utils.py @@ -15,7 +15,7 @@ import builtins import collections import copy -from mock import ANY, patch, call, MagicMock, mock_open, Mock +from unittest.mock import ANY, patch, call, MagicMock, mock_open, Mock import json import os import subprocess diff --git a/unit_tests/test_scripts_fernet_rotate_and_sync.py b/unit_tests/test_scripts_fernet_rotate_and_sync.py index 153daf44..582b22a3 100644 --- a/unit_tests/test_scripts_fernet_rotate_and_sync.py +++ b/unit_tests/test_scripts_fernet_rotate_and_sync.py @@ -14,7 +14,7 @@ import sys -from mock import patch +from unittest.mock import patch from test_utils import CharmTestCase diff --git a/unit_tests/test_utils.py b/unit_tests/test_utils.py index 3bb0b68c..b36d7617 100644 --- a/unit_tests/test_utils.py +++ b/unit_tests/test_utils.py @@ -17,7 +17,7 @@ import os import unittest import yaml -from mock import patch +from unittest.mock import patch patch('charmhelpers.contrib.openstack.utils.set_os_workload_status').start() patch('charmhelpers.core.hookenv.status_set').start()