api: Move to sub-package.

Split into sub-modules.

Split tests.
This commit is contained in:
David de la Iglesia Castro
2022-06-21 20:52:19 +03:00
committed by Ruslan Kuprieiev
parent b994c529a2
commit 20f69a121e
16 changed files with 670 additions and 651 deletions
+230
View File
@@ -0,0 +1,230 @@
import os
import pytest
from funcy import first, get_in
from dvc import api
from dvc.exceptions import (
FileMissingError,
OutputNotFoundError,
PathMissingError,
)
from dvc.testing.test_api import TestAPI # noqa, pylint: disable=unused-import
from dvc.testing.tmp_dir import make_subrepo
from dvc.utils.fs import remove
def test_get_url_external(tmp_dir, erepo_dir, cloud):
erepo_dir.add_remote(config=cloud.config)
with erepo_dir.chdir():
erepo_dir.dvc_gen("foo", "foo", commit="add foo")
# Using file url to force clone to tmp repo
repo_url = f"file://{erepo_dir.as_posix()}"
expected_url = (cloud / "ac/bd18db4cc2f85cedef654fccc4a4d8").url
assert api.get_url("foo", repo=repo_url) == expected_url
def test_get_url_requires_dvc(tmp_dir, scm):
tmp_dir.scm_gen({"foo": "foo"}, commit="initial")
with pytest.raises(OutputNotFoundError, match="output 'foo'"):
api.get_url("foo", repo=os.fspath(tmp_dir))
with pytest.raises(OutputNotFoundError, match="output 'foo'"):
api.get_url("foo", repo=f"file://{tmp_dir.as_posix()}")
def test_open_external(tmp_dir, erepo_dir, cloud):
erepo_dir.add_remote(config=cloud.config)
with erepo_dir.chdir():
erepo_dir.dvc_gen("version", "master", commit="add version")
with erepo_dir.branch("branch", new="True"):
# NOTE: need file to be other size for Mac
erepo_dir.dvc_gen("version", "branchver", commit="add version")
erepo_dir.dvc.push(all_branches=True)
# Remove cache to force download
remove(erepo_dir.dvc.odb.local.cache_dir)
# Using file url to force clone to tmp repo
repo_url = f"file://{erepo_dir.as_posix()}"
with api.open("version", repo=repo_url) as fd:
assert fd.read() == "master"
assert api.read("version", repo=repo_url, rev="branch") == "branchver"
def test_open_granular(tmp_dir, dvc, remote):
tmp_dir.dvc_gen({"dir": {"foo": "foo-text"}})
dvc.push()
# Remove cache to force download
remove(dvc.odb.local.cache_dir)
with api.open("dir/foo") as fd:
assert fd.read() == "foo-text"
def test_missing(tmp_dir, dvc, remote):
tmp_dir.dvc_gen("foo", "foo")
# Remove cache to make foo missing
remove(dvc.odb.local.cache_dir)
api.read("foo")
remove("foo")
with pytest.raises(FileMissingError):
api.read("foo")
def test_open_scm_controlled(tmp_dir, erepo_dir):
erepo_dir.scm_gen({"scm_controlled": "file content"}, commit="create file")
with api.open("scm_controlled", repo=os.fspath(erepo_dir)) as fd:
assert fd.read() == "file content"
def test_open_not_cached(dvc):
metric_file = "metric.txt"
metric_content = "0.6"
metric_code = "open('{}', 'w').write('{}')".format(
metric_file, metric_content
)
dvc.run(
single_stage=True,
metrics_no_cache=[metric_file],
cmd=(f'python -c "{metric_code}"'),
)
with api.open(metric_file) as fd:
assert fd.read() == metric_content
os.remove(metric_file)
with pytest.raises(FileMissingError):
api.read(metric_file)
def test_open_rev(tmp_dir, scm, dvc):
tmp_dir.scm_gen("foo", "foo", commit="foo")
(tmp_dir / "foo").write_text("bar")
with api.open("foo", rev="master") as fobj:
assert fobj.read() == "foo"
@pytest.mark.parametrize("as_external", [True, False])
@pytest.mark.parametrize(
"files, to_read",
[
({"foo": "foo"}, "foo"),
({"dir": {"foo": "foo", "bar": "bar"}}, os.path.join("dir", "foo")),
],
ids=["file", "inside-dir"],
)
def test_api_missing_local_cache_exists_on_remote(
tmp_dir, scm, dvc, as_external, remote, files, to_read
):
tmp_dir.dvc_gen(files, commit="DVC track files")
dvc.push()
# Remove cache to make foo missing
remove(dvc.odb.local.cache_dir)
remove(first(files))
repo_url = f"file://{tmp_dir.as_posix()}" if as_external else None
file_content = get_in(files, to_read.split(os.sep))
assert api.read(to_read, repo=repo_url) == file_content
@pytest.mark.parametrize("local_repo", [False, True])
def test_read_with_subrepos(tmp_dir, scm, local_cloud, local_repo):
tmp_dir.scm_gen("foo.txt", "foo.txt", commit="add foo.txt")
subrepo = tmp_dir / "dir" / "subrepo"
make_subrepo(subrepo, scm, config=local_cloud.config)
with subrepo.chdir():
subrepo.scm_gen({"lorem": "lorem"}, commit="add lorem")
subrepo.dvc_gen({"dir": {"file.txt": "file.txt"}}, commit="add dir")
subrepo.dvc_gen("dvc-file", "dvc-file", commit="add dir")
subrepo.dvc.push()
repo_path = None if local_repo else f"file://{tmp_dir.as_posix()}"
subrepo_path = os.path.join("dir", "subrepo")
assert api.read("foo.txt", repo=repo_path) == "foo.txt"
assert (
api.read(os.path.join(subrepo_path, "lorem"), repo=repo_path)
== "lorem"
)
assert (
api.read(os.path.join(subrepo_path, "dvc-file"), repo=repo_path)
== "dvc-file"
)
assert (
api.read(os.path.join(subrepo_path, "dir", "file.txt"), repo=repo_path)
== "file.txt"
)
def test_get_url_granular(tmp_dir, dvc, cloud):
tmp_dir.add_remote(config=cloud.config)
tmp_dir.dvc_gen(
{"dir": {"foo": "foo", "bar": "bar", "nested": {"file": "file"}}}
)
expected_url = (cloud / "5f" / "c28ea78987408341668eba6525ebd1.dir").url
assert api.get_url("dir") == expected_url
expected_url = (cloud / "ac" / "bd18db4cc2f85cedef654fccc4a4d8").url
assert api.get_url("dir/foo") == expected_url
expected_url = (cloud / "37" / "b51d194a7513e45b56f6524f2d51f2").url
assert api.get_url("dir/bar") == expected_url
expected_url = (cloud / "8c" / "7dd922ad47494fc02c388e12c00eac").url
assert api.get_url(os.path.join("dir", "nested", "file")) == expected_url
def test_get_url_subrepos(tmp_dir, scm, local_cloud):
subrepo = tmp_dir / "subrepo"
make_subrepo(subrepo, scm, config=local_cloud.config)
with subrepo.chdir():
subrepo.dvc_gen(
{"dir": {"foo": "foo"}, "bar": "bar"}, commit="add files"
)
subrepo.dvc.push()
expected_url = os.fspath(
local_cloud / "ac" / "bd18db4cc2f85cedef654fccc4a4d8"
)
assert api.get_url(os.path.join("subrepo", "dir", "foo")) == expected_url
expected_url = os.fspath(
local_cloud / "37" / "b51d194a7513e45b56f6524f2d51f2"
)
assert api.get_url("subrepo/bar") == expected_url
@pytest.mark.xfail(
raises=PathMissingError,
reason="https://github.com/iterative/dvc/issues/7341",
)
def test_open_from_remote(tmp_dir, erepo_dir, cloud, local_cloud):
erepo_dir.add_remote(config=cloud.config, name="other")
erepo_dir.add_remote(config=local_cloud.config, default=True)
erepo_dir.dvc_gen({"dir": {"foo": "foo content"}}, commit="create file")
erepo_dir.dvc.push(remote="other")
remove(erepo_dir.dvc.odb.local.cache_dir)
with api.open(
os.path.join("dir", "foo"),
repo=f"file://{erepo_dir.as_posix()}",
remote="other",
) as fd:
assert fd.read() == "foo content"
+130
View File
@@ -0,0 +1,130 @@
from textwrap import dedent
import pytest
from dvc import api
@pytest.fixture
def params_repo(tmp_dir, scm, dvc):
tmp_dir.gen("params.yaml", "foo: 1")
tmp_dir.gen("params.json", '{"bar": 2, "foobar": 3}')
tmp_dir.gen("other_params.json", '{"foo": {"bar": 4}}')
dvc.run(
name="stage-1",
cmd="echo stage-1",
params=["foo", "params.json:bar"],
)
dvc.run(
name="stage-2",
cmd="echo stage-2",
params=["other_params.json:foo"],
)
dvc.run(
name="stage-3",
cmd="echo stage-2",
params=["params.json:foobar"],
)
scm.add(
[
"params.yaml",
"params.json",
"other_params.json",
"dvc.yaml",
"dvc.lock",
]
)
scm.commit("commit dvc files")
tmp_dir.gen("params.yaml", "foo: 5")
scm.add(["params.yaml"])
scm.commit("update params.yaml")
def test_params_show_no_args(params_repo):
assert api.params_show() == {
"params.yaml:foo": 5,
"bar": 2,
"foobar": 3,
"other_params.json:foo": {"bar": 4},
}
def test_params_show_targets(params_repo):
assert api.params_show("params.yaml") == {"foo": 5}
assert api.params_show("params.yaml", "params.json") == {
"foo": 5,
"bar": 2,
"foobar": 3,
}
def test_params_show_deps(params_repo):
params = api.params_show(deps=True)
assert params == {
"params.yaml:foo": 5,
"bar": 2,
"foobar": 3,
"other_params.json:foo": {"bar": 4},
}
def test_params_show_stages(params_repo):
assert api.params_show(stages="stage-2") == {"foo": {"bar": 4}}
assert api.params_show() == api.params_show(
stages=["stage-1", "stage-2", "stage-3"]
)
assert api.params_show("params.json", stages="stage-3") == {"foobar": 3}
def test_params_show_revs(params_repo):
assert api.params_show(rev="HEAD~1") == {
"params.yaml:foo": 1,
"bar": 2,
"foobar": 3,
"other_params.json:foo": {"bar": 4},
}
def test_params_show_while_running_stage(tmp_dir, dvc):
(tmp_dir / "params.yaml").dump({"foo": {"bar": 1}})
(tmp_dir / "params.json").dump({"bar": 2})
tmp_dir.gen(
"merge.py",
dedent(
"""
import json
from dvc import api
with open("merged.json", "w") as f:
json.dump(api.params_show(stages="merge"), f)
"""
),
)
dvc.stage.add(
name="merge",
cmd="python merge.py",
params=["foo.bar", {"params.json": ["bar"]}],
outs=["merged.json"],
)
dvc.reproduce()
assert (tmp_dir / "merged.json").parse() == {"foo": {"bar": 1}, "bar": 2}
def test_params_show_repo(tmp_dir, erepo_dir):
with erepo_dir.chdir():
erepo_dir.scm_gen("params.yaml", "foo: 1", commit="Create params.yaml")
erepo_dir.dvc.run(
name="stage-1",
cmd="echo stage-1",
params=["foo"],
)
assert api.params_show(repo=erepo_dir) == {"foo": 1}