Files
dvc/tests/func/objects/db/test_index.py
T
Peter Rowlands (변기호) 114a07e7a4 objects: use object IDs and references instead of naive objs in status/transfer (#6360)
* objects.status: use object IDs instead of naive objects

* objects.transfer: use object IDs instead of naive objects

* objects: add ReferenceHashFile

* odb: add ReferenceObjectDB

* repo: collect used object IDs instead of naive objs

* support basic/naive fs serialization

* objects.stage: stage file objects in addition to trees

* objects: remove save(), update transfer()

* output/dep: update for osave removal

* path_info: support both url and path attributes

* status/gc: use object IDs instead of naive objs

* diff: update staging usage

* commit: update staging usage

* tests: clean staging when needed

* tests: update for save/transfer/stage changes

* dvcfs: don't allow config serialization (repofs should be used instead)

* utils: return mtime as str, size as int

* tests: update unit tests for save/stage/transfer changes

* objects: use Repo.open when needed in ReferenceHashFile

* fix ls test staging

* objects.stage: don't skip hash check when loading from state

- individual hashes will still be loaded from state if they are still
  valid

* ReferenceHashFile: serialize repo fs paths relative to repo root

* preserve state when staging

* objects.tree: skip hash computation in digest() when we have already
loaded hash from state

* always check file existence in referencehashfile

* update repofs test since stage no longer allows nonexistent files

* odb: only protect on check() if hash was verified

* staging: use unique memfs namespace for staging per dest ODB

* tests: clean full staging namespace

* refodb: preserve repofs cache dir

* repodependency: stage imports to local ODB and strict check circular
imports

* fetch: fetch staging last

* staging: make dest odb mandatory and preserve state

* refodb: cache nonlocal fs's

* fix rebase errors

* repofs: support full instantiation from fs config

* repofs: preserve subrepo factory for erepos

* tests: clarify repofs dirty file behavior
2021-08-04 13:55:52 +03:00

90 lines
2.8 KiB
Python

import pytest
from dvc.exceptions import DownloadError, UploadError
from dvc.fs.local import LocalFileSystem
from dvc.objects.db import get_index
from dvc.utils.fs import remove
from tests.utils import clean_staging
@pytest.fixture
def index(dvc, local_remote, mocker):
odb = dvc.cloud.get_remote_odb("upstream")
return get_index(odb)
def test_indexed_on_status(tmp_dir, dvc, index):
foo = tmp_dir.dvc_gen({"foo": "foo content"})[0].outs[0]
bar = tmp_dir.dvc_gen({"bar": {"baz": "baz content"}})[0].outs[0]
baz_hash = bar.obj.trie.get(("baz",)).hash_info
clean_staging()
dvc.push()
index.clear()
dvc.status(cloud=True)
assert {bar.hash_info.value, baz_hash.value} == set(index.hashes())
assert [bar.hash_info.value] == list(index.dir_hashes())
assert foo.hash_info.value not in index.hashes()
def test_indexed_on_push(tmp_dir, dvc, index):
foo = tmp_dir.dvc_gen({"foo": "foo content"})[0].outs[0]
bar = tmp_dir.dvc_gen({"bar": {"baz": "baz content"}})[0].outs[0]
baz_hash = bar.obj.trie.get(("baz",)).hash_info
clean_staging()
dvc.push()
assert {bar.hash_info.value, baz_hash.value} == set(index.hashes())
assert [bar.hash_info.value] == list(index.dir_hashes())
assert foo.hash_info.value not in index.hashes()
def test_indexed_dir_missing(tmp_dir, dvc, index):
bar = tmp_dir.dvc_gen({"bar": {"baz": "baz content"}})[0].outs[0]
index.update([bar.hash_info.value], [])
dvc.status(cloud=True)
assert not list(index.hashes())
def test_clear_on_gc(tmp_dir, dvc, index):
(foo,) = tmp_dir.dvc_gen({"dir": {"foo": "foo content"}})
dvc.push()
dvc.remove(foo.relpath)
assert list(index.hashes())
dvc.gc(workspace=True, cloud=True)
assert not list(index.hashes())
def test_clear_on_download_err(tmp_dir, dvc, index, mocker):
out = tmp_dir.dvc_gen({"dir": {"foo": "foo content"}})[0].outs[0]
dvc.push()
for _, entry in out.obj:
remove(dvc.odb.local.get(entry.hash_info).path_info)
remove(out.path_info)
assert list(index.hashes())
mocker.patch("dvc.fs.local.LocalFileSystem.upload", side_effect=Exception)
with pytest.raises(DownloadError):
dvc.pull()
assert not list(index.hashes())
def test_partial_upload(tmp_dir, dvc, index, mocker):
tmp_dir.dvc_gen({"foo": "foo content"})
tmp_dir.dvc_gen({"bar": {"baz": "baz content"}})
original = LocalFileSystem._upload
def unreliable_upload(self, from_file, to_info, name=None, **kwargs):
if "baz" in name:
raise Exception("stop baz")
return original(self, from_file, to_info, name, **kwargs)
mocker.patch.object(LocalFileSystem, "upload", unreliable_upload)
with pytest.raises(UploadError):
dvc.push()
assert not list(index.hashes())