Ticket #100: builderEnv-full.diff

File builderEnv-full.diff, 8.0 KB (added by bhearsum, 12 years ago)

builder env, better docs, supports properties

  • buildbot/process/base.py

    diff -rN -u old-builderEnv/buildbot/process/base.py new-builderEnv/buildbot/process/base.py
    old new  
    193193    def setLocks(self, locks):
    194194        self.locks = locks
    195195
     196    def setSlaveEnvironment(self, env):
     197        self.slaveEnvironment = env
     198
    196199    def getSourceStamp(self):
    197200        return self.source
    198201
  • buildbot/process/builder.py

    diff -rN -u old-builderEnv/buildbot/process/builder.py new-builderEnv/buildbot/process/builder.py
    old new  
    278278        self.builddir = setup['builddir']
    279279        self.buildFactory = setup['factory']
    280280        self.locks = setup.get("locks", [])
     281        self.env = setup.get('env', {})
     282        assert isinstance(self.env, dict)
    281283        if setup.has_key('periodicBuildTime'):
    282284            raise ValueError("periodicBuildTime can no longer be defined as"
    283285                             " part of the Builder: use scheduler.Periodic"
     
    587589        build = self.buildFactory.newBuild(requests)
    588590        build.setBuilder(self)
    589591        build.setLocks(self.locks)
     592        if len(self.env) > 0:
     593            build.setSlaveEnvironment(self.env)
    590594
    591595        # start it
    592596        self.startBuild(build, sb)
  • buildbot/steps/shell.py

    diff -rN -u old-builderEnv/buildbot/steps/shell.py new-builderEnv/buildbot/steps/shell.py
    old new  
    135135        return ["'%s" % words[0], "%s" % words[1], "...'"]
    136136
    137137    def setupEnvironment(self, cmd):
    138         # XXX is this used? documented? replaced by properties?
    139         # merge in anything from Build.slaveEnvironment . Earlier steps
    140         # (perhaps ones which compile libraries or sub-projects that need to
    141         # be referenced by later steps) can add keys to
    142         # self.build.slaveEnvironment to affect later steps.
     138        # merge in anything from Build.slaveEnvironment
     139        # This can be set from a Builder-level environment, or from earlier
     140        # BuildSteps. The latter method is deprecated and superceded by
     141        # BuildProperties.
     142        # Environment variables passed in by a BuildStep override
     143        # those passed in at the Builder level.
    143144        properties = self.build.getProperties()
    144145        slaveEnv = self.build.slaveEnvironment
    145146        if slaveEnv:
    146147            if cmd.args['env'] is None:
    147148                cmd.args['env'] = {}
    148             cmd.args['env'].update(properties.render(slaveEnv))
     149            fullSlaveEnv = slaveEnv.copy()
     150            fullSlaveEnv.update(cmd.args['env'])
     151            cmd.args['env'] = properties.render(fullSlaveEnv)
    149152            # note that each RemoteShellCommand gets its own copy of the
    150153            # dictionary, so we shouldn't be affecting anyone but ourselves.
    151154
  • buildbot/test/test_run.py

    diff -rN -u old-builderEnv/buildbot/test/test_run.py new-builderEnv/buildbot/test/test_run.py
    old new  
    843843# of the bug where I forgot to make Waterfall inherit from StatusReceiver
    844844# such that buildSetSubmitted failed.
    845845
     846config_test_builder = config_base + """
     847from buildbot.scheduler import Scheduler
     848c['schedulers'] = [Scheduler('quick', 'dummy', 0.1, ['dummy']),
     849                   Scheduler('quick2', 'dummy2', 0.1, ['dummy2']),
     850                   Scheduler('quick3', 'dummy3', 0.1, ['dummy3'])]
     851
     852from buildbot.steps.shell import ShellCommand
     853f3 = factory.BuildFactory([
     854    s(ShellCommand, command="sleep 3", env={'blah':'blah'})
     855    ])
     856
     857c['builders'] = [{'name': 'dummy', 'slavename': 'bot1', 'env': {'foo':'bar'},
     858                  'builddir': 'dummy', 'factory': f3}]
     859
     860c['builders'].append({'name': 'dummy2', 'slavename': 'bot1',
     861                       'env': {'blah':'bar'}, 'builddir': 'dummy2',
     862                       'factory': f3})
     863
     864f4 = factory.BuildFactory([
     865    s(ShellCommand, command="sleep 3")
     866    ])
     867
     868c['builders'].append({'name': 'dummy3', 'slavename': 'bot1',
     869                       'env': {'blah':'bar'}, 'builddir': 'dummy3',
     870                       'factory': f4})
     871"""
     872
     873class TestBuilder(RunMixin, unittest.TestCase):
     874    def setUp(self):
     875        RunMixin.setUp(self)
     876        self.master.loadConfig(config_test_builder)
     877        self.master.readConfig = True
     878        self.master.startService()
     879        self.connectSlave(builders=["dummy", "dummy2", "dummy3"])
     880
     881    def doBuilderEnvTest(self, branch, cb):
     882        c = changes.Change("bob", ["Makefile", "foo/bar.c"], "changed",
     883                           branch=branch)
     884        self.master.change_svc.addChange(c)
     885
     886        d = defer.Deferred()
     887        reactor.callLater(0.5, d.callback, None)
     888        d.addCallback(cb)
     889
     890        return d
     891
     892    def testBuilderEnv(self):
     893        return self.doBuilderEnvTest("dummy", self._testBuilderEnv1)
     894
     895    def _testBuilderEnv1(self, res):
     896        b = self.master.botmaster.builders['dummy']
     897        build = b.building[0]
     898        s = build.currentStep
     899        self.failUnless('foo' in s.cmd.args['env'])
     900        self.failUnlessEqual('bar', s.cmd.args['env']['foo'])
     901        self.failUnless('blah' in s.cmd.args['env'])
     902        self.failUnlessEqual('blah', s.cmd.args['env']['blah'])
     903
     904    def testBuilderEnvOverride(self):
     905        return self.doBuilderEnvTest("dummy2", self._testBuilderEnvOverride1)
     906
     907    def _testBuilderEnvOverride1(self, res):
     908        b = self.master.botmaster.builders['dummy2']
     909        build = b.building[0]
     910        s = build.currentStep
     911        self.failUnless('blah' in s.cmd.args['env'])
     912        self.failUnlessEqual('blah', s.cmd.args['env']['blah'])
     913
     914    def testBuilderNoStepEnv(self):
     915        return self.doBuilderEnvTest("dummy3", self._testBuilderNoStepEnv1)
     916
     917    def _testBuilderNoStepEnv1(self, res):
     918        b = self.master.botmaster.builders['dummy3']
     919        build = b.building[0]
     920        s = build.currentStep
     921        self.failUnless('blah' in s.cmd.args['env'])
     922        self.failUnlessEqual('bar', s.cmd.args['env']['blah'])
  • docs/buildbot.texinfo

    diff -rN -u old-builderEnv/docs/buildbot.texinfo new-builderEnv/docs/buildbot.texinfo
    old new  
    17691769Linux or Solaris builds) should naturally be associated with an
    17701770OS-X-based buildslave.
    17711771
     1772A @code{Builder} may be given a set of environments variables to be used
     1773in its @pxref{ShellCommand}s. These variables will override anything in the
     1774buildslave's environment. Variables passed directly to a ShellCommand will
     1775override variables of the same name passed to the Builder.
     1776
     1777For example, if you a pool of identical slaves it is often easier to manage
     1778variables like PATH from Buildbot rather than manually editing it inside of
     1779the slaves' environment.
     1780
     1781@example
     1782f = factory.BuildFactory
     1783f.addStep(ShellCommand(
     1784              command=['bash', './configure']))
     1785f.addStep(Compile())
     1786
     1787c['builders'] = [
     1788  @{'name': 'test', 'slavenames': ['slave1', 'slave2', 'slave3', 'slave4',
     1789                                   'slave5', 'slave6'],
     1790    'builddir': 'test', 'factory': f',
     1791    'env': {'PATH': '/opt/local/bin:/opt/app/bin:/usr/local/bin:/usr/bin'}}
     1792
     1793@end example
    17721794
    17731795@node Users, Build Properties, Builder, Concepts
    17741796@section Users
     
    48434865@end example
    48444866
    48454867These variable settings will override any existing ones in the
    4846 buildslave's environment. The exception is PYTHONPATH, which is merged
     4868buildslave's environment or the environment specified in the
     4869Builder. The exception is PYTHONPATH, which is merged
    48474870with (actually prepended to) any existing $PYTHONPATH setting. The
    48484871value is treated as a list of directories to prepend, and a single
    48494872string is treated like a one-item list. For example, to prepend both