From 6dbbc488d216b1c3d2163a2780d045d2a9eea80b Mon Sep 17 00:00:00 2001 From: Clark Boylan Date: Fri, 18 Oct 2013 10:57:31 -0700 Subject: [PATCH] Clone repo if it is not on disk * zuul/merger.py: Previously zuul's merger only checked an initialized flag to determine if a repo should be cloned. If the state of the disk changes under zuul the repo may need to be recloned even if the initialized flag is set. Check if the repo exists on disk to determine if the repo should be cloned to deal with external state changes. Keep initialized flag in order to preserve ability to change git repo settings for user and email. * tests/test_scheduler.py: Add a test that checks a repo is recloned when removed from the filesystem under zuul. * tests/fixtures/layout-repo-deleted.yaml: Layout fixture for new test added above. This creates a new repo unused by any other tests so that failures of this test do not interfere with other tests, they will run independent of each other. Change-Id: I14fb34a2916002cefef73e41ec9182a073d59ef3 --- tests/fixtures/layout-repo-deleted.yaml | 52 +++++++++++++++++++++++++ tests/test_scheduler.py | 37 ++++++++++++++++++ zuul/merger.py | 6 ++- 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/layout-repo-deleted.yaml diff --git a/tests/fixtures/layout-repo-deleted.yaml b/tests/fixtures/layout-repo-deleted.yaml new file mode 100644 index 0000000000..967009a25e --- /dev/null +++ b/tests/fixtures/layout-repo-deleted.yaml @@ -0,0 +1,52 @@ +pipelines: + - name: check + manager: IndependentPipelineManager + trigger: + gerrit: + - event: patchset-created + success: + gerrit: + verified: 1 + failure: + gerrit: + verified: -1 + + - name: post + manager: IndependentPipelineManager + trigger: + gerrit: + - event: ref-updated + ref: ^(?!refs/).*$ + + - name: gate + manager: DependentPipelineManager + failure-message: Build failed. For information on how to proceed, see http://wiki.example.org/Test_Failures + trigger: + gerrit: + - event: comment-added + approval: + - approved: 1 + success: + gerrit: + verified: 2 + submit: true + failure: + gerrit: + verified: -2 + start: + gerrit: + verified: 0 + precedence: high + +projects: + - name: org/delete-project + check: + - project-merge: + - project-test1 + - project-test2 + gate: + - project-merge: + - project-test1 + - project-test2 + post: + - project-post diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py index 70956b4e46..cdc67690b7 100644 --- a/tests/test_scheduler.py +++ b/tests/test_scheduler.py @@ -2807,6 +2807,43 @@ class TestScheduler(testtools.TestCase): self.assertEqual(A.data['status'], 'MERGED') self.assertEqual(A.reported, 2) + def test_repo_deleted(self): + self.config.set('zuul', 'layout_config', + 'tests/fixtures/layout-repo-deleted.yaml') + self.sched.reconfigure(self.config) + + self.init_repo("org/delete-project") + A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A') + + A.addApproval('CRVW', 2) + self.fake_gerrit.addEvent(A.addApproval('APRV', 1)) + self.waitUntilSettled() + self.assertEqual(self.getJobFromHistory('project-merge').result, + 'SUCCESS') + self.assertEqual(self.getJobFromHistory('project-test1').result, + 'SUCCESS') + self.assertEqual(self.getJobFromHistory('project-test2').result, + 'SUCCESS') + self.assertEqual(A.data['status'], 'MERGED') + self.assertEqual(A.reported, 2) + + # Delete org/new-project zuul repo. Should be recloned. + shutil.rmtree(os.path.join(self.git_root, "org/delete-project")) + + B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B') + + B.addApproval('CRVW', 2) + self.fake_gerrit.addEvent(B.addApproval('APRV', 1)) + self.waitUntilSettled() + self.assertEqual(self.getJobFromHistory('project-merge').result, + 'SUCCESS') + self.assertEqual(self.getJobFromHistory('project-test1').result, + 'SUCCESS') + self.assertEqual(self.getJobFromHistory('project-test2').result, + 'SUCCESS') + self.assertEqual(B.data['status'], 'MERGED') + self.assertEqual(B.reported, 2) + def test_timer(self): "Test that a periodic job is triggered" self.worker.hold_jobs_in_build = True diff --git a/zuul/merger.py b/zuul/merger.py index 218f7f22f5..5704d617dd 100644 --- a/zuul/merger.py +++ b/zuul/merger.py @@ -38,9 +38,11 @@ class Repo(object): self.log.exception("Unable to initialize repo for %s" % remote) def _ensure_cloned(self): - if self._initialized: + repo_is_cloned = os.path.exists(self.local_path) + if self._initialized and repo_is_cloned: return - if not os.path.exists(self.local_path): + # If the repo does not exist, clone the repo. + if not repo_is_cloned: self.log.debug("Cloning from %s to %s" % (self.remote_url, self.local_path)) git.Repo.clone_from(self.remote_url, self.local_path)