2 # this file tests the 'buildbot' command, with its various sub-commands
4 from twisted
.trial
import unittest
5 from twisted
.python
import runtime
, usage
6 import os
, os
.path
, shutil
, shlex
8 from buildbot
.scripts
import runner
, tryclient
10 class Options(unittest
.TestCase
):
11 optionsFile
= "SDFsfsFSdfsfsFSD"
13 def make(self
, d
, key
):
14 # we use a wacky filename here in case the test code discovers the
15 # user's real ~/.buildbot/ directory
16 os
.makedirs(os
.sep
.join(d
+ [".buildbot"]))
17 f
= open(os
.sep
.join(d
+ [".buildbot", self
.optionsFile
]), "w")
18 f
.write("key = '%s'\n" % key
)
21 def check(self
, d
, key
):
22 basedir
= os
.sep
.join(d
)
23 options
= runner
.loadOptions(self
.optionsFile
, here
=basedir
,
26 self
.failIf(options
.has_key('key'))
28 self
.failUnlessEqual(options
['key'], key
)
30 def testFindOptions(self
):
31 self
.make(["home", "dir1", "dir2", "dir3"], "one")
32 self
.make(["home", "dir1", "dir2"], "two")
33 self
.make(["home"], "home")
34 self
.home
= os
.path
.abspath("home")
36 self
.check(["home", "dir1", "dir2", "dir3"], "one")
37 self
.check(["home", "dir1", "dir2"], "two")
38 self
.check(["home", "dir1"], "home")
40 self
.home
= os
.path
.abspath("nothome")
41 os
.makedirs(os
.sep
.join(["nothome", "dir1"]))
42 self
.check(["nothome", "dir1"], None)
44 def doForce(self
, args
, expected
):
45 o
= runner
.ForceOptions()
47 self
.failUnlessEqual(o
.keys(), expected
.keys())
49 self
.failUnlessEqual(o
[k
], expected
[k
],
50 "[%s] got %s instead of %s" % (k
, o
[k
],
53 def testForceOptions(self
):
54 if not hasattr(shlex
, "split"):
55 raise unittest
.SkipTest("need python>=2.3 for shlex.split")
57 exp
= {"builder": "b1", "reason": "reason",
58 "branch": None, "revision": None}
59 self
.doForce(shlex
.split("b1 reason"), exp
)
60 self
.doForce(shlex
.split("b1 'reason'"), exp
)
61 self
.failUnlessRaises(usage
.UsageError
, self
.doForce
,
62 shlex
.split("--builder b1 'reason'"), exp
)
63 self
.doForce(shlex
.split("--builder b1 --reason reason"), exp
)
64 self
.doForce(shlex
.split("--builder b1 --reason 'reason'"), exp
)
65 self
.doForce(shlex
.split("--builder b1 --reason \"reason\""), exp
)
67 exp
['reason'] = "longer reason"
68 self
.doForce(shlex
.split("b1 'longer reason'"), exp
)
69 self
.doForce(shlex
.split("b1 longer reason"), exp
)
70 self
.doForce(shlex
.split("--reason 'longer reason' b1"), exp
)
73 class Create(unittest
.TestCase
):
74 def failUnlessIn(self
, substring
, string
, msg
=None):
75 # trial provides a version of this that requires python-2.3 to test
77 self
.failUnless(string
.find(substring
) != -1, msg
)
78 def failUnlessExists(self
, filename
):
79 self
.failUnless(os
.path
.exists(filename
), "%s should exist" % filename
)
80 def failIfExists(self
, filename
):
81 self
.failIf(os
.path
.exists(filename
), "%s should not exist" % filename
)
84 basedir
= "test_runner.master"
85 options
= runner
.MasterOptions()
86 options
.parseOptions(["-q", basedir
])
88 runner
.createMaster(options
)
91 tac
= os
.path
.join(basedir
, "buildbot.tac")
92 self
.failUnless(os
.path
.exists(tac
))
93 tacfile
= open(tac
,"rt").read()
94 self
.failUnlessIn("basedir", tacfile
)
95 self
.failUnlessIn("configfile = r'master.cfg'", tacfile
)
96 self
.failUnlessIn("BuildMaster(basedir, configfile)", tacfile
)
98 cfg
= os
.path
.join(basedir
, "master.cfg")
99 self
.failIfExists(cfg
)
100 samplecfg
= os
.path
.join(basedir
, "master.cfg.sample")
101 self
.failUnlessExists(samplecfg
)
102 cfgfile
= open(samplecfg
,"rt").read()
103 self
.failUnlessIn("This is a sample buildmaster config file", cfgfile
)
105 makefile
= os
.path
.join(basedir
, "Makefile.sample")
106 self
.failUnlessExists(makefile
)
108 # now verify that running it a second time (with the same options)
109 # does the right thing: nothing changes
110 runner
.createMaster(options
)
113 self
.failIfExists(os
.path
.join(basedir
, "buildbot.tac.new"))
114 self
.failUnlessExists(os
.path
.join(basedir
, "master.cfg.sample"))
116 oldtac
= open(os
.path
.join(basedir
, "buildbot.tac"), "rt").read()
118 # mutate Makefile.sample, since it should be rewritten
119 f
= open(os
.path
.join(basedir
, "Makefile.sample"), "rt")
121 f
= open(os
.path
.join(basedir
, "Makefile.sample"), "wt")
123 f
.write("# additional line added\n")
126 # also mutate master.cfg.sample
127 f
= open(os
.path
.join(basedir
, "master.cfg.sample"), "rt")
128 oldsamplecfg
= f
.read()
129 f
= open(os
.path
.join(basedir
, "master.cfg.sample"), "wt")
130 f
.write(oldsamplecfg
)
131 f
.write("# additional line added\n")
134 # now run it again (with different options)
135 options
= runner
.MasterOptions()
136 options
.parseOptions(["-q", "--config", "other.cfg", basedir
])
137 runner
.createMaster(options
)
140 tac
= open(os
.path
.join(basedir
, "buildbot.tac"), "rt").read()
141 self
.failUnlessEqual(tac
, oldtac
, "shouldn't change existing .tac")
142 self
.failUnlessExists(os
.path
.join(basedir
, "buildbot.tac.new"))
144 make
= open(os
.path
.join(basedir
, "Makefile.sample"), "rt").read()
145 self
.failUnlessEqual(make
, oldmake
, "*should* rewrite Makefile.sample")
147 samplecfg
= open(os
.path
.join(basedir
, "master.cfg.sample"),
149 self
.failUnlessEqual(samplecfg
, oldsamplecfg
,
150 "*should* rewrite master.cfg.sample")
154 basedir
= "test_runner.slave"
155 options
= runner
.SlaveOptions()
156 options
.parseOptions(["-q", basedir
, "buildmaster:1234",
157 "botname", "passwd"])
159 runner
.createSlave(options
)
162 tac
= os
.path
.join(basedir
, "buildbot.tac")
163 self
.failUnless(os
.path
.exists(tac
))
164 tacfile
= open(tac
,"rt").read()
165 self
.failUnlessIn("basedir", tacfile
)
166 self
.failUnlessIn("host = 'buildmaster'", tacfile
)
167 self
.failUnlessIn("port = 1234", tacfile
)
168 self
.failUnlessIn("slavename = 'botname'", tacfile
)
169 self
.failUnlessIn("passwd = 'passwd'", tacfile
)
170 self
.failUnlessIn("keepalive = 600", tacfile
)
171 self
.failUnlessIn("BuildSlave(host, port, slavename", tacfile
)
173 makefile
= os
.path
.join(basedir
, "Makefile.sample")
174 self
.failUnlessExists(makefile
)
176 self
.failUnlessExists(os
.path
.join(basedir
, "info", "admin"))
177 self
.failUnlessExists(os
.path
.join(basedir
, "info", "host"))
178 # edit one to make sure the later install doesn't change it
179 f
= open(os
.path
.join(basedir
, "info", "admin"), "wt")
180 f
.write("updated@buildbot.example.org\n")
183 # now verify that running it a second time (with the same options)
184 # does the right thing: nothing changes
185 runner
.createSlave(options
)
188 self
.failIfExists(os
.path
.join(basedir
, "buildbot.tac.new"))
189 admin
= open(os
.path
.join(basedir
, "info", "admin"), "rt").read()
190 self
.failUnlessEqual(admin
, "updated@buildbot.example.org\n")
193 # mutate Makefile.sample, since it should be rewritten
194 oldmake
= open(os
.path
.join(basedir
, "Makefile.sample"), "rt").read()
195 f
= open(os
.path
.join(basedir
, "Makefile.sample"), "wt")
197 f
.write("# additional line added\n")
199 oldtac
= open(os
.path
.join(basedir
, "buildbot.tac"), "rt").read()
201 # now run it again (with different options)
202 options
= runner
.SlaveOptions()
203 options
.parseOptions(["-q", "--keepalive", "30",
204 basedir
, "buildmaster:9999",
205 "newbotname", "passwd"])
206 runner
.createSlave(options
)
209 tac
= open(os
.path
.join(basedir
, "buildbot.tac"), "rt").read()
210 self
.failUnlessEqual(tac
, oldtac
, "shouldn't change existing .tac")
211 self
.failUnlessExists(os
.path
.join(basedir
, "buildbot.tac.new"))
212 tacfile
= open(os
.path
.join(basedir
, "buildbot.tac.new"),"rt").read()
213 self
.failUnlessIn("basedir", tacfile
)
214 self
.failUnlessIn("host = 'buildmaster'", tacfile
)
215 self
.failUnlessIn("port = 9999", tacfile
)
216 self
.failUnlessIn("slavename = 'newbotname'", tacfile
)
217 self
.failUnlessIn("passwd = 'passwd'", tacfile
)
218 self
.failUnlessIn("keepalive = 30", tacfile
)
219 self
.failUnlessIn("BuildSlave(host, port, slavename", tacfile
)
221 make
= open(os
.path
.join(basedir
, "Makefile.sample"), "rt").read()
222 self
.failUnlessEqual(make
, oldmake
, "*should* rewrite Makefile.sample")
224 class Try(unittest
.TestCase
):
225 # test some aspects of the 'buildbot try' command
226 def makeOptions(self
, contents
):
227 if os
.path
.exists(".buildbot"):
228 shutil
.rmtree(".buildbot")
229 os
.mkdir(".buildbot")
230 open(os
.path
.join(".buildbot", "options"), "w").write(contents
)
232 def testGetopt1(self
):
233 opts
= "try_connect = 'ssh'\n" + "try_builders = ['a']\n"
234 self
.makeOptions(opts
)
235 config
= runner
.TryOptions()
236 config
.parseOptions([])
237 t
= tryclient
.Try(config
)
238 self
.failUnlessEqual(t
.connect
, "ssh")
239 self
.failUnlessEqual(t
.builderNames
, ['a'])
241 def testGetopt2(self
):
243 self
.makeOptions(opts
)
244 config
= runner
.TryOptions()
245 config
.parseOptions(['--connect=ssh', '--builder', 'a'])
246 t
= tryclient
.Try(config
)
247 self
.failUnlessEqual(t
.connect
, "ssh")
248 self
.failUnlessEqual(t
.builderNames
, ['a'])
250 def testGetopt3(self
):
252 self
.makeOptions(opts
)
253 config
= runner
.TryOptions()
254 config
.parseOptions(['--connect=ssh',
255 '--builder', 'a', '--builder=b'])
256 t
= tryclient
.Try(config
)
257 self
.failUnlessEqual(t
.connect
, "ssh")
258 self
.failUnlessEqual(t
.builderNames
, ['a', 'b'])
260 def testGetopt4(self
):
261 opts
= "try_connect = 'ssh'\n" + "try_builders = ['a']\n"
262 self
.makeOptions(opts
)
263 config
= runner
.TryOptions()
264 config
.parseOptions(['--builder=b'])
265 t
= tryclient
.Try(config
)
266 self
.failUnlessEqual(t
.connect
, "ssh")
267 self
.failUnlessEqual(t
.builderNames
, ['b'])
269 def testGetTopdir(self
):
270 os
.mkdir("gettopdir")
271 os
.mkdir(os
.path
.join("gettopdir", "foo"))
272 os
.mkdir(os
.path
.join("gettopdir", "foo", "bar"))
273 open(os
.path
.join("gettopdir", "1"),"w").write("1")
274 open(os
.path
.join("gettopdir", "foo", "2"),"w").write("2")
275 open(os
.path
.join("gettopdir", "foo", "bar", "3"),"w").write("3")
277 target
= os
.path
.abspath("gettopdir")
278 t
= tryclient
.getTopdir("1", "gettopdir")
279 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
280 t
= tryclient
.getTopdir("1", os
.path
.join("gettopdir", "foo"))
281 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
282 t
= tryclient
.getTopdir("1", os
.path
.join("gettopdir", "foo", "bar"))
283 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
285 target
= os
.path
.abspath(os
.path
.join("gettopdir", "foo"))
286 t
= tryclient
.getTopdir("2", os
.path
.join("gettopdir", "foo"))
287 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
288 t
= tryclient
.getTopdir("2", os
.path
.join("gettopdir", "foo", "bar"))
289 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
291 target
= os
.path
.abspath(os
.path
.join("gettopdir", "foo", "bar"))
292 t
= tryclient
.getTopdir("3", os
.path
.join("gettopdir", "foo", "bar"))
293 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
295 nonexistent
= "nonexistent\n29fis3kq\tBAR"
296 # hopefully there won't be a real file with that name between here
297 # and the filesystem root.
298 self
.failUnlessRaises(ValueError, tryclient
.getTopdir
, nonexistent
)