diff options
author | Zuul <zuul@review.opendev.org> | 2020-05-08 17:32:04 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2020-05-08 17:32:04 +0000 |
commit | 0522f1bda6888880367f2c5fa716b7cc199df8cb (patch) | |
tree | 9fa6abfb49b4c7c932ab27a930f39fa8332778f8 | |
parent | 0971847a50c317233733ab6dd921ae3b36f7793e (diff) | |
parent | f9a1e1a9585dfd8b3f8136c8ccbfd154915b5b59 (diff) | |
download | zuul-0522f1bda6888880367f2c5fa716b7cc199df8cb.tar.gz |
Merge "Validate ansible extra packages"
-rw-r--r-- | tests/unit/test_executor.py | 24 | ||||
-rw-r--r-- | tests/unit/test_lib_ansible.py | 33 | ||||
-rw-r--r-- | zuul/lib/ansible.py | 61 |
3 files changed, 87 insertions, 31 deletions
diff --git a/tests/unit/test_executor.py b/tests/unit/test_executor.py index ef28ad654..c0fbc5546 100644 --- a/tests/unit/test_executor.py +++ b/tests/unit/test_executor.py @@ -842,3 +842,27 @@ class TestExecutorStart(ZuulTestCase): def test_executor_start(self): self.assertFalse(os.path.exists(self.junk_dir)) + + +class TestExecutorExtraPackages(AnsibleZuulTestCase): + tenant_config_file = 'config/single-tenant/main.yaml' + + test_package = 'pywinrm' + + def setUp(self): + super(TestExecutorExtraPackages, self).setUp() + import subprocess + ansible_manager = self.executor_server.ansible_manager + for version in ansible_manager._supported_versions: + command = [ansible_manager.getAnsibleCommand(version, 'pip'), + 'uninstall', '-y', self.test_package] + subprocess.run(command) + + @mock.patch('zuul.lib.ansible.ManagedAnsible.extra_packages', + new_callable=mock.PropertyMock) + def test_extra_packages(self, mock_extra_packages): + mock_extra_packages.return_value = [self.test_package] + ansible_manager = self.executor_server.ansible_manager + self.assertFalse(ansible_manager.validate()) + ansible_manager.install() + self.assertTrue(ansible_manager.validate()) diff --git a/tests/unit/test_lib_ansible.py b/tests/unit/test_lib_ansible.py index 2d35f0658..808719521 100644 --- a/tests/unit/test_lib_ansible.py +++ b/tests/unit/test_lib_ansible.py @@ -13,7 +13,6 @@ # under the License. import collections -import subprocess from unittest import mock from tests.base import BaseTestCase @@ -23,8 +22,11 @@ from zuul.lib.ansible import AnsibleManager class TestLibAnsibleManager(BaseTestCase): @mock.patch('zuul.lib.ansible.AnsibleManager.load_ansible_config') - @mock.patch('zuul.lib.ansible.AnsibleManager.getAnsibleCommand') - def test_validate_remembers_failures(self, getAnsibleCommand, _): + @mock.patch('zuul.lib.ansible.AnsibleManager._validate_packages') + @mock.patch('zuul.lib.ansible.AnsibleManager._validate_ansible') + def test_validate_remembers_failures(self, + mock_validate_ansible, + mock_validate_packages, _): okish = mock.Mock( 'subprocess.CompletedProcess', @@ -33,17 +35,22 @@ class TestLibAnsibleManager(BaseTestCase): am = AnsibleManager() am._supported_versions = collections.OrderedDict([ - ('1.0', subprocess.CalledProcessError(1, 'fake failure')), - ('2.8', okish), + ('1.0', False), + ('2.8', True), ]) - with mock.patch('subprocess.run') as ansible: - ansible.side_effect = am._supported_versions.values() - self.assertFalse( - am.validate(), - 'A valid ansible should not mask a previous failure') + mock_validate_packages.side_effect = am._supported_versions.values() + mock_validate_ansible.side_effect = am._supported_versions.values() + self.assertFalse( + am.validate(), + 'A valid ansible should not mask a previous failure') + self.assertEquals( - [mock.call('1.0', 'ansible'), - mock.call('2.8', 'ansible'), + [mock.call('1.0'), + mock.call('2.8') ], - getAnsibleCommand.mock_calls) + mock_validate_ansible.mock_calls) + + self.assertEquals( + [mock.call('2.8')], + mock_validate_packages.mock_calls) diff --git a/zuul/lib/ansible.py b/zuul/lib/ansible.py index f5eb7e0e8..df0ed0213 100644 --- a/zuul/lib/ansible.py +++ b/zuul/lib/ansible.py @@ -202,29 +202,54 @@ class AnsibleManager: for future in concurrent.futures.as_completed(futures): future.result() + def _validate_ansible(self, version): + result = True + try: + command = [ + self.getAnsibleCommand(version, 'ansible'), + '--version', + ] + + ret = subprocess.run(command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=True) + self.log.info('Ansible version %s information: \n%s', + version, ret.stdout.decode()) + except subprocess.CalledProcessError: + result = False + self.log.exception("Ansible version %s not working" % version) + except Exception: + result = False + self.log.exception( + 'Ansible version %s not installed' % version) + return result + + def _validate_packages(self, version): + result = True + try: + extra_packages = self._getAnsible(version).extra_packages + python_package_check = \ + "import pkg_resources; pkg_resources.require({})".format( + repr(extra_packages)) + + command = [self.getAnsibleCommand(version, 'python'), + '-c', python_package_check] + subprocess.run(command, check=True) + except Exception: + result = False + self.log.exception( + 'Ansible version %s installation is missing packages' % + version) + return result + def validate(self): result = True for version in self._supported_versions: - try: - command = [ - self.getAnsibleCommand(version, 'ansible'), - '--version', - ] - - ret = subprocess.run(command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - check=True) - self.log.info('Ansible version %s information: \n%s', - version, ret.stdout.decode()) - except subprocess.CalledProcessError: + if not self._validate_ansible(version): result = False - self.log.exception("Ansible version %s not working" % version) - except Exception: + elif not self._validate_packages(version): result = False - self.log.exception( - 'Ansible version %s not installed' % version) - return result def _getAnsible(self, version): |