From 7848189ad4b77356bb339cfb257d3498365cff85 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Wed, 9 Aug 2017 11:55:43 +1000 Subject: [PATCH] Implement rbenv state module test mode checks Fixes #42815 and updates unit tests. --- salt/states/rbenv.py | 35 ++++-- tests/unit/states/test_rbenv.py | 187 ++++++++++++++++++++++++-------- 2 files changed, 165 insertions(+), 57 deletions(-) diff --git a/salt/states/rbenv.py b/salt/states/rbenv.py index f4889be8a2..50a66e1ef4 100644 --- a/salt/states/rbenv.py +++ b/salt/states/rbenv.py @@ -77,7 +77,7 @@ def _ruby_installed(ret, ruby, user=None): for version in __salt__['rbenv.versions'](user): if version == ruby: ret['result'] = True - ret['comment'] = 'Requested ruby exists.' + ret['comment'] = 'Requested ruby exists' ret['default'] = default == ruby break @@ -97,7 +97,7 @@ def _check_and_install_ruby(ret, ruby, default=False, user=None): ret['default'] = default else: ret['result'] = False - ret['comment'] = 'Could not install ruby.' + ret['comment'] = 'Failed to install ruby' return ret if default: @@ -131,7 +131,11 @@ def installed(name, default=False, user=None): name = re.sub(r'^ruby-', '', name) if __opts__['test']: - ret['comment'] = 'Ruby {0} is set to be installed'.format(name) + ret = _ruby_installed(ret, name, user=user) + if not ret['result']: + ret['comment'] = 'Ruby {0} is set to be installed'.format(name) + else: + ret['comment'] = 'Ruby {0} is already installed'.format(name) return ret rbenv_installed_ret = _check_and_install_rbenv(rbenv_installed_ret, user) @@ -188,16 +192,22 @@ def absent(name, user=None): if name.startswith('ruby-'): name = re.sub(r'^ruby-', '', name) - if __opts__['test']: - ret['comment'] = 'Ruby {0} is set to be uninstalled'.format(name) - return ret - ret = _check_rbenv(ret, user) if ret['result'] is False: ret['result'] = True ret['comment'] = 'Rbenv not installed, {0} not either'.format(name) return ret else: + if __opts__['test']: + ret = _ruby_installed(ret, name, user=user) + if ret['result']: + ret['result'] = None + ret['comment'] = 'Ruby {0} is set to be uninstalled'.format(name) + else: + ret['result'] = True + ret['comment'] = 'Ruby {0} is already uninstalled'.format(name) + return ret + return _check_and_uninstall_ruby(ret, name, user=user) @@ -205,7 +215,6 @@ def _check_and_install_rbenv(ret, user=None): ''' Verify that rbenv is installed, install if unavailable ''' - ret = _check_rbenv(ret, user) if ret['result'] is False: if __salt__['rbenv.install'](user): @@ -216,7 +225,7 @@ def _check_and_install_rbenv(ret, user=None): ret['comment'] = 'Rbenv failed to install' else: ret['result'] = True - ret['comment'] = 'Rbenv already installed' + ret['comment'] = 'Rbenv is already installed' return ret @@ -237,7 +246,13 @@ def install_rbenv(name, user=None): ret = {'name': name, 'result': None, 'comment': '', 'changes': {}} if __opts__['test']: - ret['comment'] = 'Rbenv is set to be installed' + ret = _check_rbenv(ret, user=user) + if ret['result'] is False: + ret['result'] = None + ret['comment'] = 'Rbenv is set to be installed' + else: + ret['result'] = True + ret['comment'] = 'Rbenv is already installed' return ret return _check_and_install_rbenv(ret, user) diff --git a/tests/unit/states/test_rbenv.py b/tests/unit/states/test_rbenv.py index d368a54e52..7ab9c1f1fd 100644 --- a/tests/unit/states/test_rbenv.py +++ b/tests/unit/states/test_rbenv.py @@ -33,36 +33,71 @@ class RbenvTestCase(TestCase, LoaderModuleMockMixin): ''' Test to verify that the specified ruby is installed with rbenv. ''' - name = 'rbenv-deps' + # rbenv.is_installed is used wherever test is False. + mock_is = MagicMock(side_effect=[False, True, True, True, True]) - ret = {'name': name, - 'changes': {}, - 'result': True, - 'comment': ''} + # rbenv.install is only called when an action is attempted + # (ie. Successfully... or Failed...) + mock_i = MagicMock(side_effect=[False, False, False]) - mock_t = MagicMock(side_effect=[False, True, True]) - mock_f = MagicMock(return_value=False) - mock_def = MagicMock(return_value='2.7') - mock_ver = MagicMock(return_value=['2.7']) + # rbenv.install_ruby is only called when rbenv is successfully + # installed and an attempt to install a version of Ruby is + # made. + mock_ir = MagicMock(side_effect=[True, False]) + mock_def = MagicMock(return_value='2.3.4') + mock_ver = MagicMock(return_value=['2.3.4', '2.4.1']) with patch.dict(rbenv.__salt__, - {'rbenv.is_installed': mock_f, - 'rbenv.install': mock_t, + {'rbenv.is_installed': mock_is, + 'rbenv.install': mock_i, 'rbenv.default': mock_def, 'rbenv.versions': mock_ver, - 'rbenv.install_ruby': mock_t}): + 'rbenv.install_ruby': mock_ir}): with patch.dict(rbenv.__opts__, {'test': True}): - comt = ('Ruby rbenv-deps is set to be installed') - ret.update({'comment': comt, 'result': None}) + name = '1.9.3-p551' + comt = 'Ruby {0} is set to be installed'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'result': None} + self.assertDictEqual(rbenv.installed(name), ret) + + name = '2.4.1' + comt = 'Ruby {0} is already installed'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'default': False, 'result': True} + self.assertDictEqual(rbenv.installed(name), ret) + + name = '2.3.4' + comt = 'Ruby {0} is already installed'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'default': True, 'result': True} self.assertDictEqual(rbenv.installed(name), ret) with patch.dict(rbenv.__opts__, {'test': False}): - comt = ('Rbenv failed to install') - ret.update({'comment': comt, 'result': False}) + name = '2.4.1' + comt = 'Rbenv failed to install' + ret = {'name': name, 'changes': {}, 'comment': comt, + 'result': False} self.assertDictEqual(rbenv.installed(name), ret) - comt = ('Successfully installed ruby') - ret.update({'comment': comt, 'result': True, 'default': False, - 'changes': {name: 'Installed'}}) + comt = 'Requested ruby exists' + ret = {'name': name, 'comment': comt, 'default': False, + 'changes': {}, 'result': True} + self.assertDictEqual(rbenv.installed(name), ret) + + name = '2.3.4' + comt = 'Requested ruby exists' + ret = {'name': name, 'comment': comt, 'default': True, + 'changes': {}, 'result': True} + self.assertDictEqual(rbenv.installed(name), ret) + + name = '1.9.3-p551' + comt = 'Successfully installed ruby' + ret = {'name': name, 'comment': comt, 'default': False, + 'changes': {name: 'Installed'}, 'result': True} + self.assertDictEqual(rbenv.installed(name), ret) + + comt = 'Failed to install ruby' + ret = {'name': name, 'comment': comt, + 'changes': {}, 'result': False} self.assertDictEqual(rbenv.installed(name), ret) # 'absent' function tests: 1 @@ -71,32 +106,76 @@ class RbenvTestCase(TestCase, LoaderModuleMockMixin): ''' Test to verify that the specified ruby is not installed with rbenv. ''' - name = 'myqueue' - - ret = {'name': name, - 'changes': {}, - 'result': True, - 'comment': ''} - - mock = MagicMock(side_effect=[False, True]) - mock_def = MagicMock(return_value='2.7') - mock_ver = MagicMock(return_value=['2.7']) + # rbenv.is_installed is used for all tests here. + mock_is = MagicMock(side_effect=[False, True, True, True, False, + True, True, True, True, True]) + # rbenv.uninstall_ruby is only called when an action is + # attempted (ie. Successfully... or Failed...) + mock_uninstalled = MagicMock(side_effect=[True, False, False, True]) + mock_def = MagicMock(return_value='2.3.4') + mock_ver = MagicMock(return_value=['2.3.4', '2.4.1']) with patch.dict(rbenv.__salt__, - {'rbenv.is_installed': mock, + {'rbenv.is_installed': mock_is, 'rbenv.default': mock_def, - 'rbenv.versions': mock_ver}): + 'rbenv.versions': mock_ver, + 'rbenv.uninstall_ruby': mock_uninstalled}): + with patch.dict(rbenv.__opts__, {'test': True}): - comt = ('Ruby myqueue is set to be uninstalled') - ret.update({'comment': comt, 'result': None}) + name = '1.9.3-p551' + comt = 'Rbenv not installed, {0} not either'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'result': True} self.assertDictEqual(rbenv.absent(name), ret) + comt = 'Ruby {0} is already uninstalled'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'result': True} + self.assertDictEqual(rbenv.absent(name), ret) + + name = '2.3.4' + comt = 'Ruby {0} is set to be uninstalled'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'default': True, 'result': None} + self.assertDictEqual(rbenv.absent('2.3.4'), ret) + + name = '2.4.1' + comt = 'Ruby {0} is set to be uninstalled'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'default': False, 'result': None} + self.assertDictEqual(rbenv.absent('2.4.1'), ret) + with patch.dict(rbenv.__opts__, {'test': False}): - comt = ('Rbenv not installed, myqueue not either') - ret.update({'comment': comt, 'result': True}) + name = '1.9.3-p551' + comt = 'Rbenv not installed, {0} not either'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'result': True} self.assertDictEqual(rbenv.absent(name), ret) - comt = ('Ruby myqueue is already absent') - ret.update({'comment': comt, 'result': True}) + comt = 'Ruby {0} is already absent'.format(name) + ret = {'name': name, 'changes': {}, 'comment': comt, + 'result': True} + self.assertDictEqual(rbenv.absent(name), ret) + + name = '2.3.4' + comt = 'Successfully removed ruby' + ret = {'name': name, 'changes': {name: 'Uninstalled'}, + 'comment': comt, 'default': True, 'result': True} + self.assertDictEqual(rbenv.absent(name), ret) + + comt = 'Failed to uninstall ruby' + ret = {'name': name, 'changes': {}, 'comment': comt, + 'default': True, 'result': False} + self.assertDictEqual(rbenv.absent(name), ret) + + name = '2.4.1' + comt = 'Failed to uninstall ruby' + ret = {'name': name, 'changes': {}, 'comment': comt, + 'default': False, 'result': False} + self.assertDictEqual(rbenv.absent(name), ret) + + comt = 'Successfully removed ruby' + ret = {'name': name, 'changes': {name: 'Uninstalled'}, + 'comment': comt, 'default': False, 'result': True} self.assertDictEqual(rbenv.absent(name), ret) # 'install_rbenv' function tests: 1 @@ -112,16 +191,30 @@ class RbenvTestCase(TestCase, LoaderModuleMockMixin): 'result': True, 'comment': ''} - with patch.dict(rbenv.__opts__, {'test': True}): - comt = ('Rbenv is set to be installed') - ret.update({'comment': comt, 'result': None}) - self.assertDictEqual(rbenv.install_rbenv(name), ret) + mock_is = MagicMock(side_effect=[False, True, True, False, False]) + mock_i = MagicMock(side_effect=[False, True]) + with patch.dict(rbenv.__salt__, + {'rbenv.is_installed': mock_is, + 'rbenv.install': mock_i}): - with patch.dict(rbenv.__opts__, {'test': False}): - mock = MagicMock(side_effect=[False, True]) - with patch.dict(rbenv.__salt__, - {'rbenv.is_installed': mock, - 'rbenv.install': mock}): - comt = ('Rbenv installed') + with patch.dict(rbenv.__opts__, {'test': True}): + comt = 'Rbenv is set to be installed' + ret.update({'comment': comt, 'result': None}) + self.assertDictEqual(rbenv.install_rbenv(name), ret) + + comt = 'Rbenv is already installed' + ret.update({'comment': comt, 'result': True}) + self.assertDictEqual(rbenv.install_rbenv(name), ret) + + with patch.dict(rbenv.__opts__, {'test': False}): + comt = 'Rbenv is already installed' + ret.update({'comment': comt, 'result': True}) + self.assertDictEqual(rbenv.install_rbenv(name), ret) + + comt = 'Rbenv failed to install' + ret.update({'comment': comt, 'result': False}) + self.assertDictEqual(rbenv.install_rbenv(name), ret) + + comt = 'Rbenv installed' ret.update({'comment': comt, 'result': True}) self.assertDictEqual(rbenv.install_rbenv(name), ret)