Files
dvc/tests/unit/utils/test_fs.py
T
2020-01-09 04:57:53 +05:30

247 lines
7.7 KiB
Python

import filecmp
import os
from unittest import TestCase
import pytest
from mock import patch
import dvc
from dvc.ignore import CleanTree
from dvc.path_info import PathInfo
from dvc.scm.tree import WorkingTree
from dvc.system import System
from dvc.utils import relpath
from dvc.utils.fs import BasePathNotInCheckedPathException
from dvc.utils.fs import copyfile
from dvc.utils.fs import contains_symlink_up_to
from dvc.utils.fs import get_inode
from dvc.utils.fs import get_mtime_and_size
from dvc.utils.fs import move
from dvc.utils.fs import path_isin, remove
from dvc.utils.fs import makedirs
from tests.basic_env import TestDir
from tests.utils import spy
class TestMtimeAndSize(TestDir):
def test(self):
tree = CleanTree(WorkingTree(self.root_dir))
file_time, file_size = get_mtime_and_size(self.DATA, tree)
dir_time, dir_size = get_mtime_and_size(self.DATA_DIR, tree)
actual_file_size = os.path.getsize(self.DATA)
actual_dir_size = os.path.getsize(self.DATA) + os.path.getsize(
self.DATA_SUB
)
self.assertIs(type(file_time), str)
self.assertIs(type(file_size), str)
self.assertEqual(file_size, str(actual_file_size))
self.assertIs(type(dir_time), str)
self.assertIs(type(dir_size), str)
self.assertEqual(dir_size, str(actual_dir_size))
class TestContainsLink(TestCase):
def test_should_raise_exception_on_base_path_not_in_path(self):
with self.assertRaises(BasePathNotInCheckedPathException):
contains_symlink_up_to(os.path.join("foo", "path"), "bar")
@patch.object(System, "is_symlink", return_value=True)
def test_should_return_true_on_symlink_in_path(self, _):
base_path = "foo"
path = os.path.join(base_path, "bar")
self.assertTrue(contains_symlink_up_to(path, base_path))
@patch.object(System, "is_symlink", return_value=False)
def test_should_return_false_on_path_eq_to_base_path(self, _):
path = "path"
self.assertFalse(contains_symlink_up_to(path, path))
@patch.object(System, "is_symlink", return_value=False)
@patch.object(os.path, "dirname", side_effect=lambda arg: arg)
def test_should_return_false_on_no_more_dirs_below_path(
self, dirname_patch, _
):
self.assertFalse(
contains_symlink_up_to(os.path.join("foo", "path"), "foo")
)
dirname_patch.assert_called_once()
@patch.object(System, "is_symlink", return_value=False)
def test_should_call_recursive_on_no_condition_matched(self, _):
contains_symlink_spy = spy(contains_symlink_up_to)
with patch.object(
dvc.utils.fs, "contains_symlink_up_to", contains_symlink_spy
):
# call from full path to match contains_symlink_spy patch path
self.assertFalse(
dvc.utils.fs.contains_symlink_up_to(
os.path.join("foo", "path"), "foo"
)
)
self.assertEqual(2, contains_symlink_spy.mock.call_count)
@patch.object(System, "is_symlink", return_value=True)
def test_should_return_false_when_base_path_is_symlink(self, _):
base_path = "foo"
target_path = os.path.join(base_path, "bar")
def base_path_is_symlink(path):
if path == base_path:
return True
return False
with patch.object(
System, "is_symlink", side_effect=base_path_is_symlink
):
self.assertFalse(contains_symlink_up_to(target_path, base_path))
def test_path_object_and_str_are_valid_arg_types(self):
base_path = "foo"
target_path = os.path.join(base_path, "bar")
self.assertFalse(contains_symlink_up_to(target_path, base_path))
self.assertFalse(
contains_symlink_up_to(PathInfo(target_path), PathInfo(base_path))
)
@pytest.mark.skipif(os.name != "nt", reason="Windows specific")
def test_relpath_windows_different_drives():
path1 = os.path.join("A:", os.sep, "some", "path")
path2 = os.path.join("B:", os.sep, "other", "path")
assert relpath(path1, path2) == path1
info1, info2 = PathInfo(path1), PathInfo(path2)
rel_info = relpath(info1, info2)
assert isinstance(rel_info, str)
assert rel_info == path1
def test_get_inode(repo_dir):
path = repo_dir.FOO
path_info = PathInfo(path)
assert get_inode(path) == get_inode(path_info)
@pytest.mark.parametrize("path", [TestDir.DATA, TestDir.DATA_DIR])
def test_path_object_and_str_are_valid_types_get_mtime_and_size(
path, repo_dir
):
tree = CleanTree(WorkingTree(repo_dir.root_dir))
time, size = get_mtime_and_size(path, tree)
object_time, object_size = get_mtime_and_size(PathInfo(path), tree)
assert time == object_time
assert size == object_size
def test_move(repo_dir):
src = repo_dir.FOO
src_info = PathInfo(repo_dir.BAR)
dest = os.path.join("some", "directory")
dest_info = PathInfo(os.path.join("some", "path-like", "directory"))
os.makedirs(dest)
assert len(os.listdir(dest)) == 0
move(src, dest)
assert not os.path.isfile(src)
assert len(os.listdir(dest)) == 1
os.makedirs(dest_info.fspath)
assert len(os.listdir(dest_info.fspath)) == 0
move(src_info, dest_info)
assert not os.path.isfile(src_info.fspath)
assert len(os.listdir(dest_info.fspath)) == 1
def test_remove(repo_dir):
path = repo_dir.FOO
path_info = PathInfo(repo_dir.BAR)
remove(path)
assert not os.path.isfile(path)
remove(path_info)
assert not os.path.isfile(path_info.fspath)
def test_path_isin_positive():
child = os.path.join("path", "to", "folder")
assert path_isin(child, os.path.join("path", "to", ""))
assert path_isin(child, os.path.join("path", "to"))
assert path_isin(child, os.path.join("path", ""))
assert path_isin(child, os.path.join("path"))
def test_path_isin_on_same_path():
path = os.path.join("path", "to", "folder")
path_with_sep = os.path.join(path, "")
assert not path_isin(path, path)
assert not path_isin(path, path_with_sep)
assert not path_isin(path_with_sep, path)
assert not path_isin(path_with_sep, path_with_sep)
def test_path_isin_on_common_substring_path():
path1 = os.path.join("path", "to", "folder1")
path2 = os.path.join("path", "to", "folder")
assert not path_isin(path1, path2)
def test_path_isin_accepts_pathinfo():
child = os.path.join("path", "to", "folder")
parent = PathInfo(child) / ".."
assert path_isin(child, parent)
assert not path_isin(parent, child)
def test_path_isin_with_absolute_path():
parent = os.path.abspath("path")
child = os.path.join(parent, "to", "folder")
assert path_isin(child, parent)
def test_makedirs(repo_dir):
path = os.path.join(repo_dir.root_dir, "directory")
path_info = PathInfo(
os.path.join(repo_dir.root_dir, "another", "directory")
)
makedirs(path)
assert os.path.isdir(path)
makedirs(path_info)
assert os.path.isdir(path_info.fspath)
@pytest.mark.parametrize("path", [TestDir.DATA, TestDir.DATA_DIR])
def test_copyfile(path, repo_dir):
src = repo_dir.FOO
dest = path
src_info = PathInfo(repo_dir.BAR)
dest_info = PathInfo(path)
copyfile(src, dest)
if os.path.isdir(dest):
assert filecmp.cmp(
src, os.path.join(dest, os.path.basename(src)), shallow=False
)
else:
assert filecmp.cmp(src, dest, shallow=False)
copyfile(src_info, dest_info)
if os.path.isdir(dest_info.fspath):
assert filecmp.cmp(
src_info.fspath,
os.path.join(dest_info.fspath, os.path.basename(src_info.fspath)),
shallow=False,
)
else:
assert filecmp.cmp(src_info.fspath, dest_info.fspath, shallow=False)