dvc: initial unittests

Initial unittests for new design.

Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
Ruslan Kuprieiev
2018-01-01 16:52:06 +02:00
parent 0d7862e7f8
commit f47a2c7585
29 changed files with 481 additions and 1271 deletions
+38 -107
View File
@@ -1,124 +1,55 @@
import os
import shutil
import tempfile
from git import Repo
from unittest import TestCase
from dvc.config import ConfigI
from dvc.git_wrapper import GitWrapperI
from dvc.path.data_item import DataItem
from dvc.path.factory import PathFactory
from dvc.settings import Settings
from dvc.system import System
from dvc.utils import rmtree
from dvc.project import Project
class BasicEnvironment(TestCase):
def init_environment(self,
test_dir=System.get_long_path(tempfile.mkdtemp()),
curr_dir=None):
self._test_dir = System.realpath(test_dir)
self._proj_dir = 'proj'
self._test_git_dir = os.path.join(self._test_dir, self._proj_dir)
self._old_curr_dir_abs = System.realpath(os.curdir)
if os.path.exists(self._test_dir):
rmtree(self._test_dir)
class TestDir(TestCase):
FOO = 'foo'
FOO_CONTENTS = FOO
BAR = 'bar'
BAR_CONTENTS = BAR
CODE = 'code.py'
CODE_CONTENTS = 'import sys\nimport shutil\nshutil.copyfile(sys.argv[1], sys.argv[2])'
if curr_dir:
self._curr_dir = System.realpath(curr_dir)
else:
self._curr_dir = self._test_git_dir
def _pushd(self, d):
self._saved_dir = System.realpath(os.curdir)
os.chdir(d)
if not os.path.exists(self._curr_dir):
os.makedirs(self._curr_dir)
def _popd(self):
os.chdir(self._saved_dir)
self._saved_dir = None
if not os.path.isdir(self._test_git_dir):
os.makedirs(self._test_git_dir)
def create(self, name, contents):
with open(name, 'a') as f:
f.write(contents)
data_dir = os.path.join(self._test_git_dir, 'data')
cache_dir = os.path.join(self._test_git_dir, ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME)
state_dir = os.path.join(self._test_git_dir, ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, 'data')
os.makedirs(data_dir)
os.makedirs(cache_dir)
os.makedirs(state_dir)
os.chdir(self._curr_dir)
def setUp(self):
self._root_dir = System.get_long_path(tempfile.mkdtemp())
self._pushd(self._root_dir)
self.create(self.FOO, self.FOO_CONTENTS)
self.create(self.BAR, self.BAR_CONTENTS)
self.create(self.CODE, self.CODE_CONTENTS)
def tearDown(self):
if self._old_curr_dir_abs:
os.chdir(self._old_curr_dir_abs)
if self._test_git_dir:
rmtree(self._test_dir)
pass
self._popd()
shutil.rmtree(self._root_dir)
class DirHierarchyEnvironment(BasicEnvironment):
def init_environment(self,
test_dir=os.path.join(os.path.sep, 'tmp', 'ntx_unit_test'),
curr_dir=None,
commit='abc12345'):
''' Creates data environment with data, cache and state dirs.
data/
file1.txt --> ../cache/file1.txt_abc123
dir1/
file2.txt --> ../../cache/dir1/file2.txt_abc123
file3.txt --> ../../cache/dir1/file3.txt_abc123
dir11/
file4.txt --> ../../../cache/dir1/dir11/file4.txt_abc123
dir2/
file5.txt --> ../../cache/dir2/file5.txt_abc123
file6.txt --> an actual file
'''
class TestGit(TestDir):
def setUp(self):
super(TestGit, self).setUp()
self.git = Repo.init()
self.git.index.add([self.CODE])
self.git.index.commit('add code')
BasicEnvironment.init_environment(self, test_dir, curr_dir)
self._commit = commit
self._git = GitWrapperI(git_dir=self._test_git_dir, commit=self._commit)
self._config = ConfigI('data')
self.path_factory = PathFactory(self._git, self._config)
self.settings = Settings([], self._git, self._config)
self.dir1 = 'dir1'
self.dir11 = os.path.join('dir1', 'dir11')
self.dir2 = 'dir2'
self.create_dirs(self.dir1)
self.create_dirs(self.dir11)
self.create_dirs(self.dir2)
self.file1, self.cache1, self.state1 = self.crate_data_item('file1.txt')
self.file2, self.cache2, self.state2 = self.crate_data_item(os.path.join(self.dir1, 'file2.txt'))
self.file3, self.cache3, self.state3 = self.crate_data_item(os.path.join(self.dir1, 'file3.txt'))
self.file4, self.cache4, self.state4 = self.crate_data_item(os.path.join(self.dir11, 'file4.txt'))
self.file5, self.cache5, self.state5 = self.crate_data_item(os.path.join(self.dir2, 'file5.txt'))
self.file6, self.cache6, self.state6 = self.crate_data_item(os.path.join(self.dir2, 'file6.txt'),
cache_file=False)
pass
@staticmethod
def create_content_file(file, content='some test'):
fd = open(file, 'w+')
fd.write(content)
fd.close()
def crate_data_item(self, data_file, cache_file=True, content='random text'):
file_result = os.path.join('data', data_file)
state_result = os.path.join(ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, file_result + DataItem.STATE_FILE_SUFFIX)
dummy_md5 = os.path.basename(data_file) + DataItem.CACHE_FILE_SEP + self._commit
self.create_content_file(state_result, '{"Md5" : "' + dummy_md5 + '", "Command" : "run", "Cwd" : "dir"}')
if cache_file:
cache_result = os.path.join(ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME, dummy_md5)
self.create_content_file(cache_result, content)
System.hardlink(cache_result, file_result)
else:
cache_result = None
self.create_content_file(file_result, content)
return file_result, cache_result, state_result
def create_dirs(self, dir):
os.makedirs(os.path.join('data', dir))
os.makedirs(os.path.join(ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, 'data', dir))
class TestDvc(TestGit):
def setUp(self):
super(TestDvc, self).setUp()
self.dvc = Project.init(self._root_dir)
self.dvc.logger.be_verbose()
+45
View File
@@ -0,0 +1,45 @@
import os
import shutil
import filecmp
from dvc.data_cloud import file_md5
from dvc.stage import Stage, OutputNoCacheError, OutputOutsideOfRepoError
from dvc.stage import OutputDoesNotExistError, OutputIsNotFileError
from dvc.project import StageNotFoundError
from tests.basic_env import TestDvc
class TestAdd(TestDvc):
def test(self):
md5 = file_md5(self.FOO)[0]
stage = self.dvc.add(self.FOO)
self.assertIsInstance(stage, Stage)
self.assertTrue(os.path.isfile(stage.path))
self.assertEqual(len(stage.outs), 1)
self.assertEqual(len(stage.deps), 0)
self.assertTrue(stage.locked)
self.assertEqual(stage.cmd, None)
self.assertEqual(stage.outs[0].md5, md5)
class TestAddNonExistentFile(TestDvc):
def test(self):
with self.assertRaises(OutputDoesNotExistError) as cx:
self.dvc.add('non_existent_file')
class TestAddFileOutsideOfRepo(TestDvc):
def test(self):
with self.assertRaises(OutputOutsideOfRepoError) as cx:
self.dvc.add(os.path.join(os.path.dirname(self.dvc.root_dir), self.FOO))
class TestAddDirectory(TestDvc):
def test(self):
dname = 'directory'
os.mkdir(dname)
with self.assertRaises(OutputIsNotFileError) as cx:
self.dvc.add(dname)
+24
View File
@@ -0,0 +1,24 @@
import os
from dvc.cache import Cache
from tests.basic_env import TestDvc
class TestCache(TestDvc):
def setUp(self):
super(TestCache, self).setUp()
self.cache1 = os.path.join(self.dvc.cache.cache_dir, '1')
self.cache2 = os.path.join(self.dvc.cache.cache_dir, '2')
self.create(self.cache1, '1')
self.create(self.cache2, '2')
def test_all(self):
flist = Cache(self.dvc.dvc_dir).all()
self.assertEquals(len(flist), 2)
self.assertTrue(self.cache1 in flist)
self.assertTrue(self.cache2 in flist)
def test_get(self):
cache = Cache(self.dvc.dvc_dir).get(os.path.basename(self.cache1))
self.assertEquals(cache, self.cache1)
+30
View File
@@ -0,0 +1,30 @@
import os
import shutil
import filecmp
from dvc.data_cloud import file_md5
from dvc.stage import Stage, OutputNoCacheError, OutputOutsideOfRepoError
from dvc.stage import OutputDoesNotExistError, OutputIsNotFileError
from dvc.project import StageNotFoundError
from tests.basic_env import TestDvc
class TestCheckout(TestDvc):
def test_checkout(self):
cmd = 'python {} {} {}'.format(self.CODE, self.FOO, 'out')
deps = [self.FOO]
deps_no_cache = [self.CODE]
outs = [os.path.join(self.dvc.root_dir, 'out')]
outs_no_cache = []
locked = False
fname = os.path.join(self.dvc.root_dir, 'out.dvc')
cwd = os.curdir
stage = self.dvc.run(cmd, deps, deps_no_cache, outs, outs_no_cache, locked, fname, cwd)
shutil.copy(self.FOO, 'orig')
os.unlink(self.FOO)
self.dvc.checkout()
self.assertTrue(os.path.isfile(self.FOO))
self.assertTrue(filecmp.cmp(self.FOO, 'orig'))
-159
View File
@@ -1,159 +0,0 @@
import os
from dvc.command.remove import CmdRemove
from tests.basic_env import DirHierarchyEnvironment
class TestCmdRemove(DirHierarchyEnvironment):
def setUp(self):
DirHierarchyEnvironment.init_environment(self)
def test_file_by_file_removal(self):
self.settings.parse_args('remove --keep-in-cloud')
cmd = CmdRemove(self.settings)
dir1_dvc_name = os.path.join('data', self.dir1)
self.assertTrue(os.path.exists(dir1_dvc_name))
cmd.remove_dir(dir1_dvc_name)
self.assertFalse(os.path.exists(dir1_dvc_name))
def test_remove_deep_dir(self):
self.settings.parse_args('remove --keep-in-cloud --recursive')
cmd = CmdRemove(self.settings)
dir1_dvc_name = os.path.join('data', self.dir1)
self.assertTrue(os.path.exists(dir1_dvc_name))
cmd.remove_dir(dir1_dvc_name)
self.assertFalse(os.path.exists(dir1_dvc_name))
def test_not_recursive_removal(self):
self.settings.parse_args('remove --keep-in-cloud')
cmd = CmdRemove(self.settings)
dir1_dvc_name = os.path.join('data', self.dir1)
self.assertTrue(os.path.exists(dir1_dvc_name))
cmd.remove_dir(dir1_dvc_name)
pass
def test_data_dir_removal(self):
self.settings.parse_args('remove --keep-in-cloud --recursive')
cmd = CmdRemove(self.settings)
data_dir = 'data'
self.assertTrue(os.path.exists(data_dir))
cmd.remove_dir(data_dir)
pass
class TestRemoveDataItem(DirHierarchyEnvironment):
def setUp(self):
DirHierarchyEnvironment.init_environment(self)
def test_remove_data_instance(self):
self.settings.parse_args('remove --keep-in-cloud')
cmd = CmdRemove(self.settings)
self.assertTrue(os.path.isfile(self.file1))
self.assertTrue(os.path.isfile(self.cache1))
self.assertTrue(os.path.isfile(self.state1))
cmd.remove_file(self.file1)
self.assertFalse(os.path.exists(self.file1))
self.assertFalse(os.path.exists(self.cache1))
self.assertFalse(os.path.exists(self.state1))
def test_keep_cache(self):
self.settings.parse_args('remove --keep-in-cloud --keep-in-cache')
cmd = CmdRemove(self.settings)
self.assertTrue(os.path.isfile(self.file1))
self.assertTrue(os.path.isfile(self.cache1))
self.assertTrue(os.path.isfile(self.state1))
cmd.remove_file(self.file1)
self.assertFalse(os.path.exists(self.file1))
self.assertTrue(os.path.exists(self.cache1))
self.assertFalse(os.path.exists(self.state1))
def test_remove_data_instance_without_cache(self):
self.settings.parse_args('remove --keep-in-cloud')
cmd = CmdRemove(self.settings)
self.assertTrue(os.path.isfile(self.file6))
self.assertIsNone(self.cache6)
self.assertTrue(os.path.exists(self.state6))
self.assertTrue(os.path.isfile(self.state6))
cmd.remove_file(self.file6)
self.assertFalse(os.path.exists(self.file6))
class TestRemoveEndToEnd(DirHierarchyEnvironment):
def setUp(self):
DirHierarchyEnvironment.init_environment(self)
def test_end_to_end_with_no_error(self):
dir11_full = os.path.join('data', self.dir11)
dir2_full = os.path.join('data', self.dir2)
self.settings.parse_args('remove --no-git-actions --keep-in-cloud --recursive {} {}'.format(dir11_full, self.file5))
cmd = CmdRemove(self.settings)
self.assertTrue(os.path.exists(dir11_full))
self.assertTrue(os.path.exists(self.file5))
self.assertTrue(os.path.exists(dir2_full))
self.assertTrue(os.path.exists(self.file1))
self.assertTrue(cmd.remove_all())
self.assertFalse(os.path.exists(dir11_full))
self.assertFalse(os.path.exists(self.file5))
self.assertTrue(os.path.exists(dir2_full))
self.assertTrue(os.path.exists(self.file1))
def test_run(self):
dir11_full = os.path.join('data', self.dir11)
dir2_full = os.path.join('data', self.dir2)
self.settings.parse_args('remove --no-git-actions --keep-in-cloud --recursive {} {}'.format(dir11_full, self.file5))
cmd = CmdRemove(self.settings)
self.assertTrue(os.path.exists(dir11_full))
self.assertTrue(os.path.exists(self.file5))
self.assertTrue(os.path.exists(dir2_full))
self.assertTrue(os.path.exists(self.file1))
self.assertEqual(cmd.run(), 0)
self.assertFalse(os.path.exists(dir11_full))
self.assertFalse(os.path.exists(self.file5))
self.assertTrue(os.path.exists(dir2_full))
self.assertTrue(os.path.exists(self.file1))
class TestRemoveEndToEndWithAnError(DirHierarchyEnvironment):
def setUp(self):
DirHierarchyEnvironment.init_environment(self)
def test(self):
dir11_full = os.path.join('data', self.dir11)
dir2_full = os.path.join('data', self.dir2)
self.settings.parse_args('remove --no-git-actions --keep-in-cloud --recursive {} {}'.format(dir11_full, self.file5))
cmd = CmdRemove(self.settings)
self.assertTrue(os.path.exists(dir11_full))
self.assertTrue(os.path.exists(self.file5))
self.assertTrue(os.path.exists(dir2_full))
self.assertTrue(os.path.exists(self.file1))
self.assertTrue(os.path.exists(self.file6))
self.assertTrue(cmd.remove_all())
self.assertFalse(os.path.exists(dir11_full))
self.assertFalse(os.path.exists(self.file5))
self.assertTrue(os.path.exists(dir2_full))
self.assertTrue(os.path.exists(self.file1))
-100
View File
@@ -1,100 +0,0 @@
import os
import tempfile
from unittest import TestCase
from dvc.command.run import CmdRun, RunError
from dvc.config import ConfigI
from dvc.executor import Executor
from dvc.path.data_item import DataItem
from dvc.path.factory import PathFactory
from dvc.git_wrapper import GitWrapper
from dvc.settings import Settings
from dvc.system import System
from dvc.utils import rmtree
class RunBasicTest(TestCase):
def setUp(self):
self.test_dir = System.get_long_path(tempfile.mkdtemp())
self._old_curr_dir_abs = System.realpath(os.curdir)
self.tearDown()
os.mkdir(self.test_dir)
os.chdir(self.test_dir)
os.mkdir('data')
os.mkdir(ConfigI.CONFIG_DIR)
os.mkdir(os.path.join(ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME))
os.mkdir(os.path.join(ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME))
self.init_git_repo()
self.git = GitWrapper()
self.config = ConfigI('data')
self.path_factory = PathFactory(self.git, self.config)
self.settings = Settings('run cmd', self.git, self.config)
pass
def init_git_repo(self):
Executor.exec_cmd_only_success(['git', 'init'])
msg = os.path.join(ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME)
msg += '\n'
msg += os.path.join(ConfigI.CONFIG_DIR, '.' + ConfigI.CONFIG + '.lock')
self.create_file('.gitignore', msg)
Executor.exec_cmd_only_success(['git', 'add', '.gitignore'])
Executor.exec_cmd_only_success(['git', 'commit', '-m', '"Init test repo"'])
@staticmethod
def create_file(file2, content='random text'):
fd = open(file2, 'w+')
fd.write(content)
fd.close()
def tearDown(self):
rmtree(self.test_dir)
os.chdir(self._old_curr_dir_abs)
class RunTwoFilesBase(RunBasicTest):
def setUp(self):
super(RunTwoFilesBase, self).setUp()
self.input_param_file = os.path.join('data', 'extra_input')
self.extra_output_file = os.path.join('data', 'extra_output')
self.settings.parse_args('run --input {} --output {} cmd'.format(self.input_param_file, self.extra_output_file))
self.settings._args = []
cmd_run = CmdRun(self.settings)
self.file_name1 = os.path.join('data', 'file1')
self.file_name2 = os.path.join('data', 'file2')
self.state_objs = cmd_run.run_command(['echo', 'test'], [], [], shell=True,
stdout=self.file_name1,
stderr=self.file_name2)
self.state_file_name1 = os.path.join(ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, self.file_name1 + DataItem.STATE_FILE_SUFFIX)
self.state_file_name2 = os.path.join(ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, self.file_name2 + DataItem.STATE_FILE_SUFFIX)
self.state_file1 = None
self.state_file2 = None
for s in self.state_objs:
if s.file == self.state_file_name1:
self.state_file1 = s
elif s.file == self.state_file_name2:
self.state_file2 = s
pass
class TestRunStateFiles(RunTwoFilesBase):
def test(self):
names = [x.file for x in self.state_objs]
self.assertEqual({self.state_file_name1, self.state_file_name2}, set(names))
class TestRunExtraInExtraOutFiles(RunTwoFilesBase):
def test(self):
self.assertIsNotNone(self.state_file1)
self.assertEqual(self.state_file1.input_files, [self.input_param_file])
output_set = {self.file_name1, self.file_name2, self.extra_output_file}
self.assertEqual(set(self.state_file1.output_files), output_set)
+14 -11
View File
@@ -1,4 +1,5 @@
import os
import configparser
from unittest import TestCase
import mock
@@ -15,15 +16,18 @@ except ImportError:
# Python 3
builtin_module_name = 'builtins'
from dvc.config import Config
from dvc.data_cloud import DataCloud
from dvc.settings import Settings
class TestConfigTest(TestCase):
def setUp(self):
pass
def _conf(self, s):
c = configparser.SafeConfigParser()
c.readfp(s)
return c
def storage_path_hierarchy_test(self):
""" StoragePath should be read first from global and then from cloud section """
@@ -41,9 +45,8 @@ class TestConfigTest(TestCase):
"StoragePath = googlesb/google_storage_path"
)
s = StringIO('\n'.join(c))
conf = Config(s, conf_pseudo_file = s)
settings = Settings(None, None, conf)
cloud = DataCloud(settings)
conf = self._conf(s)
cloud = DataCloud(conf)
self.assertEqual(cloud.typ, 'AWS')
self.assertEqual(cloud._cloud.storage_bucket, 'globalsb')
self.assertEqual(cloud._cloud.storage_prefix, 'global_storage_path')
@@ -61,8 +64,8 @@ class TestConfigTest(TestCase):
"StoragePath = googlesb/google_storage_path"
)
s = StringIO('\n'.join(c))
conf = Config(s, conf_pseudo_file=s)
cloud = DataCloud(Settings(None, None, conf))
conf = self._conf(s)
cloud = DataCloud(conf)
self.assertEqual(cloud.typ, 'AWS')
self.assertEqual(cloud._cloud.storage_bucket, 'awssb')
self.assertEqual(cloud._cloud.storage_prefix, 'aws_storage_path')
@@ -100,8 +103,8 @@ class TestConfigTest(TestCase):
patcher = mock.patch(builtin_module_name + '.open', side_effect=self.mocked_open_aws_default_credentials)
# patcher.start()
conf = Config(s, conf_pseudo_file=s)
cloud = DataCloud(Settings(None, None, conf))
conf = self._conf(s)
cloud = DataCloud(conf)
aws_creds = cloud._cloud._get_credentials()
patcher.stop()
@@ -131,8 +134,8 @@ class TestConfigTest(TestCase):
patcher = mock.patch(builtin_module_name + '.open', side_effect=self.mocked_open_aws_default_credentials)
patcher.start()
conf = Config(s, conf_pseudo_file=s)
cloud = DataCloud(Settings(None, None, conf))
conf = self._conf(s)
cloud = DataCloud(conf)
aws_creds = cloud._cloud._get_credentials()
patcher.stop()
-196
View File
@@ -1,196 +0,0 @@
import os
from dvc.config import ConfigI
from dvc.git_wrapper import GitWrapperI
from dvc.path.data_item import DataDirError, DataItemError, DataItem
from dvc.path.factory import PathFactory
from dvc.system import System
from tests.basic_env import BasicEnvironment
class TestDataFileObjBasic(BasicEnvironment):
def setUp(self):
BasicEnvironment.init_environment(self, test_dir=os.path.join(os.path.sep, 'tmp', 'ntx_unit_test'))
git = GitWrapperI(git_dir=self._test_git_dir, commit='ad45ba8')
config = ConfigI()
file = os.path.join('data', 'file.txt')
self.cache_file_full_path = os.path.join(self._test_git_dir, ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME, 'file.txt_ad45ba8')
self._data_path = DataItem(file, git, config, cache_file=self.cache_file_full_path)
pass
def test_data_file(self):
data_file_full_path = os.path.join(self._test_git_dir, 'data', 'file.txt')
self.assertEqual(self._data_path.data.abs, data_file_full_path)
def test_cache_file(self):
self.assertEqual(self._data_path.cache.abs, self.cache_file_full_path)
def test_state_file(self):
state_file_full_path = os.path.join(self._test_git_dir, ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, 'data', 'file.txt.state')
self.assertEqual(self._data_path.state.abs, state_file_full_path)
class TestDataItemWithGivenCache(BasicEnvironment):
def setUp(self):
BasicEnvironment.init_environment(self, test_dir=os.path.join(os.path.sep, 'tmp', 'ntx_unit_test'))
self._git = GitWrapperI(git_dir=self._test_git_dir, commit='ad45ba8')
self._config = ConfigI('data')
self._file = os.path.join('data', 'file.txt')
self._cache = os.path.join(ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME, 'file.txt_abcd')
self._data_item = DataItem(self._file, self._git, self._config, self._cache)
pass
def test_basic(self):
self.assertEqual(self._data_item.data.relative, self._file)
self.assertEqual(self._data_item.cache.relative, self._cache)
class TestDeepDataItemWithGivenCache(BasicEnvironment):
def setUp(self):
BasicEnvironment.init_environment(self, test_dir=os.path.join(os.path.sep, 'tmp', 'ntx_unit_test'))
self._git = GitWrapperI(git_dir=self._test_git_dir, commit='ad45ba8')
self._config = ConfigI('data')
self._file = os.path.join('data', 'dir1', 'file.txt')
self._cache = os.path.join(ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME, 'dir1', 'file.txt_abcd')
self._data_item = DataItem(self._file, self._git, self._config, self._cache)
pass
def test_basic(self):
self.assertEqual(self._data_item.data.relative, self._file)
self.assertEqual(self._data_item.cache.relative, self._cache)
class TestPathFactory(BasicEnvironment):
def setUp(self):
BasicEnvironment.init_environment(self, test_dir=os.path.join(os.path.sep, 'tmp', 'ntx_unit_test'))
git = GitWrapperI(git_dir=self._test_git_dir, commit='ad45ba8')
config = ConfigI()
self.path_factory = PathFactory(git, config)
self.data_file = os.path.join('data', 'file.txt')
dummy_md5 = 'fsymlinc.txt'
self.cache_file = os.path.join(ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME, dummy_md5)
self.state_file = os.path.join(ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, 'data', 'file.txt' + DataItem.STATE_FILE_SUFFIX)
with open(self.cache_file, 'w+') as fd:
fd.write('some text')
with open(self.state_file, 'w+') as fd:
fd.write('{"Md5" : "' + dummy_md5 + '", "Command" : "run", "Cwd" : "dir"}')
os.chdir('data')
System.hardlink(os.path.join('..', self.cache_file), 'file.txt')
os.chdir('..')
pass
def test_data_file_factory(self):
data_path = self.path_factory.data_item(self.data_file)
self.assertEqual(data_path.data.dvc, self.data_file)
indirect_file_path = os.path.join('..', self._proj_dir, self.data_file)
data_path_indirect = self.path_factory.data_item(indirect_file_path)
self.assertEqual(data_path_indirect.data.dvc, self.data_file)
pass
def test_data_hardlink_factory(self):
data_path = self.path_factory.existing_data_item(self.data_file)
self.assertEqual(data_path.cache.dvc, self.cache_file)
pass
def test_data_hardlink_factory_cache(self):
data_path = self.path_factory.existing_data_item(self.data_file)
self.assertEqual(data_path.data.dvc, self.data_file)
pass
def test_data_hardlink_factory_exception(self):
with self.assertRaises(DataItemError):
self.path_factory.existing_data_item(self.cache_file)
pass
def test_data_path(self):
file = os.path.join('data', 'file1')
path = self.path_factory.path(file)
self.assertEqual(path.dvc, file)
self.assertEqual(path.relative, file)
self.assertTrue(path.abs.endswith(file))
class TestDataPathInDataDir(BasicEnvironment):
def setUp(self):
BasicEnvironment.init_environment(self, os.path.join(os.path.sep, 'tmp', 'ntx_unit_test'))
git = GitWrapperI(git_dir=self._test_git_dir, commit='eeeff8f')
self.data_dir = 'da'
config = ConfigI()
self.path_factory = PathFactory(git, config)
deep_path = os.path.join(self.data_dir, 'dir1', 'd2', 'file.txt')
self.cache_file = os.path.join(self._test_git_dir, ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME, 'dir1', 'd2', 'file.txt_eeeff8f')
self.data_path = self.path_factory.data_item(deep_path, cache_file=self.cache_file)
pass
def test_data_file(self):
target = os.path.join(self._test_git_dir, 'da', 'dir1', 'd2', 'file.txt')
self.assertEqual(self.data_path.data.abs, target)
def test_cache_file(self):
self.assertEqual(self.data_path.cache.abs, self.cache_file)
def test_state_file(self):
target = os.path.join(self._test_git_dir, ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, 'da', 'dir1', 'd2', 'file.txt.state')
self.assertEqual(self.data_path.state.abs, target)
class TestDataFileObjLongPath(BasicEnvironment):
def setUp(self):
curr_dir = os.path.join(os.path.sep, 'tmp', 'ntx_unit_test', 'proj', 'mydir', 'dd3')
BasicEnvironment.init_environment(self,
os.path.join(os.path.sep, 'tmp', 'ntx_unit_test'),
curr_dir)
self._git = GitWrapperI(git_dir=self._test_git_dir, commit='123ed8')
self._config = ConfigI('data')
self.path_factory = PathFactory(self._git, self._config)
self.cache_file = os.path.join(self._test_git_dir, ConfigI.CONFIG_DIR, ConfigI.CACHE_DIR_NAME, 'file1.txt_123ed8')
self.data_path = self.path_factory.data_item(os.path.join('..', '..', 'data', 'file1.txt'), cache_file=self.cache_file)
pass
def test_data_file(self):
target = os.path.join(self._test_git_dir, 'data', 'file1.txt')
self.assertEqual(self.data_path.data.abs, target)
def test_cache_file(self):
self.assertEqual(self.data_path.cache.abs, self.cache_file)
def test_state_file(self):
target = os.path.join(self._test_git_dir, ConfigI.CONFIG_DIR, ConfigI.STATE_DIR_NAME, 'data', 'file1.txt.state')
self.assertEqual(self.data_path.state.abs, target)
class RunOutsideGitRepoTest(BasicEnvironment):
def setUp(self):
curr_dir = os.path.join(os.path.sep, 'tmp')
BasicEnvironment.init_environment(self,
os.path.join(os.path.sep, 'tmp', 'ntx_unit_test'),
curr_dir)
def test_outside_git_dir(self):
git = GitWrapperI(git_dir=self._test_git_dir, commit='123ed8')
config = ConfigI('data')
path_factory = PathFactory(git, config)
with self.assertRaises(DataDirError):
path_factory.data_item('file.txt')
pass
-70
View File
@@ -1,70 +0,0 @@
import os
import shutil
from unittest import TestCase
from dvc.path.path import Path
from dvc.git_wrapper import GitWrapperI
from dvc.system import System
class TestDvcPathTest(TestCase):
def setUp(self):
self.curr_dir = System.realpath('.')
self.test_dir = System.realpath('/tmp/ntx_unit_test/dvc_path')
self.tearDown()
os.makedirs(os.path.join(self.test_dir, 'data'))
os.makedirs(os.path.join(self.test_dir, 'code', 'lib'))
os.makedirs(os.path.join(self.test_dir, 'd1', 'd2', 'dir3', 'd4', 'dir5'))
self._git = GitWrapperI(self.test_dir)
def tearDown(self):
os.chdir(self.curr_dir)
shutil.rmtree(self.test_dir, ignore_errors=True)
def _validate_dvc_path(self, path, dvc_file_name, relative_file_name):
self.assertEqual(path.dvc, dvc_file_name)
self.assertEqual(path.filename, os.path.basename(dvc_file_name))
self.assertEqual(path.relative, relative_file_name)
self.assertTrue(os.path.isabs(path.abs))
self.assertTrue(path.abs.endswith(dvc_file_name))
def basic_test(self):
os.chdir(self.test_dir)
file = os.path.join('data', 'file.txt')
path = Path(file, self._git)
self._validate_dvc_path(path, file, file)
pass
def from_dir_test(self):
os.chdir(os.path.join(self.test_dir, 'code'))
file_dvc_path = os.path.join('data', 'file1.txt')
file_relative_path = os.path.join('..', file_dvc_path)
path = Path(file_relative_path, self._git)
self._validate_dvc_path(path, file_dvc_path, file_relative_path)
pass
def from_deep_dirs_test(self):
deep_dir = os.path.join('d1', 'd2', 'dir3')
os.chdir(os.path.join(self.test_dir, deep_dir))
file_dvc = os.path.join('code', 'lib', 'context_switcher_structs.asm')
file_relative = os.path.join('..', '..', '..', file_dvc)
path = Path(file_relative, self._git)
self._validate_dvc_path(path, file_dvc, file_relative)
pass
def go_deeper_test(self):
deep_dir = os.path.join('d1', 'd2', 'dir3')
os.chdir(os.path.join(self.test_dir, deep_dir))
file_relative_path = os.path.join(deep_dir, 'd4', 'dir5', 'rawdata.tsv')
file_dvc_path = os.path.join(deep_dir, file_relative_path)
path = Path(file_relative_path, self._git)
self._validate_dvc_path(path, file_dvc_path, file_relative_path)
pass
+32
View File
@@ -0,0 +1,32 @@
import os
import shutil
import filecmp
from dvc.data_cloud import file_md5
from dvc.stage import Stage, OutputNoCacheError, OutputOutsideOfRepoError
from dvc.stage import OutputDoesNotExistError, OutputIsNotFileError
from dvc.project import StageNotFoundError
from tests.basic_env import TestDvc
class TestGC(TestDvc):
def test_gc(self):
stage = self.dvc.add(self.FOO)
good_cache = self.dvc.cache.all()
bad_cache = []
for i in ['1', '2', '3']:
path = os.path.join(self.dvc.cache.cache_dir, i)
self.create(path, i)
bad_cache.append(path)
self.dvc.gc()
self.assertTrue(os.path.isdir(self.dvc.cache.cache_dir))
for c in bad_cache:
self.assertFalse(os.path.exists(c))
for c in good_cache:
self.assertTrue(os.path.exists(c))
self.assertTrue(os.path.isfile(c))
-119
View File
@@ -1,119 +0,0 @@
import os
import tempfile
import filecmp
from copy import copy
from dvc.command.import_file import CmdImportFile, ImportFileError
from tests.basic_env import DirHierarchyEnvironment
class TestCmdRemove(DirHierarchyEnvironment):
def setUp(self):
DirHierarchyEnvironment.init_environment(self)
def test_import_file_to_dir(self):
with tempfile.NamedTemporaryFile(mode='w') as temp:
content = 'Some data'
temp.write(content)
temp.flush()
dir = os.path.join('data', self.dir1)
settings = copy(self.settings)
settings.parse_args('import {} {}'.format(temp.name, dir))
cmd = CmdImportFile(settings)
cmd.run()
dvc_name = os.path.join(dir, os.path.basename(temp.name))
data_item = self.path_factory.existing_data_item(dvc_name)
self.assertTrue(os.path.exists(data_item.data.relative))
self.assertTrue(filecmp.cmp(data_item.data.relative, data_item.cache.relative))
self.assertEqual(open(data_item.data.relative).read(), content)
self.assertTrue(os.path.exists(data_item.cache.relative))
self.assertEqual(open(data_item.cache.relative).read(), content)
self.assertTrue(os.path.exists(data_item.state.relative))
pass
def test_import_file_to_file(self):
with tempfile.NamedTemporaryFile(mode='w') as temp:
content = 'Some data'
temp.write(content)
temp.flush()
target_file_name = 'targ.txt'
target_file = os.path.join('data', self.dir1, target_file_name)
settings = copy(self.settings)
settings.parse_args('import {} {}'.format(temp.name, target_file))
cmd = CmdImportFile(settings)
cmd.run()
self.assertTrue(os.path.exists(target_file))
self.assertTrue(open(target_file).read(), content)
pass
def test_import_to_existing_dir(self):
with tempfile.NamedTemporaryFile(mode='w') as temp:
content = 'Some data'
temp.write(content)
temp.flush()
dir = os.path.join('data', self.dir11)
settings = copy(self.settings)
settings.parse_args('import {} {}'.format(temp.name, dir))
cmd = CmdImportFile(settings)
cmd.run()
dvc_name = os.path.join(dir, os.path.basename(temp.name))
self.assertTrue(os.path.exists(dvc_name))
self.assertTrue(open(dvc_name).read(), content)
pass
def test_import_to_not_existing_dir(self):
with tempfile.NamedTemporaryFile(mode='w') as temp:
content = 'Some data'
temp.write(content)
temp.flush()
dir = os.path.join('data', self.dir1, 'not_existing_dir/')
settings = copy(self.settings)
settings.parse_args('import {} {}'.format(temp.name, dir))
cmd = CmdImportFile(settings)
with self.assertRaises(ImportFileError):
cmd.run()
dvc_name = os.path.join(dir, os.path.basename(temp.name))
self.assertFalse(os.path.exists(dir))
self.assertFalse(os.path.exists(dvc_name))
pass
def test_multiple_import(self):
with tempfile.NamedTemporaryFile(mode='w') as temp1,\
tempfile.NamedTemporaryFile(mode='w') as temp2:
content = 'Some data'
temp1.write(content)
temp1.flush()
temp2.write(content)
temp2.flush()
dir = os.path.join('data', self.dir11)
settings = copy(self.settings)
settings.parse_args('import {} {} {}'.format(temp1.name, temp2.name, dir))
cmd = CmdImportFile(settings)
cmd.run()
dvc_name1 = os.path.join(dir, os.path.basename(temp1.name))
dvc_name2 = os.path.join(dir, os.path.basename(temp2.name))
self.assertTrue(os.path.exists(dvc_name1))
self.assertTrue(open(dvc_name1).read(), content)
self.assertTrue(os.path.exists(dvc_name2))
self.assertTrue(open(dvc_name2).read(), content)
pass
+19
View File
@@ -0,0 +1,19 @@
from dvc.lock import Lock
from tests.basic_env import TestDvc
class TestLock(TestDvc):
def test_lock(self):
lock = Lock(self.dvc.dvc_dir)
lock.lock()
self.assertTrue(lock._lock.exists())
self.assertTrue(lock._lock.acquired)
lock.unlock()
self.assertFalse(lock._lock.acquired)
def test_with(self):
lock = Lock(self.dvc.dvc_dir)
with lock:
self.assertTrue(lock._lock.acquired)
self.assertFalse(lock._lock.acquired)
+28
View File
@@ -0,0 +1,28 @@
import os
from dvc.stage import Stage, OutputOutsideOfRepoError
from dvc.project import StageNotFoundError
from tests.basic_env import TestDvc
class TestRemove(TestDvc):
def test(self):
stage = self.dvc.add(self.FOO)
stages_removed = self.dvc.remove(self.FOO)
self.assertEqual(len(stages_removed), 1)
self.assertIsInstance(stages_removed[0], Stage)
self.assertEqual(stage.path, stages_removed[0].path)
class TestRemoveNonExistentFile(TestDvc):
def test(self):
with self.assertRaises(StageNotFoundError) as cx:
self.dvc.remove('non_existent_file')
class TestRemoveFileOutsideOfRepo(TestDvc):
def test(self):
with self.assertRaises(OutputOutsideOfRepoError) as cx:
self.dvc.remove(os.path.join(os.path.dirname(self.dvc.root_dir), self.FOO))
-98
View File
@@ -1,98 +0,0 @@
import os
import shutil
import subprocess
import tempfile
from unittest import TestCase
from dvc.config import ConfigI
from dvc.path.factory import PathFactory
from dvc.git_wrapper import GitWrapperI
from dvc.repository_change import RepositoryChange
from dvc.settings import Settings
from dvc.system import System
class BasicTestRepositoryChange(TestCase):
def setUp(self):
self.test_dir = System.get_long_path(tempfile.mkdtemp())
self._old_curr_dir_abs = System.realpath(os.curdir)
self.tearDown()
os.mkdir(self.test_dir)
os.chdir(self.test_dir)
os.mkdir('data')
self._devnull = open(os.devnull, 'w')
subprocess.Popen(['git', 'init'], stdout=self._devnull, stderr=None).wait()
self.git = GitWrapperI(self.test_dir)
self.config = ConfigI()
self.path_factory = PathFactory(self.git, self.config)
self.settings = Settings([], self.git, self.config)
def tearDown(self):
shutil.rmtree(self.test_dir, ignore_errors=True)
os.chdir(self._old_curr_dir_abs)
@staticmethod
def create_file(file2):
fd = open(file2, 'w+')
fd.write('random text')
fd.close()
class TestRepositoryChange(BasicTestRepositoryChange):
def test_all(self):
file_to_modify = os.path.join('data', 'file1.txt')
file_created_before_run = os.path.join('data', 'file2.txt')
file_created_by_run = os.path.join('data', 'out.txt')
file_to_remove = os.path.join('data', 'file3.txt')
self.create_file(file_to_modify)
self.create_file(file_created_before_run)
self.create_file(file_to_remove)
subprocess.Popen(['git', 'add', file_to_modify, file_to_remove],
stdout=self._devnull, stderr=None).wait()
subprocess.Popen(['git', 'commit', '-m', '"Adding one file3"'],
stdout=self._devnull, stderr=None).wait()
os.remove(file_to_remove)
change = RepositoryChange(['echo', 'test'],
self.settings,
file_created_by_run,
file_to_modify,
shell=True)
expected_new = [file_created_by_run, file_created_before_run]
new_file_abs = [x.data.dvc for x in change.new_data_items]
self.assertEqual(set(new_file_abs), set(expected_new))
self.assertEqual(len(change.removed_data_items), 1)
self.assertEqual(change.removed_data_items[0].data.dvc, file_to_remove)
self.assertEqual(len(change.modified_data_items), 1)
self.assertEqual(change.modified_data_items[0].data.dvc, file_to_modify)
expected_to_change_set = set(expected_new + [file_to_modify])
changed_file_names = [x.data.dvc for x in change.changed_data_items]
self.assertEqual(set(changed_file_names), expected_to_change_set)
self.assertEqual([], change.externally_created_files)
pass
class TestRepositoryChangeDeepInDirectory(BasicTestRepositoryChange):
def test(self):
os.mkdir(os.path.join('data', 'dir32'))
deep_file = os.path.join('data', 'dir32', 'file1.txt')
self.create_file(deep_file)
change = RepositoryChange(['echo', 'text'],
self.settings,
deep_file,
None,
shell=True)
self.assertEqual([x.data.dvc for x in change.new_data_items], [deep_file])
+50 -72
View File
@@ -1,90 +1,73 @@
import os
from dvc.command.remove import CmdRemove
from dvc.command.repro import CmdRepro
from dvc.command.run import CmdRun
from dvc.executor import Executor
from tests.test_cmd_run import RunBasicTest
from tests.basic_env import TestDvc
class ReproBasicEnv(RunBasicTest):
class ReproBasicEnv(TestDvc):
def setUp(self):
super(ReproBasicEnv, self).setUp()
os.mkdir('data')
self.file_name1 = os.path.join('data', 'file1')
self.file1_code_file = 'file1.py'
self.create_file_and_commit(self.file1_code_file, 'print("Hello")' + os.linesep + 'print("Mary")')
self.settings.parse_args(['run',
'--stdout', self.file_name1,
'--code', self.file1_code_file,
'python', self.file1_code_file, '--not-repro'])
cmd_file1 = CmdRun(self.settings)
self.assertEqual(cmd_file1.code_dependencies, [self.file1_code_file])
cmd_file1.run()
self.create(self.file1_code_file, 'print("Hello")' + os.linesep + 'print("Mary")')
stage = self.dvc.run(fname='file1.dvc',
outs=[self.file_name1],
deps_no_cache=[self.file1_code_file],
cmd='python {} --not-repro > {}'.format(self.file1_code_file,
self.file_name1))
self.file_name11 = os.path.join('data', 'file11')
self.file11_code_file = 'file11.py'
self.create_file_and_commit(self.file11_code_file,
'import sys' + os.linesep + 'print(open(sys.argv[1]).readline().strip())')
self.create(self.file11_code_file,
'import sys' + os.linesep + 'print(open(sys.argv[1]).readline().strip())')
self.settings.parse_args(['run',
'--stdout', self.file_name11,
'--code', self.file11_code_file,
'python', self.file11_code_file, self.file_name1])
CmdRun(self.settings).run()
stage = self.dvc.run(fname='file11.dvc',
outs=[self.file_name11],
deps=[self.file_name1],
deps_no_cache=[self.file11_code_file],
cmd='python {} {} > {}'.format(self.file11_code_file,
self.file_name1,
self.file_name11))
self.file_name11_stage_name = stage.path
self.file_name2 = os.path.join('data', 'file2')
self.file2_code_file = 'file2.py'
self.create_file_and_commit(self.file2_code_file,
'print("Bobby")')
self.settings.parse_args(['run',
'--stdout', self.file_name2,
'python', self.file2_code_file, '--not-repro'])
CmdRun(self.settings).run()
self.create(self.file2_code_file, 'print("Bobby")')
self.dvc.run(fname='file2.dvc',
outs=[self.file_name2],
cmd='python {} --not-repro > {}'.format(self.file2_code_file,
self.file_name2))
self.file_res_code_file = 'code_res.py'
self.create_file_and_commit(self.file_res_code_file,
'import sys' + os.linesep +
'text1 = open(sys.argv[1]).read()' + os.linesep +
'text2 = open(sys.argv[2]).read()' + os.linesep +
'print(text1 + text2)')
self.create(self.file_res_code_file,
'import sys' + os.linesep +
'text1 = open(sys.argv[1]).read()' + os.linesep +
'text2 = open(sys.argv[2]).read()' + os.linesep +
'print(text1 + text2)')
self.file_name_res = os.path.join('data', 'file_res')
self.settings.parse_args(['run',
'--stdout', self.file_name_res,
'--code', self.file_res_code_file,
'python', self.file_res_code_file,
self.file_name11,
self.file_name2])
stage = self.dvc.run(fname='file_res.dvc',
outs=[self.file_name_res],
deps_no_cache=[self.file_res_code_file],
deps=[self.file_name11, self.file_name2],
cmd='python {} {} {} > {}'.format(self.file_res_code_file,
self.file_name11,
self.file_name2,
self.file_name_res))
self.file_name_res_stage_name = stage.path
cmd_res = CmdRun(self.settings)
self.assertEqual(cmd_res.code_dependencies, [self.file_res_code_file])
cmd_res.run()
lines = list(filter(None, map(str.strip, open(self.file_name_res).readlines())))
self.assertEqual(lines, ['Hello', 'Bobby'])
def create_file_and_commit(self, file_name, content='Any', message='Just a commit'):
self.create_file(file_name, content)
self.commit_file(file_name, message)
@staticmethod
def commit_file(file_name, message='Just a commit'):
Executor.exec_cmd_only_success(['git', 'add', file_name])
Executor.exec_cmd_only_success(['git', 'commit', '-m', message])
def modify_file_and_commit(self, filename, content_to_add=' '):
def modify_file(self, filename, content_to_add=' '):
fd = open(filename, 'a')
fd.write(content_to_add)
fd.close()
self.commit_file(filename)
class ReproCodeDependencyTest(ReproBasicEnv):
def test(self):
self.modify_file_and_commit(self.file_res_code_file)
self.modify_file(self.file_res_code_file)
self.settings.parse_args('repro {}'.format(self.file_name_res))
CmdRepro(self.settings).run()
self.dvc.reproduce([self.file_name_res_stage_name])
self.assertEqual(open(self.file_name_res).read().strip(), 'Hello\nBobby')
@@ -93,30 +76,25 @@ class ReproChangedDependency(ReproBasicEnv):
def test(self):
self.recreate_file1()
self.settings.parse_args('repro {}'.format(self.file_name11))
CmdRepro(self.settings).run()
self.dvc.reproduce([self.file_name11_stage_name])
self.assertEqual(open(self.file_name11).read(), 'Goodbye\n')
def recreate_file1(self):
self.settings.parse_args('remove {} --keep-in-cloud'.format(self.file_name1))
CmdRemove(self.settings).run()
self.dvc.remove(self.file_name1)
file1_code_file = 'file1_2.py'
self.create_file_and_commit(file1_code_file, 'print("Goodbye")' + os.linesep + 'print("Jack")')
self.settings.parse_args(['run',
'--stdout', self.file_name1,
'--code', file1_code_file,
'python', file1_code_file, '--not-repro'])
CmdRun(self.settings).run()
self.create(file1_code_file, 'print("Goodbye")' + os.linesep + 'print("Jack")')
self.dvc.run(fname='file1.dvc',
outs=[self.file_name1],
deps_no_cache=[file1_code_file],
cmd='python {} --not-repro > {}'.format(file1_code_file, self.file_name1))
class ReproChangedDeepDependency(ReproChangedDependency):
def test(self):
self.recreate_file1()
self.settings.parse_args('repro {}'.format(self.file_name_res))
CmdRepro(self.settings).run()
self.dvc.reproduce([self.file_name_res_stage_name])
self.assertEqual(open(self.file_name_res).read().strip(), 'Goodbye\nBobby')
+35
View File
@@ -0,0 +1,35 @@
import os
import filecmp
from dvc.data_cloud import file_md5
from tests.basic_env import TestDvc
class TestRun(TestDvc):
def test(self):
cmd = 'python {} {} {}'.format(self.CODE, self.FOO, 'out')
deps = [self.FOO]
deps_no_cache = [self.CODE]
outs = [os.path.join(self.dvc.root_dir, 'out')]
outs_no_cache = []
locked = False
fname = os.path.join(self.dvc.root_dir, 'out.dvc')
cwd = os.curdir
stage = self.dvc.run(cmd, deps, deps_no_cache, outs, outs_no_cache, locked, fname, cwd)
self.assertTrue(filecmp.cmp(self.FOO, 'out'))
self.assertTrue(os.path.isfile(stage.path))
self.assertEqual(stage.cmd, cmd)
self.assertEqual(len(stage.deps), len(deps + deps_no_cache))
self.assertEqual(len(stage.outs), len(outs + outs_no_cache))
self.assertEqual(stage.outs[0].path, outs[0])
self.assertEqual(stage.outs[0].md5, file_md5(self.FOO)[0])
self.assertEqual(stage.locked, locked)
self.assertTrue(stage.path, fname)
class TestRunEmpty(TestDvc):
def test(self):
self.dvc.run('', [], [], [], [], False, 'empty.dvc', os.curdir)
+32
View File
@@ -0,0 +1,32 @@
import os
from git import Repo
from dvc.scm import SCM, Base, Git
from tests.basic_env import TestDir, TestGit
class TestSCM(TestDir):
def test_none(self):
self.assertIsInstance(SCM(self._root_dir), Base)
def test_git(self):
Repo.init(os.curdir)
self.assertIsInstance(SCM(self._root_dir), Git)
class TestSCMGit(TestGit):
def test_is_repo(self):
self.assertTrue(Git.is_repo(os.curdir))
def test_ignore(self):
Git(self._root_dir).ignore('foo')
self.assertTrue(os.path.isfile(Git.GITIGNORE))
self.assertTrue('foo' in open(Git.GITIGNORE, 'r').readlines())
def test_commit(self):
G = Git(self._root_dir)
G.add(['foo'])
G.commit('add')
self.assertTrue('foo' in self.git.git.ls_files())
+31
View File
@@ -0,0 +1,31 @@
import os
from dvc.state import State, StateEntry
from tests.basic_env import TestDvc
class TestState(TestDvc):
def test_update(self):
path = os.path.join(self.dvc.root_dir, '1')
md5_1 = '1'
md5_2 = '2'
mtime_1 = 1
mtime_2 = 2
state = State(self.dvc.root_dir, self.dvc.dvc_dir)
self.assertIsNone(state.get(path))
state.add(path, md5_1, mtime_1)
entry = state.get(path)
self.assertIsInstance(entry, StateEntry)
self.assertEqual(entry.path, path)
self.assertEqual(entry.md5, md5_1)
self.assertEqual(entry.mtime, mtime_1)
state.update(path, md5_2, mtime_2)
entry = state.get(path)
self.assertIsInstance(entry, StateEntry)
self.assertEqual(entry.path, path)
self.assertEqual(entry.md5, md5_2)
self.assertEqual(entry.mtime, mtime_2)
+2 -19
View File
@@ -3,27 +3,10 @@ import shutil
import filecmp
from dvc import utils
from tests.basic_env import DirHierarchyEnvironment
from tests.basic_env import TestDvc
class TestExecutor(DirHierarchyEnvironment):
def setUp(self):
DirHierarchyEnvironment.init_environment(self)
def tearDown(self):
pass
def test_rmtree(self):
root = 'testdir'
os.makedirs(root + '/subdir')
with open(root + '/file1', 'w+') as f:
f.write('file1contents')
with open(root + '/subdir/file2', 'w+') as f:
f.write('file2contents')
utils.rmtree(root)
self.assertFalse(os.path.exists(root))
class TestUtils(TestDvc):
def test_copyfile(self):
src = 'file1'
dest = 'file2'