Skip to content

Commit

Permalink
Merge branch 'master' into nine
Browse files Browse the repository at this point in the history
Conflicts:
	master/buildbot/config.py
	master/buildbot/test/unit/test_process_users_manual.py
  • Loading branch information
djmitche committed Sep 11, 2013
2 parents 520a5ff + 6da63fb commit 55933f6
Show file tree
Hide file tree
Showing 126 changed files with 1,150 additions and 28,445 deletions.
6 changes: 5 additions & 1 deletion README
@@ -1,7 +1,11 @@
BuildBot: build/test automation
http://buildbot.net
Brian Warner <warner-buildbot @ lothar . com>
Dustin J. Mitchell <dustin@v.igoro.us >
Dustin J. Mitchell <dustin@v.igoro.us>

Buildbot consists of two separate components: the master and the slave. See
master/README and slave/README for more information.

Related repositories:
https://github.com/buildbot/buildbot-media - Buildbot-related media
https://github.com/buildbot/buildbot-website - Source for http://buildbot.net
2 changes: 0 additions & 2 deletions common/pylintrc
Expand Up @@ -90,9 +90,7 @@ disable=
C0323,
C0324,
C1001,
E0101,
E0202,
E0203,
E0211,
E0213,
E0603,
Expand Down
4 changes: 2 additions & 2 deletions master/buildbot/buildslave/base.py
Expand Up @@ -218,12 +218,12 @@ def reconfigService(self, new_config):
# do we need to re-register?
if (not self.registration or
self.password != new.password or
new_config.slavePortnum != self.registered_port):
new_config.protocols['pb']['port'] != self.registered_port):
if self.registration:
yield self.registration.unregister()
self.registration = None
self.password = new.password
self.registered_port = new_config.slavePortnum
self.registered_port = new_config.protocols['pb']['port']
self.registration = self.master.pbmanager.register(
self.registered_port, self.slavename,
self.password, self.getPerspective)
Expand Down
2 changes: 1 addition & 1 deletion master/buildbot/changes/pb.py
Expand Up @@ -130,7 +130,7 @@ def reconfigService(self, new_config):
# calculate the new port
port = self.port
if port is None:
port = new_config.slavePortnum
port = new_config.protocols['pb']['port']

# and, if it's changed, re-register
if port != self.registered_port and self.isActive():
Expand Down
52 changes: 43 additions & 9 deletions master/buildbot/config.py
Expand Up @@ -75,6 +75,7 @@ def __init__(self):
self.multiMaster = False
self.debugPassword = None
self.manhole = None
self.protocols = {}

self.validation = dict(
branch=re.compile(r'^[\w.+/~-]*$'),
Expand Down Expand Up @@ -113,8 +114,8 @@ def __init__(self):
"logCompressionLimit", "logCompressionMethod", "logHorizon",
"logMaxSize", "logMaxTailSize", "manhole", "mergeRequests", "metrics",
"multiMaster", "prioritizeBuilders", "projectName", "projectURL",
"properties", "revlink", "schedulers", "slavePortnum", "slaves",
"status", "title", "titleURL", "user_managers", "validation", 'mq',
"properties", "protocols", "revlink", "schedulers", "slavePortnum",
"slaves", "status", "title", "titleURL", "user_managers", "validation",
'www'
])

Expand Down Expand Up @@ -215,7 +216,7 @@ def loadConfig(cls, basedir, filename):
config.check_builders()
config.check_status()
config.check_horizons()
config.check_slavePortnum()
config.check_ports()
finally:
_errors = None

Expand Down Expand Up @@ -293,11 +294,32 @@ def copy_str_param(name, alt_key=None):
else:
self.prioritizeBuilders = prioritizeBuilders

protocols = config_dict.get('protocols', {})
if isinstance(protocols, dict):
for proto, options in protocols.iteritems():
if not isinstance(proto, str):
error("c['protocols'] keys must be strings")
if not isinstance(options, dict):
error("c['protocols']['%s'] must be a dict" % proto)
return
if (proto == "pb" and options.get("port") and
'slavePortnum' in config_dict):
error("Both c['slavePortnum'] and c['protocols']['pb']['port']"
" defined, recommended to remove slavePortnum and leave"
" only c['protocols']['pb']['port']")
else:
error("c['protocols'] must be dict")
return
self.protocols = protocols

# saved for backward compatability
if 'slavePortnum' in config_dict:
slavePortnum = config_dict.get('slavePortnum')
if isinstance(slavePortnum, int):
slavePortnum = "tcp:%d" % slavePortnum
self.slavePortnum = slavePortnum
pb_options = self.protocols.get('pb', {})
pb_options['port'] = slavePortnum
self.protocols['pb'] = pb_options

if 'multiMaster' in config_dict:
self.multiMaster = config_dict["multiMaster"]
Expand Down Expand Up @@ -643,14 +665,26 @@ def check_horizons(self):
if self.logHorizon > self.buildHorizon:
error("logHorizon must be less than or equal to buildHorizon")

def check_slavePortnum(self):
if self.slavePortnum:
def check_ports(self):
ports = set()
if self.protocols:
for proto, options in self.protocols.iteritems():
port = options.get("port")
if not port:
continue
if isinstance(port, int):
# Conversion needed to compare listenTCP and strports ports
port = "tcp:%d" % port
if port in ports:
error("Some of ports in c['protocols'] duplicated")
ports.add(port)

if ports:
return

if self.slaves:
error("slaves are configured, but no slavePortnum is set")
error("slaves are configured, but c['protocols'] not")
if self.debugPassword:
error("debug client is configured, but no slavePortnum is set")
error("debug client is configured, but c['protocols'] not")


class BuilderConfig:
Expand Down
2 changes: 1 addition & 1 deletion master/buildbot/ec2buildslave.py
Expand Up @@ -16,7 +16,7 @@
from twisted.python.deprecate import deprecatedModuleAttribute
from twisted.python.versions import Version

from buildbot.buildslave.libvirt import (
from buildbot.buildslave.ec2 import (
EC2LatentBuildSlave)

deprecatedModuleAttribute(Version("Buildbot", 0, 8, 8),
Expand Down
9 changes: 9 additions & 0 deletions master/buildbot/monkeypatches/__init__.py
Expand Up @@ -67,6 +67,14 @@ def patch_gatherResults():
from buildbot.monkeypatches import gatherResults
gatherResults.patch()

def patch_testcase_assert_raises_regexp():
# pythons before 2.7 does not have TestCase.assertRaisesRegexp() method
# add our local implementation if needed
import sys
if sys.version_info[:2] < (2,7):
from buildbot.monkeypatches import testcase_assert
testcase_assert.patch()

def patch_all(for_tests=False):
if for_tests:
from buildbot.monkeypatches import servicechecks
Expand All @@ -77,6 +85,7 @@ def patch_all(for_tests=False):
decorators.patch()
from buildbot.monkeypatches import testcase_synctest
testcase_synctest.patch_testcase_synctest()
patch_testcase_assert_raises_regexp()

patch_bug4881()
patch_bug4520()
Expand Down
48 changes: 48 additions & 0 deletions master/buildbot/monkeypatches/testcase_assert.py
@@ -0,0 +1,48 @@
# This file is part of Buildbot. Buildbot is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright Buildbot Team Members


import re
import unittest


def _assertRaisesRegexp(self, expected_exception, expected_regexp,
callable_obj, *args, **kwds):
"""
Asserts that the message in a raised exception matches a regexp.
This is a simple clone of unittest.TestCase.assertRaisesRegexp() method
introduced in python 2.7. The goal for this function is to behave exactly
as assertRaisesRegexp() in standard library.
"""
exception = None
try:
callable_obj(*args, **kwds)
except expected_exception, ex: # let unexpected exceptions pass through
exception = ex

if exception == None:
self.fail("%s not raised" % str(expected_exception.__name__))

if isinstance(expected_regexp, basestring):
expected_regexp = re.compile(expected_regexp)

if not expected_regexp.search(str(exception)):
self.fail('"%s" does not match "%s"' %
(expected_regexp.pattern, str(exception)))


def patch():
unittest.TestCase.assertRaisesRegexp = _assertRaisesRegexp
9 changes: 6 additions & 3 deletions master/buildbot/process/buildstep.py
Expand Up @@ -147,7 +147,7 @@ def interrupt(self, why):

# tell the remote command to halt. Returns a Deferred that will fire
# when the interrupt command has been delivered.

d = defer.maybeDeferred(self.remote.callRemote, "interruptCommand",
self.commandID, str(why))
# the slave may not have remote_interruptCommand
Expand Down Expand Up @@ -357,8 +357,8 @@ def errLineReceived(self, line):
class RemoteShellCommand(RemoteCommand):
def __init__(self, workdir, command, env=None,
want_stdout=1, want_stderr=1,
timeout=20*60, maxTime=None, logfiles={},
usePTY="slave-config", logEnviron=True,
timeout=20*60, maxTime=None, sigtermTime=None,
logfiles={}, usePTY="slave-config", logEnviron=True,
collectStdout=False,collectStderr=False,
interruptSignal=None,
initialStdin=None, decodeRC={0:SUCCESS}):
Expand All @@ -378,6 +378,7 @@ def __init__(self, workdir, command, env=None,
'logfiles': logfiles,
'timeout': timeout,
'maxTime': maxTime,
'sigtermTime': sigtermTime,
'usePTY': usePTY,
'logEnviron': logEnviron,
'initial_stdin': initialStdin
Expand All @@ -395,6 +396,8 @@ def _start(self):
# fixup themselves
if self.step.slaveVersion("shell", "old") == "old":
self.args['dir'] = self.args['workdir']
if not self.step.slaveVersionIsOlderThan("shell", "2.16"):
self.args.pop('sigtermTime', None)
what = "command '%s' in dir '%s'" % (self.fake_command,
self.args['workdir'])
log.msg(what)
Expand Down
9 changes: 6 additions & 3 deletions master/buildbot/process/debug.py
Expand Up @@ -36,7 +36,10 @@ def __init__(self, master):
def reconfigService(self, new_config):

# debug client
config_changed = (self.debug_port != new_config.slavePortnum or
new_config_port = None
if new_config.protocols.get('pb'):
new_config_port = new_config.protocols['pb']['port']
config_changed = (self.debug_port != new_config_port or
self.debug_password != new_config.debugPassword)

if not new_config.debugPassword or config_changed:
Expand All @@ -47,12 +50,12 @@ def reconfigService(self, new_config):
if new_config.debugPassword and config_changed:
factory = lambda mind, user : DebugPerspective(self.master)
self.debug_registration = self.master.pbmanager.register(
new_config.slavePortnum, "debug", new_config.debugPassword,
new_config_port, "debug", new_config.debugPassword,
factory)

self.debug_password = new_config.debugPassword
if self.debug_password:
self.debug_port = new_config.slavePortnum
self.debug_port = new_config_port
else:
self.debug_port = None

Expand Down
6 changes: 3 additions & 3 deletions master/buildbot/process/mtrlogobserver.py
Expand Up @@ -37,9 +37,9 @@ class EqConnectionPool(adbapi.ConnectionPool):
"""
def __init__(self, *args, **kwargs):
self._eqKey = (args, kwargs)
return adbapi.ConnectionPool.__init__(self,
cp_reconnect=True, cp_min=1, cp_max=3,
*args, **kwargs)
adbapi.ConnectionPool.__init__(self,
cp_reconnect=True, cp_min=1, cp_max=3,
*args, **kwargs)

def __eq__(self, other):
if isinstance(other, EqConnectionPool):
Expand Down
9 changes: 6 additions & 3 deletions master/buildbot/scripts/sample.cfg
Expand Up @@ -16,10 +16,13 @@ c = BuildmasterConfig = {}
from buildbot.buildslave import BuildSlave
c['slaves'] = [BuildSlave("example-slave", "pass")]

# 'slavePortnum' defines the TCP port to listen on for connections from slaves.
# This must match the value configured into the buildslaves (with their
# 'protocols' contains information about protocols which master will use for
# communicating with slaves.
# You must define at least 'port' option that slaves could connect to your master
# with this protocol.
# 'port' must match the value configured into the buildslaves (with their
# --master option)
c['slavePortnum'] = 9989
c['protocols'] = {'pb': {'port': 9989}}

####### CHANGESOURCES

Expand Down

0 comments on commit 55933f6

Please sign in to comment.