From 9cdeacaea8528c1bc090046715374882e9be0e15 Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Thu, 19 Feb 2015 17:14:15 +0000 Subject: sourceresolver: Fix LsTreeError raised when constructing build graph If you had a repo that was not in your local or remote cache in your definitions, Morph might raise LsTreeError and abort. The code was assuming the repo would already be cached in the local cache by the time it got to detecting build systems, but that's not always true -- if the (reponame, ref) pair was already in the 'resolved_trees' cache but the repo had been deleted from the local Git cache, to name one possibility. Also, the remoterepocache.ls_tree operation can fail if the repo is not hosted in the Trove, so we shouldn't abort the program in that case. Finally, this patch removes an unused variable. --- morphlib/sourceresolver_tests.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'morphlib/sourceresolver_tests.py') diff --git a/morphlib/sourceresolver_tests.py b/morphlib/sourceresolver_tests.py index 2410218a..6d6a83fa 100644 --- a/morphlib/sourceresolver_tests.py +++ b/morphlib/sourceresolver_tests.py @@ -24,7 +24,7 @@ from morphlib.sourceresolver import (SourceResolver, PickleCacheManager, MorphologyNotFoundError, NotcachedError) -from morphlib.remoterepocache import CatFileError +from morphlib.remoterepocache import CatFileError, LsTreeError class FakeRemoteRepoCache(object): @@ -135,6 +135,9 @@ class FakeLocalRepo(object): def list_files(self, ref, recurse): return self.morphologies.keys() + def update(self): + pass + class FakeLocalRepoCache(object): @@ -147,6 +150,9 @@ class FakeLocalRepoCache(object): def get_repo(self, reponame): return self.lr + def cache_repo(self, reponame): + return self.lr + class SourceResolverTests(unittest.TestCase): @@ -188,6 +194,9 @@ class SourceResolverTests(unittest.TestCase): def noremotefile(self, *args): raise CatFileError('reponame', 'ref', 'filename') + def noremoterepo(self, *args): + raise LsTreeError('reponame', 'ref') + def localmorph(self, *args): return ['chunk.morph'] @@ -241,6 +250,15 @@ class SourceResolverTests(unittest.TestCase): 'assumed-local.morph') self.assertEqual('autotools', name) + def test_cache_repo_if_not_in_either_cache(self): + self.lrc.has_repo = self.doesnothaverepo + self.lr.read_file = self.nolocalmorph + self.lr.list_files = self.autotoolsbuildsystem + self.rrc.ls_tree = self.noremoterepo + name = self.sr._detect_build_system('reponame', 'sha1', + 'assumed-local.morph') + self.assertEqual('autotools', name) + def test_autodetects_remote_morphology(self): self.lrc.has_repo = self.doesnothaverepo self.rrc.cat_file = self.noremotemorph @@ -262,7 +280,8 @@ class SourceResolverTests(unittest.TestCase): def test_raises_error_when_repo_does_not_exist(self): self.lrc.has_repo = self.doesnothaverepo - self.assertRaises(NotcachedError, self.lsr._detect_build_system, + self.assertRaises(MorphologyNotFoundError, + self.lsr._detect_build_system, 'reponame', 'sha1', 'non-existent.morph') def test_raises_error_when_failed_to_detect_build_system(self): -- cgit v1.2.1 From 9c53c8b12a2ff92e850daf3def87aa489dfafecf Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Fri, 20 Feb 2015 10:50:35 +0000 Subject: sourceresolver: Simplify some code paths It turns out that always looking for the chunk morph in the definitions repo allows us to make the code a little less nasty. Bonus! --- morphlib/sourceresolver_tests.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'morphlib/sourceresolver_tests.py') diff --git a/morphlib/sourceresolver_tests.py b/morphlib/sourceresolver_tests.py index 6d6a83fa..75025a9a 100644 --- a/morphlib/sourceresolver_tests.py +++ b/morphlib/sourceresolver_tests.py @@ -308,10 +308,12 @@ class SourceResolverTests(unittest.TestCase): 'assumed-local.morph') self.assertEqual('autotools', name) - def test_fails_when_local_not_cached_and_no_remote(self): + def test_succeeds_when_local_not_cached_and_no_remote(self): self.lrc.has_repo = self.doesnothaverepo - self.assertRaises(NotcachedError, self.lsr._get_morphology, - 'reponame', 'sha1', 'unreached.morph') + self.lr.list_files = self.localmorph + morph = self.sr._get_morphology('reponame', 'sha1', + 'chunk.morph') + self.assertEqual('chunk', morph['name']) def test_arch_is_validated(self): self.lr.arch = 'unknown' -- cgit v1.2.1 From 1d7e39b955f4da58230f9c5a06ff1b05f8bc020b Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Fri, 20 Feb 2015 11:13:24 +0000 Subject: sourceresolver: Factor out 'cache repo locally' code into a function Also, move the repo.update() call into the 'fetch from tarball' code path in the localrepocache module -- there's no need to update straight after doing a `git clone`, but we do need to do one if we got the repo from a `git archive` tarball that may be out of date. --- morphlib/sourceresolver_tests.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'morphlib/sourceresolver_tests.py') diff --git a/morphlib/sourceresolver_tests.py b/morphlib/sourceresolver_tests.py index 75025a9a..638f593f 100644 --- a/morphlib/sourceresolver_tests.py +++ b/morphlib/sourceresolver_tests.py @@ -22,8 +22,7 @@ import unittest import morphlib from morphlib.sourceresolver import (SourceResolver, PickleCacheManager, - MorphologyNotFoundError, - NotcachedError) + MorphologyNotFoundError) from morphlib.remoterepocache import CatFileError, LsTreeError -- cgit v1.2.1