[tune] docker syncer (#11035)

* Add DockerSyncer

* Add docs

* Update python/ray/tune/integration/docker.py

Co-authored-by: Richard Liaw <rliaw@berkeley.edu>

* Updated docs

* fix dir

* Added docker integration test

* added docker integration test to bazel build

* Use sdk.rsync API

Co-authored-by: Richard Liaw <rliaw@berkeley.edu>
This commit is contained in:
Kai Fricke
2020-10-01 19:59:23 +01:00
committed by GitHub
parent 98ebf8e2d8
commit bdf647c4ec
6 changed files with 261 additions and 5 deletions
@@ -0,0 +1,110 @@
import unittest
from typing import Optional
from ray.tune.integration.docker import DockerSyncer, DockerSyncClient
from ray.tune.sync_client import SyncClient
from ray.tune.syncer import NodeSyncer
class _MockRsync:
def __init__(self):
self.history = []
def __call__(self, *args, **kwargs):
self.history.append(kwargs)
class _MockLookup:
def __init__(self, node_ips):
self.node_to_ip = {}
self.ip_to_node = {}
for node, ip in node_ips.items():
self.node_to_ip[node] = ip
self.ip_to_node[ip] = node
def get_ip(self, node):
return self.node_to_ip[node]
def get_node(self, ip):
return self.ip_to_node[ip]
def _create_mock_syncer(local_ip, local_dir, remote_dir):
class _MockSyncer(DockerSyncer):
def __init__(self,
local_dir: str,
remote_dir: str,
sync_client: Optional[SyncClient] = None):
self.local_ip = local_ip
self.worker_ip = None
sync_client = sync_client or DockerSyncClient()
sync_client.configure("__nofile__")
super(NodeSyncer, self).__init__(local_dir, remote_dir,
sync_client)
return _MockSyncer(local_dir, remote_dir)
class DockerIntegrationTest(unittest.TestCase):
def setUp(self):
self.lookup = _MockLookup({
"head": "1.0.0.0",
"w1": "1.0.0.1",
"w2": "1.0.0.2"
})
self.local_dir = "/tmp/local"
self.remote_dir = "/tmp/remote"
self.mock_command = _MockRsync()
from ray.tune.integration import docker
docker.rsync = self.mock_command
def tearDown(self):
pass
def testDockerRsyncUpDown(self):
syncer = _create_mock_syncer(
self.lookup.get_ip("head"), self.local_dir, self.remote_dir)
syncer.set_worker_ip(self.lookup.get_ip("w1"))
# Test sync up. Should add / to the dirs and call rsync
syncer.sync_up()
print(self.mock_command.history[-1])
self.assertEqual(self.mock_command.history[-1]["source"],
self.local_dir + "/")
self.assertEqual(self.mock_command.history[-1]["target"],
self.remote_dir + "/")
self.assertEqual(self.mock_command.history[-1]["down"], False)
self.assertEqual(self.mock_command.history[-1]["ip_address"],
self.lookup.get_ip("w1"))
# Test sync down.
syncer.sync_down()
print(self.mock_command.history[-1])
self.assertEqual(self.mock_command.history[-1]["target"],
self.local_dir + "/")
self.assertEqual(self.mock_command.history[-1]["source"],
self.remote_dir + "/")
self.assertEqual(self.mock_command.history[-1]["down"], True)
self.assertEqual(self.mock_command.history[-1]["ip_address"],
self.lookup.get_ip("w1"))
# Sync to same node should be ignored
prev = len(self.mock_command.history)
syncer.set_worker_ip(self.lookup.get_ip("head"))
syncer.sync_up()
self.assertEqual(len(self.mock_command.history), prev)
syncer.sync_down()
self.assertEqual(len(self.mock_command.history), prev)
if __name__ == "__main__":
import pytest
import sys
sys.exit(pytest.main(["-v", __file__]))