move BuildSlave to new class, merge with BotPerspective, make it long-lived
[buildbot.git] / buildbot / test / test_properties.py
blob03e979d8dd181038f65b488807541937b7dbc4d2
1 # -*- test-case-name: buildbot.test.test_properties -*-
3 import os
5 from twisted.trial import unittest
7 from buildbot.sourcestamp import SourceStamp
8 from buildbot.process import base
9 from buildbot.steps.shell import ShellCommand, WithProperties
10 from buildbot.status import builder
11 from buildbot.slave.commands import rmdirRecursive
12 from buildbot.test.runutils import RunMixin
14 class MyBuildStep(ShellCommand):
15 def _interpolateProperties(self, command):
16 command = ["tar", "czf",
17 "build-%s.tar.gz" % self.getProperty("revision"),
18 "source"]
19 return ShellCommand._interpolateProperties(self, command)
22 class FakeBuild:
23 pass
24 class FakeBuilder:
25 statusbag = None
26 name = "fakebuilder"
27 class FakeSlave:
28 slavename = "bot12"
29 class FakeSlaveBuilder:
30 slave = FakeSlave()
31 def getSlaveCommandVersion(self, command, oldversion=None):
32 return "1.10"
34 class Interpolate(unittest.TestCase):
35 def setUp(self):
36 self.builder = FakeBuilder()
37 self.builder_status = builder.BuilderStatus("fakebuilder")
38 self.builder_status.basedir = "test_properties"
39 self.builder_status.nextBuildNumber = 5
40 rmdirRecursive(self.builder_status.basedir)
41 os.mkdir(self.builder_status.basedir)
42 self.build_status = self.builder_status.newBuild()
43 req = base.BuildRequest("reason", SourceStamp(branch="branch2",
44 revision=1234))
45 self.build = base.Build([req])
46 self.build.setBuilder(self.builder)
47 self.build.setupStatus(self.build_status)
48 self.build.setupSlaveBuilder(FakeSlaveBuilder())
50 def testWithProperties(self):
51 self.build.setProperty("revision", 47)
52 self.failUnlessEqual(self.build_status.getProperty("revision"), 47)
53 c = ShellCommand(workdir=dir,
54 command=["tar", "czf",
55 WithProperties("build-%s.tar.gz",
56 "revision"),
57 "source"])
58 c.setBuild(self.build)
59 cmd = c._interpolateProperties(c.command)
60 self.failUnlessEqual(cmd,
61 ["tar", "czf", "build-47.tar.gz", "source"])
63 def testWorkdir(self):
64 self.build.setProperty("revision", 47)
65 self.failUnlessEqual(self.build_status.getProperty("revision"), 47)
66 c = ShellCommand(command=["tar", "czf", "foo.tar.gz", "source"])
67 c.setBuild(self.build)
68 workdir = WithProperties("workdir-%d", "revision")
69 workdir = c._interpolateWorkdir(workdir)
70 self.failUnlessEqual(workdir, "workdir-47")
72 def testWithPropertiesDict(self):
73 self.build.setProperty("other", "foo")
74 self.build.setProperty("missing", None)
75 c = ShellCommand(workdir=dir,
76 command=["tar", "czf",
77 WithProperties("build-%(other)s.tar.gz"),
78 "source"])
79 c.setBuild(self.build)
80 cmd = c._interpolateProperties(c.command)
81 self.failUnlessEqual(cmd,
82 ["tar", "czf", "build-foo.tar.gz", "source"])
84 def testWithPropertiesEmpty(self):
85 self.build.setProperty("empty", None)
86 c = ShellCommand(workdir=dir,
87 command=["tar", "czf",
88 WithProperties("build-%(empty)s.tar.gz"),
89 "source"])
90 c.setBuild(self.build)
91 cmd = c._interpolateProperties(c.command)
92 self.failUnlessEqual(cmd,
93 ["tar", "czf", "build-.tar.gz", "source"])
95 def testCustomBuildStep(self):
96 c = MyBuildStep(workdir=dir)
97 c.setBuild(self.build)
98 cmd = c._interpolateProperties(c.command)
99 self.failUnlessEqual(cmd,
100 ["tar", "czf", "build-1234.tar.gz", "source"])
102 def testSourceStamp(self):
103 c = ShellCommand(workdir=dir,
104 command=["touch",
105 WithProperties("%s-dir", "branch"),
106 WithProperties("%s-rev", "revision"),
108 c.setBuild(self.build)
109 cmd = c._interpolateProperties(c.command)
110 self.failUnlessEqual(cmd,
111 ["touch", "branch2-dir", "1234-rev"])
113 def testSlaveName(self):
114 c = ShellCommand(workdir=dir,
115 command=["touch",
116 WithProperties("%s-slave", "slavename"),
118 c.setBuild(self.build)
119 cmd = c._interpolateProperties(c.command)
120 self.failUnlessEqual(cmd,
121 ["touch", "bot12-slave"])
123 def testBuildNumber(self):
124 c = ShellCommand(workdir=dir,
125 command=["touch",
126 WithProperties("build-%d", "buildnumber"),
127 WithProperties("builder-%s", "buildername"),
129 c.setBuild(self.build)
130 cmd = c._interpolateProperties(c.command)
131 self.failUnlessEqual(cmd,
132 ["touch", "build-5", "builder-fakebuilder"])
135 run_config = """
136 from buildbot.process import factory
137 from buildbot.steps.shell import ShellCommand, WithProperties
138 from buildbot.buildslave import BuildSlave
139 s = factory.s
141 BuildmasterConfig = c = {}
142 c['slaves'] = [BuildSlave('bot1', 'sekrit')]
143 c['schedulers'] = []
144 c['slavePortnum'] = 0
146 # Note: when run against twisted-1.3.0, this locks up about 5% of the time. I
147 # suspect that a command with no output that finishes quickly triggers a race
148 # condition in 1.3.0's process-reaping code. The 'touch' process becomes a
149 # zombie and the step never completes. To keep this from messing up the unit
150 # tests too badly, this step runs with a reduced timeout.
152 f1 = factory.BuildFactory([s(ShellCommand,
153 flunkOnFailure=True,
154 command=['touch',
155 WithProperties('%s-slave', 'slavename'),
157 workdir='.',
158 timeout=10,
161 b1 = {'name': 'full1', 'slavename': 'bot1', 'builddir': 'bd1', 'factory': f1}
162 c['builders'] = [b1]
166 class Run(RunMixin, unittest.TestCase):
167 def testInterpolate(self):
168 # run an actual build with a step that interpolates a build property
169 d = self.master.loadConfig(run_config)
170 d.addCallback(lambda res: self.master.startService())
171 d.addCallback(lambda res: self.connectOneSlave("bot1"))
172 d.addCallback(lambda res: self.requestBuild("full1"))
173 d.addCallback(self.failUnlessBuildSucceeded)
174 def _check_touch(res):
175 f = os.path.join("slavebase-bot1", "bd1", "bot1-slave")
176 self.failUnless(os.path.exists(f))
177 return res
178 d.addCallback(_check_touch)
179 return d
182 # we test got_revision in test_vc