def test_docker_command_runner(): process_runner = MockProcessRunner() provider = MockProvider() provider.create_node({}, {}, 1) cluster_name = "cluster" ssh_control_hash = hashlib.md5(cluster_name.encode()).hexdigest() ssh_user_hash = hashlib.md5(getuser().encode()).hexdigest() ssh_control_path = "/tmp/ray_ssh_{}/{}".format(ssh_user_hash[:10], ssh_control_hash[:10]) docker_config = {"container_name": "container"} args = { "log_prefix": "prefix", "node_id": 0, "provider": provider, "auth_config": auth_config, "cluster_name": cluster_name, "process_runner": process_runner, "use_internal_ip": False, "docker_config": docker_config, } cmd_runner = DockerCommandRunner(**args) process_runner.assert_has_call("1.2.3.4", "command -v docker") process_runner.clear_history() env_vars = {"var1": "quote between this \" and this", "var2": "123"} cmd_runner.run("echo hello", environment_variables=env_vars) # This string is insane because there are an absurd number of embedded # quotes. While this is a ridiculous string, the escape behavior is # important and somewhat difficult to get right for environment variables. cmd = """'true && source ~/.bashrc && export OMP_NUM_THREADS=1 PYTHONWARNINGS=ignore && docker exec -it container /bin/bash -c '"'"'bash --login -c -i '"'"'"'"'"'"'"'"'true && source ~/.bashrc && export OMP_NUM_THREADS=1 PYTHONWARNINGS=ignore && export var1='"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'quote between this " and this'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"';export var2=123;echo hello'"'"'"'"'"'"'"'"''"'"' '""" # noqa: E501 expected = [ "ssh", "-tt", "-i", "8265.pem", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-o", "IdentitiesOnly=yes", "-o", "ExitOnForwardFailure=yes", "-o", "ServerAliveInterval=5", "-o", "ServerAliveCountMax=3", "-o", "ControlMaster=auto", "-o", "ControlPath={}/%C".format(ssh_control_path), "-o", "ControlPersist=10s", "-o", "ConnectTimeout=120s", "[email protected]", "bash", "--login", "-c", "-i", cmd ] # Much easier to debug this loop than the function call. for x, y in zip(process_runner.calls[0], expected): assert x == y process_runner.assert_has_call("1.2.3.4", exact=expected)
def test_docker_rsync(): process_runner = MockProcessRunner() provider = MockProvider() provider.create_node({}, {}, 1) cluster_name = "cluster" docker_config = {"container_name": "container"} args = { "log_prefix": "prefix", "node_id": 0, "provider": provider, "auth_config": auth_config, "cluster_name": cluster_name, "process_runner": process_runner, "use_internal_ip": False, "docker_config": docker_config, } cmd_runner = DockerCommandRunner(**args) local_mount = "/home/ubuntu/base/mount/" remote_mount = "/root/protected_mount/" docker_mount_prefix = get_docker_host_mount_location(cluster_name) remote_host_mount = f"{docker_mount_prefix}{remote_mount}" local_file = "/home/ubuntu/base-file" remote_file = "/root/protected-file" remote_host_file = f"{docker_mount_prefix}{remote_file}" process_runner.respond_to_call("docker inspect -f", ["true"]) cmd_runner.run_rsync_up(local_mount, remote_mount, options={"docker_mount_if_possible": True}) # Make sure we do not copy directly to raw destination process_runner.assert_not_has_call( "1.2.3.4", pattern=f"-avz {local_mount} [email protected]:{remote_mount}") process_runner.assert_not_has_call("1.2.3.4", pattern=f"mkdir -p {remote_mount}") # No docker cp for file_mounts process_runner.assert_not_has_call("1.2.3.4", pattern="docker cp") process_runner.assert_has_call( "1.2.3.4", pattern=f"-avz {local_mount} [email protected]:{remote_host_mount}") process_runner.clear_history() ############################## process_runner.respond_to_call("docker inspect -f", ["true"]) cmd_runner.run_rsync_up(local_file, remote_file, options={"docker_mount_if_possible": False}) # Make sure we do not copy directly to raw destination process_runner.assert_not_has_call( "1.2.3.4", pattern=f"-avz {local_file} [email protected]:{remote_file}") process_runner.assert_not_has_call("1.2.3.4", pattern=f"mkdir -p {remote_file}") process_runner.assert_has_call("1.2.3.4", pattern="docker cp") process_runner.assert_has_call( "1.2.3.4", pattern=f"-avz {local_file} [email protected]:{remote_host_file}") process_runner.clear_history() ############################## cmd_runner.run_rsync_down(remote_mount, local_mount, options={"docker_mount_if_possible": True}) process_runner.assert_not_has_call("1.2.3.4", pattern="docker cp") process_runner.assert_not_has_call( "1.2.3.4", pattern=f"-avz [email protected]:{remote_mount} {local_mount}") process_runner.assert_has_call( "1.2.3.4", pattern=f"-avz [email protected]:{remote_host_mount} {local_mount}") process_runner.clear_history() ############################## cmd_runner.run_rsync_down(remote_file, local_file, options={"docker_mount_if_possible": False}) process_runner.assert_has_call("1.2.3.4", pattern="docker cp") process_runner.assert_not_has_call( "1.2.3.4", pattern=f"-avz [email protected]:{remote_file} {local_file}") process_runner.assert_has_call( "1.2.3.4", pattern=f"-avz [email protected]:{remote_host_file} {local_file}")