Merge pull request #52040 from garethgreenaway/52036_rsync_state_no_changes_when_error

[2019.2] Fix to rsync state
This commit is contained in:
Gareth J. Greenaway 2019-03-21 12:08:19 -07:00 committed by GitHub
commit a00245eb6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 129 additions and 1 deletions

View file

@ -28,10 +28,13 @@ State to synchronize files and directories with rsync.
'''
from __future__ import absolute_import, print_function, unicode_literals
import logging
import os
import salt.utils.path
log = logging.getLogger(__name__)
def __virtual__():
'''
@ -155,7 +158,6 @@ def synchronized(name, source,
if result.get('retcode'):
ret['result'] = False
ret['comment'] = result['stderr']
ret['changes'] = result['stdout']
# Changed
elif _get_changes(result['stdout'])['changed']:
ret['comment'] = _get_summary(result['stdout'])

View file

@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: Gareth J. Greenaway <gareth@saltstack.com>
'''
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
# Import Salt Libs
import salt.states.rsync as rsync
# Import Salt Testing Libs
from tests.support.mixins import LoaderModuleMockMixin
from tests.support.unit import skipIf, TestCase
from tests.support.mock import (
NO_MOCK,
NO_MOCK_REASON,
MagicMock,
patch
)
@skipIf(NO_MOCK, NO_MOCK_REASON)
class RsyncTestCase(TestCase, LoaderModuleMockMixin):
'''
Validate the Rsync state
'''
def setup_loader_modules(self):
return {rsync: {}}
def test_syncronized_failed(self):
'''
Test to perform an rsync.synchorized call that fails
'''
ret = {'pid': 100, 'retcode': 23, 'stderr': '', 'stdout': ''}
_expected = {'changes': {},
'comment': 'Destination directory name was not found.',
'name': u'name',
'result': False}
with patch.dict(rsync.__opts__, {'test': True}):
mock = MagicMock(return_value=ret)
with patch.dict(rsync.__salt__, {'rsync.rsync': mock}):
self.assertDictEqual(rsync.synchronized("name", "source"),
_expected)
# Run again mocking os.path.exists as True
ret = {'pid': 100,
'retcode': 23,
'stderr': 'Something went wrong',
'stdout': ''}
_expected = {'changes': {},
'comment': 'Something went wrong',
'name': u'name',
'result': False}
with patch('os.path.exists', MagicMock(return_value=True)):
with patch.dict(rsync.__opts__, {'test': False}):
mock = MagicMock(return_value=ret)
with patch.dict(rsync.__salt__, {'rsync.rsync': mock}):
self.assertDictEqual(rsync.synchronized("name", "source"),
_expected)
def test_syncronized(self):
'''
Test to perform an rsync.synchorized call that succeeds
'''
ret = {'pid': 100,
'retcode': 0,
'stderr': '',
'stdout': ('sending incremental file list\nsnapshot.jar\n\n'
'sent 106 bytes received 35 bytes 282.00 bytes/sec\n'
'total size is 0 speedup is 0.00')}
_expected = {'changes': {'copied': 'snapshot.jar', 'deleted': u'N/A'},
'comment': ('- sent 106 bytes\n- received 35 bytes\n- '
'282.00 bytes/sec\n- total size is 0\n- speedup is 0.00'),
'name': 'name',
'result': True}
with patch('os.path.exists', MagicMock(return_value=True)):
with patch.dict(rsync.__opts__, {'test': False}):
mock = MagicMock(return_value=ret)
with patch.dict(rsync.__salt__, {'rsync.rsync': mock}):
self.assertDictEqual(rsync.synchronized("name", "source"),
_expected)
# Second pass simulating the file being in place
ret = {'pid': 100,
'retcode': 0,
'stderr': '',
'stdout': ('sending incremental file list\n\n'
'sent 106 bytes received 35 bytes '
'282.00 bytes/sec\ntotal size is 0 '
'speedup is 0.00')}
_expected = {'changes': {},
'comment': ('- sent 106 bytes\n- received '
'35 bytes\n- 282.00 bytes/sec\n- total '
'size is 0\n- speedup is 0.00'),
'name': 'name',
'result': True}
with patch('os.path.exists', MagicMock(return_value=True)):
with patch.dict(rsync.__opts__, {'test': False}):
mock = MagicMock(return_value=ret)
with patch.dict(rsync.__salt__, {'rsync.rsync': mock}):
self.assertDictEqual(rsync.synchronized("name", "source"),
_expected)
def test_syncronized_test_true(self):
'''
Test to perform an rsync.synchorized call that fails
'''
ret = {'pid': 100,
'retcode': 23,
'stderr': 'Something went wrong',
'stdout': ''}
_expected = {'changes': {},
'comment': '- ',
'name': u'name',
'result': None}
with patch('os.path.exists', MagicMock(return_value=True)):
with patch.dict(rsync.__opts__, {'test': True}):
mock = MagicMock(return_value=ret)
with patch.dict(rsync.__salt__, {'rsync.rsync': mock}):
self.assertDictEqual(rsync.synchronized("name", "source"),
_expected)