Ticket #251: buildbot_colors.diff
| File buildbot_colors.diff, 30.1 kB (added by nhemingway, 9 months ago) |
|---|
-
old-buildbot_colors/buildbot/changes/changes.py
old new 128 128 129 129 def getText(self): 130 130 return [html.escape(self.who)] 131 def getColor(self):132 return "white"133 131 def getLogs(self): 134 132 return {} 135 133 -
old-buildbot_colors/buildbot/clients/gtkPanes.py
old new 16 16 from buildbot.clients.base import TextClient 17 17 from buildbot.util import now 18 18 19 from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, EXCEPTION 20 19 21 ''' 20 22 class Pane: 21 23 def __init__(self): … … 329 331 def gotLastBuild(self, build): 330 332 if build: 331 333 build.callRemote("getText").addCallback(self.gotLastText) 332 build.callRemote("get Color").addCallback(self.gotLastColor)334 build.callRemote("getResults").addCallback(self.gotLastResult) 333 335 334 336 def gotLastText(self, text): 337 print "Got text", text 335 338 self.last.setText("\n".join(text)) 336 def gotLastColor(self, color): 337 self.last.setColor(color) 339 340 def gotLastResult(self, result): 341 colormap = {SUCCESS: 'green', 342 FAILURE: 'red', 343 WARNINGS: 'orange', 344 EXCEPTION: 'purple', 345 } 346 self.last.setColor(colormap[result]) 338 347 339 348 def getState(self): 340 349 self.ref.callRemote("getState").addCallback(self.gotState) -
old-buildbot_colors/buildbot/interfaces.py
old new 529 529 available, the caller should join them together with spaces before 530 530 presenting them to the user.""" 531 531 532 def getColor():533 """Returns a single string with the color that should be used to534 display the build. 'green', 'orange', or 'red' are the most likely535 ones."""536 537 532 def getResults(): 538 533 """Return a constant describing the results of the build: one of the 539 534 constants in buildbot.status.builder: SUCCESS, WARNINGS, or … … 654 649 available, the caller should join them together with spaces before 655 650 presenting them to the user.""" 656 651 657 def getColor():658 """Returns a single string with the color that should be used to659 display this step. 'green', 'orange', 'red' and 'yellow' are the660 most likely ones."""661 662 652 def getResults(): 663 653 """Return a tuple describing the results of the step: (result, 664 654 strings). 'result' is one of the constants in … … 697 687 available, the caller should join them together with spaces before 698 688 presenting them to the user.""" 699 689 700 def getColor():701 """Returns a single string with the color that should be used to702 display this event. 'red' and 'yellow' are the most likely ones."""703 704 690 705 691 LOG_CHANNEL_STDOUT = 0 706 692 LOG_CHANNEL_STDERR = 1 -
old-buildbot_colors/buildbot/process/base.py
old new 307 307 log.msg("Build.setupBuild failed") 308 308 log.err(Failure()) 309 309 self.builder.builder_status.addPointEvent(["setupBuild", 310 "exception"], 311 color="purple") 310 "exception"]) 312 311 self.finished = True 313 312 self.results = FAILURE 314 313 self.deferred = None … … 499 498 # XXX: really .fail or something 500 499 self.currentStep.progress.finish() 501 500 text = ["stopped", reason] 502 self.buildFinished(text, "red",FAILURE)501 self.buildFinished(text, FAILURE) 503 502 504 503 def allStepsDone(self): 505 504 if self.result == FAILURE: 506 color = "red"507 505 text = ["failed"] 508 506 elif self.result == WARNINGS: 509 color = "orange"510 507 text = ["warnings"] 511 508 elif self.result == EXCEPTION: 512 color = "purple"513 509 text = ["exception"] 514 510 else: 515 color = "green"516 511 text = ["build", "successful"] 517 512 text.extend(self.text) 518 return self.buildFinished(text, color,self.result)513 return self.buildFinished(text, self.result) 519 514 520 515 def buildException(self, why): 521 516 log.msg("%s.buildException" % self) 522 517 log.err(why) 523 self.buildFinished(["build", "exception"], "purple",FAILURE)518 self.buildFinished(["build", "exception"], FAILURE) 524 519 525 def buildFinished(self, text, color,results):520 def buildFinished(self, text, results): 526 521 """This method must be called when the last Step has completed. It 527 522 marks the Build as complete and returns the Builder to the 'idle' 528 523 state. 529 524 530 It takes three arguments which describe the overall build status: 531 text, color, results. 'results' is one of SUCCESS, WARNINGS, or 532 FAILURE. 525 It takes two arguments which describe the overall build status: 526 text, results. 'results' is one of SUCCESS, WARNINGS, or FAILURE. 533 527 534 528 If 'results' is SUCCESS or WARNINGS, we will permit any dependant 535 529 builds to start. If it is 'FAILURE', those builds will be … … 542 536 543 537 log.msg(" %s: build finished" % self) 544 538 self.build_status.setText(text) 545 self.build_status.setColor(color)546 539 self.build_status.setResults(results) 547 540 self.build_status.buildFinished() 548 541 if self.progress: -
old-buildbot_colors/buildbot/process/builder.py
old new 131 131 self.ping_watchers.append(d) 132 132 if newping: 133 133 if status: 134 event = status.addEvent(["pinging"] , "yellow")134 event = status.addEvent(["pinging"]) 135 135 d2 = defer.Deferred() 136 136 d2.addCallback(self._pong_status, event) 137 137 self.ping_watchers.insert(0, d2) … … 149 149 def _pong_status(self, res, event): 150 150 if res: 151 151 event.text = ["ping", "success"] 152 event.color = "green"153 152 else: 154 153 event.text = ["ping", "failed"] 155 event.color = "red"156 154 event.finish() 157 155 158 156 class Ping: -
old-buildbot_colors/buildbot/process/buildstep.py
old new 719 719 As the step runs, it should send status information to the 720 720 BuildStepStatus:: 721 721 722 self.step_status.setColor('red')723 722 self.step_status.setText(['compile', 'failed']) 724 723 self.step_status.setText2(['4', 'warnings']) 725 724 … … 792 791 self.addHTMLLog("err.html", formatFailure(why)) 793 792 self.addCompleteLog("err.text", why.getTraceback()) 794 793 # could use why.getDetailedTraceback() for more information 795 self.step_status.setColor("purple")796 794 self.step_status.setText([self.name, "exception"]) 797 795 self.step_status.setText2([self.name]) 798 796 self.step_status.stepFinished(EXCEPTION) … … 946 944 """ 947 945 log.msg("ShellCommand.startCommand(cmd=%s)", (cmd,)) 948 946 self.cmd = cmd # so we can interrupt it 949 self.step_status.setColor("yellow")950 947 self.step_status.setText(self.describe(False)) 951 948 952 949 # stdio is the first log … … 991 988 992 989 def checkDisconnect(self, f): 993 990 f.trap(error.ConnectionLost) 994 self.step_status.setColor("red")995 991 self.step_status.setText(self.describe(True) + 996 992 ["failed", "slave", "lost"]) 997 993 self.step_status.setText2(["failed", "slave", "lost"]) … … 1076 1072 return self.getText2(cmd, results) 1077 1073 return [] 1078 1074 1079 def getColor(self, cmd, results):1080 assert results in (SUCCESS, WARNINGS, FAILURE)1081 if results == SUCCESS:1082 return "green"1083 elif results == WARNINGS:1084 return "orange"1085 else:1086 return "red"1087 1088 1075 def setStatus(self, cmd, results): 1089 1076 # this is good enough for most steps, but it can be overridden to 1090 1077 # get more control over the displayed text 1091 self.step_status.setColor(self.getColor(cmd, results))1092 1078 self.step_status.setText(self.getText(cmd, results)) 1093 1079 self.step_status.setText2(self.maybeGetText2(cmd, results)) 1094 1080 -
old-buildbot_colors/buildbot/process/step_twisted2.py
old new 141 141 def finishStatus(self, result): 142 142 total = self.results.countTests() 143 143 count = self.results.countFailures() 144 color = "green"145 144 text = [] 146 145 if count == 0: 147 146 text.extend(["%d %s" % \ … … 153 152 text.append("%d %s" % \ 154 153 (count, 155 154 count == 1 and "failure" or "failures")) 156 color = "red" 157 self.updateCurrentActivity(color=color, text=text) 155 self.updateCurrentActivity(text=text) 158 156 self.addFileToCurrentActivity("tests", self.results) 159 157 #self.finishStatusSummary() 160 158 self.finishCurrentActivity() -
old-buildbot_colors/buildbot/status/builder.py
old new 502 502 started = None 503 503 finished = None 504 504 text = [] 505 color = None506 505 507 506 # IStatusEvent methods 508 507 def getTimes(self): 509 508 return (self.started, self.finished) 510 509 def getText(self): 511 510 return self.text 512 def getColor(self):513 return self.color514 511 def getLogs(self): 515 512 return [] 516 513 … … 641 638 I represent a collection of output status for a 642 639 L{buildbot.process.step.BuildStep}. 643 640 644 @type color: string645 @cvar color: color that this step feels best represents its646 current mood. yellow,green,red,orange are the647 most likely choices, although purple indicates648 an exception649 641 @type progress: L{buildbot.status.progress.StepProgress} 650 642 @cvar progress: tracks ETA for the step 651 643 @type text: list of strings … … 664 656 finished = None 665 657 progress = None 666 658 text = [] 667 color = None668 659 results = (None, []) 669 660 text2 = [] 670 661 watchers = [] … … 742 733 presenting them to the user.""" 743 734 return self.text 744 735 745 def getColor(self):746 """Returns a single string with the color that should be used to747 display this step. 'green', 'orange', 'red', 'yellow' and 'purple'748 are the most likely ones."""749 return self.color750 751 736 def getResults(self): 752 737 """Return a tuple describing the results of the step. 753 738 'result' is one of the constants in L{buildbot.status.builder}: … … 839 824 def addURL(self, name, url): 840 825 self.urls[name] = url 841 826 842 def setColor(self, color):843 self.color = color844 827 def setText(self, text): 845 828 self.text = text 846 829 def setText2(self, text): … … 899 882 finished = None 900 883 currentStep = None 901 884 text = [] 902 color = None903 885 results = None 904 886 slavename = "???" 905 887 … … 1011 993 text.extend(s.text2) 1012 994 return text 1013 995 1014 def getColor(self):1015 return self.color1016 1017 996 def getResults(self): 1018 997 return self.results 1019 998 … … 1106 1085 def setText(self, text): 1107 1086 assert isinstance(text, (list, tuple)) 1108 1087 self.text = text 1109 def setColor(self, color):1110 self.color = color1111 1088 def setResults(self, results): 1112 1089 self.results = results 1113 1090 … … 1550 1527 def setSlavenames(self, names): 1551 1528 self.slavenames = names 1552 1529 1553 def addEvent(self, text=[] , color=None):1530 def addEvent(self, text=[]): 1554 1531 # this adds a duration event. When it is done, the user should call 1555 # e.finish(). They can also mangle it by modifying .text and .color1532 # e.finish(). They can also mangle it by modifying .text 1556 1533 e = Event() 1557 1534 e.started = util.now() 1558 1535 e.text = text 1559 e.color = color1560 1536 self.events.append(e) 1561 1537 return e # they are free to mangle it further 1562 1538 1563 def addPointEvent(self, text=[] , color=None):1539 def addPointEvent(self, text=[]): 1564 1540 # this adds a point event, one which occurs as a single atomic 1565 1541 # instant of time. 1566 1542 e = Event() 1567 1543 e.started = util.now() 1568 1544 e.finished = 0 1569 1545 e.text = text 1570 e.color = color1571 1546 self.events.append(e) 1572 1547 return e # for consistency, but they really shouldn't touch it 1573 1548 -
old-buildbot_colors/buildbot/status/client.py
old new 175 175 def remote_getText(self): 176 176 return self.b.getText() 177 177 178 def remote_getColor(self):179 return self.b.getColor()180 181 178 def remote_getResults(self): 182 179 return self.b.getResults() 183 180 … … 267 264 def remote_getText(self): 268 265 return self.s.getText() 269 266 270 def remote_getColor(self):271 return self.s.getColor()272 273 267 def remote_getResults(self): 274 268 return self.s.getResults() 275 269 … … 300 294 return self.s.getTimes() 301 295 def remote_getText(self): 302 296 return self.s.getText() 303 def remote_getColor(self):304 return self.s.getColor()305 297 306 298 components.registerAdapter(RemoteEvent, 307 299 interfaces.IStatusEvent, IRemote) -
old-buildbot_colors/buildbot/status/web/base.py
old new 89 89 "<input type='text' name='revision' />") 90 90 + '<input type="submit" value="Force Build" /></form>\n') 91 91 92 colormap = {93 'green': '#72ff75',94 }95 92 def td(text="", parms={}, **props): 96 93 data = "" 97 94 data += " " 98 95 #if not props.has_key("border"): 99 96 # props["border"] = 1 100 97 props.update(parms) 101 if props.has_key("bgcolor"):102 props["bgcolor"] = colormap.get(props["bgcolor"], props["bgcolor"])103 98 comment = props.get("comment", None) 104 99 if comment: 105 100 data += "<!-- %s -->" % comment … … 107 102 class_ = props.get('class_', None) 108 103 if class_: 109 104 props["class"] = class_ 110 for prop in ("align", " bgcolor", "colspan", "rowspan", "border",105 for prop in ("align", "colspan", "rowspan", "border", 111 106 "valign", "halign", "class"): 112 107 p = props.get(prop, None) 113 108 if p != None: … … 175 170 # lack, and it has a base URL to which each File's name is relative. 176 171 # Events don't know about HTML. 177 172 spacer = False 178 def __init__(self, text=[], c olor=None, class_=None, urlbase=None,173 def __init__(self, text=[], class_=None, urlbase=None, 179 174 **parms): 180 175 self.text = text 181 self.color = color182 176 self.class_ = class_ 183 177 self.urlbase = urlbase 184 178 self.show_idle = 0 … … 195 189 text = self.text 196 190 if not text and self.show_idle: 197 191 text = ["[idle]"] 198 return td(text, props, bgcolor=self.color,class_=self.class_)192 return td(text, props, class_=self.class_) 199 193 200 194 201 195 class HtmlResource(resource.Resource): -
old-buildbot_colors/buildbot/status/web/baseweb.py
old new 213 213 label = "#%d" % b.getNumber() 214 214 text = ['<a href="%s">%s</a>' % (url, label)] 215 215 text.extend(b.getText()) 216 box = Box(text, b.getColor(),216 box = Box(text, 217 217 class_="LastBuild box %s" % build_get_class(b)) 218 218 data += box.td(align="center") 219 219 else: -
old-buildbot_colors/buildbot/status/web/build.py
old new 32 32 projectName = status.getProjectName() 33 33 data = ('<div class="title"><a href="%s">%s</a></div>\n' 34 34 % (self.path_to_root(req), projectName)) 35 # the color in the following line gives python-mode trouble36 35 builder_name = b.getBuilder().getName() 37 36 data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" 38 37 % (path_to_builder(req, b.getBuilder()), -
old-buildbot_colors/buildbot/status/web/changes.py
old new 36 36 def getBox(self, req): 37 37 url = req.childLink("../changes/%d" % self.original.number) 38 38 text = self.original.get_HTML_box(url) 39 return Box([text], c olor="white", class_="Change")39 return Box([text], class_="Change") 40 40 components.registerAdapter(ChangeBox, Change, IBox) 41 41 -
old-buildbot_colors/buildbot/status/web/waterfall.py
old new 55 55 state = "waiting" 56 56 57 57 if state == "building": 58 color = "yellow"59 58 text = ["building"] 60 59 if builds: 61 60 for b in builds: 62 61 eta = b.getETA() 63 62 text.extend(self.formatETA("ETA in", eta)) 64 63 elif state == "offline": 65 color = "red"66 64 text = ["offline"] 67 65 elif state == "idle": 68 color = "white"69 66 text = ["idle"] 70 67 elif state == "waiting": 71 color = "yellow"72 68 text = ["waiting"] 73 69 else: 74 70 # just in case I add a state and forget to update this 75 color = "white"76 71 text = [state] 77 72 78 73 # TODO: for now, this pending/upcoming stuff is in the "current … … 87 82 for t in upcoming: 88 83 eta = t - util.now() 89 84 text.extend(self.formatETA("next in", eta)) 90 return Box(text, c olor=color, class_="Activity " + state)85 return Box(text, class_="Activity " + state) 91 86 92 87 components.registerAdapter(CurrentBox, builder.BuilderStatus, ICurrentBox) 93 88 … … 104 99 builds = list(builder.generateFinishedBuilds(map_branches(branches), 105 100 num_builds=1)) 106 101 if not builds: 107 return Box(["none"], "white",class_="LastBuild")102 return Box(["none"], class_="LastBuild") 108 103 b = builds[0] 109 104 name = b.getBuilder().getName() 110 105 number = b.getNumber() … … 112 107 text = b.getText() 113 108 # TODO: maybe add logs? 114 109 # TODO: add link to the per-build page at 'url' 115 c = b.getColor()116 110 class_ = build_get_class(b) 117 return Box(text, c , class_="LastBuild %s" % class_)111 return Box(text, class_="LastBuild %s" % class_) 118 112 components.registerAdapter(BuildTopBox, builder.BuilderStatus, ITopBox) 119 113 120 114 class BuildBox(components.Adapter): … … 128 122 reason = b.getReason() 129 123 text = ('<a title="Reason: %s" href="%s">Build %d</a>' 130 124 % (html.escape(reason), url, number)) 131 color = "yellow"132 125 class_ = "start" 133 126 if b.isFinished() and not b.getSteps(): 134 127 # the steps have been pruned, so there won't be any indication 135 # of whether it succeeded or failed. Color the box red or green 136 # to show its status 137 color = b.getColor() 128 # of whether it succeeded or failed. 138 129 class_ = build_get_class(b) 139 return Box([text], c olor=color, class_="BuildStep " + class_)130 return Box([text], class_="BuildStep " + class_) 140 131 components.registerAdapter(BuildBox, builder.BuildStatus, IBox) 141 132 142 133 class StepBox(components.Adapter): … … 162 153 for name, target in urls.items(): 163 154 text.append('[<a href="%s" class="%s">%s</a>]' % 164 155 (target, ex_url_class, html.escape(name))) 165 color = self.original.getColor()166 156 class_ = "BuildStep " + build_get_class(self.original) 167 return Box(text, c olor, class_=class_)157 return Box(text, class_=class_) 168 158 components.registerAdapter(StepBox, builder.BuildStepStatus, IBox) 169 159 170 160 … … 173 163 174 164 def getBox(self, req): 175 165 text = self.original.getText() 176 color = self.original.getColor()177 166 class_ = "Event" 178 if color: 179 class_ += " " + color 180 return Box(text, color, class_=class_) 167 return Box(text, class_=class_) 181 168 components.registerAdapter(EventBox, builder.Event, IBox) 182 169 183 170 … … 192 179 return (self.started, self.finished) 193 180 def getText(self): 194 181 return [] 195 def getColor(self):196 return None197 182 198 183 class SpacerBox(components.Adapter): 199 184 implements(IBox) … … 608 593 data += td("", colspan=2) 609 594 for b in builders: 610 595 text = "" 611 color = "#ca88f7"612 596 state, builds = b.getState() 613 597 if state != "offline": 614 598 text += "%s<br />\n" % state #b.getCurrentBig().text[0] 615 599 else: 616 600 text += "OFFLINE<br />\n" 617 color = "#ffe0e0" 618 data += td(text, align="center", bgcolor=color) 601 data += td(text, align="center") 619 602 620 603 # the next row has the column headers: time, changes, builder names 621 604 data += " <tr>\n" … … 632 615 data += td("04:00", align="bottom") 633 616 data += td("fred", align="center") 634 617 for name in names: 635 data += td("stuff", align="center" , bgcolor="red")618 data += td("stuff", align="center") 636 619 data += " </tr>\n" 637 620 638 621 data += "</table>\n" … … 790 773 for e in row[c]: 791 774 log.msg("Event", r, c, sourceNames[c], e.getText()) 792 775 lognames = [loog.getName() for loog in e.getLogs()] 793 data += "%s: %s: %s %s<br />" % (e.getText(),776 data += "%s: %s: %s<br />" % (e.getText(), 794 777 e.getTimes()[0], 795 e.getColor(),796 778 lognames) 797 779 else: 798 780 data += "<b>%s</b> [none]<br />\n" % sourceNames[c] -
old-buildbot_colors/buildbot/steps/dummy.py
old new 25 25 self.timer = None 26 26 27 27 def start(self): 28 self.step_status.setColor("yellow")29 28 self.step_status.setText(["delay", "%s secs" % self.timeout]) 30 29 self.timer = reactor.callLater(self.timeout, self.done) 31 30 … … 33 32 if self.timer: 34 33 self.timer.cancel() 35 34 self.timer = None 36 self.step_status.setColor("red")37 35 self.step_status.setText(["delay", "interrupted"]) 38 36 self.finished(FAILURE) 39 37 40 38 def done(self): 41 self.step_status.setColor("green")42 39 self.finished(SUCCESS) 43 40 44 41 class FailingDummy(Dummy): … … 48 45 name = "failing dummy" 49 46 50 47 def start(self): 51 self.step_status.setColor("yellow")52 48 self.step_status.setText(["boom", "%s secs" % self.timeout]) 53 49 self.timer = reactor.callLater(self.timeout, self.done) 54 50 55 51 def done(self): 56 self.step_status.setColor("red")57 52 self.finished(FAILURE) 58 53 59 54 class RemoteDummy(LoggingBuildStep): -
old-buildbot_colors/buildbot/steps/maxq.py
old new 34 34 35 35 def finishStatus(self, result): 36 36 if self.failures: 37 color = "red"38 37 text = ["maxq", "failed"] 39 38 else: 40 color = "green"41 39 text = ['maxq', 'tests'] 42 self.updateCurrentActivity( color=color,text=text)40 self.updateCurrentActivity(text=text) 43 41 self.finishStatusSummary() 44 42 self.finishCurrentActivity() 45 43 -
old-buildbot_colors/buildbot/steps/source.py
old new 159 159 def start(self): 160 160 if self.notReally: 161 161 log.msg("faking %s checkout/update" % self.name) 162 self.step_status.setColor("green")163 162 self.step_status.setText(["fake", self.name, "successful"]) 164 163 self.addCompleteLog("log", 165 164 "Faked %s checkout/update 'successful'\n" \ -
old-buildbot_colors/buildbot/steps/transfer.py
old new 125 125 log.msg("FileUpload started, from slave %r to master %r" 126 126 % (source, masterdest)) 127 127 128 self.step_status.setColor('yellow')129 128 self.step_status.setText(['uploading', os.path.basename(source)]) 130 129 131 130 # we use maxsize to limit the amount of data on both sides … … 149 148 self.addCompleteLog('stderr', self.cmd.stderr) 150 149 151 150 if self.cmd.rc is None or self.cmd.rc == 0: 152 self.step_status.setColor('green')153 151 return BuildStep.finished(self, SUCCESS) 154 self.step_status.setColor('red')155 152 return BuildStep.finished(self, FAILURE) 156 153 157 154 … … 250 247 log.msg("FileDownload started, from master %r to slave %r" % 251 248 (source, slavedest)) 252 249 253 self.step_status.setColor('yellow')254 250 self.step_status.setText(['downloading', "to", 255 251 os.path.basename(slavedest)]) 256 252 … … 286 282 self.addCompleteLog('stderr', self.cmd.stderr) 287 283 288 284 if self.cmd.rc is None or self.cmd.rc == 0: 289 self.step_status.setColor('green')290 285 return BuildStep.finished(self, SUCCESS) 291 self.step_status.setColor('red')292 286 return BuildStep.finished(self, FAILURE) 293 287 -
old-buildbot_colors/buildbot/steps/trigger.py
old new 47 47 def interrupt(self, reason): 48 48 # TODO: this doesn't actually do anything. 49 49 if self.running: 50 self.step_status.setColor("red")51 50 self.step_status.setText(["interrupted"]) 52 51 53 52 def start(self): … … 83 82 unknown_schedulers.append(scheduler) 84 83 85 84 if unknown_schedulers: 86 self.step_status.setColor("red")87 85 self.step_status.setText(['no scheduler:'] + unknown_schedulers) 88 86 rc = FAILURE 89 87 else: 90 88 rc = SUCCESS 91 89 self.step_status.setText(['triggered'] + triggered_schedulers) 92 if self.waitForFinish:93 self.step_status.setColor("yellow")94 else:95 self.step_status.setColor("green")96 90 97 91 if self.waitForFinish: 98 92 d = defer.DeferredList(dl, consumeErrors=1) -
old-buildbot_colors/buildbot/test/test_status.py
old new 920 920 self.failUnlessEqual(b.getResponsibleUsers(), []) 921 921 self.failUnless(b.isFinished()) 922 922 self.failUnlessEqual(b.getText(), ['build', 'successful']) 923 self.failUnlessEqual(b.getColor(), "green")924 923 self.failUnlessEqual(b.getResults(), builder.SUCCESS) 925 924 926 925 steps = b.getSteps()
![[Buildbot Logo]](/trac/chrome/site/header-text-transparent.png)