summaryrefslogtreecommitdiff
path: root/obnam
diff options
context:
space:
mode:
authorLars Wirzenius <liw@gytha>2008-04-20 18:44:25 +0300
committerLars Wirzenius <liw@gytha>2008-04-20 18:44:25 +0300
commit69187a7c8d9a176f19bf1109243961cbd4cff372 (patch)
tree83abfb481348fcbf26a8a6972fcbf7b62465e5fb /obnam
parentce82a16369689a43dad7304836fdfc0649a5a223 (diff)
downloadobnam-69187a7c8d9a176f19bf1109243961cbd4cff372.tar.gz
Implemented Application.select_files_to_back_up.
Diffstat (limited to 'obnam')
-rw-r--r--obnam/app.py39
-rw-r--r--obnam/appTests.py73
2 files changed, 109 insertions, 3 deletions
diff --git a/obnam/app.py b/obnam/app.py
index a832a841..001cdd70 100644
--- a/obnam/app.py
+++ b/obnam/app.py
@@ -279,7 +279,37 @@ class Application:
def get_dir_in_previous_generation(self, dirname):
"""Return directory in previous generation, or None."""
gen = self.get_previous_generation()
- return self.get_store().lookup_dir(gen, dirname)
+ if gen:
+ return self.get_store().lookup_dir(gen, dirname)
+ else:
+ return None
+
+ def select_files_to_back_up(self, dirname, filenames, stat=os.stat):
+ """Select files to backup in a directory, compared to previous gen.
+
+ Look up the directory in the previous generation, and see which
+ files need backing up compared to that generation.
+
+ Return list of unchanged filegroups, plus list of filenames
+ that need backing up.
+
+ """
+
+ filenames = filenames[:]
+ old_dir = self.get_dir_in_previous_generation(dirname)
+ if old_dir:
+ old_groups = [self.get_store().get_object(id)
+ for id in old_dir.get_filegrouprefs()]
+ filegroups = self.find_unchanged_filegroups(old_groups,
+ filenames,
+ stat=stat)
+ for fg in filegroups:
+ for name in fg.get_names():
+ filenames.remove(name)
+
+ return filegroups, filenames
+ else:
+ return [], filenames
def backup_one_dir(self, dirname, subdirs, filenames):
"""Back up non-recursively one directory.
@@ -292,7 +322,11 @@ class Application:
"""
filenames = self._make_absolute(dirname, filenames)
- filegroups = self.make_filegroups(filenames)
+ filegroups, filenames = self.select_files_to_back_up(dirname,
+ filenames)
+
+
+ filegroups += self.make_filegroups(filenames)
filegrouprefs = [fg.get_id() for fg in filegroups]
dirrefs = [subdir.get_id() for subdir in subdirs]
@@ -303,7 +337,6 @@ class Application:
dirrefs=dirrefs,
filegrouprefs=filegrouprefs)
-
self.get_store().queue_object(dir)
return dir
diff --git a/obnam/appTests.py b/obnam/appTests.py
index bce9bddc..845f2105 100644
--- a/obnam/appTests.py
+++ b/obnam/appTests.py
@@ -409,6 +409,7 @@ class ApplicationGetDirInPreviousGenerationTests(unittest.TestCase):
context = obnam.context.Context()
self.app = obnam.Application(context)
self.app._store = self.MockStore()
+ self.app.set_previous_generation("prevgen")
def testReturnsNoneIfDirectoryDidNotExist(self):
self.failUnlessEqual(self.app.get_dir_in_previous_generation("xx"),
@@ -419,6 +420,78 @@ class ApplicationGetDirInPreviousGenerationTests(unittest.TestCase):
self.failUnlessEqual(dir.get_name(), "pink")
+class ApplicationSelectFilesToBackUpTests(unittest.TestCase):
+
+ class MockStore:
+
+ def __init__(self, objs):
+ self._objs = objs
+
+ def get_object(self, id):
+ for obj in self._objs:
+ if obj.get_id() == id:
+ return obj
+ return None
+
+ def setUp(self):
+ self.stats = {
+ "pink": obnam.utils.make_stat_result(st_mtime=42),
+ "pretty": obnam.utils.make_stat_result(st_mtime=105),
+ }
+ self.names = ["pink", "pretty"]
+ self.pink = self.mock_filegroup(["pink"])
+ self.pretty = self.mock_filegroup(["pretty"])
+ self.groups = [self.pink, self.pretty]
+
+ self.dirname = "dirname"
+ self.dir = obnam.obj.DirObject(id="id", name=self.dirname,
+ filegrouprefs=[x.get_id()
+ for x in self.groups])
+
+ store = self.MockStore(self.groups + [self.dir])
+
+ context = obnam.context.Context()
+ self.app = obnam.Application(context)
+ self.app._store = store
+ self.app.get_dir_in_previous_generation = self.mock_get_dir_in_prevgen
+
+ def mock_get_dir_in_prevgen(self, dirname):
+ if dirname == self.dirname:
+ return self.dir
+ else:
+ return None
+
+ def mock_filegroup(self, filenames):
+ fg = obnam.obj.FileGroupObject(id=obnam.obj.object_id_new())
+ for filename in filenames:
+ st = self.mock_stat(filename)
+ fg.add_file(filename, st, None, None, None)
+ return fg
+
+ def mock_stat(self, filename):
+ return self.stats[filename]
+
+ def select(self):
+ return self.app.select_files_to_back_up(self.dirname, self.names,
+ stat=self.mock_stat)
+
+ def testReturnsNoOldGroupsIfDirectoryDidNotExist(self):
+ self.dir = None
+ self.failUnlessEqual(self.select(), ([], self.names))
+
+ def testReturnsNoOldGroupsIfEverythingIsChanged(self):
+ self.stats["pink"] = obnam.utils.make_stat_result()
+ self.stats["pretty"] = obnam.utils.make_stat_result()
+ self.failUnlessEqual(self.select(), ([], self.names))
+
+ def testReturnsOneGroupAndOneFileWhenJustOneIsChanged(self):
+ self.stats["pink"] = obnam.utils.make_stat_result()
+ self.failUnlessEqual(self.select(), ([self.pretty], ["pink"]))
+
+ def testReturnsBothGroupsWhenNothingIsChanged(self):
+ self.failUnlessEqual(self.select(), (self.groups, []))
+
+
class ApplicationFindFileByNameTests(unittest.TestCase):
def setUp(self):