From d4c9c71a2f7e0d0f18b73ff58d3a578e543a9dd9 Mon Sep 17 00:00:00 2001 From: pawel Date: Wed, 11 Sep 2019 11:14:34 +0200 Subject: [PATCH] remote: checkout: reuse _checkout_file functionality --- dvc/remote/base.py | 5 ---- tests/func/test_checkout.py | 56 +++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/dvc/remote/base.py b/dvc/remote/base.py index 73d0710ac3..156719f4ba 100644 --- a/dvc/remote/base.py +++ b/dvc/remote/base.py @@ -851,11 +851,6 @@ def checkout( self.safe_remove(path_info, force=force) skip = True - elif not self.changed(path_info, checksum_info): - msg = "Data '{}' didn't change." - logger.debug(msg.format(str(path_info))) - skip = True - elif self.changed_cache(checksum): msg = "Cache '{}' not found. File '{}' won't be created." logger.warning(msg.format(checksum, str(path_info))) diff --git a/tests/func/test_checkout.py b/tests/func/test_checkout.py index d489a71b9a..b555a70568 100644 --- a/tests/func/test_checkout.py +++ b/tests/func/test_checkout.py @@ -4,6 +4,8 @@ import collections import logging +import pytest + from dvc.main import main from dvc.repo import Repo as DvcRepo from dvc.system import System @@ -23,6 +25,7 @@ from mock import patch +from tests.utils import spy logger = logging.getLogger("dvc") @@ -475,3 +478,56 @@ def test_checkout_no_checksum(repo_dir, dvc_repo): stage = dvc_repo.run(outs=[repo_dir.FOO], no_exec=True, cmd="somecmd") dvc_repo.checkout(stage.path, force=True) assert not os.path.exists(repo_dir.FOO) + + +@pytest.mark.parametrize( + "link, link_test_func", + [("hardlink", System.is_hardlink), ("symlink", System.is_symlink)], +) +def test_should_relink_on_checkout(link, link_test_func, repo_dir, dvc_repo): + dvc_repo.cache.local.cache_types = [link] + + dvc_repo.add(repo_dir.DATA_DIR) + dvc_repo.unprotect(repo_dir.DATA_SUB) + + dvc_repo.checkout(repo_dir.DATA_DIR + Stage.STAGE_FILE_SUFFIX) + + assert link_test_func(repo_dir.DATA_SUB) + + +@pytest.mark.parametrize("link", ["hardlink", "symlink", "copy"]) +def test_should_protect_on_checkout(link, dvc_repo, repo_dir): + dvc_repo.cache.local.cache_types = [link] + dvc_repo.cache.local.protected = True + + dvc_repo.add(repo_dir.FOO) + dvc_repo.unprotect(repo_dir.FOO) + + dvc_repo.checkout(repo_dir.FOO + Stage.STAGE_FILE_SUFFIX) + + assert not os.access(repo_dir.FOO, os.W_OK) + + +def test_should_relink_only_one_file_in_dir(dvc_repo, repo_dir): + dvc_repo.cache.local.cache_types = ["symlink"] + + dvc_repo.add(repo_dir.DATA_DIR) + dvc_repo.unprotect(repo_dir.DATA_SUB) + + link_spy = spy(System.symlink) + with patch.object(dvc_repo.cache.local, "symlink", link_spy): + dvc_repo.checkout(repo_dir.DATA_DIR + Stage.STAGE_FILE_SUFFIX) + + assert link_spy.mock.call_count == 1 + + +@pytest.mark.parametrize("link", ["hardlink", "symlink", "copy"]) +def test_should_not_relink_on_unchanged_dependency(link, dvc_repo, repo_dir): + dvc_repo.cache.local.cache_types = [link] + + dvc_repo.add(repo_dir.DATA_DIR) + + with patch.object(dvc_repo.cache.local, "link") as mock_link: + dvc_repo.checkout(repo_dir.DATA_DIR + Stage.STAGE_FILE_SUFFIX) + + assert not mock_link.called