dvcfs: add fsspec-compliance tests (#8296)

dvcfs: add tests
This commit is contained in:
skshetry
2022-09-15 18:42:50 +05:45
committed by GitHub
parent d762372d55
commit 1b90683e02
2 changed files with 109 additions and 0 deletions
+6
View File
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, Callable, Optional, Tuple, Type, Union
from fsspec.spec import AbstractFileSystem
from funcy import cached_property, wrap_prop, wrap_with
from dvc.utils.fs import makedirs
from dvc_objects.fs.base import FileSystem
from dvc_objects.fs.callbacks import DEFAULT_CALLBACK
from dvc_objects.fs.path import Path
@@ -296,6 +297,11 @@ class _DvcFileSystem(AbstractFileSystem): # pylint:disable=abstract-method
key = self._get_key_from_relative(rpath)
fs_path = self._from_key(key)
fs = self.repo.fs
if self.isdir(rpath):
makedirs(lpath, exist_ok=True)
return None
try:
fs.get_file(fs_path, lpath, callback=callback, **kwargs)
return
+103
View File
@@ -1,4 +1,7 @@
import pytest
from dvc import api
from dvc.api import DvcFileSystem
from dvc.utils.fs import remove
@@ -18,3 +21,103 @@ class TestAPI:
with api.open("foo") as fd:
assert fd.read() == "foo-text"
@pytest.mark.parametrize(
"clear_cache", [True, False], ids=["cache", "no_cache"]
)
@pytest.mark.parametrize(
"fs_kwargs",
[
{},
{"url": "{path}"},
{"url": "{path}", "rev": "master"},
{"url": "file://{posixpath}"},
{"url": "file://{posixpath}", "rev": "master"},
],
ids=["current", "local", "local_rev", "git", "git_rev"],
)
def test_filesystem(
self,
M,
tmp_dir,
make_tmp_dir,
scm,
dvc,
remote,
fs_kwargs,
clear_cache,
):
tmp_dir.scm_gen({"scripts": {"script1": "script1"}}, commit="scripts")
tmp_dir.dvc_gen({"data": {"foo": "foo", "bar": "bar"}}, commit="data")
dvc.push()
if clear_cache:
remove(dvc.odb.repo.path)
if url := fs_kwargs.get("url"):
fs_kwargs["url"] = url.format(
path=tmp_dir, posixpath=tmp_dir.as_posix()
)
fs = DvcFileSystem(**fs_kwargs)
assert fs.ls("/", detail=False) == M.unordered(
"/.gitignore", "/scripts", "/data"
)
assert fs.ls("scripts", detail=False) == ["scripts/script1"]
assert fs.ls("data", detail=False) == M.unordered(
"data/foo", "data/bar"
)
data_info = M.dict(
name="/data",
type="directory",
dvc_info=M.dict(isdvc=True, isout=True),
)
scripts_info = M.dict(name="/scripts", type="directory", isexec=False)
assert sorted(fs.ls("/"), key=lambda i: i["name"]) == [
M.dict(name="/.gitignore", type="file", isexec=False),
data_info,
scripts_info,
]
with pytest.raises(FileNotFoundError):
fs.info("/not-existing-path")
assert fs.info("/") == M.dict(name="/", isexec=False, type="directory")
assert fs.info("/data") == data_info
assert fs.info("/scripts") == scripts_info
assert fs.info("/data/foo") == M.dict(name="/data/foo", type="file")
assert fs.info("/scripts/script1") == M.dict(
name="/scripts/script1", type="file"
)
assert not fs.isdvc("/")
assert fs.isdvc("/data")
assert fs.isdvc("/data/foo")
assert not fs.isdvc("/scripts")
assert not fs.isdvc("/scripts/script1")
with pytest.raises((IsADirectoryError, PermissionError)):
fs.open("data")
with pytest.raises((IsADirectoryError, PermissionError)):
fs.open("scripts")
with fs.open("/data/foo") as fobj:
assert fobj.read() == b"foo"
with fs.open("/scripts/script1") as fobj:
assert fobj.read() == b"script1"
tmp = make_tmp_dir("temp-download")
fs.get_file("data/foo", tmp / "foo")
assert (tmp / "foo").read_text() == "foo"
fs.get_file("scripts/script1", tmp / "script1")
assert (tmp / "script1").read_text() == "script1"
fs.get("/", (tmp / "all").fs_path, recursive=True)
assert (tmp / "all").read_text() == {
".gitignore": "/data\n",
"data": {"bar": "bar", "foo": "foo"},
"scripts": {"script1": "script1"},
}