2 # this file tests the 'buildbot' command, with its various sub-commands
4 from twisted
.trial
import unittest
5 from twisted
.python
import usage
6 import os
, 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("buildmaster_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(buildmaster_host, port, slavename",
174 makefile
= os
.path
.join(basedir
, "Makefile.sample")
175 self
.failUnlessExists(makefile
)
177 self
.failUnlessExists(os
.path
.join(basedir
, "info", "admin"))
178 self
.failUnlessExists(os
.path
.join(basedir
, "info", "host"))
179 # edit one to make sure the later install doesn't change it
180 f
= open(os
.path
.join(basedir
, "info", "admin"), "wt")
181 f
.write("updated@buildbot.example.org\n")
184 # now verify that running it a second time (with the same options)
185 # does the right thing: nothing changes
186 runner
.createSlave(options
)
189 self
.failIfExists(os
.path
.join(basedir
, "buildbot.tac.new"))
190 admin
= open(os
.path
.join(basedir
, "info", "admin"), "rt").read()
191 self
.failUnlessEqual(admin
, "updated@buildbot.example.org\n")
194 # mutate Makefile.sample, since it should be rewritten
195 oldmake
= open(os
.path
.join(basedir
, "Makefile.sample"), "rt").read()
196 f
= open(os
.path
.join(basedir
, "Makefile.sample"), "wt")
198 f
.write("# additional line added\n")
200 oldtac
= open(os
.path
.join(basedir
, "buildbot.tac"), "rt").read()
202 # now run it again (with different options)
203 options
= runner
.SlaveOptions()
204 options
.parseOptions(["-q", "--keepalive", "30",
205 basedir
, "buildmaster:9999",
206 "newbotname", "passwd"])
207 runner
.createSlave(options
)
210 tac
= open(os
.path
.join(basedir
, "buildbot.tac"), "rt").read()
211 self
.failUnlessEqual(tac
, oldtac
, "shouldn't change existing .tac")
212 self
.failUnlessExists(os
.path
.join(basedir
, "buildbot.tac.new"))
213 tacfile
= open(os
.path
.join(basedir
, "buildbot.tac.new"),"rt").read()
214 self
.failUnlessIn("basedir", tacfile
)
215 self
.failUnlessIn("buildmaster_host = 'buildmaster'", tacfile
)
216 self
.failUnlessIn("port = 9999", tacfile
)
217 self
.failUnlessIn("slavename = 'newbotname'", tacfile
)
218 self
.failUnlessIn("passwd = 'passwd'", tacfile
)
219 self
.failUnlessIn("keepalive = 30", tacfile
)
220 self
.failUnlessIn("BuildSlave(buildmaster_host, port, slavename",
223 make
= open(os
.path
.join(basedir
, "Makefile.sample"), "rt").read()
224 self
.failUnlessEqual(make
, oldmake
, "*should* rewrite Makefile.sample")
226 class Try(unittest
.TestCase
):
227 # test some aspects of the 'buildbot try' command
228 def makeOptions(self
, contents
):
229 if os
.path
.exists(".buildbot"):
230 shutil
.rmtree(".buildbot")
231 os
.mkdir(".buildbot")
232 open(os
.path
.join(".buildbot", "options"), "w").write(contents
)
234 def testGetopt1(self
):
235 opts
= "try_connect = 'ssh'\n" + "try_builders = ['a']\n"
236 self
.makeOptions(opts
)
237 config
= runner
.TryOptions()
238 config
.parseOptions([])
239 t
= tryclient
.Try(config
)
240 self
.failUnlessEqual(t
.connect
, "ssh")
241 self
.failUnlessEqual(t
.builderNames
, ['a'])
243 def testGetopt2(self
):
245 self
.makeOptions(opts
)
246 config
= runner
.TryOptions()
247 config
.parseOptions(['--connect=ssh', '--builder', 'a'])
248 t
= tryclient
.Try(config
)
249 self
.failUnlessEqual(t
.connect
, "ssh")
250 self
.failUnlessEqual(t
.builderNames
, ['a'])
252 def testGetopt3(self
):
254 self
.makeOptions(opts
)
255 config
= runner
.TryOptions()
256 config
.parseOptions(['--connect=ssh',
257 '--builder', 'a', '--builder=b'])
258 t
= tryclient
.Try(config
)
259 self
.failUnlessEqual(t
.connect
, "ssh")
260 self
.failUnlessEqual(t
.builderNames
, ['a', 'b'])
262 def testGetopt4(self
):
263 opts
= "try_connect = 'ssh'\n" + "try_builders = ['a']\n"
264 self
.makeOptions(opts
)
265 config
= runner
.TryOptions()
266 config
.parseOptions(['--builder=b'])
267 t
= tryclient
.Try(config
)
268 self
.failUnlessEqual(t
.connect
, "ssh")
269 self
.failUnlessEqual(t
.builderNames
, ['b'])
271 def testGetTopdir(self
):
272 os
.mkdir("gettopdir")
273 os
.mkdir(os
.path
.join("gettopdir", "foo"))
274 os
.mkdir(os
.path
.join("gettopdir", "foo", "bar"))
275 open(os
.path
.join("gettopdir", "1"),"w").write("1")
276 open(os
.path
.join("gettopdir", "foo", "2"),"w").write("2")
277 open(os
.path
.join("gettopdir", "foo", "bar", "3"),"w").write("3")
279 target
= os
.path
.abspath("gettopdir")
280 t
= tryclient
.getTopdir("1", "gettopdir")
281 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
282 t
= tryclient
.getTopdir("1", os
.path
.join("gettopdir", "foo"))
283 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
284 t
= tryclient
.getTopdir("1", os
.path
.join("gettopdir", "foo", "bar"))
285 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
287 target
= os
.path
.abspath(os
.path
.join("gettopdir", "foo"))
288 t
= tryclient
.getTopdir("2", os
.path
.join("gettopdir", "foo"))
289 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
290 t
= tryclient
.getTopdir("2", os
.path
.join("gettopdir", "foo", "bar"))
291 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
293 target
= os
.path
.abspath(os
.path
.join("gettopdir", "foo", "bar"))
294 t
= tryclient
.getTopdir("3", os
.path
.join("gettopdir", "foo", "bar"))
295 self
.failUnlessEqual(os
.path
.abspath(t
), target
)
297 nonexistent
= "nonexistent\n29fis3kq\tBAR"
298 # hopefully there won't be a real file with that name between here
299 # and the filesystem root.
300 self
.failUnlessRaises(ValueError, tryclient
.getTopdir
, nonexistent
)