Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into monotone-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
levitte committed Apr 4, 2011
2 parents 66ac2d2 + 0113968 commit 79f5c11
Show file tree
Hide file tree
Showing 13 changed files with 643 additions and 47 deletions.
15 changes: 15 additions & 0 deletions master/buildbot/buildslave.py
Expand Up @@ -89,6 +89,8 @@ def __init__(self, name, password, max_builds=None,
self.missing_timer = None
self.keepalive_interval = keepalive_interval

self._old_builder_list = None

def update(self, new):
"""
Given a new BuildSlave, configure this one identically. Because
Expand Down Expand Up @@ -429,7 +431,15 @@ def _disconnected(rref):
def sendBuilderList(self):
our_builders = self.botmaster.getBuildersForSlave(self.slavename)
blist = [(b.name, b.slavebuilddir) for b in our_builders]
if blist == self._old_builder_list:
log.msg("Builder list is unchanged; not calling setBuilderList")
return defer.succeed(None)

d = self.slave.callRemote("setBuilderList", blist)
def sentBuilderList(ign):
self._old_builder_list = blist
return ign
d.addCallback(sentBuilderList)
return d

def perspective_keepalive(self):
Expand Down Expand Up @@ -579,6 +589,9 @@ class BuildSlave(AbstractBuildSlave):
def sendBuilderList(self):
d = AbstractBuildSlave.sendBuilderList(self)
def _sent(slist):
# Nothing has changed, so don't need to re-attach to everything
if not slist:
return
dl = []
for name, remote in slist.items():
# use get() since we might have changed our mind since then
Expand Down Expand Up @@ -821,6 +834,8 @@ def updateSlave(self):
def sendBuilderList(self):
d = AbstractBuildSlave.sendBuilderList(self)
def _sent(slist):
if not slist:
return
dl = []
for name, remote in slist.items():
# use get() since we might have changed our mind since then.
Expand Down
2 changes: 1 addition & 1 deletion master/buildbot/status/web/files/default.css
Expand Up @@ -5,7 +5,7 @@ body.interface {
margin-bottom: 50px;
padding: 0;
background: url(bg_gradient.jpg) repeat-x;
font-family: Verdana, Cursor;
font-family: Verdana, Cursor, sans-serif;
font-size: 10px;
background-color: #fff;
color: #333;
Expand Down
3 changes: 2 additions & 1 deletion master/buildbot/steps/subunit.py
Expand Up @@ -23,6 +23,7 @@ class SubunitShellCommand(ShellCommand):

def __init__(self, failureOnNoTests=False, *args, **kwargs):
ShellCommand.__init__(self, *args, **kwargs)
self.failureOnNoTests = failureOnNoTests
# importing here gets around an import loop
from buildbot.process import subunitlogobserver
self.ioObverser = subunitlogobserver.SubunitLogObserver()
Expand Down Expand Up @@ -55,7 +56,7 @@ def commandComplete(self, cmd):
text += ["no tests", "run"]
else:
results = FAILURE
text.append("Total % test(s)" % total)
text.append("Total %d test(s)" % total)
if failures:
text.append("%d %s" % \
(failures,
Expand Down
6 changes: 3 additions & 3 deletions master/docs/cfg-buildsteps.texinfo
Expand Up @@ -1654,14 +1654,14 @@ through a subunit filter to extract test and failure counts.

@example
from buildbot.steps.subunit import SubunitShellCommand
f.addStep(SubunitShellCommand(command="make test", failureOnNoError=False))
f.addStep(SubunitShellCommand(command="make test", failureOnNoTests=False))
@end example

This runs @code{make test} and filters it through subunit. The 'tests' and
'test failed' progress metrics will now accumulate test data from the test run.

If @code{failureOnNoError} is True, this step will fail if no test is run. By
default @code{failureOnNoError} is False.
If @code{failureOnNoTests} is True, this step will fail if no test is run. By
default @code{failureOnNoTests} is False.

@node Python BuildSteps
@subsection Python BuildSteps
Expand Down
2 changes: 1 addition & 1 deletion master/docs/cfg-statustargets.texinfo
Expand Up @@ -864,7 +864,7 @@ def html_message_formatter(mode, name, build, results, master_status):
text.append(u'<br>')
text.append(u'<h4>Last %d lines of "%s"</h4>' % (limit_lines, name))
unilist = list()
for line in content[len(content)-limit_lines:]:
for line in content[-limit_lines:]:
unilist.append(cgi.escape(unicode(line,'utf-8')))
text.append(u'<pre>'.join([uniline for uniline in unilist]))
text.append(u'</pre>')
Expand Down
13 changes: 13 additions & 0 deletions master/docs/installation.texinfo
Expand Up @@ -374,6 +374,19 @@ database with the changes the buildmaster has seen. Note that, as of this
release, build history is @i{not} contained in the database, and is thus not
migrated.

You will need to add an entry into your @file{master.cfg} to reflect the
database version you are using. The upgrade process does @i{not} edit your
@file{master.cfg} for you. So something like:

@example
# for the default sqlite you need:
c['db_url'] = "sqlite:///state.sqlite"
# or for using mysql:
c['db_url'] = 'mysql://bbuser:<password>@@localhost/buildbot'
@end example

See @pxref{Database Specification} for more options.

The upgrade process renames the Changes pickle (@code{$basedir/changes.pck}) to
@code{changes.pck.old} once the upgrade is complete. To reverse the upgrade,
simply downgrade Buildbot and move this file back to its original name. You
Expand Down
20 changes: 20 additions & 0 deletions slave/buildslave/commands/base.py
Expand Up @@ -365,6 +365,12 @@ def parseGotRevision(self):
return None

def readSourcedata(self):
"""
Read the sourcedata file and return its contents
@returns: source data
@raises: IOError if the file does not exist
"""
return open(self.sourcedatafile, "r").read()

def writeSourcedata(self, res):
Expand All @@ -388,6 +394,12 @@ def maybeDoVCFallback(self, rc):
return rc
if self.interrupted:
raise AbandonChain(1)

# allow AssertionErrors to fall through, for benefit of the tests; for
# all other errors, carry on to try the fallback
if isinstance(rc, failure.Failure) and rc.check(AssertionError):
return rc

# Let VCS subclasses have an opportunity to handle
# unrecoverable errors without having to clobber the repo
self.maybeNotDoVCFallback(rc)
Expand Down Expand Up @@ -597,3 +609,11 @@ def cleanup(x):
d.addCallback(self._abandonOnFailure)
return d

def setFileContents(self, filename, contents):
"""Put the given C{contents} in C{filename}; this is a bit more
succinct than opening, writing, and closing, and has the advantage of
being patchable in tests. Note that the enclosing directory is
not automatically created, nor is this an "atomic" overwrite."""
f = open(filename, 'w')
f.write(contents)
f.close()
27 changes: 12 additions & 15 deletions slave/buildslave/commands/git.py
Expand Up @@ -31,13 +31,16 @@ class Git(SourceBaseCommand):
to retrieve. Default: "master".
['submodules'] (optional): whether to initialize and update
submodules. Default: False.
['ignore_ignores'] (optional): ignore ignores when purging changes.
['ignore_ignores'] (optional): ignore ignores when purging changes
(default true)
['reference'] (optional): use this reference repository
to fetch objects.
['gerrit_branch'] (optional): which virtual branch to retrieve.
['progress'] (optional): have git output progress markers,
avoiding timeouts for long fetches;
requires Git 1.7.2 or later.
['shallow'] (optional): if true, use shallow clones that do not
also fetch history
"""

header = "git operation"
Expand All @@ -57,11 +60,6 @@ def setup(self, args):
def _fullSrcdir(self):
return os.path.join(self.builder.basedir, self.srcdir)

def _commitSpec(self):
if self.revision:
return self.revision
return self.branch

def sourcedirIsUpdateable(self):
return os.path.isdir(os.path.join(self._fullSrcdir(), ".git"))

Expand All @@ -77,20 +75,20 @@ def _dovccmd(self, command, cb=None, **kwargs):
d.addCallback(cb)
return d

# If the repourl matches the sourcedata file, then
# we can say that the sourcedata matches. We can
# ignore branch changes, since Git can work with
# many branches fetched, and we deal with it properly
# in doVCUpdate.
def sourcedataMatches(self):
# If the repourl matches the sourcedata file, then we can say that the
# sourcedata matches. We can ignore branch changes, since Git can work
# with many branches fetched, and we deal with it properly in
# doVCUpdate. So, basically, as long as the file exists, consider it
# to match
try:
self.readSourcedata()
except IOError:
return False
return True

def _cleanSubmodules(self, res):
command = ['submodule', 'foreach', 'git', 'clean', '-d', '-f']
command = ['submodule', 'foreach', 'git', 'clean', '-f', '-d']
if self.ignore_ignores:
command.append('-x')
return self._dovccmd(command)
Expand Down Expand Up @@ -180,9 +178,8 @@ def _didInit(self, res):
# up after the 'git init'.
if self.reference:
git_alts_path = os.path.join(self._fullSrcdir(), '.git', 'objects', 'info', 'alternates')
git_alts_file = open(git_alts_path, 'w')
git_alts_file.write(os.path.join(self.reference, 'objects'))
git_alts_file.close()
git_alts_content = os.path.join(self.reference, 'objects')
self.setFileContents(git_alts_path, git_alts_content)
return self.doVCUpdate()

def doVCFull(self):
Expand Down
2 changes: 1 addition & 1 deletion slave/buildslave/commands/mtn.py
Expand Up @@ -182,4 +182,4 @@ def _parse(res):
d = c.start()
d.addCallback(self._abandonOnFailure)
d.addCallback(_parse)

return d
9 changes: 9 additions & 0 deletions slave/buildslave/test/fake/runprocess.py
Expand Up @@ -52,6 +52,15 @@ def __add__(self, other):
raise ValueError("invalid expectation '%r'" % (other,))
return self

def __str__(self):
other_kwargs = self.kwargs.copy()
del other_kwargs['command']
del other_kwargs['workdir']
return "Command: %s\n workdir: %s\n kwargs: %s\n result: %s\n" % (
self.kwargs['command'], self.kwargs['workdir'],
other_kwargs, self.result)


class FakeRunProcess:
"""
A fake version of L{buildslave.runprocess.RunProcess} which will
Expand Down

0 comments on commit 79f5c11

Please sign in to comment.