CachedRepo: implement close() method
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 4 Mar 2014 13:45:47 +0000 (15:45 +0200)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 4 Mar 2014 13:48:25 +0000 (15:48 +0200)
For invalidating the object without the need of deleting it.

Change-Id: I6e5210c06f7eb559609d956456be958a8a4232c2
Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
gbp_repocache/__init__.py
tests/test_gbp_repocache.py

index 2d05de0e4955a75ea165a2368b2713daf49873c4..7400bb3c42d09a0bcc40f7c934c2c507ab6f6c54 100644 (file)
@@ -193,18 +193,36 @@ class CachedRepo(object):
     def __del__(self):
         self._release_lock()
 
+    def _check_instance(self):
+        """Check that the cached repo is "open", raise an exception if not."""
+        if not self._lock:
+            raise CachedRepoError('Trying to operate on closed CachedRepo'
+                                   'instance')
+
     @property
     def repo(self):
         """Get the GitRepository instance of the cached repo"""
+        self._check_instance()
         return self._repo
 
     @property
     def repodir(self):
         """Get the file system path to the cached git repository"""
+        self._check_instance()
         return self._repodir
 
+    def close(self):
+        """Close the cached git repository rendering it unusable.
+        Releases locks to make the cache directory usable for another
+        CachedRepository object. You should not operate on closed CachedRepo
+        instances.
+        """
+        self._release_lock()
+        self._repo = None
+
     def update_working_copy(self, commitish='HEAD', submodules=True):
         """Reset HEAD to the given commit-ish"""
+        self._check_instance()
         if self.repo.bare:
             raise CachedRepoError('Cannot update working copy of a bare repo')
 
index 8af2445d5c4a2b0dbc39c8baee3ad574f047d178..fad343d8cdb8cec6ebfb3bd22d523f90b2235298 100644 (file)
@@ -58,7 +58,7 @@ class TestCachedRepo(UnitTestsBase):
 
         # Try updating from non-existing repo
         repo = self.MockCachedRepo(self.orig_repo.path)
-        del repo
+        repo.close()
         shutil.move(self.orig_repo.path, self.orig_repo.path + '.tmp')
         with assert_raises(CachedRepoError):
             repo = self.MockCachedRepo(self.orig_repo.path)
@@ -72,7 +72,7 @@ class TestCachedRepo(UnitTestsBase):
         ok_(repo.repo.bare is not True)
         sha = repo.repo.rev_parse('master')
         path = repo.repo.path
-        del repo
+        repo.close()
         # Make new commit in "upstream"
         self.update_repository_file(self.orig_repo, 'foo.txt', 'more data\n')
         # Fetch
@@ -103,7 +103,7 @@ class TestCachedRepo(UnitTestsBase):
                 self.orig_repo.rev_parse('HEAD')]
         repo = self.MockCachedRepo(self.orig_repo.path)
         repo.update_working_copy(shas[-1])
-        del repo
+        repo.close()
 
         # Change upstream, after this index cached repo will be out-of-sync
         # from orig HEAD
@@ -111,6 +111,22 @@ class TestCachedRepo(UnitTestsBase):
         repo = self.MockCachedRepo(self.orig_repo.path)
         eq_(repo.update_working_copy(shas[0]), shas[0])
 
+    def test_close(self):
+        """Test closing of cached repo"""
+        repo = self.MockCachedRepo(self.orig_repo.path)
+        ok_(repo)
+        # Operating on a closed repository should fail
+        repo.close()
+        with assert_raises(CachedRepoError):
+            repo.update_working_copy('HEAD')
+        with assert_raises(CachedRepoError):
+            _repo_obj = repo.repo
+        with assert_raises(CachedRepoError):
+            _repo_dir = repo.repodir
+
+        # Multiple closes should be ok
+        repo.close()
+
     def test_update_bare(self):
         """Test update for bare repository"""
         repo = self.MockCachedRepo(self.orig_repo.path, bare=True)
@@ -120,7 +136,7 @@ class TestCachedRepo(UnitTestsBase):
     def test_invalid_remote_head(self):
         """Test clone/update from remote whose HEAD is invalid"""
         repo = self.MockCachedRepo(self.orig_repo.path)
-        del repo
+        repo.close()
 
         # Make remote HEAD point to a non-existent branch
         orig_branch = self.orig_repo.get_branch()
@@ -145,7 +161,7 @@ class TestCachedRepo(UnitTestsBase):
         shutil.rmtree(os.path.join(repo.repo.path, '.git/refs'))
         with assert_raises(GitRepositoryError):
             repo.repo.rev_parse('HEAD')
-        del repo
+        repo.close()
         # Update and check status
         repo = self.MockCachedRepo(self.orig_repo.path)
         ok_(repo.repo.rev_parse('HEAD'))
@@ -155,7 +171,7 @@ class TestCachedRepo(UnitTestsBase):
         # Clone
         repo = self.MockCachedRepo(self.orig_repo.path, bare=True)
         eq_(repo.repo.bare, True)
-        del repo
+        repo.close()
         repo = self.MockCachedRepo(self.orig_repo.path, bare=False)
         eq_(repo.repo.bare, False)
 
@@ -171,7 +187,7 @@ class TestCachedRepo(UnitTestsBase):
             finally:
                 os.chmod(self.workdir, s_rwx)
         repo = self.MockCachedRepo(self.orig_repo.path)
-        del repo
+        repo.close()
 
         # Check cache base dir access error
         os.chmod(self.cachedir, 0)
@@ -182,7 +198,7 @@ class TestCachedRepo(UnitTestsBase):
                 os.chmod(self.cachedir, s_rwx)
         repo = self.MockCachedRepo(self.orig_repo.path)
         subdir = os.path.dirname(repo.repodir)
-        del repo
+        repo.close()
 
         # Check cache subdir access error
         os.chmod(subdir, 0)
@@ -192,7 +208,7 @@ class TestCachedRepo(UnitTestsBase):
             finally:
                 os.chmod(subdir, s_rwx)
         repo = self.MockCachedRepo(self.orig_repo.path)
-        del repo
+        repo.close()
 
         # Check repodir delete error
         os.chmod(subdir, stat.S_IREAD | stat.S_IEXEC)