Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/buildbot_7_12/buildbot/test/test_steps.py

Issue 12207158: Bye bye buildbot 0.7.12. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: buildbot.test.test_steps -*-
2
3 # create the BuildStep with a fake .remote instance that logs the
4 # .callRemote invocations and compares them against the expected calls. Then
5 # the test harness should send statusUpdate() messages in with assorted
6 # data, eventually calling remote_complete(). Then we can verify that the
7 # Step's rc was correct, and that the status it was supposed to return
8 # matches.
9
10 # sometimes, .callRemote should raise an exception because of a stale
11 # reference. Sometimes it should errBack with an UnknownCommand failure.
12 # Or other failure.
13
14 # todo: test batched updates, by invoking remote_update(updates) instead of
15 # statusUpdate(update). Also involves interrupted builds.
16
17 import sys
18 import os
19
20 from twisted.trial import unittest
21 from twisted.internet import reactor, defer
22
23 from buildbot.sourcestamp import SourceStamp
24 from buildbot.process import buildstep, base, factory
25 from buildbot.process.properties import Properties, WithProperties
26 from buildbot.buildslave import BuildSlave
27 from buildbot.steps import shell, source, python, master
28 from buildbot.status import builder
29 from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, SKIPPED
30 from buildbot.test.runutils import RunMixin, rmtree
31 from buildbot.test.runutils import makeBuildStep, StepTester
32 from buildbot.slave import commands, registry
33
34
35 class MyShellCommand(shell.ShellCommand):
36 started = False
37 def runCommand(self, c):
38 self.started = True
39 self.rc = c
40 return shell.ShellCommand.runCommand(self, c)
41
42 class FakeBuild:
43 pass
44 class FakeBuilder:
45 statusbag = None
46 name = "fakebuilder"
47 class FakeSlaveBuilder:
48 def getSlaveCommandVersion(self, command, oldversion=None):
49 return "1.10"
50
51 class FakeRemote:
52 def __init__(self):
53 self.events = []
54 self.remoteCalls = 0
55 #self.callRemoteNotifier = None
56 def callRemote(self, methname, *args):
57 event = ["callRemote", methname, args]
58 self.events.append(event)
59 ## if self.callRemoteNotifier:
60 ## reactor.callLater(0, self.callRemoteNotifier, event)
61 self.remoteCalls += 1
62 self.deferred = defer.Deferred()
63 return self.deferred
64 def notifyOnDisconnect(self, callback):
65 pass
66 def dontNotifyOnDisconnect(self, callback):
67 pass
68
69
70 class BuildStep(unittest.TestCase):
71
72 def setUp(self):
73 rmtree("test_steps")
74 self.builder = FakeBuilder()
75 self.builder_status = builder.BuilderStatus("fakebuilder")
76 self.builder_status.basedir = "test_steps"
77 self.builder_status.nextBuildNumber = 0
78 os.mkdir(self.builder_status.basedir)
79 self.build_status = self.builder_status.newBuild()
80 req = base.BuildRequest("reason", SourceStamp(), 'test_builder')
81 self.build = base.Build([req])
82 self.build.build_status = self.build_status # fake it
83 self.build.builder = self.builder
84 self.build.slavebuilder = FakeSlaveBuilder()
85 self.remote = FakeRemote()
86 self.finished = 0
87
88 def callback(self, results):
89 self.failed = 0
90 self.failure = None
91 self.results = results
92 self.finished = 1
93 def errback(self, failure):
94 self.failed = 1
95 self.failure = failure
96 self.results = None
97 self.finished = 1
98
99 def testShellCommand1(self):
100 cmd = "argle bargle"
101 dir = "murkle"
102 self.expectedEvents = []
103 buildstep.RemoteCommand.commandCounter[0] = 3
104 c = MyShellCommand(workdir=dir, command=cmd, timeout=10)
105 c.setBuild(self.build)
106 c.setBuildSlave(BuildSlave("name", "password"))
107 self.assertEqual(self.remote.events, self.expectedEvents)
108 c.step_status = self.build_status.addStepWithName("myshellcommand")
109 d = c.startStep(self.remote)
110 self.failUnless(c.started)
111 d.addCallbacks(self.callback, self.errback)
112 d2 = self.poll()
113 d2.addCallback(self._testShellCommand1_2, c)
114 return d2
115 testShellCommand1.timeout = 10
116
117 def poll(self, ignored=None):
118 # TODO: This is gross, but at least it's no longer using
119 # reactor.iterate() . Still, get rid of this some day soon.
120 if self.remote.remoteCalls == 0:
121 d = defer.Deferred()
122 d.addCallback(self.poll)
123 reactor.callLater(0.1, d.callback, None)
124 return d
125 return defer.succeed(None)
126
127 def _testShellCommand1_2(self, res, c):
128 rc = c.rc
129 self.expectedEvents.append(["callRemote", "startCommand",
130 (rc, "3",
131 "shell",
132 {'command': "argle bargle",
133 'workdir': "murkle",
134 'logEnviron' : True,
135 'want_stdout': 1,
136 'want_stderr': 1,
137 'logfiles': {},
138 'timeout': 10,
139 'maxTime': None,
140 'usePTY': 'slave-config',
141 'env': None}) ] )
142 self.assertEqual(self.remote.events, self.expectedEvents)
143
144 # we could do self.remote.deferred.errback(UnknownCommand) here. We
145 # could also do .callback(), but generally the master end silently
146 # ignores the slave's ack
147
148 logs = c.step_status.getLogs()
149 for log in logs:
150 if log.getName() == "log":
151 break
152
153 rc.remoteUpdate({'header':
154 "command 'argle bargle' in dir 'murkle'\n\n"})
155 rc.remoteUpdate({'stdout': "foo\n"})
156 self.assertEqual(log.getText(), "foo\n")
157 self.assertEqual(log.getTextWithHeaders(),
158 "command 'argle bargle' in dir 'murkle'\n\n"
159 "foo\n")
160 rc.remoteUpdate({'stderr': "bar\n"})
161 self.assertEqual(log.getText(), "foo\nbar\n")
162 self.assertEqual(log.getTextWithHeaders(),
163 "command 'argle bargle' in dir 'murkle'\n\n"
164 "foo\nbar\n")
165 rc.remoteUpdate({'rc': 0})
166 self.assertEqual(rc.rc, 0)
167
168 rc.remote_complete()
169 # that should fire the Deferred
170 d = self.poll2()
171 d.addCallback(self._testShellCommand1_3)
172 return d
173
174 def poll2(self, ignored=None):
175 if not self.finished:
176 d = defer.Deferred()
177 d.addCallback(self.poll2)
178 reactor.callLater(0.1, d.callback, None)
179 return d
180 return defer.succeed(None)
181
182 def _testShellCommand1_3(self, res):
183 self.assertEqual(self.failed, 0)
184 self.assertEqual(self.results, 0)
185
186
187 class MyObserver(buildstep.LogObserver):
188 out = ""
189 def outReceived(self, data):
190 self.out = self.out + data
191
192 class Steps(unittest.TestCase):
193 def testMultipleStepInstances(self):
194 steps = [
195 (source.CVS, {'cvsroot': "root", 'cvsmodule': "module"}),
196 (shell.Configure, {'command': "./configure"}),
197 (shell.Compile, {'command': "make"}),
198 (shell.Compile, {'command': "make more"}),
199 (shell.Compile, {'command': "make evenmore"}),
200 (shell.Test, {'command': "make test"}),
201 (shell.Test, {'command': "make testharder"}),
202 ]
203 f = factory.ConfigurableBuildFactory(steps)
204 req = base.BuildRequest("reason", SourceStamp(), 'test_builder')
205 b = f.newBuild([req])
206 #for s in b.steps: print s.name
207
208 def failUnlessClones(self, s1, attrnames):
209 f1 = s1.getStepFactory()
210 f,args = f1
211 s2 = f(**args)
212 for name in attrnames:
213 self.failUnlessEqual(getattr(s1, name), getattr(s2, name))
214
215 def clone(self, s1):
216 f1 = s1.getStepFactory()
217 f,args = f1
218 s2 = f(**args)
219 return s2
220
221 def testClone(self):
222 s1 = shell.ShellCommand(command=["make", "test"],
223 timeout=1234,
224 workdir="here",
225 description="yo",
226 descriptionDone="yoyo",
227 env={'key': 'value'},
228 want_stdout=False,
229 want_stderr=False,
230 logfiles={"name": "filename"},
231 )
232 shellparms = (buildstep.BuildStep.parms +
233 ("remote_kwargs description descriptionDone "
234 "command logfiles").split() )
235 self.failUnlessClones(s1, shellparms)
236
237
238 # test the various methods available to buildsteps
239
240 def test_getProperty(self):
241 s = makeBuildStep("test_steps.Steps.test_getProperty")
242 bs = s.step_status.getBuild()
243
244 s.setProperty("prop1", "value1", "test")
245 s.setProperty("prop2", "value2", "test")
246 self.failUnlessEqual(s.getProperty("prop1"), "value1")
247 self.failUnlessEqual(bs.getProperty("prop1"), "value1")
248 self.failUnlessEqual(s.getProperty("prop2"), "value2")
249 self.failUnlessEqual(bs.getProperty("prop2"), "value2")
250 s.setProperty("prop1", "value1a", "test")
251 self.failUnlessEqual(s.getProperty("prop1"), "value1a")
252 self.failUnlessEqual(bs.getProperty("prop1"), "value1a")
253
254
255 def test_addURL(self):
256 s = makeBuildStep("test_steps.Steps.test_addURL")
257 s.addURL("coverage", "http://coverage.example.org/target")
258 s.addURL("icon", "http://coverage.example.org/icon.png")
259 bs = s.step_status
260 links = bs.getURLs()
261 expected = {"coverage": "http://coverage.example.org/target",
262 "icon": "http://coverage.example.org/icon.png",
263 }
264 self.failUnlessEqual(links, expected)
265
266 def test_addLog(self):
267 s = makeBuildStep("test_steps.Steps.test_addLog")
268 l = s.addLog("newlog")
269 l.addStdout("some stdout here")
270 l.finish()
271 bs = s.step_status
272 logs = bs.getLogs()
273 self.failUnlessEqual(len(logs), 1)
274 l1 = logs[0]
275 self.failUnlessEqual(l1.getText(), "some stdout here")
276 l1a = s.getLog("newlog")
277 self.failUnlessEqual(l1a.getText(), "some stdout here")
278
279 def test_addHTMLLog(self):
280 s = makeBuildStep("test_steps.Steps.test_addHTMLLog")
281 l = s.addHTMLLog("newlog", "some html here")
282 bs = s.step_status
283 logs = bs.getLogs()
284 self.failUnlessEqual(len(logs), 1)
285 l1 = logs[0]
286 self.failUnless(isinstance(l1, builder.HTMLLogFile))
287 self.failUnlessEqual(l1.getText(), "some html here")
288
289 def test_addCompleteLog(self):
290 s = makeBuildStep("test_steps.Steps.test_addCompleteLog")
291 l = s.addCompleteLog("newlog", "some stdout here")
292 bs = s.step_status
293 logs = bs.getLogs()
294 self.failUnlessEqual(len(logs), 1)
295 l1 = logs[0]
296 self.failUnlessEqual(l1.getText(), "some stdout here")
297 l1a = s.getLog("newlog")
298 self.failUnlessEqual(l1a.getText(), "some stdout here")
299
300 def test_addLogObserver(self):
301 s = makeBuildStep("test_steps.Steps.test_addLogObserver")
302 bss = s.step_status
303 o1,o2,o3 = MyObserver(), MyObserver(), MyObserver()
304
305 # add the log before the observer
306 l1 = s.addLog("one")
307 l1.addStdout("onestuff")
308 s.addLogObserver("one", o1)
309 self.failUnlessEqual(o1.out, "onestuff")
310 l1.addStdout(" morestuff")
311 self.failUnlessEqual(o1.out, "onestuff morestuff")
312
313 # add the observer before the log
314 s.addLogObserver("two", o2)
315 l2 = s.addLog("two")
316 l2.addStdout("twostuff")
317 self.failUnlessEqual(o2.out, "twostuff")
318
319 # test more stuff about ShellCommands
320
321 def test_description(self):
322 s = makeBuildStep("test_steps.Steps.test_description.1",
323 step_class=shell.ShellCommand,
324 workdir="dummy",
325 description=["list", "of", "strings"],
326 descriptionDone=["another", "list"])
327 self.failUnlessEqual(s.description, ["list", "of", "strings"])
328 self.failUnlessEqual(s.descriptionDone, ["another", "list"])
329
330 s = makeBuildStep("test_steps.Steps.test_description.2",
331 step_class=shell.ShellCommand,
332 workdir="dummy",
333 description="single string",
334 descriptionDone="another string")
335 self.failUnlessEqual(s.description, ["single string"])
336 self.failUnlessEqual(s.descriptionDone, ["another string"])
337
338 class VersionCheckingStep(buildstep.BuildStep):
339 def start(self):
340 # give our test a chance to run. It is non-trivial for a buildstep to
341 # claw its way back out to the test case which is currently running.
342 master = self.build.builder.botmaster.parent
343 checker = master._checker
344 checker(self)
345 # then complete
346 self.finished(buildstep.SUCCESS)
347
348 version_config = """
349 from buildbot.process import factory
350 from buildbot.test.test_steps import VersionCheckingStep
351 from buildbot.buildslave import BuildSlave
352 from buildbot.config import BuilderConfig
353 BuildmasterConfig = c = {}
354 f1 = factory.BuildFactory([
355 factory.s(VersionCheckingStep),
356 ])
357 c['slaves'] = [BuildSlave('bot1', 'sekrit')]
358 c['schedulers'] = []
359 c['builders'] = [
360 BuilderConfig(name='quick', slavename='bot1', factory=f1,
361 builddir='quickdir', slavebuilddir='quickslavedir'),
362 ]
363 c['slavePortnum'] = 0
364 """
365
366 class SlaveVersion(RunMixin, unittest.TestCase):
367 def setUp(self):
368 RunMixin.setUp(self)
369 self.master.loadConfig(version_config)
370 self.master.startService()
371 d = self.connectSlave(["quick"])
372 return d
373
374 def doBuild(self, buildername):
375 br = base.BuildRequest("forced", SourceStamp(), 'test_builder')
376 d = br.waitUntilFinished()
377 self.control.getBuilder(buildername).requestBuild(br)
378 return d
379
380
381 def checkCompare(self, s):
382 cver = commands.command_version
383 v = s.slaveVersion("svn", None)
384 # this insures that we are getting the version correctly
385 self.failUnlessEqual(s.slaveVersion("svn", None), cver)
386 # and that non-existent commands do not provide a version
387 self.failUnlessEqual(s.slaveVersion("NOSUCHCOMMAND"), None)
388 # TODO: verify that a <=0.5.0 buildslave (which does not implement
389 # remote_getCommands) handles oldversion= properly. This requires a
390 # mutant slave which does not offer that method.
391 #self.failUnlessEqual(s.slaveVersion("NOSUCHCOMMAND", "old"), "old")
392
393 # now check the comparison functions
394 self.failIf(s.slaveVersionIsOlderThan("svn", cver))
395 self.failIf(s.slaveVersionIsOlderThan("svn", "1.1"))
396 self.failUnless(s.slaveVersionIsOlderThan("svn", cver + ".1"))
397
398 self.failUnlessEqual(s.getSlaveName(), "bot1")
399
400 def testCompare(self):
401 self.master._checker = self.checkCompare
402 d = self.doBuild("quick")
403 return d
404
405
406 class _SimpleBuildStep(buildstep.BuildStep):
407 def start(self):
408 args = {"arg1": "value"}
409 cmd = buildstep.RemoteCommand("simple", args)
410 d = self.runCommand(cmd)
411 d.addCallback(lambda res: self.finished(SUCCESS))
412
413 class _SimpleCommand(commands.Command):
414 def start(self):
415 self.builder.flag = True
416 self.builder.flag_args = self.args
417 return defer.succeed(None)
418
419 class CheckStepTester(StepTester, unittest.TestCase):
420 def testSimple(self):
421 self.slavebase = "testSimple.slave"
422 self.masterbase = "testSimple.master"
423 sb = self.makeSlaveBuilder()
424 sb.flag = False
425 registry.registerSlaveCommand("simple", _SimpleCommand, "1")
426 step = self.makeStep(_SimpleBuildStep)
427 d = self.runStep(step)
428 def _checkSimple(results):
429 self.failUnless(sb.flag)
430 self.failUnlessEqual(sb.flag_args, {"arg1": "value"})
431 d.addCallback(_checkSimple)
432 return d
433
434 class Python(StepTester, unittest.TestCase):
435 def testPyFlakes1(self):
436 self.masterbase = "Python.testPyFlakes1"
437 step = self.makeStep(python.PyFlakes)
438 output = \
439 """pyflakes buildbot
440 buildbot/changes/freshcvsmail.py:5: 'FCMaildirSource' imported but unused
441 buildbot/clients/debug.py:9: redefinition of unused 'gtk' from line 9
442 buildbot/clients/debug.py:9: 'gnome' imported but unused
443 buildbot/scripts/runner.py:323: redefinition of unused 'run' from line 321
444 buildbot/scripts/runner.py:325: redefinition of unused 'run' from line 323
445 buildbot/scripts/imaginary.py:12: undefined name 'size'
446 buildbot/scripts/imaginary.py:18: 'from buildbot import *' used; unable to detec t undefined names
447 """
448 log = step.addLog("stdio")
449 log.addStdout(output)
450 log.finish()
451 step.createSummary(log)
452 desc = step.descriptionDone
453 self.failUnless("unused=2" in desc)
454 self.failUnless("undefined=1" in desc)
455 self.failUnless("redefs=3" in desc)
456 self.failUnless("import*=1" in desc)
457 self.failIf("misc=" in desc)
458
459 self.failUnlessEqual(step.getProperty("pyflakes-unused"), 2)
460 self.failUnlessEqual(step.getProperty("pyflakes-undefined"), 1)
461 self.failUnlessEqual(step.getProperty("pyflakes-redefs"), 3)
462 self.failUnlessEqual(step.getProperty("pyflakes-import*"), 1)
463 self.failUnlessEqual(step.getProperty("pyflakes-misc"), 0)
464 self.failUnlessEqual(step.getProperty("pyflakes-total"), 7)
465
466 logs = {}
467 for log in step.step_status.getLogs():
468 logs[log.getName()] = log
469
470 for name in ["unused", "undefined", "redefs", "import*"]:
471 self.failUnless(name in logs)
472 self.failIf("misc" in logs)
473 lines = logs["unused"].readlines()
474 self.failUnlessEqual(len(lines), 2)
475 self.failUnlessEqual(lines[0], "buildbot/changes/freshcvsmail.py:5: 'FCM aildirSource' imported but unused\n")
476
477 cmd = buildstep.RemoteCommand(None, {})
478 cmd.rc = 0
479 results = step.evaluateCommand(cmd)
480 self.failUnlessEqual(results, FAILURE) # because of the 'undefined'
481
482 def testPyFlakes2(self):
483 self.masterbase = "Python.testPyFlakes2"
484 step = self.makeStep(python.PyFlakes)
485 output = \
486 """pyflakes buildbot
487 some more text here that should be ignored
488 buildbot/changes/freshcvsmail.py:5: 'FCMaildirSource' imported but unused
489 buildbot/clients/debug.py:9: redefinition of unused 'gtk' from line 9
490 buildbot/clients/debug.py:9: 'gnome' imported but unused
491 buildbot/scripts/runner.py:323: redefinition of unused 'run' from line 321
492 buildbot/scripts/runner.py:325: redefinition of unused 'run' from line 323
493 buildbot/scripts/imaginary.py:12: undefined name 'size'
494 could not compile 'blah/blah.py':3:
495 pretend there was an invalid line here
496 buildbot/scripts/imaginary.py:18: 'from buildbot import *' used; unable to detec t undefined names
497 """
498 log = step.addLog("stdio")
499 log.addStdout(output)
500 log.finish()
501 step.createSummary(log)
502 desc = step.descriptionDone
503 self.failUnless("unused=2" in desc)
504 self.failUnless("undefined=1" in desc)
505 self.failUnless("redefs=3" in desc)
506 self.failUnless("import*=1" in desc)
507 self.failUnless("misc=2" in desc)
508
509
510 def testPyFlakes3(self):
511 self.masterbase = "Python.testPyFlakes3"
512 step = self.makeStep(python.PyFlakes)
513 output = \
514 """buildbot/changes/freshcvsmail.py:5: 'FCMaildirSource' imported but unused
515 buildbot/clients/debug.py:9: redefinition of unused 'gtk' from line 9
516 buildbot/clients/debug.py:9: 'gnome' imported but unused
517 buildbot/scripts/runner.py:323: redefinition of unused 'run' from line 321
518 buildbot/scripts/runner.py:325: redefinition of unused 'run' from line 323
519 buildbot/scripts/imaginary.py:12: undefined name 'size'
520 buildbot/scripts/imaginary.py:18: 'from buildbot import *' used; unable to detec t undefined names
521 """
522 log = step.addLog("stdio")
523 log.addStdout(output)
524 log.finish()
525 step.createSummary(log)
526 desc = step.descriptionDone
527 self.failUnless("unused=2" in desc)
528 self.failUnless("undefined=1" in desc)
529 self.failUnless("redefs=3" in desc)
530 self.failUnless("import*=1" in desc)
531 self.failIf("misc" in desc)
532
533
534 class OrdinaryCompile(shell.Compile):
535 warningPattern = "ordinary line"
536
537 class Warnings(StepTester, unittest.TestCase):
538 def testCompile1(self):
539 self.masterbase = "Warnings.testCompile1"
540 step = self.makeStep(shell.Compile)
541 output = \
542 """Compile started
543 normal line
544 warning: oh noes!
545 ordinary line
546 error (but we aren't looking for errors now, are we)
547 line 23: warning: we are now on line 23
548 ending line
549 """
550 log = step.addLog("stdio")
551 log.addStdout(output)
552 log.finish()
553 step.createSummary(log)
554 self.failUnlessEqual(step.getProperty("warnings-count"), 2)
555 logs = {}
556 for log in step.step_status.getLogs():
557 logs[log.getName()] = log
558 self.failUnless("warnings" in logs)
559 lines = logs["warnings"].readlines()
560 self.failUnlessEqual(len(lines), 2)
561 self.failUnlessEqual(lines[0], "warning: oh noes!\n")
562 self.failUnlessEqual(lines[1],
563 "line 23: warning: we are now on line 23\n")
564
565 cmd = buildstep.RemoteCommand(None, {})
566 cmd.rc = 0
567 results = step.evaluateCommand(cmd)
568 self.failUnlessEqual(results, WARNINGS)
569
570 def testCompile2(self):
571 self.masterbase = "Warnings.testCompile2"
572 step = self.makeStep(shell.Compile, warningPattern="ordinary line")
573 output = \
574 """Compile started
575 normal line
576 warning: oh noes!
577 ordinary line
578 error (but we aren't looking for errors now, are we)
579 line 23: warning: we are now on line 23
580 ending line
581 """
582 log = step.addLog("stdio")
583 log.addStdout(output)
584 log.finish()
585 step.createSummary(log)
586 self.failUnlessEqual(step.getProperty("warnings-count"), 1)
587 logs = {}
588 for log in step.step_status.getLogs():
589 logs[log.getName()] = log
590 self.failUnless("warnings" in logs)
591 lines = logs["warnings"].readlines()
592 self.failUnlessEqual(len(lines), 1)
593 self.failUnlessEqual(lines[0], "ordinary line\n")
594
595 cmd = buildstep.RemoteCommand(None, {})
596 cmd.rc = 0
597 results = step.evaluateCommand(cmd)
598 self.failUnlessEqual(results, WARNINGS)
599
600 def testCompile3(self):
601 self.masterbase = "Warnings.testCompile3"
602 step = self.makeStep(OrdinaryCompile)
603 output = \
604 """Compile started
605 normal line
606 warning: oh noes!
607 ordinary line
608 error (but we aren't looking for errors now, are we)
609 line 23: warning: we are now on line 23
610 ending line
611 """
612 step.setProperty("warnings-count", 10, "test")
613 log = step.addLog("stdio")
614 log.addStdout(output)
615 log.finish()
616 step.createSummary(log)
617 self.failUnlessEqual(step.getProperty("warnings-count"), 11)
618 logs = {}
619 for log in step.step_status.getLogs():
620 logs[log.getName()] = log
621 self.failUnless("warnings" in logs)
622 lines = logs["warnings"].readlines()
623 self.failUnlessEqual(len(lines), 1)
624 self.failUnlessEqual(lines[0], "ordinary line\n")
625
626 cmd = buildstep.RemoteCommand(None, {})
627 cmd.rc = 0
628 results = step.evaluateCommand(cmd)
629 self.failUnlessEqual(results, WARNINGS)
630
631 def testCompile4(self):
632 # Test suppression of warnings.
633 self.masterbase = "Warnings.testCompile4"
634 step = self.makeStep(shell.Compile,
635 warningPattern="^(.*?):([0-9]+): [Ww]arning: (.*)$" ,
636 warningExtractor=shell.Compile.warnExtractFromRegex pGroups,
637 directoryEnterPattern="make.*: Entering directory [ \"`'](.*)['`\"]",
638 directoryLeavePattern="make.*: Leaving directory")
639 step.addSuppression([(r"/subdir/", r"xyzzy", None, None),
640 (r"foo.c", r".*", None, 20),
641 (r"foo.c", r".*", 200, None),
642 (r"foo.c", r".*", 50, 50),
643 (r"xxx", r".*", None, None),
644 ])
645 log = step.addLog("stdio")
646 output = \
647 """Making all in .
648 make[1]: Entering directory `/abs/path/build'
649 foo.c:10: warning: `bar' defined but not used
650 foo.c:50: warning: `bar' defined but not used
651 make[2]: Entering directory `/abs/path/build/subdir'
652 baz.c:33: warning: `xyzzy' defined but not used
653 baz.c:34: warning: `magic' defined but not used
654 make[2]: Leaving directory `/abs/path/build/subdir'
655 foo.c:100: warning: `xyzzy' defined but not used
656 foo.c:200: warning: `bar' defined but not used
657 make[2]: Leaving directory `/abs/path/build'
658 """
659 log.addStdout(output)
660 log.finish()
661 step.createSummary(log)
662 self.failUnlessEqual(step.getProperty("warnings-count"), 2)
663 logs = {}
664 for log in step.step_status.getLogs():
665 logs[log.getName()] = log
666 self.failUnless("warnings" in logs)
667 lines = logs["warnings"].readlines()
668 self.failUnlessEqual(len(lines), 2)
669 self.failUnlessEqual(lines[0], "baz.c:34: warning: `magic' defined but n ot used\n")
670 self.failUnlessEqual(lines[1], "foo.c:100: warning: `xyzzy' defined but not used\n")
671
672 cmd = buildstep.RemoteCommand(None, {})
673 cmd.rc = 0
674 results = step.evaluateCommand(cmd)
675 self.failUnlessEqual(results, WARNINGS)
676
677 def filterArgs(self, args):
678 if "writer" in args:
679 args["writer"] = self.wrap(args["writer"])
680 return args
681
682 suppressionFileData = """
683 # Sample suppressions file for testing
684
685 /subdir/ : xyzzy
686 foo.c: .* : 0-20
687 foo.c: .*: 200-10000
688 foo.c :.*: 50
689 xxx : .*
690 """
691 def testCompile5(self):
692 # Test downloading warning suppression file from slave.
693 self.slavebase = "Warnings.testCompile5.slave"
694 self.masterbase = "Warnings.testCompile5.master"
695 sb = self.makeSlaveBuilder()
696 os.mkdir(os.path.join(self.slavebase, self.slavebuilderbase,
697 "build"))
698 output = \
699 """Making all in .
700 make[1]: Entering directory `/abs/path/build'
701 foo.c:10: warning: `bar' defined but not used
702 foo.c:50: warning: `bar' defined but not used
703 make[2]: Entering directory `/abs/path/build/subdir'
704 baz.c:33: warning: `xyzzy' defined but not used
705 baz.c:34: warning: `magic' defined but not used
706 make[2]: Leaving directory `/abs/path/build/subdir'
707 foo.c:100: warning: `xyzzy' defined but not used
708 foo.c:200: warning: `bar' defined but not used
709 make[2]: Leaving directory `/abs/path/build'
710 """
711 printStatement = ('print """%s"""' % output)
712 step = self.makeStep(shell.Compile,
713 warningPattern="^(.*?):([0-9]+): [Ww]arning: (.*)$" ,
714 warningExtractor=shell.Compile.warnExtractFromRegex pGroups,
715 suppressionFile="warnings.supp",
716 command=[sys.executable, "-c", printStatement])
717 self.failUnlessEqual(step.step_status.getText(), ['compiling'])
718 slavesrc = os.path.join(self.slavebase,
719 self.slavebuilderbase,
720 "build",
721 "warnings.supp")
722 open(slavesrc, "w").write(self.suppressionFileData)
723
724 d = self.runStep(step)
725 def _checkResult(result):
726 self.failUnlessEqual(step.getProperty("warnings-count"), 2)
727 logs = {}
728 for log in step.step_status.getLogs():
729 logs[log.getName()] = log
730 self.failUnless("warnings" in logs)
731 lines = logs["warnings"].readlines()
732 self.failUnlessEqual(len(lines), 2)
733 self.failUnlessEqual(lines[0], "baz.c:34: warning: `magic' defined b ut not used\n")
734 self.failUnlessEqual(lines[1], "foo.c:100: warning: `xyzzy' defined but not used\n")
735 self.failUnlessEqual(step.step_status.getText(), ['compile',
736 'warnings'])
737
738 d.addCallback(_checkResult)
739 return d
740
741 class TreeSize(StepTester, unittest.TestCase):
742 def testTreeSize(self):
743 self.slavebase = "TreeSize.testTreeSize.slave"
744 self.masterbase = "TreeSize.testTreeSize.master"
745
746 sb = self.makeSlaveBuilder()
747 step = self.makeStep(shell.TreeSize)
748 d = self.runStep(step)
749 def _check(results):
750 self.failUnlessEqual(results, SUCCESS)
751 kib = step.getProperty("tree-size-KiB")
752 self.failUnless(isinstance(kib, int))
753 self.failUnless(kib < 100) # should be empty, I get '4'
754 s = step.step_status
755 self.failUnlessEqual(" ".join(s.getText()),
756 "treesize %d KiB" % kib)
757 d.addCallback(_check)
758 return d
759
760 class FakeCommand:
761 def __init__(self, rc):
762 self.rc = rc
763
764 class PerlModuleTest(StepTester, unittest.TestCase):
765 def testAllTestsPassed(self):
766 self.masterbase = "PMT.testAllTestsPassed"
767 step = self.makeStep(shell.PerlModuleTest)
768 output = \
769 """ok 1
770 ok 2
771 All tests successful
772 Files=1, Tests=123, other stuff
773 """
774 log = step.addLog("stdio")
775 log.addStdout(output)
776 log.finish()
777 rc = step.evaluateCommand(FakeCommand(rc=241))
778 self.failUnlessEqual(rc, SUCCESS)
779 ss = step.step_status
780 self.failUnlessEqual(ss.getStatistic('tests-failed'), 0)
781 self.failUnlessEqual(ss.getStatistic('tests-total'), 123)
782 self.failUnlessEqual(ss.getStatistic('tests-passed'), 123)
783
784 def testFailures_OldTestHarness(self):
785 self.masterbase = "PMT.testFailures_OldTestHarness"
786 step = self.makeStep(shell.PerlModuleTest)
787 output = \
788 """
789 ok 1
790 ok 2
791 3/7 subtests failed
792 """
793 log = step.addLog("stdio")
794 log.addStdout(output)
795 log.finish()
796 rc = step.evaluateCommand(FakeCommand(rc = 123))
797 self.failUnlessEqual(rc, FAILURE)
798 ss = step.step_status
799 self.failUnlessEqual(ss.getStatistic('tests-failed'), 3)
800 self.failUnlessEqual(ss.getStatistic('tests-total'), 7)
801 self.failUnlessEqual(ss.getStatistic('tests-passed'), 4)
802
803 def testFailures_UnparseableStdio(self):
804 self.masterbase = "PMT.testFailures_UnparseableStdio"
805 step = self.makeStep(shell.PerlModuleTest)
806 output = \
807 """
808 just some random stuff, you know
809 """
810 log = step.addLog("stdio")
811 log.addStdout(output)
812 log.finish()
813 rc = step.evaluateCommand(FakeCommand(rc = 243))
814 self.failUnlessEqual(rc, 243)
815 ss = step.step_status
816 self.failUnlessEqual(ss.getStatistic('tests-failed'), None)
817 self.failUnlessEqual(ss.getStatistic('tests-total'), None)
818 self.failUnlessEqual(ss.getStatistic('tests-passed'), None)
819
820 def testFailures_NewTestHarness(self):
821 self.masterbase = "PMT.testFailures_NewTestHarness"
822 step = self.makeStep(shell.PerlModuleTest)
823 output = \
824 """
825 # Looks like you failed 15 tests of 18.
826 tests/services.......................... Failed 265/30904 subtests
827 (less 16 skipped subtests: 30623 okay)
828 tests/simple_query_backend..............ok
829 tests/simple_query_middleware...........ok
830 tests/soap_globalcollect................ok
831 tests/three_d_me........................ok
832 tests/three_d_me_callback...............ok
833 tests/transaction_create................ok
834 tests/unique_txid.......................ok
835
836 Test Summary Report
837 -------------------
838 tests/000policies (Wstat: 5632 Tests: 9078 Failed: 22)
839 Failed tests: 2409, 2896-2897, 2900-2901, 2940-2941, 2944-2945
840 2961-2962, 2965-2966, 2969-2970, 2997-2998
841 3262, 3281-3282, 3288-3289
842 Non-zero exit status: 22
843 tests/services (Wstat: 0 Tests: 30904 Failed: 265)
844 Failed tests: 14, 16-21, 64-69, 71-96, 98, 30157, 30159
845 30310, 30316, 30439-30543, 30564, 30566-30577
846 30602, 30604-30607, 30609-30612, 30655
847 30657-30668, 30675, 30697-30716, 30718-30720
848 30722-30736, 30773-30774, 30776-30777, 30786
849 30791, 30795, 30797, 30801, 30822-30827
850 30830-30831, 30848-30855, 30858-30859, 30888-30899
851 30901, 30903-30904
852 Files=68, Tests=264809, 1944 wallclock secs (17.59 usr 0.63 sys + 470.04 cusr 1 31.40 csys = 619.66 CPU)
853 Result: FAIL
854 """
855 log = step.addLog("stdio")
856 log.addStdout(output)
857 log.finish()
858 rc = step.evaluateCommand(FakeCommand(rc=87))
859 self.failUnlessEqual(rc, FAILURE)
860 ss = step.step_status
861 self.failUnlessEqual(ss.getStatistic('tests-failed'), 287)
862 self.failUnlessEqual(ss.getStatistic('tests-total'), 264809)
863 self.failUnlessEqual(ss.getStatistic('tests-passed'), 264522)
864
865 class MasterShellCommand(StepTester, unittest.TestCase):
866 def testMasterShellCommand(self):
867 self.slavebase = "testMasterShellCommand.slave"
868 self.masterbase = "testMasterShellCommand.master"
869 sb = self.makeSlaveBuilder()
870 step = self.makeStep(master.MasterShellCommand, command=['echo',
871 WithProperties("hi build-%(other)s.tar.gz")])
872 step.build.setProperty("other", "foo", "test")
873
874 # we can't invoke runStep until the reactor is started .. hence this
875 # little dance
876 d = defer.Deferred()
877 def _dotest(_):
878 return self.runStep(step)
879 d.addCallback(_dotest)
880
881 def _check(results):
882 self.failUnlessEqual(results, SUCCESS)
883 logtxt = step.getLog("stdio").getText()
884 self.failUnlessEqual(logtxt.strip(), "hi build-foo.tar.gz")
885 d.addCallback(_check)
886 reactor.callLater(0, d.callback, None)
887 return d
888
889 def testMasterShellCommand_badexit(self):
890 self.slavebase = "testMasterShellCommand_badexit.slave"
891 self.masterbase = "testMasterShellCommand_badexit.master"
892 sb = self.makeSlaveBuilder()
893 step = self.makeStep(master.MasterShellCommand, command="exit 1")
894
895 # we can't invoke runStep until the reactor is started .. hence this
896 # little dance
897 d = defer.Deferred()
898 def _dotest(_):
899 return self.runStep(step)
900 d.addCallback(_dotest)
901
902 def _check(results):
903 self.failUnlessEqual(results, FAILURE)
904 d.addCallback(_check)
905 reactor.callLater(0, d.callback, None)
906 return d
907
908 class SuccessStep(buildstep.BuildStep):
909 def start(self):
910 self.finished(buildstep.SUCCESS)
911
912 class ConditionalStepTest(StepTester, unittest.TestCase):
913 def testNotSkipped(self):
914 self.slavebase = "testNotSkipped.slave"
915 self.masterbase = "testNotSkipped.master"
916 sb = self.makeSlaveBuilder()
917 step = self.makeStep(SuccessStep)
918 d = self.runStep(step)
919 def _checkResults(results):
920 self.failUnlessEqual(SUCCESS, results)
921 d.addCallback(_checkResults)
922 return d
923
924 def testSkipped(self):
925 self.slavebase = "testSkipped.slave"
926 self.masterbase = "testSkipped.master"
927 sb = self.makeSlaveBuilder()
928 step = self.makeStep(SuccessStep, doStepIf=False)
929 d = self.runStep(step)
930 def _checkResults(results):
931 self.failUnlessEqual(SKIPPED, results)
932 d.addCallback(_checkResults)
933 return d
934
935 def testNotSkippedFunc(self):
936 self.slavebase = "testNotSkippedFunc.slave"
937 self.masterbase = "testNotSkippedFunc.master"
938 sb = self.makeSlaveBuilder()
939 step = self.makeStep(SuccessStep, doStepIf=lambda s: True)
940 d = self.runStep(step)
941 def _checkResults(results):
942 self.failUnlessEqual(SUCCESS, results)
943 d.addCallback(_checkResults)
944 return d
945
946 def testSkippedFunc(self):
947 self.slavebase = "testSkippedFunc.slave"
948 self.masterbase = "testSkippedFunc.master"
949 sb = self.makeSlaveBuilder()
950 step = self.makeStep(SuccessStep, doStepIf=lambda s: False)
951 d = self.runStep(step)
952 def _checkResults(results):
953 self.failUnlessEqual(SKIPPED, results)
954 d.addCallback(_checkResults)
955 return d
OLDNEW
« no previous file with comments | « third_party/buildbot_7_12/buildbot/test/test_status_push.py ('k') | third_party/buildbot_7_12/buildbot/test/test_svnpoller.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698