def build_line(self, build, req): buildnum = build.getNumber() buildurl = path_to_build(req, build) data = '<a href="%(builderurl)s">%(builder_name)s</a>' % self.get_line_values( req, build) data += ' <a href="%s">#%d</a> ' % (buildurl, buildnum) when = build.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "ETA %ds (%s) " % (when, when_time) step = build.getCurrentStep() if step: data += "[%s]" % step.getName() else: data += "[waiting for Lock]" # TODO: is this necessarily the case? builder_control = self.getControl(req) if builder_control is not None: stopURL = path_to_build(req, build) + '/stop' data += ''' <form action="%s" class="command stopbuild" style="display:inline" method="post"> <input type="submit" value="Stop Build" /> </form>''' % stopURL return data
def build_line(self, build, req): buildnum = build.getNumber() buildurl = path_to_build(req, build) data = '<a href="%(builderurl)s">%(builder_name)s</a>' % self.get_line_values(req, build) data += ' <a href="%s">#%d</a> ' % (buildurl, buildnum) when = build.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "ETA %ds (%s) " % (when, when_time) step = build.getCurrentStep() if step: data += "[%s]" % step.getName() else: data += "[waiting for Lock]" # TODO: is this necessarily the case? builder_control = self.getControl(req) if builder_control is not None: stopURL = path_to_build(req, build) + '/stop' data += ''' <form action="%s" class="command stopbuild" style="display:inline" method="post"> <input type="submit" value="Stop Build" /> </form>''' % stopURL return data
def builder(self, build, req): b = {} b['num'] = build.getNumber() b['link'] = path_to_build(req, build) when = build.getETA() if when is not None: b['when'] = util.formatInterval(when) b['when_time'] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) step = build.getCurrentStep() # TODO: is this necessarily the case? if not step: b['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): b['current_step'] = "%s [waiting for Lock]" % step.getName() else: b['current_step'] = step.getName() b['stop_url'] = path_to_build(req, build) + '/stop' return b
def performAction(self, req): authz = self.getAuthz(req) res = yield authz.actionAllowed(self.action, req, self.build_status) if not res: defer.returnValue(path_to_authzfail(req)) return b = self.build_status log.msg("web stopEntireBuildChain of build %s:%s" % \ (b.getBuilder().getName(), b.getNumber())) name = authz.getUsernameFull(req) reason = ( "The web-page 'Stop Entire Build Chain' button was pressed by '%s'\n" % html.escape(name)) master = interfaces.IControl(self.getBuildmaster(req)) buildername = self.build_status.getBuilder().getName() number = self.build_status.getNumber() builderc = master.getBuilder(buildername) if builderc: build = builderc.getBuild(number) if build: yield self.stopEntireBuildChain(master, build, buildername, reason) build.stopBuild(reason) defer.returnValue(path_to_build(req, self.build_status))
def performAction(self, req): authz = self.getAuthz(req) res = yield authz.actionAllowed(self.action, req, self.build_status) if not res: defer.returnValue(path_to_authzfail(req)) return b = self.build_status log.msg("web stopBuild of build %s:%s" % \ (b.getBuilder().getName(), b.getNumber())) name = authz.getUsernameFull(req) comments = req.args.get("comments", ["<no reason specified>"])[0] comments.decode(getRequestCharset(req)) # html-quote both the username and comments, just to be safe reason = ("The web-page 'Stop Build' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) c = interfaces.IControl(self.getBuildmaster(req)) bldrc = c.getBuilder(self.build_status.getBuilder().getName()) if bldrc: bldc = bldrc.getBuild(self.build_status.getNumber()) if bldc: bldc.stopBuild(reason) defer.returnValue(path_to_build(req, self.build_status))
def content(self, req, cxt): s = self.step_status b = s.getBuild() logs = cxt['logs'] = [] for l in s.getLogs(): # FIXME: If the step name has a / in it, this is broken # either way. If we quote it but say '/'s are safe, # it chops up the step name. If we quote it and '/'s # are not safe, it escapes the / that separates the # step name from the log number. logs.append({'has_contents': l.hasContents(), 'name': l.getName(), 'link': req.childLink("logs/%s" % urllib.quote(l.getName())) }) start, end = s.getTimes() if start: cxt['start'] = ctime(start) if end: cxt['end'] = ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: cxt['end'] = "Not Finished" cxt['elapsed'] = util.formatInterval(util.now() - start) cxt.update(dict(builder_link = path_to_builder(req, b.getBuilder()), build_link = path_to_build(req, b), b = b, s = s, result_css = css_classes[s.getResults()[0]])) template = req.site.buildbot_service.templates.get_template("buildstep.html"); return template.render(**cxt)
def content(self, req, cxt): tr = self.test_result b = self.status cxt['b'] = self.status logs = cxt['logs'] = [] for lname, log in tr.getLogs().items(): if isinstance(log, str): log = log.decode('utf-8') logs.append({ 'name': lname, 'log': log, 'link': req.childLink("logs/%s" % urllib.quote(lname)) }) cxt['text'] = tr.text cxt['result_word'] = Results[tr.getResults()] cxt.update( dict(builder_link=path_to_builder(req, b.getBuilder()), build_link=path_to_build(req, b), result_css=css_classes[tr.getResults()], b=b, tr=tr)) template = req.site.buildbot_service.templates.get_template( "testresult.html") return template.render(**cxt)
def body(self, req): s = self.step_status b = s.getBuild() builder_name = b.getBuilder().getName() build_num = b.getNumber() data = "" data += '<h1>BuildStep <a href="%s">%s</a>:' % (path_to_builder(req, b.getBuilder()), builder_name) data += '<a href="%s">#%d</a>' % (path_to_build(req, b), build_num) data += ":%s</h1>\n" % s.getName() if s.isFinished(): data += "<h2>Finished</h2>\n" "<p>%s</p>\n" % html.escape("%s" % s.getText()) else: data += "<h2>Not Finished</h2>\n" "<p>ETA %s seconds</p>\n" % s.getETA() exp = s.getExpectations() if exp: data += "<h2>Expectations</h2>\n" "<ul>\n" for e in exp: data += "<li>%s: current=%s, target=%s</li>\n" % (html.escape(e[0]), e[1], e[2]) data += "</ul>\n" (start, end) = s.getTimes() if not start: start_text = end_text = elapsed = "Not Started" else: start_text = ctime(start) if end: end_text = ctime(end) elapsed = util.formatInterval(end - start) else: end_text = "Not Finished" elapsed = util.formatInterval(util.now() - start) data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % start_text data += "<tr><td>End</td><td>%s</td></tr>\n" % end_text data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % elapsed data += "</table>\n" logs = s.getLogs() if logs: data += "<h2>Logs</h2>\n" "<ul>\n" for logfile in logs: if logfile.hasContents(): # FIXME: If the step name has a / in it, this is broken # either way. If we quote it but say '/'s are safe, # it chops up the step name. If we quote it and '/'s # are not safe, it escapes the / that separates the # step name from the log number. logname = logfile.getName() logurl = req.childLink("logs/%s" % urllib.quote(logname)) data += '<li><a href="%s">%s</a></li>\n' % (logurl, html.escape(logname)) else: data += "<li>%s</li>\n" % html.escape(logname) data += "</ul>\n" return data
def builder_row(self, bn, req, branches, num_builds): status = self.getStatus(req) builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() builderLink = path_to_builder(req, builder) row(tags.td(class_="box %s" % (state, ))(tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if set(map_branches(branches)) & builder._getBuildBranches(build) ], key=lambda build: build.getNumber(), reverse=True) builds.extend( builder.generateFinishedBuilds(map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when), ), "%s" % (time.strftime( "%H:%M:%S", time.localtime(time.time() + when)), ) ] else: text = [] row( tags.td(align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text ])) else: row(tags.td(class_="LastBuild box")("no build")) return row
def body(self, req): s = self.step_status b = s.getBuild() builder_name = b.getBuilder().getName() build_num = b.getNumber() data = "" data += ('<h1>BuildStep <a href="%s">%s</a>:' % (path_to_builder(req, b.getBuilder()), builder_name)) data += '<a href="%s">#%d</a>' % (path_to_build(req, b), build_num) data += ":%s</h1>\n" % s.getName() if s.isFinished(): data += ("<h2>Finished</h2>\n" "<p>%s</p>\n" % html.escape("%s" % s.getText())) else: data += ("<h2>Not Finished</h2>\n" "<p>ETA %s seconds</p>\n" % s.getETA()) exp = s.getExpectations() if exp: data += ("<h2>Expectations</h2>\n" "<ul>\n") for e in exp: data += "<li>%s: current=%s, target=%s</li>\n" % \ (html.escape(e[0]), e[1], e[2]) data += "</ul>\n" (start, end) = s.getTimes() data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % ctime(start) if end: data += "<tr><td>End</td><td>%s</td></tr>\n" % ctime(end) data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval( end - start) data += "</table>\n" logs = s.getLogs() if logs: data += ("<h2>Logs</h2>\n" "<ul>\n") for logfile in logs: if logfile.hasContents(): # FIXME: If the step name has a / in it, this is broken # either way. If we quote it but say '/'s are safe, # it chops up the step name. If we quote it and '/'s # are not safe, it escapes the / that separates the # step name from the log number. logname = logfile.getName() logurl = req.childLink("logs/%s" % urllib.quote(logname)) data += ('<li><a href="%s">%s</a></li>\n' % (logurl, html.escape(logname))) else: data += '<li>%s</li>\n' % html.escape(logname) data += "</ul>\n" return data
def builder_row(self, bn, req, branches, num_builds): status = self.getStatus(req) builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() builderLink = path_to_builder(req, builder) row(tags.td(class_="box %s" % (state,)) (tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if set(map_branches(branches)) & builder._getBuildBranches(build) ], key=lambda build: build.getNumber(), reverse=True) builds.extend(builder.generateFinishedBuilds( map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when),), "%s" % (time.strftime( "%H:%M:%S", time.localtime(time.time() + when)),) ] else: text = [] row(tags.td( align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text])) else: row(tags.td(class_="LastBuild box")("no build")) return row
def builder(self, build, req): b = {} b["num"] = build.getNumber() b["link"] = path_to_build(req, build) when = build.getETA() if when is not None: b["when"] = util.formatInterval(when) b["when_time"] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) step = build.getCurrentStep() if step: b["current_step"] = step.getName() else: b["current_step"] = "[waiting for Lock]" # TODO: is this necessarily the case? b["stop_url"] = path_to_build(req, build) + "/stop" return b
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) ssList = b.getSourceStamps() sourcestamps = cxt['sourcestamps'] = ssList all_got_revisions = b.getAllGotRevisions() cxt['got_revisions'] = all_got_revisions cxt.update(self.getCommonBuildInfo(req, b)) cxt['builds'] = [] for c in self.getChildren(req): cxt['builds'].append(self.getChildBuild(req, c)) pending = yield self.getPending(req) for p in pending: cxt['builds'].append(p) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): if not isinstance(value, dict): cxt_value = unicode(value) else: cxt_value = value p = {'name': name, 'value': cxt_value, 'source': source} if len(cxt_value) > 500: p['short_value'] = cxt_value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) exactly = True has_changes = False for ss in sourcestamps: exactly = exactly and (ss.revision is not None) has_changes = has_changes or ss.changes cxt['exactly'] = (exactly) or b.getChanges() cxt['has_changes'] = has_changes cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) cxt['shutting_down'] = status.shuttingDown template = req.site.buildbot_service.templates.get_template( "travis.build.html") defer.returnValue(template.render(**cxt))
def getBox(self, req): b = self.original number = b.getNumber() url = path_to_build(req, b) reason = b.getReason() text = ('<a title="Reason: %s" href="%s">Build %d</a>' % (html.escape(reason), url, number)) class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. class_ = build_get_class(b) return Box([text], class_="BuildStep " + class_)
def getBox(self, req): b = self.original number = b.getNumber() url = path_to_build(req, b) reason = b.getReason() template = req.site.buildbot_service.templates.get_template("box_macros.html") text = template.module.build_box(reason=reason,url=url,number=number) class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. class_ = build_get_class(b) return Box([text], class_="BuildStep " + class_)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) ssList = b.getSourceStamps() sourcestamps = cxt['sourcestamps'] = ssList all_got_revisions = b.getAllGotRevisions() cxt['got_revisions'] = all_got_revisions cxt.update(self.getCommonBuildInfo(req, b)) cxt['builds'] = [] for c in self.getChildren(req): cxt['builds'].append(self.getChildBuild(req, c)) pending = yield self.getPending(req) for p in pending: cxt['builds'].append(p) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): if not isinstance(value, dict): cxt_value = unicode(value) else: cxt_value = value p = { 'name': name, 'value': cxt_value, 'source': source} if len(cxt_value) > 500: p['short_value'] = cxt_value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) exactly = True has_changes = False for ss in sourcestamps: exactly = exactly and (ss.revision is not None) has_changes = has_changes or ss.changes cxt['exactly'] = (exactly) or b.getChanges() cxt['has_changes'] = has_changes cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) cxt['shutting_down'] = status.shuttingDown template = req.site.buildbot_service.templates.get_template("travis.build.html") defer.returnValue(template.render(**cxt))
def getChildBuild(self, req, b): cxt = self.getCommonBuildInfo(req, b) env = cxt['environment'] = {} for name, value, source in b.getProperties().asList(): if source != ".travis.yml": continue env[name] = value cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isFinished(): if s.isHidden(): continue step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "warning" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "warning" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) link = step['link'] = path_to_build( req, b) + "/steps/%s" % urllib.quote(s.getName(), safe='') step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append( dict( link=link + "/logs/%s" % urllib.quote(logname, safe=''), name=logname, )) return cxt
def builder(self, build, req): b = {} b['num'] = build.getNumber() b['link'] = path_to_build(req, build) when = b['when'] = build.getETA() if when is not None: b['when_time'] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) step = build.getCurrentStep() if step: b['current_step'] = step.getName() else: b['current_step'] = "[waiting for Lock]" # TODO: is this necessarily the case? builder_control = self.getControl(req) if builder_control is not None: b['stop_url'] = path_to_build(req, build) + '/stop' return b
def getBox(self, req): assert interfaces.IBuilderStatus(self.original) branches = [b for b in req.args.get("branch", []) if b] builder = self.original builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if not builds: return Box(["none"], class_="LastBuild") b = builds[0] url = path_to_build(req, b) text = b.getText() tests_failed = b.getSummaryStatistic('tests-failed', operator.add, 0) if tests_failed: text.extend(["Failed tests: %d" % tests_failed]) # TODO: maybe add logs? class_ = build_get_class(b) return Box(text, urlbase=url, class_="LastBuild %s" % class_)
def getChildBuild(self, req, b): cxt = self.getCommonBuildInfo(req, b) env = cxt['environment'] = {} for name, value, source in b.getProperties().asList(): if source != ".travis.yml": continue env[name] = value cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName() } if s.isFinished(): if s.isHidden(): continue step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) link = step['link'] = path_to_build(req, b) + "/steps/%s" % urllib.quote(s.getName(), safe='') step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x:dict(url=x[1],logname=x[0]), s.getURLs().items()) step['logs']= [] for l in s.getLogs(): logname = l.getName() step['logs'].append(dict( link = link + "/logs/%s" % urllib.quote(logname, safe=''), name = logname, )) return cxt
def body(self, req): s = self.step_status b = s.getBuild() builder_name = b.getBuilder().getName() build_num = b.getNumber() data = "" data += ('<h1>BuildStep <a href="%s">%s</a>:' % (path_to_builder(req, b.getBuilder()), builder_name)) data += '<a href="%s">#%d</a>' % (path_to_build(req, b), build_num) data += ":%s</h1>\n" % s.getName() if s.isFinished(): data += ("<h2>Finished</h2>\n" "<p>%s</p>\n" % html.escape("%s" % s.getText())) else: data += ("<h2>Not Finished</h2>\n" "<p>ETA %s seconds</p>\n" % s.getETA()) exp = s.getExpectations() if exp: data += ("<h2>Expectations</h2>\n" "<ul>\n") for e in exp: data += "<li>%s: current=%s, target=%s</li>\n" % \ (html.escape(e[0]), e[1], e[2]) data += "</ul>\n" logs = s.getLogs() if logs: data += ("<h2>Logs</h2>\n" "<ul>\n") for logfile in logs: if logfile.hasContents(): # FIXME: If the step name has a / in it, this is broken # either way. If we quote it but say '/'s are safe, # it chops up the step name. If we quote it and '/'s # are not safe, it escapes the / that separates the # step name from the log number. logname = logfile.getName() logurl = req.childLink("logs/%s" % urllib.quote(logname)) data += ('<li><a href="%s">%s</a></li>\n' % (logurl, html.escape(logname))) else: data += '<li>%s</li>\n' % html.escape(logname) data += "</ul>\n" return data
def build_cxt(self, request, build): if not build: return {} if build.isFinished(): # get the text and annotate the first line with a link text = build.getText() if not text: text = [ "(no information)" ] if text == [ "build", "successful" ]: text = [ "OK" ] else: text = [ 'building' ] name = build.getBuilder().getName() cxt = {} cxt['name'] = name cxt['got_revision'] = build.getProperty("got_revision") cxt['DEST'] = build.getProperty("DEST") cxt['url'] = path_to_build(request, build) cxt['text'] = text cxt['class'] = build_get_class(build) if build.getProperty("repourl_poky"): if build.getProperty("repourl_poky") == "git://git.yoctoproject.org/poky": cxt['repository'] = "poky" cxt['cgiturl'] = "http://git.yoctoproject.org/cgit/cgit.cgi/poky/commit/?h=" elif "git://git.yoctoproject.org/poky-contrib" in build.getProperty("repourl_poky"): cxt['repository'] = "poky-contrib" cxt['cgiturl'] = "http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/commit/?h=" else: cxt['repository'] = build.getProperty("repourl_poky") if build.getProperty("branch_poky"): if build.getProperty("branch_poky") == "stage/master_under_test": cxt['branchshortname']="mut" else: cxt['branchshortname']=build.getProperty("branch_poky") cxt['branch'] = build.getProperty("branch_poky") if 'cgiturl' in cxt and 'got_revision' in cxt and cxt['cgiturl'] is not None and cxt['got_revision'] is not None: cxt['cgiturl'] = cxt['cgiturl'] + build.getProperty("branch_poky") + "&id=" + cxt['got_revision'] if build.getProperty("custom_release_name_nightly"): cxt['release_name'] = build.getProperty("custom_release_name_nightly") else: cxt['commit_desc'] = build.getProperty("commit-description") return cxt
def getBox(self, req): assert interfaces.IBuilderStatus(self.original) branches = [b for b in req.args.get("branch", []) if b] builder = self.original builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if not builds: return Box(["none"], "white", class_="LastBuild") b = builds[0] name = b.getBuilder().getName() number = b.getNumber() url = path_to_build(req, b) text = b.getText() # TODO: maybe add logs? # TODO: add link to the per-build page at 'url' c = b.getColor() class_ = build_get_class(b) return Box(text, c, class_="LastBuild %s" % class_)
def getBox(self, req): assert interfaces.IBuilderStatus(self.original) branches = [b for b in req.args.get("branch", []) if b] builder = self.original builds = list( builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if not builds: return Box(["none"], "white", class_="LastBuild") b = builds[0] name = b.getBuilder().getName() number = b.getNumber() url = path_to_build(req, b) text = b.getText() # TODO: maybe add logs? # TODO: add link to the per-build page at 'url' c = b.getColor() class_ = build_get_class(b) return Box(text, c, class_="LastBuild %s" % class_)
def getBox(self, req): b = self.original number = b.getNumber() url = base.path_to_build(req, b) reason = b.getReason() if reason: text = (('%s<br><a href="%s">Build %d</a><br>%s') % (b.getBuilder().getName(), url, number, html.escape(reason))) else: text = ('%s<br><a href="%s">Build %d</a>' % (b.getBuilder().getName(), url, number)) color = "yellow" class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. Color the box red or green # to show its status color = b.getColor() class_ = base.build_get_class(b) return base.Box([text], color=color, class_="BuildStep " + class_)
def build_cxt(self, request, build): if not build: return {} if build.isFinished(): # get the text and annotate the first line with a link text = build.getText() if not text: text = ["(no information)"] if text == ["build", "successful"]: text = ["OK"] else: text = ['building'] name = build.getBuilder().getName() cxt = {} cxt['name'] = name cxt['url'] = path_to_build(request, build) cxt['text'] = text cxt['class'] = build_get_class(build) return cxt
def build_cxt(self, request, build): if not build: return {} if build.isFinished(): # get the text and annotate the first line with a link text = build.getText() if not text: text = [ "(no information)" ] if text == [ "build", "successful" ]: text = [ "OK" ] else: text = [ 'building' ] name = build.getBuilder().getName() cxt = {} cxt['name'] = name cxt['url'] = path_to_build(request, build) cxt['text'] = text cxt['class'] = build_get_class(build) return cxt
def getBox(self, req): b = self.original number = b.getNumber() url = path_to_build(req, b) reason = b.getReason() # Update the buildbot BuildStatus so that it displays the hg revision number as the build number changedesc = '(%d)' % number revision = b.getSourceStamp().revision if (len(b.changes) > 0): changedesc = '%s (%d)' % (b.changes[0].revision, number) if (revision): changedesc = "%s (%d)" % (revision, number) text = ('<a title="Reason: %s" href="%s">Build %s</a>' % (html.escape(reason), url, changedesc)) class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. class_ = build_get_class(b) return Box([text], class_="BuildStep " + class_)
def getBox(self, req): b = self.original number = b.getNumber() url = path_to_build(req, b) reason = b.getReason() # Update the buildbot BuildStatus so that it displays the hg revision number as the build number changedesc='(%d)' % number revision=b.getSourceStamp().revision if (len(b.changes)>0): changedesc='%s (%d)' % (b.changes[0].revision,number) if (revision): changedesc="%s (%d)" % (revision,number) text = ('<a title="Reason: %s" href="%s">Build %s</a>' % (html.escape(reason), url, changedesc)) class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. class_ = build_get_class(b) return Box([text], class_="BuildStep " + class_)
def content(self, req, cxt): tr = self.test_result b = self.status cxt['b'] = self.status logs = cxt['logs'] = [] for lname, log in tr.getLogs().items(): if isinstance(log, str): log = log.decode('utf-8') logs.append({'name': lname, 'log': log, 'link': req.childLink("logs/%s" % urllib.quote(lname)) }) cxt['text'] = tr.text cxt['result_word'] = Results[tr.getResults()] cxt.update(dict(builder_link = path_to_builder(req, b.getBuilder()), build_link = path_to_build(req, b), result_css = css_classes[tr.getResults()], b = b, tr = tr)) template = req.site.buildbot_service.templates.get_template("testresult.html") return template.render(**cxt)
def performAction(self, req): authz = self.getAuthz(req) res = yield authz.actionAllowed(self.action, req, self.build_status) if not res: defer.returnValue(path_to_authzfail(req)) return b = self.build_status log.msg("web cancel of build %s:%s" % \ (b.getBuilder().getName(), b.getNumber())) name = authz.getUsernameFull(req) comments = req.args.get("comments", ["<no reason specified>"])[0] comments.decode(getRequestCharset(req)) # html-quote both the username and comments, just to be safe reason = ("The web-page 'Cancel Build' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) if self.build_status.getResults() == RESUME: yield self.build_status.builder.cancelBuildRequestsOnResume( self.build_status.getNumber()) defer.returnValue(path_to_build(req, self.build_status))
def content(self, req, cxt): s = self.step_status b = s.getBuild() # FIXME: If the step name has a / in it, this is broken # either way. If we quote it but say '/'s are safe, # it chops up the step name. If we quote it and '/'s # are not safe, it escapes the / that separates the # step name from the log number. logs, _, _ = getStepLogsURLsAndAliases( s, True, lambda l: req.childLink("logs/%s" % urllib.quote(l.getName())), ) cxt['logs'] = logs start, end = s.getTimes() if start: cxt['start'] = ctime(start) if end: cxt['end'] = ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: cxt['end'] = "Not Finished" cxt['elapsed'] = util.formatInterval(util.now() - start) cxt.update( dict(builder_link=path_to_builder(req, b.getBuilder()), build_link=path_to_build(req, b), b=b, s=s, result_css=css_classes[s.getResults()[0]])) template = req.site.buildbot_service.templates.get_template( "buildstep.html") return template.render(**unicodify(cxt))
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName( ) else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime( "%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ss = cxt['ss'] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt['most_recent_rev_build'] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: cxt['got_revision'] = str(got_revision) try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isHidden(): continue if s.isFinished(): step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName(), safe='')) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step['nest_level'] = s.getNestLevel() step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(logname, safe=''))), 'name': logname }) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = {'name': name, 'value': value, 'source': source} if len(value) > 500: p['short_value'] = value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) cxt['exactly'] = (ss.revision is not None) or b.getChanges() cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template( "build.html") return template.render(**cxt)
def __prepare_context(self, request, cxt=None): """ This method prepares context for templates :param request: http request object :param cxt: default context variable :type cxt: dictionary :return: dictionary with variables for template """ if not cxt: context = {} else: context = cxt.copy() builder = self.build_status.getBuilder() context['builder_name'] = builder.name context['builder_friendly_name'] = builder.getFriendlyName() context['selected_project'] = builder.getProject() context['build_number'] = self.build_status.getNumber() context['custom_build_urls'] = self.build_status.getCustomUrls() context['source_stamps'] = self.build_status.getSourceStamps() context['got_revisions'] = self.build_status.getAllGotRevisions() context['slave_friendly_name'] = self.build_status.getSlavename() context['build_reason'] = self.build_status.getReason() context['build_is_resuming'] = self.build_status.isResuming() context['build_is_finished'] = self.build_status.isFinished() context['path_to_builder'] = path_to_builder( request, self.build_status.getBuilder()) context['path_to_builders'] = path_to_builders(request, builder.getProject()) context['path_to_codebases'] = path_to_codebases( request, builder.getProject()) context['build_url'] = path_to_build(request, self.build_status, False) context['slave_debug_url'] = self.getBuildmaster( request).config.slave_debug_url context['codebases_arg'] = getCodebasesArg(request=request) context['parent_build_url'] = None context['top_build_url'] = None start, end = self.build_status.getTimes() context['start'] = time.ctime(start) context['end'] = time.ctime(end) if end else None context['elapsed'] = None if not end: end = util.now() if start: context['elapsed'] = util.formatInterval(end - start) context['authz'] = self.getAuthz(request) context['has_changes'] = False context['tests_link'] = None context['resume'] = None context['top_build_name'] = None context['parent_build_name'] = None context['result_css'] = "" context['slave_url'] = "" context['steps'] = [] context['properties'] = [] return context
def render_GET(self, req): self._setContentType(req) self.req = req if self.original.isFinished(): req.setHeader("Cache-Control", "max-age=604800") else: req.setHeader("Cache-Control", "no-cache") # If plaintext is requested just return the content of the logfile if self.asDownload: with_headers = "_with_headers" if self.withHeaders else "" base_name = self.original.step.getName( ) + "_" + self.original.getName() + with_headers base_name = re.sub(r'[\W]', '_', base_name) + ".log" req.setHeader("Content-Disposition", "attachment; filename =\"" + base_name + "\"") return self.original.getTextWithHeaders( ) if self.withHeaders else self.original.getText() # Or open in new window if self.newWindow: req.setHeader("Content-Disposition", "inline") return self.original.getTextWithHeaders( ) if self.withHeaders else self.original.getText() # Else render the logs template self.template = req.site.buildbot_service.templates.get_template( "logs.html") self.chunk_template = req.site.buildbot_service.templates.get_template( "log_chunk.html") builder = self.original.step.build.builder build_id = self.original.step.build.number url_dict = self.original.master.status.getURLForBuild( builder.getName(), build_id) if self.iFrame: data = self.chunk_template.module.page_header(version) data = data.encode('utf-8') req.write(data) self.original.subscribeConsumer(ChunkConsumer(req, self)) return server.NOT_DONE_YET cxt = self.getContext(req) build = self.original.step.build builder_status = build.builder project = builder_status.getProject() cxt["pageTitle"] = "Log File Contents" cxt["new_window_url"] = req.path + "/plaintext" cxt["new_window_with_headers_url"] = req.path + "/plaintext_with_headers" cxt["download_url"] = req.path + "/download" cxt["download_with_headers_url"] = req.path + "/download_with_headers" cxt["iframe_url"] = req.path + "/iframe" cxt["builder_name"] = builder.getFriendlyName() cxt['path_to_builder'] = path_to_builder(req, builder_status) cxt['path_to_builders'] = path_to_builders(req, project) cxt["builder_url"] = url_dict['path'] + getCodebasesArg(request=req) cxt['path_to_codebases'] = path_to_codebases(req, project) cxt['path_to_build'] = path_to_build(req, build) cxt['build_number'] = build.getNumber() cxt['selectedproject'] = project data = self.template.render(**cxt) data = data.encode('utf-8') req.write(data) return ""
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName() else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ss = cxt['ss'] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt['most_recent_rev_build'] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: cxt['got_revision'] = str(got_revision) try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName() } cxt['steps'].append(step) if s.isFinished(): step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName())) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x:dict(url=x[1],logname=x[0]), s.getURLs().items()) step['logs']= [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName()), urllib.quote(logname))), 'name': logname }) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = { 'name': name, 'value': value, 'source': source} if len(value) > 500: p['short_value'] = value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) cxt['exactly'] = (ss.revision is not None) or b.getChanges() cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template("build.html") return template.render(**cxt)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName() else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ssList = b.getSourceStamps() sourcestamps = cxt['sourcestamps'] = ssList all_got_revisions = b.getAllGotRevisions() cxt['got_revisions'] = all_got_revisions try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isFinished(): if s.isHidden(): continue step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName(), safe='')) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append({'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(logname, safe=''))), 'name': logname}) scheduler = b.getProperty("scheduler", None) parameters = {} master = self.getBuildmaster(req) for sch in master.allSchedulers(): if isinstance(sch, ForceScheduler) and scheduler == sch.name: for p in sch.all_fields: parameters[p.name] = p ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): if not isinstance(value, dict): cxt_value = unicode(value) else: cxt_value = value p = {'name': name, 'value': cxt_value, 'source': source} if len(cxt_value) > 500: p['short_value'] = cxt_value[:500] if name in parameters: param = parameters[name] if isinstance(param, TextParameter): p['text'] = param.value_to_text(value) p['cols'] = param.cols p['rows'] = param.rows p['label'] = param.label ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) has_changes = False for ss in sourcestamps: has_changes = has_changes or ss.changes cxt['has_changes'] = has_changes cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template("build.html") return template.render(**cxt)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName( ) else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime( "%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ss = cxt['ss'] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt['most_recent_rev_build'] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: cxt['got_revision'] = str(got_revision) try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isHidden(): continue if s.isFinished(): step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) step_logs, step_urls, step_aliases = getStepLogsURLsAndAliases( s, False, lambda l: req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(l.getName(), safe=''))), ) step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName(), safe='')) step['text'] = " ".join(s.getText()) step['urls'] = step_urls step['nest_level'] = s.getNestLevel() step['logs'] = step_logs step['aliases'] = {} seen_aliases = set() for base, aliases in step_aliases.iteritems(): step['aliases'][base] = [{ 'text': a[0], 'url': a[1], } for a in aliases] seen_aliases.add(base) seen_aliases.difference_update(s['logname'] for s in step['urls']) seen_aliases.difference_update(s['name'] for s in step['logs']) # Append link-less log anchors for unbased aliases to attach to. # # We include an empty link so that custom templates that don't # support aliases don't crash when trying to render these anchors. # This will cause waterfalls that have alias data but haven't # updated their templates to render them to show blank links. This # is okay, since waterfalls that accept alias data should have # their templates updated to render this data. for base in sorted(seen_aliases): step['logs'].append({'name': base, 'link': ''}) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = {'name': name, 'value': value, 'source': source} if len(value) > 500: p['short_value'] = value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) cxt['exactly'] = (ss.revision is not None) or b.getChanges() cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template( "build.html") return template.render(**unicodify(cxt))
def body(self, req): status = self.getStatus(req) authz = self.getAuthz(req) builders = req.args.get( "builder", status.getBuilderNames(categories=self.categories)) branches = [b for b in req.args.get("branch", []) if b] if not branches: branches = ["trunk"] if branches and "trunk" not in branches: defaultCount = "1" else: defaultCount = "10" num_builds = int(req.args.get("num_builds", [defaultCount])[0]) tag = tags.div() tag(tags.script(src="txbuildbot.js")) tag( tags.h2(style="float:left; margin-top:0")("Latest builds: ", ", ".join(branches))) form = tags.form(method="get", action="", style="float:right", onsubmit="return checkBranch(branch.value)") form( tags.input(type="test", name="branch", placeholder=branches[0], size="40")) form(tags.input(type="submit", value="View")) if (yield authz.actionAllowed('forceAllBuilds', req)): # XXX: Unsafe interpolation form( tags.button(type="button", onclick="forceBranch(branch.value || %r, %r)" % ( branches[0], self.categories, ))("Force")) tag(form) table = tags.table(style="clear:both") tag(table) for bn in builders: builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() table(row) builderLink = path_to_builder(req, builder) row( tags.td(class_="box %s" % (state, ))( tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if build.getSourceStamp().branch in map_branches(branches) ], key=lambda build: build.getNumber(), reverse=True) builds.extend( builder.generateFinishedBuilds(map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when), ), "%s" % (time.strftime( "%H:%M:%S", time.localtime(time.time() + when)), ) ] else: text = [] row( tags.td( align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text ])) else: row(tags.td(class_="LastBuild box")("no build")) defer.returnValue((yield flattenString(req, tag)))
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName( ) else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime( "%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ssList = b.getSourceStamps() sourcestamps = cxt['sourcestamps'] = ssList all_got_revisions = b.getAllGotRevisions() cxt['got_revisions'] = all_got_revisions try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isFinished(): if s.isHidden(): continue step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName(), safe='')) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(logname, safe=''))), 'name': logname }) scheduler = b.getProperty("scheduler", None) parameters = {} master = self.getBuildmaster(req) for sch in master.allSchedulers(): if isinstance(sch, ForceScheduler) and scheduler == sch.name: for p in sch.all_fields: parameters[p.name] = p ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): if not isinstance(value, dict): cxt_value = unicode(value) else: cxt_value = value p = {'name': name, 'value': cxt_value, 'source': source} if len(cxt_value) > 500: p['short_value'] = cxt_value[:500] if name in parameters: param = parameters[name] if isinstance(param, TextParameter): p['text'] = param.value_to_text(value) p['cols'] = param.cols p['rows'] = param.rows p['label'] = param.label ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) exactly = True has_changes = False for ss in sourcestamps: exactly = exactly and (ss.revision is not None) has_changes = has_changes or ss.changes cxt['exactly'] = (exactly) or b.getChanges() cxt['has_changes'] = has_changes cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template( "build.html") return template.render(**cxt)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') builder = self.build_status.getBuilder() cxt['builder'] = builder cxt['builder_name'] = builder.getFriendlyName() cxt['build_number'] = b.getNumber() cxt['builder_name_link'] = urllib.quote( self.build_status.getBuilder().getName(), safe='') cxt['b'] = b project = cxt['selectedproject'] = builder.getProject() cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) cxt['path_to_builders'] = path_to_builders(req, project) cxt['path_to_codebases'] = path_to_codebases(req, project) cxt['build_url'] = path_to_build(req, b, False) cxt['slave_debug_url'] = self.getBuildmaster( req).config.slave_debug_url cxt['customBuildUrls'] = b.getCustomUrls() codebases_arg = cxt['codebases_arg'] = getCodebasesArg(request=req) cxt['build_chain_top_build_url'] = yield b.getTopBuildUrl( codebases_arg) if not b.isFinished(): cxt['stop_build_chain'] = False step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for build slave]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for build slave]" % step.getName( ) else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime( "%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ssList = b.getSourceStamps() sourcestamps = cxt['sourcestamps'] = ssList all_got_revisions = b.getAllGotRevisions() cxt['got_revisions'] = all_got_revisions try: slave_obj = status.getSlave(b.getSlavename()) if slave_obj is not None: cxt['slave_friendly_name'] = slave_obj.getFriendlyName() cxt['slave_url'] = path_to_slave(req, slave_obj) else: cxt['slave_friendly_name'] = b.getSlavename() cxt['slave_url'] = "" except KeyError: pass if b.resume: cxt['resume'] = b.resume cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isFinished(): if s.isHidden(): continue step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not-started" step['time_to_run'] = "" cxt['steps'].append(step) step['link'] = path_to_step(req, s) step['text'] = " ".join(s.getText()) urls = [] getUrls = s.getURLs().items() for k, v in s.getURLs().items(): if isinstance(v, dict): if 'results' in v.keys() and v['results'] in css_classes: url_dict = dict(logname=k, url=v['url'] + codebases_arg, results=css_classes[v['results']]) else: url_dict = dict(logname=k, url=v['url'] + codebases_arg) else: url_dict = dict(logname=k, url=v + codebases_arg) urls.append(url_dict) step['urls'] = urls step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink( "steps/%s/logs/%s%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(logname, safe=''), codebases_arg)), 'name': logname }) scheduler = b.getProperty("scheduler", None) parameters = {} master = self.getBuildmaster(req) for sch in master.allSchedulers(): if isinstance(sch, ForceScheduler) and scheduler == sch.name: for p in sch.all_fields: parameters[p.name] = p ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): if not isinstance(value, dict): cxt_value = unicode(value) else: cxt_value = value if name == 'submittedTime': cxt_value = time.ctime(value) p = {'name': name, 'value': cxt_value, 'source': source} if len(cxt_value) > 500: p['short_value'] = cxt_value[:500] if name in parameters: param = parameters[name] if isinstance(param, TextParameter): p['text'] = param.value_to_text(value) p['cols'] = param.cols p['rows'] = param.rows p['label'] = param.label ps.append(p) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) cxt['elapsed'] = None if end and start: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) elif start: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) has_changes = False for ss in sourcestamps: has_changes = has_changes or ss.changes cxt['has_changes'] = has_changes cxt['authz'] = self.getAuthz(req) filters = {"number": b.getNumber()} build_json = BuildJsonResource(status, b) build_dict = yield build_json.asDict(req) cxt['instant_json']['build'] = { "url": path_to_json_build(status, req, builder.name, b.getNumber()), "data": json.dumps(build_dict, separators=(',', ':')), "waitForPush": status.master.config.autobahn_push, "pushFilters": { "buildStarted": filters, "buildFinished": filters, "stepStarted": filters, "stepFinished": filters, } } template = req.site.buildbot_service.templates.get_template( "build.html") defer.returnValue(template.render(**cxt))
def content(self, req, cxt): s = self.step_status b = s.getBuild() builder_status = b.getBuilder() project = builder_status.getProject() cxt['builder_name'] = builder_status.getFriendlyName() cxt['path_to_builder'] = path_to_builder(req, builder_status) cxt['path_to_builders'] = path_to_builders(req, project) cxt['path_to_codebases'] = path_to_codebases(req, project) cxt['path_to_build'] = path_to_build(req, b) cxt['build_number'] = b.getNumber() cxt['path_to_artifacts'] = self.get_artifact_path(b) cxt['join'] = join cxt['basename'] = basename cxt['splitext'] = splitext cxt['selectedproject'] = project cxt['removeTestFilter'] = removeTestFilter cxt['results'] = { 0: 'Inconclusive', 1: 'NotRunnable', 2: 'Skipped', 3: 'Ignored', 4: 'Success', 5: 'Failed', 6: 'Error', 7: 'Cancelled' } json_data = None error_message = None try: json_data = json.loads(self.log.getText()) if json_data is not None: if 'summary' in json_data: success_count = json_data['summary']['successCount'] total_count = json_data['summary']['testsCount'] if success_count != 0 and total_count != 0: success_per = (float(success_count) / float(total_count)) * 100.0 json_data['summary']['success_rate'] = success_per json_data['filters'] = { 'Inconclusive': True, 'Skipped': False, 'Ignored': False, 'Success': False, 'Failed': True, 'Error': True, 'Cancelled': True } cxt['data'] = json_data else: error_message = "[{0}] Error occurred while parsing JSON test report data" \ .format(self.__class__.__name__) except KeyError as e: error_message = "[{0}] Key error in json: {1}".format( self.__class__.__name__, e) except Exception: import sys import traceback extype, ex, tb = sys.exc_info() formatted = traceback.format_exception_only(extype, ex)[-1] error_message = "[{0}] Unexpected exception caught while loading JSON test report data: {1}"\ .format(self.__class__.__name__, '\n\t'.join(formatted.splitlines())) log.msg( Failure(), "Unexpected exception caught while loading JSON test report data" ) if error_message is not None: cxt['data_error'] = error_message template = req.site.buildbot_service.templates.get_template( "jsontestresults.html") return template.render(**cxt)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) cxt["b"] = b cxt["path_to_builder"] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): when = b.getETA() if when is not None: cxt["when"] = util.formatInterval(when) cxt["when_time"] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) else: cxt["result_css"] = css_classes[b.getResults()] if b.getTestResults(): cxt["tests_link"] = req.childLink("tests") ss = cxt["ss"] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt["most_recent_rev_build"] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" cxt["got_revision"] = got_revision try: cxt["slave_url"] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt["steps"] = [] for s in b.getSteps(): step = {"name": s.getName()} cxt["steps"].append(step) if s.isFinished(): step["css_class"] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step["time_to_run"] = util.formatInterval(end - start) elif s.isStarted(): step["css_class"] = "running" step["time_to_run"] = "running" else: step["css_class"] = "not_started" step["time_to_run"] = "" step["link"] = req.childLink("steps/%s" % urllib.quote(s.getName())) step["text"] = " ".join(s.getText()) step["urls"] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step["logs"] = [] for l in s.getLogs(): logname = l.getName() step["logs"].append( { "link": req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName()), urllib.quote(logname))), "name": logname, } ) ps = cxt["properties"] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = {"name": name, "value": value, "source": source} if len(value) > 500: p["short_value"] = value[:500] ps.append(p) cxt["responsible_users"] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt["start"] = time.ctime(start) if end: cxt["end"] = time.ctime(end) cxt["elapsed"] = util.formatInterval(end - start) else: now = util.now() cxt["elapsed"] = util.formatInterval(now - start) cxt["exactly"] = (ss.revision is not None) or b.getChanges() cxt["build_url"] = path_to_build(req, b) cxt["authz"] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template("build.html") return template.render(**cxt)
def content(self, req, cxt): s = self.step_status b = s.getBuild() builder_status = b.getBuilder() project = builder_status.getProject() cxt['builder_name'] = b.getBuilder().getFriendlyName() cxt['path_to_builder'] = path_to_builder(req, builder_status) cxt['path_to_builders'] = path_to_builders(req, project) cxt['path_to_codebases'] = path_to_codebases(req, project) cxt['path_to_build'] = path_to_build(req, b) cxt['build_number'] = b.getNumber() cxt['selectedproject'] = project xml_type = NUNIT try: html = self.log.getText() if "nosetests" in html: xml_type = NOSE elif "<testsuites>" and "testsuite" in html: xml_type = JUNIT if "utf-16" in html: html = html.replace("utf-16", "utf-8") root = ElementTree.fromstring(html) root_dict = self.etree_to_dict(root) xpath = ".//test-suite/results/test-case/../.." if xml_type is NOSE or xml_type is JUNIT: xpath = ".//testcase" test_suites_dict = [ self.etree_to_dict(r) for r in root.findall(xpath) ] if xml_type is JUNIT: root_dict = root_dict["testsuites"][0] def parseTest(test, xml_type): total = 0 time_count = 0 test_parent = self.test_dict() def updateTime(result_object): t = 0 if result_object.has_key('time'): t = result_object['time'] test_parent['time'] += t return t if test.has_key("name"): test_parent["name"] = test["name"] if xml_type is NUNIT and 'results' in test: test_parent['tests_length'] = len(test['results']) for r in tso['results']: result_object = self.test_result_xml_to_dict( r, xml_type) test_parent['results'].append(result_object) total += 1 time_count += updateTime(result_object) test_parent[self.test_result_to_status( r, xml_type)[0]] += 1 elif xml_type is NOSE: result_object = self.test_result_xml_to_dict( test, xml_type) test_parent['results'].append(result_object) total += 1 time_count += updateTime(result_object) test_parent[self.test_result_to_status(test, xml_type)[0]] += 1 elif xml_type is JUNIT: result_object = self.test_result_xml_to_dict( test, xml_type) test_parent["results"].append(result_object) total += 1 time_count += updateTime(result_object) test_parent[self.test_result_to_status(test, xml_type)[0]] += 1 return test_parent, total, time_count # Collect summary information for each test suite time_count = 0 total = 0 output_tests = [] if xml_type is NUNIT: for ts in test_suites_dict: tests = ts['test-suite'] for tso in tests: o, c, t = parseTest(tso, xml_type) o["name"] = ts["name"] output_tests.append(o) total += c time_count += t elif xml_type is NOSE: classes = {} for tso in test_suites_dict: class_name = tso["classname"] o, c, t = parseTest(tso, xml_type) if class_name not in classes: classes[class_name] = self.test_dict() classes[class_name]["name"] = class_name classes[class_name]["results"].append(o["results"][0]) classes[class_name]["passed"] += o["passed"] classes[class_name]["failed"] += o["failed"] classes[class_name]["time"] += t classes[class_name]["tests"] += c total += c time_count += t output_tests = classes.values() elif xml_type is JUNIT: classes = {} for tso in test_suites_dict: o, c, t = parseTest(tso, xml_type) class_name = tso["classname"] if class_name not in classes: classes[class_name] = self.test_dict() classes[class_name]["name"] = class_name classes[class_name]["results"].append(o["results"][0]) classes[class_name]["passed"] += o["passed"] classes[class_name]["failed"] += o["failed"] classes[class_name]["time"] += t classes[class_name]["tests"] += c total += c time_count += t output_tests = classes.values() cxt['data'] = {} cxt['data']['test_suites'] = output_tests failed = int(0 if ( 'failures' not in root_dict) else root_dict['failures']) error = int(0 if ( 'errors' not in root_dict) else root_dict['errors']) ignored = int(0 if ( 'ignored' not in root_dict) else root_dict['ignored']) skipped = int(0 if ( 'skipped' not in root_dict) else root_dict['skipped']) inconclusive = int(0 if ('inconclusive' not in root_dict ) else root_dict['inconclusive']) if skipped == 0 and 'skipped' not in root_dict: skipped = int(0 if ( 'not-run' not in root_dict) else root_dict['not-run']) success = (total - failed - inconclusive - skipped - ignored) success_per = 0 if success != 0 and total != 0: success_per = (float(success) / float(total)) * 100.0 cxt['data']['summary'] = { 'testsCount': total, 'passedCount': success, 'success_rate': success_per, 'failedCount': failed, 'ignoredCount': ignored, 'skippedCount': skipped, 'errorCount': error, 'inconclusiveCount': inconclusive, 'time': time_count } cxt['data']['filters'] = { 'Failed': True, 'Passed': False, 'Ignored': False, 'Inconclusive': False, 'Skipped': False } except ElementTree.ParseError as e: log.msg("Error with parsing XML: {0}".format(e)) template = req.site.buildbot_service.templates.get_template( "xmltestresults.html") return template.render(**cxt)
def body(self, req): status = self.getStatus(req) authz = self.getAuthz(req) builders = req.args.get("builder", status.getBuilderNames(categories=self.categories)) branches = [b for b in req.args.get("branch", []) if b] if not branches: branches = ["trunk"] if branches and "trunk" not in branches: defaultCount = "1" else: defaultCount = "10" num_builds = int(req.args.get("num_builds", [defaultCount])[0]) tag = tags.div() tag(tags.script(src="txbuildbot.js")) tag(tags.h2(style="float:left; margin-top:0")("Latest builds: ", ", ".join(branches))) form = tags.form(method="get", action="", style="float:right", onsubmit="return checkBranch(branch.value)") form(tags.input(type="test", name="branch", placeholder=branches[0], size="40")) form(tags.input(type="submit", value="View")) if (yield authz.actionAllowed('forceAllBuilds', req)): # XXX: Unsafe interpolation form(tags.button(type="button", onclick="forceBranch(branch.value || %r, %r)" % (branches[0], self.categories,) )("Force")) tag(form) table = tags.table(style="clear:both") tag(table) for bn in builders: builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() table(row) builderLink = path_to_builder(req, builder) row(tags.td(class_="box %s" % (state,))(tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if build.getSourceStamps()[0].branch in map_branches(branches) ], key=lambda build: build.getNumber(), reverse=True) builds.extend(builder.generateFinishedBuilds(map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when),), "%s" % (time.strftime("%H:%M:%S", time.localtime(time.time() + when)),) ] else: text = [] row(tags.td( align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text]) ) else: row(tags.td(class_="LastBuild box")("no build")) defer.returnValue((yield flattenString(req, tag)))