--- /dev/null
+from .lib import execnet
+from .connection import Connection, FakeRemoteLogger
+
+
+class _RSync(execnet.RSync):
+ """
+ Inherits from ``execnet.RSync`` so that we can log nicely with the user
+ logger instance (if any) back with the ``_report_send_file`` method
+ """
+
+ def __init__(self, sourcedir, callback=None, verbose=True, logger=None):
+ self.logger = logger
+ super(_RSync, self).__init__(sourcedir, callback, verbose)
+
+ def _report_send_file(self, gateway, modified_rel_path):
+ if self._verbose:
+ self.logger.info("syncing file: %s" % modified_rel_path)
+
+
+def rsync(hosts, source, destination, logger=None, sudo=False):
+ """
+ Grabs the hosts (or single host), creates the connection object for each
+ and set the rsync execnet engine to push the files.
+
+ It assumes that all of the destinations for the different hosts is the
+ same. This deviates from what execnet does because it has the flexibility
+ to push to different locations.
+ """
+ logger = logger or FakeRemoteLogger()
+ sync = _RSync(source, logger=logger)
+
+ # setup_targets
+ if not isinstance(hosts, list):
+ hosts = [hosts]
+
+ for host in hosts:
+ conn = Connection(
+ host,
+ logger,
+ sudo,
+ )
+ sync.add_target(conn.gateway, destination)
+
+ return sync.send()
+++ /dev/null
-from .lib import execnet
-from .connection import Connection, FakeRemoteLogger
-
-
-class _RSync(execnet.RSync):
- """
- Inherits from ``execnet.RSync`` so that we can log nicely with the user
- logger instance (if any) back with the ``_report_send_file`` method
- """
-
- def __init__(self, sourcedir, callback=None, verbose=True, logger=None):
- self.logger = logger
- super(_RSync, self).__init__(sourcedir, callback, verbose)
-
- def _report_send_file(self, gateway, modified_rel_path):
- if self._verbose:
- self.logger.info("syncing file: %s" % modified_rel_path)
-
-
-def rsync(hosts, source, destination, logger=None, sudo=False):
- """
- Grabs the hosts (or single host), creates the connection object for each
- and set the rsync execnet engine to push the files.
-
- It assumes that all of the destinations for the different hosts is the
- same. This deviates from what execnet does because it has the flexibility
- to push to different locations.
- """
- logger = logger or FakeRemoteLogger()
- sync = _RSync(source, logger=logger)
-
- # setup_targets
- if not isinstance(hosts, list):
- hosts = [hosts]
-
- for host in hosts:
- conn = Connection(
- host,
- logger,
- sudo,
- )
- sync.add_target(conn.gateway, destination)
-
- return sync.send()
--- /dev/null
+from mock import Mock, patch
+from remoto import file_sync
+
+
+class TestRsync(object):
+
+ def make_fake_sync(self):
+ fake_sync = Mock()
+ fake_sync.return_value = fake_sync
+ fake_sync.targets = []
+ fake_sync.add_target = lambda gw, destination: fake_sync.targets.append(destination)
+ return fake_sync
+
+ @patch('remoto.file_sync.Connection', Mock())
+ def test_rsync_fallback_to_host_list(self):
+ fake_sync = self.make_fake_sync()
+ with patch('remoto.file_sync._RSync', fake_sync):
+ file_sync.rsync('host1', '/source', '/destination')
+
+ # should've added just one target
+ assert len(fake_sync.targets) == 1
+
+ @patch('remoto.file_sync.Connection', Mock())
+ def test_rsync_use_host_list(self):
+ fake_sync = self.make_fake_sync()
+ with patch('remoto.file_sync._RSync', fake_sync):
+ file_sync.rsync(
+ ['host1', 'host2'], '/source', '/destination')
+
+ # should've added just one target
+ assert len(fake_sync.targets) == 2