Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/buildbot/buildbot/test/test_config.py
diff options
context:
space:
mode:
Diffstat (limited to 'buildbot/buildbot/test/test_config.py')
-rw-r--r--buildbot/buildbot/test/test_config.py1277
1 files changed, 0 insertions, 1277 deletions
diff --git a/buildbot/buildbot/test/test_config.py b/buildbot/buildbot/test/test_config.py
deleted file mode 100644
index 900dcad..0000000
--- a/buildbot/buildbot/test/test_config.py
+++ /dev/null
@@ -1,1277 +0,0 @@
-# -*- test-case-name: buildbot.test.test_config -*-
-
-import os, warnings, exceptions
-
-from twisted.trial import unittest
-from twisted.python import failure
-from twisted.internet import defer
-
-from buildbot.master import BuildMaster
-from buildbot import scheduler
-from twisted.application import service, internet
-from twisted.spread import pb
-from twisted.web.server import Site
-from twisted.web.distrib import ResourcePublisher
-from buildbot.process.builder import Builder
-from buildbot.process.factory import BasicBuildFactory
-from buildbot.changes.pb import PBChangeSource
-from buildbot.changes.mail import SyncmailMaildirSource
-from buildbot.steps.source import CVS, Darcs
-from buildbot.steps.shell import Compile, Test, ShellCommand
-from buildbot.status import base
-from buildbot.steps import dummy, maxq, python, python_twisted, shell, \
- source, transfer
-words = None
-try:
- from buildbot.status import words
-except ImportError:
- pass
-
-emptyCfg = \
-"""
-from buildbot.buildslave import BuildSlave
-BuildmasterConfig = c = {}
-c['slaves'] = []
-c['schedulers'] = []
-c['builders'] = []
-c['slavePortnum'] = 9999
-c['projectName'] = 'dummy project'
-c['projectURL'] = 'http://dummy.example.com'
-c['buildbotURL'] = 'http://dummy.example.com/buildbot'
-"""
-
-buildersCfg = \
-"""
-from buildbot.process.factory import BasicBuildFactory
-from buildbot.buildslave import BuildSlave
-BuildmasterConfig = c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-c['slavePortnum'] = 9999
-f1 = BasicBuildFactory('cvsroot', 'cvsmodule')
-c['builders'] = [{'name':'builder1', 'slavename':'bot1',
- 'builddir':'workdir', 'factory':f1}]
-"""
-
-buildersCfg2 = buildersCfg + \
-"""
-f1 = BasicBuildFactory('cvsroot', 'cvsmodule2')
-c['builders'] = [{'name':'builder1', 'slavename':'bot1',
- 'builddir':'workdir', 'factory':f1}]
-"""
-
-buildersCfg3 = buildersCfg2 + \
-"""
-c['builders'].append({'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f1 })
-"""
-
-buildersCfg4 = buildersCfg2 + \
-"""
-c['builders'] = [{ 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'newworkdir', 'factory': f1 },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f1 }]
-"""
-
-wpCfg1 = buildersCfg + \
-"""
-from buildbot.steps import shell
-f1 = BasicBuildFactory('cvsroot', 'cvsmodule')
-f1.addStep(shell.ShellCommand, command=[shell.WithProperties('echo')])
-c['builders'] = [{'name':'builder1', 'slavename':'bot1',
- 'builddir':'workdir1', 'factory': f1}]
-"""
-
-wpCfg2 = buildersCfg + \
-"""
-from buildbot.steps import shell
-f1 = BasicBuildFactory('cvsroot', 'cvsmodule')
-f1.addStep(shell.ShellCommand,
- command=[shell.WithProperties('echo %s', 'revision')])
-c['builders'] = [{'name':'builder1', 'slavename':'bot1',
- 'builddir':'workdir1', 'factory': f1}]
-"""
-
-
-
-ircCfg1 = emptyCfg + \
-"""
-from buildbot.status import words
-c['status'] = [words.IRC('irc.us.freenode.net', 'buildbot', ['twisted'])]
-"""
-
-ircCfg2 = emptyCfg + \
-"""
-from buildbot.status import words
-c['status'] = [words.IRC('irc.us.freenode.net', 'buildbot', ['twisted']),
- words.IRC('irc.example.com', 'otherbot', ['chan1', 'chan2'])]
-"""
-
-ircCfg3 = emptyCfg + \
-"""
-from buildbot.status import words
-c['status'] = [words.IRC('irc.us.freenode.net', 'buildbot', ['knotted'])]
-"""
-
-webCfg1 = emptyCfg + \
-"""
-from buildbot.status import html
-c['status'] = [html.Waterfall(http_port=9980)]
-"""
-
-webCfg2 = emptyCfg + \
-"""
-from buildbot.status import html
-c['status'] = [html.Waterfall(http_port=9981)]
-"""
-
-webCfg3 = emptyCfg + \
-"""
-from buildbot.status import html
-c['status'] = [html.Waterfall(http_port='tcp:9981:interface=127.0.0.1')]
-"""
-
-webNameCfg1 = emptyCfg + \
-"""
-from buildbot.status import html
-c['status'] = [html.Waterfall(distrib_port='~/.twistd-web-pb')]
-"""
-
-webNameCfg2 = emptyCfg + \
-"""
-from buildbot.status import html
-c['status'] = [html.Waterfall(distrib_port='./bar.socket')]
-"""
-
-debugPasswordCfg = emptyCfg + \
-"""
-c['debugPassword'] = 'sekrit'
-"""
-
-interlockCfgBad = \
-"""
-from buildbot.process.factory import BasicBuildFactory
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-f1 = BasicBuildFactory('cvsroot', 'cvsmodule')
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f1 },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f1 },
- ]
-# interlocks have been removed
-c['interlocks'] = [('lock1', ['builder1'], ['builder2', 'builder3']),
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-lockCfgBad1 = \
-"""
-from buildbot.steps.dummy import Dummy
-from buildbot.process.factory import BuildFactory, s
-from buildbot.locks import MasterLock
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-l1 = MasterLock('lock1')
-l2 = MasterLock('lock1') # duplicate lock name
-f1 = BuildFactory([s(Dummy, locks=[])])
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f1, 'locks': [l1, l2] },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f1 },
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-lockCfgBad2 = \
-"""
-from buildbot.steps.dummy import Dummy
-from buildbot.process.factory import BuildFactory, s
-from buildbot.locks import MasterLock, SlaveLock
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-l1 = MasterLock('lock1')
-l2 = SlaveLock('lock1') # duplicate lock name
-f1 = BuildFactory([s(Dummy, locks=[])])
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f1, 'locks': [l1, l2] },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f1 },
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-lockCfgBad3 = \
-"""
-from buildbot.steps.dummy import Dummy
-from buildbot.process.factory import BuildFactory, s
-from buildbot.locks import MasterLock
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-l1 = MasterLock('lock1')
-l2 = MasterLock('lock1') # duplicate lock name
-f1 = BuildFactory([s(Dummy, locks=[l2])])
-f2 = BuildFactory([s(Dummy)])
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f2, 'locks': [l1] },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f1 },
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-lockCfg1a = \
-"""
-from buildbot.process.factory import BasicBuildFactory
-from buildbot.locks import MasterLock
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-f1 = BasicBuildFactory('cvsroot', 'cvsmodule')
-l1 = MasterLock('lock1')
-l2 = MasterLock('lock2')
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f1, 'locks': [l1, l2] },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f1 },
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-lockCfg1b = \
-"""
-from buildbot.process.factory import BasicBuildFactory
-from buildbot.locks import MasterLock
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-f1 = BasicBuildFactory('cvsroot', 'cvsmodule')
-l1 = MasterLock('lock1')
-l2 = MasterLock('lock2')
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f1, 'locks': [l1] },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f1 },
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-# test out step Locks
-lockCfg2a = \
-"""
-from buildbot.steps.dummy import Dummy
-from buildbot.process.factory import BuildFactory, s
-from buildbot.locks import MasterLock
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-l1 = MasterLock('lock1')
-l2 = MasterLock('lock2')
-f1 = BuildFactory([s(Dummy, locks=[l1,l2])])
-f2 = BuildFactory([s(Dummy)])
-
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f1 },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f2 },
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-lockCfg2b = \
-"""
-from buildbot.steps.dummy import Dummy
-from buildbot.process.factory import BuildFactory, s
-from buildbot.locks import MasterLock
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-l1 = MasterLock('lock1')
-l2 = MasterLock('lock2')
-f1 = BuildFactory([s(Dummy, locks=[l1])])
-f2 = BuildFactory([s(Dummy)])
-
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f1 },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f2 },
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-lockCfg2c = \
-"""
-from buildbot.steps.dummy import Dummy
-from buildbot.process.factory import BuildFactory, s
-from buildbot.locks import MasterLock
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-l1 = MasterLock('lock1')
-l2 = MasterLock('lock2')
-f1 = BuildFactory([s(Dummy)])
-f2 = BuildFactory([s(Dummy)])
-
-c['builders'] = [
- { 'name': 'builder1', 'slavename': 'bot1',
- 'builddir': 'workdir', 'factory': f1 },
- { 'name': 'builder2', 'slavename': 'bot1',
- 'builddir': 'workdir2', 'factory': f2 },
- ]
-c['slavePortnum'] = 9999
-BuildmasterConfig = c
-"""
-
-schedulersCfg = \
-"""
-from buildbot.scheduler import Scheduler, Dependent
-from buildbot.process.factory import BasicBuildFactory
-from buildbot.buildslave import BuildSlave
-c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-f1 = BasicBuildFactory('cvsroot', 'cvsmodule')
-b1 = {'name':'builder1', 'slavename':'bot1',
- 'builddir':'workdir', 'factory':f1}
-c['builders'] = [b1]
-c['schedulers'] = [Scheduler('full', None, 60, ['builder1'])]
-c['slavePortnum'] = 9999
-c['projectName'] = 'dummy project'
-c['projectURL'] = 'http://dummy.example.com'
-c['buildbotURL'] = 'http://dummy.example.com/buildbot'
-BuildmasterConfig = c
-"""
-
-class ConfigTest(unittest.TestCase):
- def setUp(self):
- # this class generates several deprecation warnings, which the user
- # doesn't need to see.
- warnings.simplefilter('ignore', exceptions.DeprecationWarning)
- self.buildmaster = BuildMaster(".")
-
- def failUnlessListsEquivalent(self, list1, list2):
- l1 = list1[:]
- l1.sort()
- l2 = list2[:]
- l2.sort()
- self.failUnlessEqual(l1, l2)
-
- def servers(self, s, types):
- # perform a recursive search of s.services, looking for instances of
- # twisted.application.internet.TCPServer, then extract their .args
- # values to find the TCP ports they want to listen on
- for child in s:
- if service.IServiceCollection.providedBy(child):
- for gc in self.servers(child, types):
- yield gc
- if isinstance(child, types):
- yield child
-
- def TCPports(self, s):
- return list(self.servers(s, internet.TCPServer))
- def UNIXports(self, s):
- return list(self.servers(s, internet.UNIXServer))
- def TCPclients(self, s):
- return list(self.servers(s, internet.TCPClient))
-
- def checkPorts(self, svc, expected):
- """Verify that the TCPServer and UNIXServer children of the given
- service have the expected portnum/pathname and factory classes. As a
- side-effect, return a list of servers in the same order as the
- 'expected' list. This can be used to verify properties of the
- factories contained therein."""
-
- expTCP = [e for e in expected if type(e[0]) == int]
- expUNIX = [e for e in expected if type(e[0]) == str]
- haveTCP = [(p.args[0], p.args[1].__class__)
- for p in self.TCPports(svc)]
- haveUNIX = [(p.args[0], p.args[1].__class__)
- for p in self.UNIXports(svc)]
- self.failUnlessListsEquivalent(expTCP, haveTCP)
- self.failUnlessListsEquivalent(expUNIX, haveUNIX)
- ret = []
- for e in expected:
- for have in self.TCPports(svc) + self.UNIXports(svc):
- if have.args[0] == e[0]:
- ret.append(have)
- continue
- assert(len(ret) == len(expected))
- return ret
-
- def testEmpty(self):
- self.failUnlessRaises(KeyError, self.buildmaster.loadConfig, "")
-
- def testSimple(self):
- # covers slavePortnum, base checker passwords
- master = self.buildmaster
- master.loadChanges()
-
- master.loadConfig(emptyCfg)
- # note: this doesn't actually start listening, because the app
- # hasn't been started running
- self.failUnlessEqual(master.slavePortnum, "tcp:9999")
- self.checkPorts(master, [(9999, pb.PBServerFactory)])
- self.failUnlessEqual(list(master.change_svc), [])
- self.failUnlessEqual(master.botmaster.builders, {})
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw"})
- self.failUnlessEqual(master.projectName, "dummy project")
- self.failUnlessEqual(master.projectURL, "http://dummy.example.com")
- self.failUnlessEqual(master.buildbotURL,
- "http://dummy.example.com/buildbot")
-
- def testSlavePortnum(self):
- master = self.buildmaster
- master.loadChanges()
-
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.slavePortnum, "tcp:9999")
- ports = self.checkPorts(master, [(9999, pb.PBServerFactory)])
- p = ports[0]
-
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.slavePortnum, "tcp:9999")
- ports = self.checkPorts(master, [(9999, pb.PBServerFactory)])
- self.failUnlessIdentical(p, ports[0],
- "the slave port was changed even " + \
- "though the configuration was not")
-
- master.loadConfig(emptyCfg + "c['slavePortnum'] = 9000\n")
- self.failUnlessEqual(master.slavePortnum, "tcp:9000")
- ports = self.checkPorts(master, [(9000, pb.PBServerFactory)])
- self.failIf(p is ports[0],
- "slave port was unchanged but configuration was changed")
-
- def testSlaves(self):
- master = self.buildmaster
- master.loadChanges()
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.botmaster.builders, {})
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw"})
- # 'botsCfg' is testing backwards compatibility, for 0.7.5 config
- # files that have not yet been updated to 0.7.6 . This compatibility
- # (and this test) is scheduled for removal in 0.8.0 .
- botsCfg = (emptyCfg +
- "c['bots'] = [('bot1', 'pw1'), ('bot2', 'pw2')]\n")
- master.loadConfig(botsCfg)
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw",
- "bot1": "pw1",
- "bot2": "pw2"})
- master.loadConfig(botsCfg)
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw",
- "bot1": "pw1",
- "bot2": "pw2"})
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw"})
- slavesCfg = (emptyCfg +
- "from buildbot.buildslave import BuildSlave\n"
- "c['slaves'] = [BuildSlave('bot1','pw1'), "
- "BuildSlave('bot2','pw2')]\n")
- master.loadConfig(slavesCfg)
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw",
- "bot1": "pw1",
- "bot2": "pw2"})
-
-
- def testChangeSource(self):
- master = self.buildmaster
- master.loadChanges()
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(list(master.change_svc), [])
-
- sourcesCfg = emptyCfg + \
-"""
-from buildbot.changes.pb import PBChangeSource
-c['change_source'] = PBChangeSource()
-"""
-
- d = master.loadConfig(sourcesCfg)
- def _check1(res):
- self.failUnlessEqual(len(list(self.buildmaster.change_svc)), 1)
- s1 = list(self.buildmaster.change_svc)[0]
- self.failUnless(isinstance(s1, PBChangeSource))
- self.failUnlessEqual(s1, list(self.buildmaster.change_svc)[0])
- self.failUnless(s1.parent)
-
- # verify that unchanged sources are not interrupted
- d1 = self.buildmaster.loadConfig(sourcesCfg)
-
- def _check2(res):
- self.failUnlessEqual(len(list(self.buildmaster.change_svc)), 1)
- s2 = list(self.buildmaster.change_svc)[0]
- self.failUnlessIdentical(s1, s2)
- self.failUnless(s1.parent)
- d1.addCallback(_check2)
- return d1
- d.addCallback(_check1)
-
- # make sure we can get rid of the sources too
- d.addCallback(lambda res: self.buildmaster.loadConfig(emptyCfg))
-
- def _check3(res):
- self.failUnlessEqual(list(self.buildmaster.change_svc), [])
- d.addCallback(_check3)
-
- return d
-
- def testChangeSources(self):
- # make sure we can accept a list
- master = self.buildmaster
- master.loadChanges()
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(list(master.change_svc), [])
-
- sourcesCfg = emptyCfg + \
-"""
-from buildbot.changes.pb import PBChangeSource
-from buildbot.changes.mail import SyncmailMaildirSource
-c['change_source'] = [PBChangeSource(),
- SyncmailMaildirSource('.'),
- ]
-"""
-
- d = master.loadConfig(sourcesCfg)
- def _check1(res):
- self.failUnlessEqual(len(list(self.buildmaster.change_svc)), 2)
- s1,s2 = list(self.buildmaster.change_svc)
- if isinstance(s2, PBChangeSource):
- s1,s2 = s2,s1
- self.failUnless(isinstance(s1, PBChangeSource))
- self.failUnless(s1.parent)
- self.failUnless(isinstance(s2, SyncmailMaildirSource))
- self.failUnless(s2.parent)
- d.addCallback(_check1)
- return d
-
- def testSources(self):
- # test backwards compatibility. c['sources'] is deprecated.
- master = self.buildmaster
- master.loadChanges()
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(list(master.change_svc), [])
-
- sourcesCfg = emptyCfg + \
-"""
-from buildbot.changes.pb import PBChangeSource
-c['sources'] = [PBChangeSource()]
-"""
-
- d = master.loadConfig(sourcesCfg)
- def _check1(res):
- self.failUnlessEqual(len(list(self.buildmaster.change_svc)), 1)
- s1 = list(self.buildmaster.change_svc)[0]
- self.failUnless(isinstance(s1, PBChangeSource))
- self.failUnless(s1.parent)
- d.addCallback(_check1)
- return d
-
- def shouldBeFailure(self, res, *expected):
- self.failUnless(isinstance(res, failure.Failure),
- "we expected this to fail, not produce %s" % (res,))
- res.trap(*expected)
- return None # all is good
-
- def testSchedulerErrors(self):
- master = self.buildmaster
- master.loadChanges()
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.allSchedulers(), [])
-
- def _shouldBeFailure(res, hint=None):
- self.shouldBeFailure(res, AssertionError, ValueError)
- if hint:
- self.failUnless(str(res).find(hint) != -1)
-
- def _loadConfig(res, newcfg):
- return self.buildmaster.loadConfig(newcfg)
- d = defer.succeed(None)
-
- # c['schedulers'] must be a list
- badcfg = schedulersCfg + \
-"""
-c['schedulers'] = Scheduler('full', None, 60, ['builder1'])
-"""
- d.addCallback(_loadConfig, badcfg)
- d.addBoth(_shouldBeFailure,
- "c['schedulers'] must be a list of Scheduler instances")
-
- # c['schedulers'] must be a list of IScheduler objects
- badcfg = schedulersCfg + \
-"""
-c['schedulers'] = ['oops', 'problem']
-"""
- d.addCallback(_loadConfig, badcfg)
- d.addBoth(_shouldBeFailure,
- "c['schedulers'] must be a list of Scheduler instances")
-
- # c['schedulers'] must point at real builders
- badcfg = schedulersCfg + \
-"""
-c['schedulers'] = [Scheduler('full', None, 60, ['builder-bogus'])]
-"""
- d.addCallback(_loadConfig, badcfg)
- d.addBoth(_shouldBeFailure, "uses unknown builder")
-
- # builderNames= must be a list
- badcfg = schedulersCfg + \
-"""
-c['schedulers'] = [Scheduler('full', None, 60, 'builder1')]
-"""
- d.addCallback(_loadConfig, badcfg)
- d.addBoth(_shouldBeFailure,
- "must be a list of Builder description names")
-
- # builderNames= must be a list of strings, not dicts
- badcfg = schedulersCfg + \
-"""
-c['schedulers'] = [Scheduler('full', None, 60, [b1])]
-"""
- d.addCallback(_loadConfig, badcfg)
- d.addBoth(_shouldBeFailure,
- "must be a list of Builder description names")
-
- # builderNames= must be a list of strings, not a dict
- badcfg = schedulersCfg + \
-"""
-c['schedulers'] = [Scheduler('full', None, 60, b1)]
-"""
- d.addCallback(_loadConfig, badcfg)
- d.addBoth(_shouldBeFailure,
- "must be a list of Builder description names")
-
- # each Scheduler must have a unique name
- badcfg = schedulersCfg + \
-"""
-c['schedulers'] = [Scheduler('dup', None, 60, []),
- Scheduler('dup', None, 60, [])]
-"""
- d.addCallback(_loadConfig, badcfg)
- d.addBoth(_shouldBeFailure, "Schedulers must have unique names")
-
- return d
-
- def testSchedulers(self):
- master = self.buildmaster
- master.loadChanges()
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.allSchedulers(), [])
-
- d = self.buildmaster.loadConfig(schedulersCfg)
- d.addCallback(self._testSchedulers_1)
- return d
-
- def _testSchedulers_1(self, res):
- sch = self.buildmaster.allSchedulers()
- self.failUnlessEqual(len(sch), 1)
- s = sch[0]
- self.failUnless(isinstance(s, scheduler.Scheduler))
- self.failUnlessEqual(s.name, "full")
- self.failUnlessEqual(s.branch, None)
- self.failUnlessEqual(s.treeStableTimer, 60)
- self.failUnlessEqual(s.builderNames, ['builder1'])
-
- newcfg = schedulersCfg + \
-"""
-s1 = Scheduler('full', None, 60, ['builder1'])
-c['schedulers'] = [s1, Dependent('downstream', s1, ['builder1'])]
-"""
- d = self.buildmaster.loadConfig(newcfg)
- d.addCallback(self._testSchedulers_2, newcfg)
- return d
- def _testSchedulers_2(self, res, newcfg):
- sch = self.buildmaster.allSchedulers()
- self.failUnlessEqual(len(sch), 2)
- s = sch[0]
- self.failUnless(isinstance(s, scheduler.Scheduler))
- s = sch[1]
- self.failUnless(isinstance(s, scheduler.Dependent))
- self.failUnlessEqual(s.name, "downstream")
- self.failUnlessEqual(s.builderNames, ['builder1'])
-
- # reloading the same config file should leave the schedulers in place
- d = self.buildmaster.loadConfig(newcfg)
- d.addCallback(self._testSchedulers_3, sch)
- return d
- def _testSchedulers_3(self, res, sch1):
- sch2 = self.buildmaster.allSchedulers()
- self.failUnlessEqual(len(sch2), 2)
- sch1.sort()
- sch2.sort()
- self.failUnlessEqual(sch1, sch2)
- self.failUnlessIdentical(sch1[0], sch2[0])
- self.failUnlessIdentical(sch1[1], sch2[1])
- self.failUnlessIdentical(sch1[0].parent, self.buildmaster)
- self.failUnlessIdentical(sch1[1].parent, self.buildmaster)
-
-
-
- def testBuilders(self):
- master = self.buildmaster
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.botmaster.builders, {})
-
- master.loadConfig(buildersCfg)
- self.failUnlessEqual(master.botmaster.builderNames, ["builder1"])
- self.failUnlessEqual(master.botmaster.builders.keys(), ["builder1"])
- b = master.botmaster.builders["builder1"]
- self.failUnless(isinstance(b, Builder))
- self.failUnlessEqual(b.name, "builder1")
- self.failUnlessEqual(b.slavenames, ["bot1"])
- self.failUnlessEqual(b.builddir, "workdir")
- f1 = b.buildFactory
- self.failUnless(isinstance(f1, BasicBuildFactory))
- steps = f1.steps
- self.failUnlessEqual(len(steps), 3)
- self.failUnlessEqual(steps[0], (CVS,
- {'cvsroot': 'cvsroot',
- 'cvsmodule': 'cvsmodule',
- 'mode': 'clobber'}))
- self.failUnlessEqual(steps[1], (Compile,
- {'command': 'make all'}))
- self.failUnlessEqual(steps[2], (Test,
- {'command': 'make check'}))
-
-
- # make sure a reload of the same data doesn't interrupt the Builder
- master.loadConfig(buildersCfg)
- self.failUnlessEqual(master.botmaster.builderNames, ["builder1"])
- self.failUnlessEqual(master.botmaster.builders.keys(), ["builder1"])
- b2 = master.botmaster.builders["builder1"]
- self.failUnlessIdentical(b, b2)
- # TODO: test that the BuilderStatus object doesn't change
- #statusbag2 = master.client_svc.statusbags["builder1"]
- #self.failUnlessIdentical(statusbag, statusbag2)
-
- # but changing something should result in a new Builder
- master.loadConfig(buildersCfg2)
- self.failUnlessEqual(master.botmaster.builderNames, ["builder1"])
- self.failUnlessEqual(master.botmaster.builders.keys(), ["builder1"])
- b3 = master.botmaster.builders["builder1"]
- self.failIf(b is b3)
- # the statusbag remains the same TODO
- #statusbag3 = master.client_svc.statusbags["builder1"]
- #self.failUnlessIdentical(statusbag, statusbag3)
-
- # adding new builder
- master.loadConfig(buildersCfg3)
- self.failUnlessEqual(master.botmaster.builderNames, ["builder1",
- "builder2"])
- self.failUnlessListsEquivalent(master.botmaster.builders.keys(),
- ["builder1", "builder2"])
- b4 = master.botmaster.builders["builder1"]
- self.failUnlessIdentical(b3, b4)
-
- # changing first builder should leave it at the same place in the list
- master.loadConfig(buildersCfg4)
- self.failUnlessEqual(master.botmaster.builderNames, ["builder1",
- "builder2"])
- self.failUnlessListsEquivalent(master.botmaster.builders.keys(),
- ["builder1", "builder2"])
- b5 = master.botmaster.builders["builder1"]
- self.failIf(b4 is b5)
-
- # and removing it should make the Builder go away
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.botmaster.builderNames, [])
- self.failUnlessEqual(master.botmaster.builders, {})
- #self.failUnlessEqual(master.client_svc.statusbags, {}) # TODO
-
- def testWithProperties(self):
- master = self.buildmaster
- master.loadConfig(wpCfg1)
- self.failUnlessEqual(master.botmaster.builderNames, ["builder1"])
- self.failUnlessEqual(master.botmaster.builders.keys(), ["builder1"])
- b1 = master.botmaster.builders["builder1"]
-
- # reloading the same config should leave the builder unchanged
- master.loadConfig(wpCfg1)
- b2 = master.botmaster.builders["builder1"]
- self.failUnlessIdentical(b1, b2)
-
- # but changing the parameters of the WithProperties should change it
- master.loadConfig(wpCfg2)
- b3 = master.botmaster.builders["builder1"]
- self.failIf(b1 is b3)
-
- # again, reloading same config should leave the builder unchanged
- master.loadConfig(wpCfg2)
- b4 = master.botmaster.builders["builder1"]
- self.failUnlessIdentical(b3, b4)
-
- def checkIRC(self, m, expected):
- ircs = {}
- for irc in self.servers(m, words.IRC):
- ircs[irc.host] = (irc.nick, irc.channels)
- self.failUnlessEqual(ircs, expected)
-
- def testIRC(self):
- if not words:
- raise unittest.SkipTest("Twisted Words package is not installed")
- master = self.buildmaster
- master.loadChanges()
- d = master.loadConfig(emptyCfg)
- e1 = {}
- d.addCallback(lambda res: self.checkIRC(master, e1))
- d.addCallback(lambda res: master.loadConfig(ircCfg1))
- e2 = {'irc.us.freenode.net': ('buildbot', ['twisted'])}
- d.addCallback(lambda res: self.checkIRC(master, e2))
- d.addCallback(lambda res: master.loadConfig(ircCfg2))
- e3 = {'irc.us.freenode.net': ('buildbot', ['twisted']),
- 'irc.example.com': ('otherbot', ['chan1', 'chan2'])}
- d.addCallback(lambda res: self.checkIRC(master, e3))
- d.addCallback(lambda res: master.loadConfig(ircCfg3))
- e4 = {'irc.us.freenode.net': ('buildbot', ['knotted'])}
- d.addCallback(lambda res: self.checkIRC(master, e4))
- d.addCallback(lambda res: master.loadConfig(ircCfg1))
- e5 = {'irc.us.freenode.net': ('buildbot', ['twisted'])}
- d.addCallback(lambda res: self.checkIRC(master, e5))
- return d
-
- def testWebPortnum(self):
- master = self.buildmaster
- master.loadChanges()
-
- d = master.loadConfig(webCfg1)
- def _check1(res):
- ports = self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory), (9980, Site)])
- p = ports[1]
- self.p = p
- # nothing should be changed
- d.addCallback(_check1)
-
- d.addCallback(lambda res: self.buildmaster.loadConfig(webCfg1))
- def _check2(res):
- ports = self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory), (9980, Site)])
- self.failUnlessIdentical(self.p, ports[1],
- "web port was changed even though "
- "configuration was not")
- # WebStatus is no longer a ComparableMixin, so it will be
- # rebuilt on each reconfig
- #d.addCallback(_check2)
-
- d.addCallback(lambda res: self.buildmaster.loadConfig(webCfg2))
- # changes port to 9981
- def _check3(p):
- ports = self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory), (9981, Site)])
- self.failIf(self.p is ports[1],
- "configuration was changed but web port was unchanged")
- d.addCallback(_check3)
-
- d.addCallback(lambda res: self.buildmaster.loadConfig(webCfg3))
- # make 9981 on only localhost
- def _check4(p):
- ports = self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory), (9981, Site)])
- self.failUnlessEqual(ports[1].kwargs['interface'], "127.0.0.1")
- d.addCallback(_check4)
-
- d.addCallback(lambda res: self.buildmaster.loadConfig(emptyCfg))
- d.addCallback(lambda res:
- self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory)]))
- return d
-
- def testWebPathname(self):
- master = self.buildmaster
- master.loadChanges()
-
- d = master.loadConfig(webNameCfg1)
- def _check1(res):
- self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory),
- ('~/.twistd-web-pb', pb.PBServerFactory)])
- unixports = self.UNIXports(self.buildmaster)
- self.f = f = unixports[0].args[1]
- self.failUnless(isinstance(f.root, ResourcePublisher))
- d.addCallback(_check1)
-
- d.addCallback(lambda res: self.buildmaster.loadConfig(webNameCfg1))
- # nothing should be changed
- def _check2(res):
- self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory),
- ('~/.twistd-web-pb', pb.PBServerFactory)])
- newf = self.UNIXports(self.buildmaster)[0].args[1]
- self.failUnlessIdentical(self.f, newf,
- "web factory was changed even though "
- "configuration was not")
- # WebStatus is no longer a ComparableMixin, so it will be
- # rebuilt on each reconfig
- #d.addCallback(_check2)
-
- d.addCallback(lambda res: self.buildmaster.loadConfig(webNameCfg2))
- def _check3(res):
- self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory),
- ('./bar.socket', pb.PBServerFactory)])
- newf = self.UNIXports(self.buildmaster)[0].args[1],
- self.failIf(self.f is newf,
- "web factory was unchanged but "
- "configuration was changed")
- d.addCallback(_check3)
-
- d.addCallback(lambda res: self.buildmaster.loadConfig(emptyCfg))
- d.addCallback(lambda res:
- self.checkPorts(self.buildmaster,
- [(9999, pb.PBServerFactory)]))
- return d
-
- def testDebugPassword(self):
- master = self.buildmaster
-
- master.loadConfig(debugPasswordCfg)
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw",
- "debug": "sekrit"})
-
- master.loadConfig(debugPasswordCfg)
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw",
- "debug": "sekrit"})
-
- master.loadConfig(emptyCfg)
- self.failUnlessEqual(master.checker.users,
- {"change": "changepw"})
-
- def testLocks(self):
- master = self.buildmaster
- botmaster = master.botmaster
-
- # make sure that c['interlocks'] is rejected properly
- self.failUnlessRaises(KeyError, master.loadConfig, interlockCfgBad)
- # and that duplicate-named Locks are caught
- self.failUnlessRaises(ValueError, master.loadConfig, lockCfgBad1)
- self.failUnlessRaises(ValueError, master.loadConfig, lockCfgBad2)
- self.failUnlessRaises(ValueError, master.loadConfig, lockCfgBad3)
-
- # create a Builder that uses Locks
- master.loadConfig(lockCfg1a)
- b1 = master.botmaster.builders["builder1"]
- self.failUnlessEqual(len(b1.locks), 2)
-
- # reloading the same config should not change the Builder
- master.loadConfig(lockCfg1a)
- self.failUnlessIdentical(b1, master.botmaster.builders["builder1"])
- # but changing the set of locks used should change it
- master.loadConfig(lockCfg1b)
- self.failIfIdentical(b1, master.botmaster.builders["builder1"])
- b1 = master.botmaster.builders["builder1"]
- self.failUnlessEqual(len(b1.locks), 1)
-
- # similar test with step-scoped locks
- master.loadConfig(lockCfg2a)
- b1 = master.botmaster.builders["builder1"]
- # reloading the same config should not change the Builder
- master.loadConfig(lockCfg2a)
- self.failUnlessIdentical(b1, master.botmaster.builders["builder1"])
- # but changing the set of locks used should change it
- master.loadConfig(lockCfg2b)
- self.failIfIdentical(b1, master.botmaster.builders["builder1"])
- b1 = master.botmaster.builders["builder1"]
- # remove the locks entirely
- master.loadConfig(lockCfg2c)
- self.failIfIdentical(b1, master.botmaster.builders["builder1"])
-
-class ConfigElements(unittest.TestCase):
- # verify that ComparableMixin is working
- def testSchedulers(self):
- s1 = scheduler.Scheduler(name='quick', branch=None,
- treeStableTimer=30,
- builderNames=['quick'])
- s2 = scheduler.Scheduler(name="all", branch=None,
- treeStableTimer=5*60,
- builderNames=["a", "b"])
- s3 = scheduler.Try_Userpass("try", ["a","b"], port=9989,
- userpass=[("foo","bar")])
- s1a = scheduler.Scheduler(name='quick', branch=None,
- treeStableTimer=30,
- builderNames=['quick'])
- s2a = scheduler.Scheduler(name="all", branch=None,
- treeStableTimer=5*60,
- builderNames=["a", "b"])
- s3a = scheduler.Try_Userpass("try", ["a","b"], port=9989,
- userpass=[("foo","bar")])
- self.failUnless(s1 == s1)
- self.failUnless(s1 == s1a)
- self.failUnless(s1a in [s1, s2, s3])
- self.failUnless(s2a in [s1, s2, s3])
- self.failUnless(s3a in [s1, s2, s3])
-
-
-
-class ConfigFileTest(unittest.TestCase):
-
- def testFindConfigFile(self):
- os.mkdir("test_cf")
- open(os.path.join("test_cf", "master.cfg"), "w").write(emptyCfg)
- slaveportCfg = emptyCfg + "c['slavePortnum'] = 9000\n"
- open(os.path.join("test_cf", "alternate.cfg"), "w").write(slaveportCfg)
-
- m = BuildMaster("test_cf")
- m.loadTheConfigFile()
- self.failUnlessEqual(m.slavePortnum, "tcp:9999")
-
- m = BuildMaster("test_cf", "alternate.cfg")
- m.loadTheConfigFile()
- self.failUnlessEqual(m.slavePortnum, "tcp:9000")
-
-
-class MyTarget(base.StatusReceiverMultiService):
- def __init__(self, name):
- self.name = name
- base.StatusReceiverMultiService.__init__(self)
- def startService(self):
- # make a note in a list stashed in the BuildMaster
- self.parent.targetevents.append(("start", self.name))
- return base.StatusReceiverMultiService.startService(self)
- def stopService(self):
- self.parent.targetevents.append(("stop", self.name))
- return base.StatusReceiverMultiService.stopService(self)
-
-class MySlowTarget(MyTarget):
- def stopService(self):
- from twisted.internet import reactor
- d = base.StatusReceiverMultiService.stopService(self)
- def stall(res):
- d2 = defer.Deferred()
- reactor.callLater(0.1, d2.callback, res)
- return d2
- d.addCallback(stall)
- m = self.parent
- def finishedStalling(res):
- m.targetevents.append(("stop", self.name))
- return res
- d.addCallback(finishedStalling)
- return d
-
-# we can't actually startService a buildmaster with a config that uses a
-# fixed slavePortnum like 9999, so instead this makes it possible to pass '0'
-# for the first time, and then substitute back in the allocated port number
-# on subsequent passes.
-startableEmptyCfg = emptyCfg + \
-"""
-c['slavePortnum'] = %d
-"""
-
-targetCfg1 = startableEmptyCfg + \
-"""
-from buildbot.test.test_config import MyTarget
-c['status'] = [MyTarget('a')]
-"""
-
-targetCfg2 = startableEmptyCfg + \
-"""
-from buildbot.test.test_config import MySlowTarget
-c['status'] = [MySlowTarget('b')]
-"""
-
-class StartService(unittest.TestCase):
- def tearDown(self):
- return self.master.stopService()
-
- def testStartService(self):
- os.mkdir("test_ss")
- self.master = m = BuildMaster("test_ss")
- # inhibit the usual read-config-on-startup behavior
- m.readConfig = True
- m.startService()
- d = m.loadConfig(startableEmptyCfg % 0)
- d.addCallback(self._testStartService_0)
- return d
-
- def _testStartService_0(self, res):
- m = self.master
- m.targetevents = []
- # figure out what port got allocated
- self.portnum = m.slavePort._port.getHost().port
- d = m.loadConfig(targetCfg1 % self.portnum)
- d.addCallback(self._testStartService_1)
- return d
-
- def _testStartService_1(self, res):
- self.failUnlessEqual(len(self.master.statusTargets), 1)
- self.failUnless(isinstance(self.master.statusTargets[0], MyTarget))
- self.failUnlessEqual(self.master.targetevents,
- [('start', 'a')])
- self.master.targetevents = []
- # reloading the same config should not start or stop the target
- d = self.master.loadConfig(targetCfg1 % self.portnum)
- d.addCallback(self._testStartService_2)
- return d
-
- def _testStartService_2(self, res):
- self.failUnlessEqual(self.master.targetevents, [])
- # but loading a new config file should stop the old one, then
- # start the new one
- d = self.master.loadConfig(targetCfg2 % self.portnum)
- d.addCallback(self._testStartService_3)
- return d
-
- def _testStartService_3(self, res):
- self.failUnlessEqual(self.master.targetevents,
- [('stop', 'a'), ('start', 'b')])
- self.master.targetevents = []
- # and going back to the old one should do the same, in the same
- # order, even though the current MySlowTarget takes a moment to shut
- # down
- d = self.master.loadConfig(targetCfg1 % self.portnum)
- d.addCallback(self._testStartService_4)
- return d
-
- def _testStartService_4(self, res):
- self.failUnlessEqual(self.master.targetevents,
- [('stop', 'b'), ('start', 'a')])
-
-cfg1 = \
-"""
-from buildbot.process.factory import BuildFactory, s
-from buildbot.steps.shell import ShellCommand
-from buildbot.steps.source import Darcs
-from buildbot.buildslave import BuildSlave
-BuildmasterConfig = c = {}
-c['slaves'] = [BuildSlave('bot1', 'pw1')]
-c['schedulers'] = []
-c['slavePortnum'] = 9999
-f1 = BuildFactory([ShellCommand(command='echo yes'),
- s(ShellCommand, command='old-style'),
- ])
-f1.addStep(Darcs(repourl='http://buildbot.net/repos/trunk'))
-f1.addStep(ShellCommand, command='echo old-style')
-c['builders'] = [{'name':'builder1', 'slavename':'bot1',
- 'builddir':'workdir', 'factory':f1}]
-"""
-
-class Factories(unittest.TestCase):
-
- def failUnlessExpectedShell(self, factory, defaults=True, **kwargs):
- shell_args = {}
- if defaults:
- shell_args.update({'descriptionDone': None,
- 'description': None,
- 'workdir': None,
- 'logfiles': {},
- 'usePTY': "slave-config",
- })
- shell_args.update(kwargs)
- self.failUnlessIdentical(factory[0], ShellCommand)
- if factory[1] != shell_args:
- print
- print "factory had:"
- for k in sorted(factory[1].keys()):
- print k
- print "but we were expecting:"
- for k in sorted(shell_args.keys()):
- print k
- self.failUnlessEqual(factory[1], shell_args)
-
- def failUnlessExpectedDarcs(self, factory, **kwargs):
- darcs_args = {'workdir': None,
- 'alwaysUseLatest': False,
- 'mode': 'update',
- 'timeout': 1200,
- 'retry': None,
- 'baseURL': None,
- 'defaultBranch': None,
- 'logfiles': {},
- }
- darcs_args.update(kwargs)
- self.failUnlessIdentical(factory[0], Darcs)
- if factory[1] != darcs_args:
- print
- print "factory had:"
- for k in sorted(factory[1].keys()):
- print k
- print "but we were expecting:"
- for k in sorted(darcs_args.keys()):
- print k
- self.failUnlessEqual(factory[1], darcs_args)
-
- def testSteps(self):
- m = BuildMaster(".")
- m.loadConfig(cfg1)
- b = m.botmaster.builders["builder1"]
- steps = b.buildFactory.steps
- self.failUnlessEqual(len(steps), 4)
-
- self.failUnlessExpectedShell(steps[0], command="echo yes")
- self.failUnlessExpectedShell(steps[1], defaults=False,
- command="old-style")
- self.failUnlessExpectedDarcs(steps[2],
- repourl="http://buildbot.net/repos/trunk")
- self.failUnlessExpectedShell(steps[3], defaults=False,
- command="echo old-style")
-
- def _loop(self, orig):
- step_class, kwargs = orig.getStepFactory()
- newstep = step_class(**kwargs)
- return newstep
-
- def testAllSteps(self):
- # make sure that steps can be created from the factories that they
- # return
- for s in ( dummy.Dummy(), dummy.FailingDummy(), dummy.RemoteDummy(),
- maxq.MaxQ("testdir"),
- python.BuildEPYDoc(), python.PyFlakes(),
- python_twisted.HLint(),
- python_twisted.Trial(testpath=None, tests="tests"),
- python_twisted.ProcessDocs(), python_twisted.BuildDebs(),
- python_twisted.RemovePYCs(),
- shell.ShellCommand(), shell.TreeSize(),
- shell.Configure(), shell.Compile(), shell.Test(),
- source.CVS("cvsroot", "module"),
- source.SVN("svnurl"), source.Darcs("repourl"),
- source.Git("repourl"),
- source.Arch("url", "version"),
- source.Bazaar("url", "version", "archive"),
- source.Bzr("repourl"),
- source.Mercurial("repourl"),
- source.P4("p4base"),
- source.P4Sync(1234, "p4user", "passwd", "client",
- mode="copy"),
- source.Monotone("server", "branch"),
- transfer.FileUpload("src", "dest"),
- transfer.FileDownload("src", "dest"),
- ):
- try:
- self._loop(s)
- except:
- print "error checking %s" % s
- raise
-