mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
migrate test_{add,analytics,init,unprotect,local,process}.py to pytest
This commit is contained in:
committed by
skshetry
parent
08a643e005
commit
1cad8ea7fd
+145
-194
@@ -4,8 +4,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import stat
|
import stat
|
||||||
import textwrap
|
import textwrap
|
||||||
import time
|
from unittest.mock import call
|
||||||
from unittest.mock import call, patch
|
|
||||||
|
|
||||||
import colorama
|
import colorama
|
||||||
import pytest
|
import pytest
|
||||||
@@ -35,12 +34,11 @@ from dvc.stage.exceptions import (
|
|||||||
StagePathNotFoundError,
|
StagePathNotFoundError,
|
||||||
)
|
)
|
||||||
from dvc.testing.workspace_tests import TestAdd
|
from dvc.testing.workspace_tests import TestAdd
|
||||||
from dvc.utils import LARGE_DIR_SIZE, relpath
|
from dvc.utils import LARGE_DIR_SIZE
|
||||||
from dvc.utils.fs import path_isin
|
from dvc.utils.fs import path_isin
|
||||||
from dvc.utils.serialize import YAMLFileCorruptedError, load_yaml
|
from dvc.utils.serialize import YAMLFileCorruptedError
|
||||||
from dvc_data.hashfile.hash import file_md5
|
from dvc_data.hashfile.hash import file_md5
|
||||||
from dvc_data.hashfile.hash_info import HashInfo
|
from dvc_data.hashfile.hash_info import HashInfo
|
||||||
from tests.basic_env import TestDvc
|
|
||||||
from tests.utils import get_gitignore_content
|
from tests.utils import get_gitignore_content
|
||||||
|
|
||||||
|
|
||||||
@@ -120,49 +118,38 @@ def test_add_directory(tmp_dir, dvc):
|
|||||||
assert "\\" not in part
|
assert "\\" not in part
|
||||||
|
|
||||||
|
|
||||||
class TestAddDirectoryRecursive(TestDvc):
|
def test_add_directory_recursive(tmp_dir, dvc):
|
||||||
def test(self):
|
tmp_dir.gen("data", {"file1": "file1", "sub": {"file2": "file2"}})
|
||||||
stages = self.dvc.add(self.DATA_DIR, recursive=True)
|
stages = dvc.add("data", recursive=True)
|
||||||
self.assertEqual(len(stages), 2)
|
assert len(stages) == 2
|
||||||
|
|
||||||
|
|
||||||
class TestAddCmdDirectoryRecursive(TestDvc):
|
def test_add_cmd_directory_recursive(tmp_dir, dvc):
|
||||||
def test(self):
|
tmp_dir.gen("data", {"file1": "file1", "sub": {"file2": "file2"}})
|
||||||
ret = main(["add", "--recursive", self.DATA_DIR])
|
assert main(["add", "--recursive", "data"]) == 0
|
||||||
self.assertEqual(ret, 0)
|
|
||||||
|
|
||||||
def test_warn_about_large_directories(self):
|
|
||||||
warning = (
|
|
||||||
"You are adding a large directory 'large-dir' recursively."
|
|
||||||
"\nConsider tracking it as a whole instead with "
|
|
||||||
"`{cyan}dvc add large-dir{nc}`"
|
|
||||||
).format(
|
|
||||||
cyan=colorama.Fore.CYAN,
|
|
||||||
nc=colorama.Style.RESET_ALL,
|
|
||||||
)
|
|
||||||
|
|
||||||
os.mkdir("large-dir")
|
|
||||||
|
|
||||||
# Create a lot of files
|
|
||||||
for iteration in range(LARGE_DIR_SIZE + 1):
|
|
||||||
path = os.path.join("large-dir", str(iteration))
|
|
||||||
with open(path, "w", encoding="utf-8") as fobj:
|
|
||||||
fobj.write(path)
|
|
||||||
|
|
||||||
assert main(["add", "--recursive", "large-dir"]) == 0
|
|
||||||
assert warning in self._capsys.readouterr()[1]
|
|
||||||
|
|
||||||
|
|
||||||
class TestAddDirectoryWithForwardSlash(TestDvc):
|
def test_warn_about_large_directories_recursive_add(tmp_dir, dvc, capsys):
|
||||||
def test(self):
|
warning = (
|
||||||
dname = "directory/"
|
"You are adding a large directory 'large-dir' recursively."
|
||||||
os.mkdir(dname)
|
"\nConsider tracking it as a whole instead with "
|
||||||
self.create(os.path.join(dname, "file"), "file")
|
"`{cyan}dvc add large-dir{nc}`"
|
||||||
stages = self.dvc.add(dname)
|
).format(
|
||||||
self.assertEqual(len(stages), 1)
|
cyan=colorama.Fore.CYAN,
|
||||||
stage = stages[0]
|
nc=colorama.Style.RESET_ALL,
|
||||||
self.assertTrue(stage is not None)
|
)
|
||||||
self.assertEqual(os.path.abspath("directory.dvc"), stage.path)
|
|
||||||
|
tmp_dir.gen(
|
||||||
|
"large-dir", {f"{i}": f"{i}" for i in range(LARGE_DIR_SIZE + 1)}
|
||||||
|
)
|
||||||
|
assert main(["add", "--recursive", "large-dir"]) == 0
|
||||||
|
assert warning in capsys.readouterr()[1]
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_directory_with_forward_slash(tmp_dir, dvc):
|
||||||
|
tmp_dir.gen("directory", {"file": "file"})
|
||||||
|
(stage,) = dvc.add("directory/")
|
||||||
|
assert stage.relpath == "directory.dvc"
|
||||||
|
|
||||||
|
|
||||||
def test_add_tracked_file(tmp_dir, scm, dvc):
|
def test_add_tracked_file(tmp_dir, scm, dvc):
|
||||||
@@ -178,33 +165,23 @@ def test_add_tracked_file(tmp_dir, scm, dvc):
|
|||||||
dvc.add(path)
|
dvc.add(path)
|
||||||
|
|
||||||
|
|
||||||
class TestAddDirWithExistingCache(TestDvc):
|
def test_add_dir_with_existing_cache(tmp_dir, dvc):
|
||||||
def test(self):
|
tmp_dir.gen({"foo": "foo", "dir": {"file": "foo"}})
|
||||||
dname = "a"
|
|
||||||
fname = os.path.join(dname, "b")
|
|
||||||
os.mkdir(dname)
|
|
||||||
shutil.copyfile(self.FOO, fname)
|
|
||||||
|
|
||||||
stages = self.dvc.add(self.FOO)
|
(stage,) = dvc.add("foo")
|
||||||
self.assertEqual(len(stages), 1)
|
assert stage is not None
|
||||||
self.assertTrue(stages[0] is not None)
|
(stage,) = dvc.add("dir")
|
||||||
stages = self.dvc.add(dname)
|
assert stage is not None
|
||||||
self.assertEqual(len(stages), 1)
|
|
||||||
self.assertTrue(stages[0] is not None)
|
|
||||||
|
|
||||||
|
|
||||||
class TestAddModifiedDir(TestDvc):
|
def test_add_modified_dir(tmp_dir, dvc):
|
||||||
def test(self):
|
tmp_dir.gen("data", {"foo": "foo", "sub": {"bar": "bar"}})
|
||||||
stages = self.dvc.add(self.DATA_DIR)
|
(stage,) = dvc.add("data")
|
||||||
self.assertEqual(len(stages), 1)
|
assert stage is not None
|
||||||
self.assertTrue(stages[0] is not None)
|
|
||||||
os.unlink(self.DATA)
|
|
||||||
|
|
||||||
time.sleep(2)
|
(tmp_dir / "data" / "foo").unlink()
|
||||||
|
(stage,) = dvc.add("data")
|
||||||
stages = self.dvc.add(self.DATA_DIR)
|
assert stage is not None
|
||||||
self.assertEqual(len(stages), 1)
|
|
||||||
self.assertTrue(stages[0] is not None)
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_file_in_dir(tmp_dir, dvc):
|
def test_add_file_in_dir(tmp_dir, dvc):
|
||||||
@@ -326,57 +303,47 @@ def test_add_external_relpath(tmp_dir, dvc, local_cloud):
|
|||||||
assert dvc.status() == {}
|
assert dvc.status() == {}
|
||||||
|
|
||||||
|
|
||||||
class TestAddLocalRemoteFile(TestDvc):
|
def test_add_local_remote_file(tmp_dir, dvc):
|
||||||
def test(self):
|
"""
|
||||||
"""
|
Making sure that 'remote' syntax is handled properly for local outs.
|
||||||
Making sure that 'remote' syntax is handled properly for local outs.
|
"""
|
||||||
"""
|
tmp_dir.gen({"foo": "foo", "bar": "bar"})
|
||||||
cwd = os.getcwd()
|
tmp_dir.add_remote(url=tmp_dir.fs_path, name="myremote")
|
||||||
remote = "myremote"
|
|
||||||
|
|
||||||
ret = main(["remote", "add", remote, cwd])
|
assert main(["add", "remote://myremote/foo"]) == 0
|
||||||
self.assertEqual(ret, 0)
|
d = (tmp_dir / "foo.dvc").load_yaml()
|
||||||
|
assert d["outs"][0]["path"] == "remote://myremote/foo"
|
||||||
|
|
||||||
self.dvc.config.load()
|
assert main(["add", (tmp_dir / "bar").fs_path]) == 0
|
||||||
|
d = (tmp_dir / "bar.dvc").load_yaml()
|
||||||
foo = f"remote://{remote}/{self.FOO}"
|
assert d["outs"][0]["path"] == "bar"
|
||||||
ret = main(["add", foo])
|
|
||||||
self.assertEqual(ret, 0)
|
|
||||||
|
|
||||||
d = load_yaml("foo.dvc")
|
|
||||||
self.assertEqual(d["outs"][0]["path"], foo)
|
|
||||||
|
|
||||||
bar = os.path.join(cwd, self.BAR)
|
|
||||||
ret = main(["add", bar])
|
|
||||||
self.assertEqual(ret, 0)
|
|
||||||
|
|
||||||
d = load_yaml("bar.dvc")
|
|
||||||
self.assertEqual(d["outs"][0]["path"], self.BAR)
|
|
||||||
|
|
||||||
|
|
||||||
class TestCmdAdd(TestDvc):
|
def test_cmd_add(tmp_dir, dvc):
|
||||||
def test(self):
|
tmp_dir.gen("foo", "foo")
|
||||||
ret = main(["add", self.FOO])
|
ret = main(["add", "foo"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
|
|
||||||
ret = main(["add", "non-existing-file"])
|
ret = main(["add", "non-existing-file"])
|
||||||
self.assertNotEqual(ret, 0)
|
assert ret != 0
|
||||||
|
|
||||||
|
|
||||||
class TestDoubleAddUnchanged(TestDvc):
|
def test_double_add_unchanged_file(tmp_dir, dvc):
|
||||||
def test_file(self):
|
tmp_dir.gen("foo", "foo")
|
||||||
ret = main(["add", self.FOO])
|
ret = main(["add", "foo"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
|
|
||||||
ret = main(["add", self.FOO])
|
ret = main(["add", "foo"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
|
|
||||||
def test_dir(self):
|
|
||||||
ret = main(["add", self.DATA_DIR])
|
|
||||||
self.assertEqual(ret, 0)
|
|
||||||
|
|
||||||
ret = main(["add", self.DATA_DIR])
|
def test_double_add_unchanged_dir(tmp_dir, dvc):
|
||||||
self.assertEqual(ret, 0)
|
tmp_dir.gen("data", {"foo": "foo"})
|
||||||
|
ret = main(["add", "data"])
|
||||||
|
assert ret == 0
|
||||||
|
|
||||||
|
ret = main(["add", "data"])
|
||||||
|
assert ret == 0
|
||||||
|
|
||||||
|
|
||||||
def test_should_update_state_entry_for_file_after_add(mocker, dvc, tmp_dir):
|
def test_should_update_state_entry_for_file_after_add(mocker, dvc, tmp_dir):
|
||||||
@@ -443,19 +410,17 @@ def test_should_update_state_entry_for_directory_after_add(
|
|||||||
assert file_md5_counter.mock.call_count == 10
|
assert file_md5_counter.mock.call_count == 10
|
||||||
|
|
||||||
|
|
||||||
class TestAddCommit(TestDvc):
|
def test_add_commit(tmp_dir, dvc):
|
||||||
def test(self):
|
tmp_dir.gen("foo", "foo")
|
||||||
ret = main(["add", self.FOO, "--no-commit"])
|
ret = main(["add", "foo", "--no-commit"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
self.assertTrue(os.path.isfile(self.FOO))
|
assert os.path.isfile("foo")
|
||||||
self.assertFalse(os.path.exists(self.dvc.odb.local.path))
|
assert not os.path.exists(dvc.odb.local.path)
|
||||||
|
|
||||||
ret = main(["commit", self.FOO + ".dvc"])
|
ret = main(["commit", "foo" + ".dvc"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
self.assertTrue(os.path.isfile(self.FOO))
|
assert os.path.isfile("foo")
|
||||||
self.assertTrue(
|
assert dvc.odb.local.exists("acbd18db4cc2f85cedef654fccc4a4d8")
|
||||||
self.dvc.odb.local.exists("acbd18db4cc2f85cedef654fccc4a4d8")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_should_collect_dir_cache_only_once(mocker, tmp_dir, dvc):
|
def test_should_collect_dir_cache_only_once(mocker, tmp_dir, dvc):
|
||||||
@@ -474,80 +439,66 @@ def test_should_collect_dir_cache_only_once(mocker, tmp_dir, dvc):
|
|||||||
assert counter.mock.call_count == 5
|
assert counter.mock.call_count == 5
|
||||||
|
|
||||||
|
|
||||||
class TestShouldPlaceStageInDataDirIfRepositoryBelowSymlink(TestDvc):
|
def test_should_place_stage_in_data_dir_if_repository_below_symlink(
|
||||||
def test(self):
|
mocker, tmp_dir, dvc
|
||||||
def is_symlink_true_below_dvc_root(path):
|
):
|
||||||
if path == os.path.dirname(self.dvc.root_dir):
|
def is_symlink_true_below_dvc_root(path):
|
||||||
return True
|
return path == os.path.dirname(dvc.root_dir)
|
||||||
return False
|
|
||||||
|
|
||||||
with patch.object(
|
tmp_dir.gen({"data": {"foo": "foo"}})
|
||||||
system, "is_symlink", side_effect=is_symlink_true_below_dvc_root
|
mocker.patch.object(
|
||||||
):
|
system, "is_symlink", side_effect=is_symlink_true_below_dvc_root
|
||||||
|
)
|
||||||
|
ret = main(["add", os.path.join("data", "foo")])
|
||||||
|
assert ret == 0
|
||||||
|
|
||||||
ret = main(["add", self.DATA])
|
assert not (tmp_dir / "foo.dvc").exists()
|
||||||
self.assertEqual(0, ret)
|
assert (tmp_dir / "data" / "foo.dvc").exists()
|
||||||
|
|
||||||
stage_file_path_on_data_below_symlink = (
|
|
||||||
os.path.basename(self.DATA) + DVC_FILE_SUFFIX
|
|
||||||
)
|
|
||||||
self.assertFalse(
|
|
||||||
os.path.exists(stage_file_path_on_data_below_symlink)
|
|
||||||
)
|
|
||||||
|
|
||||||
stage_file_path = self.DATA + DVC_FILE_SUFFIX
|
|
||||||
self.assertTrue(os.path.exists(stage_file_path))
|
|
||||||
|
|
||||||
|
|
||||||
class TestShouldThrowProperExceptionOnCorruptedStageFile(TestDvc):
|
def test_should_throw_proper_exception_on_corrupted_stage_file(
|
||||||
def test(self):
|
caplog, tmp_dir, dvc
|
||||||
ret = main(["add", self.FOO])
|
):
|
||||||
assert 0 == ret
|
tmp_dir.gen({"foo": "foo", "bar": " bar"})
|
||||||
|
assert main(["add", "foo"]) == 0
|
||||||
|
|
||||||
foo_stage = relpath(self.FOO + DVC_FILE_SUFFIX)
|
with (tmp_dir / "foo.dvc").open("a+") as f:
|
||||||
|
f.write("this will break yaml file structure")
|
||||||
|
|
||||||
# corrupt stage file
|
caplog.clear()
|
||||||
with open(foo_stage, "a+", encoding="utf-8") as file:
|
assert main(["add", "bar"]) == 1
|
||||||
file.write("this will break yaml file structure")
|
expected_error = (
|
||||||
|
"unable to read: 'foo.dvc', YAML file structure is corrupted"
|
||||||
self._caplog.clear()
|
)
|
||||||
|
assert expected_error in caplog.text
|
||||||
ret = main(["add", self.BAR])
|
|
||||||
assert 1 == ret
|
|
||||||
|
|
||||||
expected_error = (
|
|
||||||
f"unable to read: '{foo_stage}', YAML file structure is corrupted"
|
|
||||||
)
|
|
||||||
|
|
||||||
assert expected_error in self._caplog.text
|
|
||||||
|
|
||||||
|
|
||||||
class TestAddFilename(TestDvc):
|
def test_add_filename(tmp_dir, dvc):
|
||||||
def test(self):
|
tmp_dir.gen({"foo": "foo", "bar": "bar", "data": {"file": "file"}})
|
||||||
ret = main(["add", self.FOO, self.BAR, "--file", "error.dvc"])
|
ret = main(["add", "foo", "bar", "--file", "error.dvc"])
|
||||||
self.assertNotEqual(0, ret)
|
assert ret != 0
|
||||||
|
|
||||||
ret = main(["add", "-R", self.DATA_DIR, "--file", "error.dvc"])
|
ret = main(["add", "-R", "data", "--file", "error.dvc"])
|
||||||
self.assertNotEqual(0, ret)
|
assert ret != 0
|
||||||
|
|
||||||
with self.assertRaises(RecursiveAddingWhileUsingFilename):
|
with pytest.raises(RecursiveAddingWhileUsingFilename):
|
||||||
self.dvc.add(self.DATA_DIR, recursive=True, fname="error.dvc")
|
dvc.add("data", recursive=True, fname="error.dvc")
|
||||||
|
|
||||||
ret = main(["add", self.DATA_DIR, "--file", "data_directory.dvc"])
|
ret = main(["add", "data", "--file", "data_directory.dvc"])
|
||||||
self.assertEqual(0, ret)
|
assert ret == 0
|
||||||
self.assertTrue(os.path.exists("data_directory.dvc"))
|
assert (tmp_dir / "data_directory.dvc").exists()
|
||||||
|
|
||||||
ret = main(["add", self.FOO, "--file", "bar.dvc"])
|
ret = main(["add", "foo", "--file", "bar.dvc"])
|
||||||
self.assertEqual(0, ret)
|
assert ret == 0
|
||||||
self.assertTrue(os.path.exists("bar.dvc"))
|
assert (tmp_dir / "bar.dvc").exists()
|
||||||
self.assertFalse(os.path.exists("foo.dvc"))
|
assert not (tmp_dir / "foo.dvc").exists()
|
||||||
|
|
||||||
os.remove("bar.dvc")
|
(tmp_dir / "bar.dvc").unlink()
|
||||||
|
|
||||||
ret = main(["add", self.FOO, "--file", "bar.dvc"])
|
ret = main(["add", "foo", "--file", "bar.dvc"])
|
||||||
self.assertEqual(0, ret)
|
assert ret == 0
|
||||||
self.assertTrue(os.path.exists("bar.dvc"))
|
assert (tmp_dir / "bar.dvc").exists()
|
||||||
self.assertFalse(os.path.exists("foo.dvc"))
|
assert not (tmp_dir / "foo.dvc").exists()
|
||||||
|
|
||||||
|
|
||||||
def test_failed_add_cleanup(tmp_dir, scm, dvc):
|
def test_failed_add_cleanup(tmp_dir, scm, dvc):
|
||||||
@@ -577,25 +528,25 @@ def test_should_not_track_git_internal_files(mocker, dvc, tmp_dir):
|
|||||||
assert ".git" not in fname
|
assert ".git" not in fname
|
||||||
|
|
||||||
|
|
||||||
class TestAddUnprotected(TestDvc):
|
def test_add_unprotected(tmp_dir, dvc):
|
||||||
def test(self):
|
tmp_dir.gen("foo", "foo")
|
||||||
ret = main(["config", "cache.type", "hardlink"])
|
ret = main(["config", "cache.type", "hardlink"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
|
|
||||||
ret = main(["add", self.FOO])
|
ret = main(["add", "foo"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
|
|
||||||
self.assertFalse(os.access(self.FOO, os.W_OK))
|
assert not os.access("foo", os.W_OK)
|
||||||
self.assertTrue(system.is_hardlink(self.FOO))
|
assert system.is_hardlink("foo")
|
||||||
|
|
||||||
ret = main(["unprotect", self.FOO])
|
ret = main(["unprotect", "foo"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
|
|
||||||
ret = main(["add", self.FOO])
|
ret = main(["add", "foo"])
|
||||||
self.assertEqual(ret, 0)
|
assert ret == 0
|
||||||
|
|
||||||
self.assertFalse(os.access(self.FOO, os.W_OK))
|
assert not os.access("foo", os.W_OK)
|
||||||
self.assertTrue(system.is_hardlink(self.FOO))
|
assert system.is_hardlink("foo")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from tests.utils import ANY
|
|||||||
def test_daemon_analytics(mocker, tmp_path):
|
def test_daemon_analytics(mocker, tmp_path):
|
||||||
mock_send = mocker.patch("dvc.analytics.send")
|
mock_send = mocker.patch("dvc.analytics.send")
|
||||||
report = os.fspath(tmp_path)
|
report = os.fspath(tmp_path)
|
||||||
assert 0 == main(["daemon", "analytics", report])
|
assert main(["daemon", "analytics", report]) == 0
|
||||||
|
|
||||||
mock_send.assert_called_with(report)
|
mock_send.assert_called_with(report)
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ def test_main_analytics(mocker, tmp_dir, dvc):
|
|||||||
mock_is_enabled = mocker.patch("dvc.analytics.collect_and_send_report")
|
mock_is_enabled = mocker.patch("dvc.analytics.collect_and_send_report")
|
||||||
mock_report = mocker.patch("dvc.analytics.is_enabled", return_value=True)
|
mock_report = mocker.patch("dvc.analytics.is_enabled", return_value=True)
|
||||||
tmp_dir.gen("foo", "text")
|
tmp_dir.gen("foo", "text")
|
||||||
assert 0 == main(["add", "foo"])
|
assert main(["add", "foo"]) == 0
|
||||||
assert mock_is_enabled.called
|
assert mock_is_enabled.called
|
||||||
assert mock_report.called
|
assert mock_report.called
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ def test_init_quiet_should_not_display_welcome_screen(tmp_dir, scm, caplog):
|
|||||||
with caplog.at_level(logging.INFO, logger="dvc"):
|
with caplog.at_level(logging.INFO, logger="dvc"):
|
||||||
ret = main(["init", "--quiet"])
|
ret = main(["init", "--quiet"])
|
||||||
|
|
||||||
assert 0 == ret
|
assert ret == 0
|
||||||
assert "" == caplog.text
|
assert "" == caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,27 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from dvc.cli import main
|
|
||||||
from tests.basic_env import TestDvc
|
|
||||||
|
|
||||||
|
def test_unprotect(tmp_dir, dvc):
|
||||||
|
tmp_dir.gen("foo", "foo")
|
||||||
|
|
||||||
class TestUnprotect(TestDvc):
|
dvc.odb.local.cache_types = ["hardlink"]
|
||||||
def test(self):
|
dvc.add("foo")
|
||||||
ret = main(["config", "cache.type", "hardlink"])
|
cache = os.path.join(
|
||||||
self.assertEqual(ret, 0)
|
".dvc", "cache", "ac", "bd18db4cc2f85cedef654fccc4a4d8"
|
||||||
|
)
|
||||||
|
assert not os.access("foo", os.W_OK)
|
||||||
|
assert not os.access(cache, os.W_OK)
|
||||||
|
|
||||||
ret = main(["add", self.FOO])
|
dvc.unprotect("foo")
|
||||||
self.assertEqual(ret, 0)
|
assert os.access("foo", os.W_OK)
|
||||||
|
|
||||||
cache = os.path.join(
|
if os.name == "nt":
|
||||||
".dvc", "cache", "ac", "bd18db4cc2f85cedef654fccc4a4d8"
|
# NOTE: cache is now unprotected, because NTFS doesn't allow
|
||||||
)
|
# deleting read-only files, so we have to try to set write perms
|
||||||
|
# on files that we try to delete, which propagates to the cache
|
||||||
|
# file. But it should be restored after the next cache check, hence
|
||||||
|
# why we call `dvc status` here.
|
||||||
|
assert os.access(cache, os.W_OK)
|
||||||
|
dvc.status()
|
||||||
|
|
||||||
self.assertFalse(os.access(self.FOO, os.W_OK))
|
assert not os.access(cache, os.W_OK)
|
||||||
self.assertFalse(os.access(cache, os.W_OK))
|
|
||||||
|
|
||||||
ret = main(["unprotect", self.FOO])
|
|
||||||
self.assertEqual(ret, 0)
|
|
||||||
|
|
||||||
self.assertTrue(os.access(self.FOO, os.W_OK))
|
|
||||||
|
|
||||||
if os.name == "nt":
|
|
||||||
# NOTE: cache is now unprotected, because NTFS doesn't allow
|
|
||||||
# deleting read-only files, so we have to try to set write perms
|
|
||||||
# on files that we try to delete, which propagates to the cache
|
|
||||||
# file. But it should be restored after the next cache check, hence
|
|
||||||
# why we call `dvc status` here.
|
|
||||||
self.assertTrue(os.access(cache, os.W_OK))
|
|
||||||
ret = main(["status"])
|
|
||||||
self.assertEqual(ret, 0)
|
|
||||||
|
|
||||||
self.assertFalse(os.access(cache, os.W_OK))
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
from dvc.output import Output
|
from dvc.output import Output
|
||||||
from dvc.stage import Stage
|
from dvc.stage import Stage
|
||||||
from dvc.utils import relpath
|
from dvc.utils import relpath
|
||||||
from dvc_data.hashfile.hash_info import HashInfo
|
from dvc_data.hashfile.hash_info import HashInfo
|
||||||
from dvc_data.hashfile.meta import Meta
|
from dvc_data.hashfile.meta import Meta
|
||||||
from tests.basic_env import TestDvc
|
|
||||||
|
|
||||||
|
|
||||||
def test_str_workdir_outside_repo(tmp_dir, erepo_dir):
|
def test_str_workdir_outside_repo(tmp_dir, erepo_dir):
|
||||||
@@ -52,24 +50,21 @@ def test_str_on_external_absolute_path(dvc):
|
|||||||
assert str(output) == abs_path
|
assert str(output) == abs_path
|
||||||
|
|
||||||
|
|
||||||
class TestGetFilesNumber(TestDvc):
|
def test_return_0_on_no_cache(dvc):
|
||||||
def _get_output(self):
|
o = Output(Stage(dvc), "path")
|
||||||
stage = Stage(self.dvc)
|
o.use_cache = False
|
||||||
return Output(stage, "path")
|
assert o.get_files_number() == 0
|
||||||
|
|
||||||
def test_return_0_on_no_cache(self):
|
|
||||||
o = self._get_output()
|
|
||||||
o.use_cache = False
|
|
||||||
self.assertEqual(0, o.get_files_number())
|
|
||||||
|
|
||||||
def test_return_multiple_for_dir(self):
|
def test_return_multiple_for_dir(dvc):
|
||||||
o = self._get_output()
|
o = Output(Stage(dvc), "path")
|
||||||
o.hash_info = HashInfo("md5", "12345678.dir")
|
o.hash_info = HashInfo("md5", "12345678.dir")
|
||||||
o.meta = Meta(nfiles=2)
|
o.meta = Meta(nfiles=2)
|
||||||
self.assertEqual(2, o.get_files_number())
|
assert o.get_files_number() == 2
|
||||||
|
|
||||||
@patch.object(Output, "is_dir_checksum", False)
|
|
||||||
def test_return_1_on_single_file_cache(self):
|
def test_return_1_on_single_file_cache(mocker, dvc):
|
||||||
o = self._get_output()
|
mocker.patch.object(Output, "is_dir_checksum", False)
|
||||||
o.hash_info = HashInfo("md5", "12345678")
|
o = Output(Stage(dvc), "path")
|
||||||
self.assertEqual(1, o.get_files_number())
|
o.hash_info = HashInfo("md5", "12345678")
|
||||||
|
assert o.get_files_number() == 1
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ def test_wait(tmp_dir, mocker):
|
|||||||
|
|
||||||
proc._proc.wait = mocker.Mock(return_value=None)
|
proc._proc.wait = mocker.Mock(return_value=None)
|
||||||
proc._proc.returncode = 0
|
proc._proc.returncode = 0
|
||||||
assert 0 == proc.wait()
|
assert proc.wait() == 0
|
||||||
proc._proc.wait.assert_called_once()
|
proc._proc.wait.assert_called_once()
|
||||||
|
|
||||||
# once subprocess return code is set, future ManagedProcess.wait() calls
|
# once subprocess return code is set, future ManagedProcess.wait() calls
|
||||||
# should not block
|
# should not block
|
||||||
proc._proc.wait.reset_mock()
|
proc._proc.wait.reset_mock()
|
||||||
assert 0 == proc.wait()
|
assert proc.wait() == 0
|
||||||
proc._proc.wait.assert_not_called()
|
proc._proc.wait.assert_not_called()
|
||||||
|
|||||||
Reference in New Issue
Block a user