diff --git a/tests/base.py b/tests/base.py index 7cd9de39c2..67de802109 100755 --- a/tests/base.py +++ b/tests/base.py @@ -500,7 +500,7 @@ class FakeURLOpener(object): return ret -class FakeGerritSource(zuul.source.gerrit.Gerrit): +class FakeGerritSource(zuul.source.gerrit.GerritSource): name = 'gerrit' def __init__(self, upstream_root, *args): diff --git a/tests/test_source.py b/tests/test_source.py new file mode 100644 index 0000000000..8a3e7d5402 --- /dev/null +++ b/tests/test_source.py @@ -0,0 +1,25 @@ +# Copyright 2014 Rackspace Australia +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging +import testtools + +import zuul.source + + +class TestGerritSource(testtools.TestCase): + log = logging.getLogger("zuul.test_source") + + def test_source_name(self): + self.assertEqual('gerrit', zuul.source.gerrit.GerritSource.name) diff --git a/zuul/cmd/server.py b/zuul/cmd/server.py index 5393289f15..e0f19a93ae 100755 --- a/zuul/cmd/server.py +++ b/zuul/cmd/server.py @@ -148,7 +148,8 @@ class Server(zuul.cmd.ZuulApp): # Register the available sources # See comment at top of file about zuul imports import zuul.source.gerrit - self.gerrit_source = zuul.source.gerrit.Gerrit(self.config, self.sched) + self.gerrit_source = zuul.source.gerrit.GerritSource(self.config, + self.sched) self.sched.registerSource(self.gerrit_source) diff --git a/zuul/source/__init__.py b/zuul/source/__init__.py index e69de29bb2..3ef474efb7 100644 --- a/zuul/source/__init__.py +++ b/zuul/source/__init__.py @@ -0,0 +1,68 @@ +# Copyright 2014 Rackspace Australia +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import abc + +import six + + +@six.add_metaclass(abc.ABCMeta) +class BaseSource(object): + """Base class for sources. + + A source class gives methods for fetching and updating changes. Each + pipeline must have (only) one source. It is the canonical provider of the + change to be tested. + + Defines the exact public methods that must be supplied.""" + + @abc.abstractmethod + def __init__(self, config, sched): + """Constructor.""" + + @abc.abstractmethod + def getRefSha(self, project, ref): + """Return a sha for a given project ref.""" + + @abc.abstractmethod + def isMerged(self, change, head=None): + """Determine if change is merged. + + If head is provided the change is checked if it is at head.""" + + @abc.abstractmethod + def canMerge(self, change, allow_needs): + """Determine if change can merge.""" + + def maintainCache(self, relevant): + """Make cache contain relevant changes. + + This lets the user supply a list of change objects that are + still in use. Anything in our cache that isn't in the supplied + list should be safe to remove from the cache.""" + + def postConfig(self): + """Called after configuration has been processed.""" + + @abc.abstractmethod + def getChange(self, event, project): + """Get the change representing an event.""" + + @abc.abstractmethod + def getProjectOpenChanges(self, project): + """Get the open changes for a project.""" + + @abc.abstractmethod + def getGitUrl(self, project): + """Get the git url for a project.""" diff --git a/zuul/source/gerrit.py b/zuul/source/gerrit.py index 44b8609f3b..5fd0cdf64b 100644 --- a/zuul/source/gerrit.py +++ b/zuul/source/gerrit.py @@ -18,9 +18,10 @@ import time import urllib2 from zuul.lib import gerrit from zuul.model import Change, Ref, NullChange +from zuul.source import BaseSource -class Gerrit(object): +class GerritSource(BaseSource): name = 'gerrit' log = logging.getLogger("zuul.source.Gerrit") replication_timeout = 300 @@ -104,7 +105,7 @@ class Gerrit(object): sha = refs.get(ref, '') return sha - def waitForRefSha(self, project, ref, old_sha=''): + def _waitForRefSha(self, project, ref, old_sha=''): # Wait for the ref to show up in the repo start = time.time() while time.time() - start < self.replication_timeout: @@ -132,7 +133,7 @@ class Gerrit(object): ref = 'refs/heads/' + change.branch self.log.debug("Waiting for %s to appear in git repo" % (change)) - if self.waitForRefSha(change.project, ref, change._ref_sha): + if self._waitForRefSha(change.project, ref, change._ref_sha): self.log.debug("Change %s is in the git repo" % (change)) return True @@ -210,7 +211,7 @@ class Gerrit(object): change.ref = event.ref change.oldrev = event.oldrev change.newrev = event.newrev - change.url = self.getGitwebUrl(project, sha=event.newrev) + change.url = self._getGitwebUrl(project, sha=event.newrev) else: change = NullChange(project) return change @@ -229,7 +230,7 @@ class Gerrit(object): key = '%s,%s' % (change.number, change.patchset) self._change_cache[key] = change try: - self.updateChange(change, history) + self._updateChange(change, history) except Exception: del self._change_cache[key] raise @@ -289,7 +290,7 @@ class Gerrit(object): records.append(result) return records - def updateChange(self, change, history=None): + def _updateChange(self, change, history=None): self.log.info("Updating information for %s,%s" % (change.number, change.patchset)) data = self.gerrit.query(change.number) @@ -401,7 +402,7 @@ class Gerrit(object): url = 'ssh://%s@%s:%s/%s' % (user, server, port, project.name) return url - def getGitwebUrl(self, project, sha=None): + def _getGitwebUrl(self, project, sha=None): url = '%s/gitweb?p=%s.git' % (self.baseurl, project) if sha: url += ';a=commitdiff;h=' + sha