From 9961956c0133193d42890312df51f70a63fab66e Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Fri, 22 Feb 2019 13:47:26 +0200 Subject: [PATCH] output/deps: raise proper exception when file/dir doesn't exist From discussion on discord https://discordapp.com/channels/485586884165107732/485596304961962003/548083580052701205 Signed-off-by: Ruslan Kuprieiev --- dvc/output/base.py | 6 +++++- tests/unit/dependency/__init__.py | 0 tests/unit/dependency/gs.py | 8 ++++++++ tests/unit/dependency/hdfs.py | 8 ++++++++ tests/unit/dependency/http.py | 8 ++++++++ tests/unit/dependency/local.py | 21 +++++++++++++++++++++ tests/unit/dependency/s3.py | 8 ++++++++ tests/unit/dependency/ssh.py | 8 ++++++++ tests/unit/output/__init__.py | 0 tests/unit/output/gs.py | 8 ++++++++ tests/unit/output/hdfs.py | 8 ++++++++ tests/unit/output/local.py | 21 +++++++++++++++++++++ tests/unit/output/s3.py | 8 ++++++++ tests/unit/output/ssh.py | 8 ++++++++ 14 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 tests/unit/dependency/__init__.py create mode 100644 tests/unit/dependency/gs.py create mode 100644 tests/unit/dependency/hdfs.py create mode 100644 tests/unit/dependency/http.py create mode 100644 tests/unit/dependency/local.py create mode 100644 tests/unit/dependency/s3.py create mode 100644 tests/unit/dependency/ssh.py create mode 100644 tests/unit/output/__init__.py create mode 100644 tests/unit/output/gs.py create mode 100644 tests/unit/output/hdfs.py create mode 100644 tests/unit/output/local.py create mode 100644 tests/unit/output/s3.py create mode 100644 tests/unit/output/ssh.py diff --git a/dvc/output/base.py b/dvc/output/base.py index c956e89c9..14ad6de4e 100644 --- a/dvc/output/base.py +++ b/dvc/output/base.py @@ -5,6 +5,7 @@ from schema import Or, Optional from dvc.exceptions import DvcException from dvc.utils.compat import str +from dvc.remote.base import RemoteBase class OutputDoesNotExistError(DvcException): @@ -28,7 +29,7 @@ class OutputAlreadyTrackedError(DvcException): class OutputBase(object): IS_DEPENDENCY = False - REMOTE = None + REMOTE = RemoteBase PARAM_PATH = "path" PARAM_CACHE = "cache" @@ -152,6 +153,9 @@ class OutputBase(object): return bool(self.status()) def save(self): + if not self.exists: + raise self.DoesNotExistError(self) + self.info = self.remote.save_info(self.path_info) def commit(self): diff --git a/tests/unit/dependency/__init__.py b/tests/unit/dependency/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/unit/dependency/gs.py b/tests/unit/dependency/gs.py new file mode 100644 index 000000000..e363a0c2d --- /dev/null +++ b/tests/unit/dependency/gs.py @@ -0,0 +1,8 @@ +from dvc.dependency.gs import DependencyGS + +from tests.unit.dependency.local import TestDependencyLOCAL + + +class TestDependencyGS(TestDependencyLOCAL): + def _get_cls(self): + return DependencyGS diff --git a/tests/unit/dependency/hdfs.py b/tests/unit/dependency/hdfs.py new file mode 100644 index 000000000..0261b0403 --- /dev/null +++ b/tests/unit/dependency/hdfs.py @@ -0,0 +1,8 @@ +from dvc.dependency.hdfs import DependencyHDFS + +from tests.unit.dependency.local import TestDependencyLOCAL + + +class TestDependencyHDFS(TestDependencyLOCAL): + def _get_cls(self): + return DependencyHDFS diff --git a/tests/unit/dependency/http.py b/tests/unit/dependency/http.py new file mode 100644 index 000000000..582ef0e62 --- /dev/null +++ b/tests/unit/dependency/http.py @@ -0,0 +1,8 @@ +from dvc.dependency.http import DependencyHTTP + +from tests.unit.dependency.local import TestDependencyLOCAL + + +class TestDependencyHTTP(TestDependencyLOCAL): + def _get_cls(self): + return DependencyHTTP diff --git a/tests/unit/dependency/local.py b/tests/unit/dependency/local.py new file mode 100644 index 000000000..8beaaa9f8 --- /dev/null +++ b/tests/unit/dependency/local.py @@ -0,0 +1,21 @@ +import mock + +from dvc.stage import Stage +from dvc.dependency import DependencyLOCAL + +from tests.basic_env import TestDvc + + +class TestDependencyLOCAL(TestDvc): + def _get_cls(self): + return DependencyLOCAL + + def _get_dependency(self): + stage = Stage(self.dvc) + return self._get_cls()(stage, "path") + + def test_save_missing(self): + d = self._get_dependency() + with mock.patch.object(d.remote, "exists", return_value=False): + with self.assertRaises(d.DoesNotExistError): + d.save() diff --git a/tests/unit/dependency/s3.py b/tests/unit/dependency/s3.py new file mode 100644 index 000000000..48096a851 --- /dev/null +++ b/tests/unit/dependency/s3.py @@ -0,0 +1,8 @@ +from dvc.dependency.s3 import DependencyS3 + +from tests.unit.dependency.local import TestDependencyLOCAL + + +class TestDependencyS3(TestDependencyLOCAL): + def _get_cls(self): + return DependencyS3 diff --git a/tests/unit/dependency/ssh.py b/tests/unit/dependency/ssh.py new file mode 100644 index 000000000..ef9ae5a2c --- /dev/null +++ b/tests/unit/dependency/ssh.py @@ -0,0 +1,8 @@ +from dvc.dependency.ssh import DependencySSH + +from tests.unit.dependency.local import TestDependencyLOCAL + + +class TestDependencySSH(TestDependencyLOCAL): + def _get_cls(self): + return DependencySSH diff --git a/tests/unit/output/__init__.py b/tests/unit/output/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/unit/output/gs.py b/tests/unit/output/gs.py new file mode 100644 index 000000000..ce3d5590e --- /dev/null +++ b/tests/unit/output/gs.py @@ -0,0 +1,8 @@ +from dvc.output.gs import OutputGS + +from tests.unit.output.local import TestOutputLOCAL + + +class TestOutputGS(TestOutputLOCAL): + def _get_cls(self): + return OutputGS diff --git a/tests/unit/output/hdfs.py b/tests/unit/output/hdfs.py new file mode 100644 index 000000000..b1191accd --- /dev/null +++ b/tests/unit/output/hdfs.py @@ -0,0 +1,8 @@ +from dvc.output.hdfs import OutputHDFS + +from tests.unit.output.local import TestOutputLOCAL + + +class TestOutputHDFS(TestOutputLOCAL): + def _get_cls(self): + return OutputHDFS diff --git a/tests/unit/output/local.py b/tests/unit/output/local.py new file mode 100644 index 000000000..2a5895842 --- /dev/null +++ b/tests/unit/output/local.py @@ -0,0 +1,21 @@ +import mock + +from dvc.stage import Stage +from dvc.output import OutputLOCAL + +from tests.basic_env import TestDvc + + +class TestOutputLOCAL(TestDvc): + def _get_cls(self): + return OutputLOCAL + + def _get_output(self): + stage = Stage(self.dvc) + return self._get_cls()(stage, "path", cache=False) + + def test_save_missing(self): + o = self._get_output() + with mock.patch.object(o.remote, "exists", return_value=False): + with self.assertRaises(o.DoesNotExistError): + o.save() diff --git a/tests/unit/output/s3.py b/tests/unit/output/s3.py new file mode 100644 index 000000000..975945107 --- /dev/null +++ b/tests/unit/output/s3.py @@ -0,0 +1,8 @@ +from dvc.output.s3 import OutputS3 + +from tests.unit.output.local import TestOutputLOCAL + + +class TestOutputS3(TestOutputLOCAL): + def _get_cls(self): + return OutputS3 diff --git a/tests/unit/output/ssh.py b/tests/unit/output/ssh.py new file mode 100644 index 000000000..cd21297d8 --- /dev/null +++ b/tests/unit/output/ssh.py @@ -0,0 +1,8 @@ +from dvc.output.ssh import OutputSSH + +from tests.unit.output.local import TestOutputLOCAL + + +class TestOutputSSH(TestOutputLOCAL): + def _get_cls(self): + return OutputSSH