Example #1
0
    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))
        if build.started:
            b['delay'] = util.formatInterval(time.time() - build.started)

        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
Example #2
0
    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)
Example #3
0
    def getCommonBuildInfo(self, req, b):
        cxt = {}
        cxt['number'] = b.getNumber()

        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))

            cxt['result_css'] = "building"
        else:
            cxt['result_css'] = css_classes[b.getResults()]

        (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)

        return cxt
Example #4
0
    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
Example #5
0
  def finishStep(self, section, status=None):
    """Mark the specified step as 'finished.'"""
    # Update status if set as an argument.
    if status is not None:
      section['status'] = status

    self.ensureStepIsStarted(section)
    # Final update of text.
    updateText(section)
    # Add timing info.
    section['ended'] = section.get('ended', util.now())
    started = section['started']
    ended = section['ended']

    msg = '\n\n' + '-' * 80 + '\n'
    msg += '\n'.join([
        'started: %s' % time.ctime(started),
        'ended: %s' % time.ctime(ended),
        'duration: %s' % util.formatInterval(ended - started),
        '',  # So we get a final \n
    ])
    section['log'].addHeader(msg)
    # Change status (unless handling the preamble).
    if len(self.sections) != 1:
      section['step'].stepFinished(section['status'])
    # Finish log.
    section['log'].finish()
Example #6
0
  def fixupLast(self, status=None):
    # Potentially start initial section here, as initial section might have
    # no output at all.
    self.initialSection()

    last = self.sections[-1]
    # Update status if set as an argument.
    if status is not None:
      last['status'] = status
    # Final update of text.
    self.updateText()
    # Add timing info.
    (start, end) = self.command.step_status.getTimes()
    msg = '\n\n' + '-' * 80 + '\n'
    if start is None:
      msg += 'Not Started\n'
    else:
      if end is None:
        end = util.now()
      msg += '\n'.join([
          'started: %s' % time.ctime(start),
          'ended: %s' % time.ctime(end),
          'duration: %s' % util.formatInterval(end - start),
          '',  # So we get a final \n
      ])
    last['log'].addStdout(msg)
    # Change status (unless handling the preamble).
    if len(self.sections) != 1:
      last['step'].stepFinished(last['status'])
    # Finish log.
    last['log'].finish()
def formatSteps(logFile, build):
    """
    Writes the steps of build to the logfile
    """
    # Steps
    total_master_lag = 0.0
    for step in build.getSteps():
        times = step.getTimes()
        if not times or not times[0]:
            elapsed = "not started"
        elif not times[1]:
            elapsed = "not finished"
        else:
            elapsed = util.formatInterval(times[1] - times[0])

        results = step.getResults()[0]
        if results == (None, []):
            results = "not started"

        shortText = ' '.join(step.getText(
        )) + ' (results: %s, elapsed: %s)' % (results, elapsed)
        if times and times[0]:
            logFile.write("========= Started %s (at %s) =========\n" %
                          (shortText, datetime.fromtimestamp(times[0])))
        else:
            logFile.write("========= Skipped %s =========\n" % shortText)
            continue

        slave_time = None
        for log in step.getLogs():
            data = log.getTextWithHeaders()
            logFile.write(data)
            if not data.endswith("\n"):
                logFile.write("\n")

            # Look for if the slave reported its elapsedTime
            m = re.search("^elapsedTime=([.0-9]+)$", data, re.M)
            if m:
                try:
                    slave_time = float(m.group(1))
                except ValueError:
                    pass

        if times and times[0] and times[1] and slave_time:
            master_lag = times[1] - times[0] - slave_time
            total_master_lag += master_lag
            logFile.write("========= master_lag: %.2f =========\n" % master_lag)
            if STATSD:
                # statsd expects milliseconds
                STATSD.timing('master_lag', master_lag * 1000.0)

        if times and times[1]:
            logFile.write("========= Finished %s (at %s) =========\n\n" %
                          (shortText, datetime.fromtimestamp(times[1])))
        else:
            logFile.write("========= Finished %s =========\n\n" % shortText)

    if STATSD:
        STATSD.timing('total_master_lag', total_master_lag * 1000.0)
    logFile.write("========= Total master_lag: %.2f =========\n\n" % total_master_lag)
Example #8
0
    def request_line(self, build_request, req):
        when = time.strftime("%b %d %H:%M:%S", time.localtime(build_request.getSubmitTime()))
        delay = util.formatInterval(util.now() - build_request.getSubmitTime())
        changes = build_request.source.changes
        if changes:
            change_strings = []
            for c in changes:
                change_strings.append("<a href=\"%s\">%s</a>" % (path_to_change(req, c), c.who))
            if len(change_strings) == 1:
                reason = "change by %s" % change_strings[0]
            else:
                reason = "changes by %s" % ", ".join(change_strings)
        elif build_request.source.revision:
            reason = build_request.source.revision
        else:
            reason = "no changes specified"

        if self.builder_control is not None:
            cancelURL = path_to_builder(req, self.builder_status) + '/cancelbuild'
            cancelButton = '''
<form action="%s" class="command cancelbuild" style="display:inline" method="post">
  <input type="hidden" name="id" value="%s" />
  <input type="submit" value="Cancel Build" />
</form>''' % (cancelURL, id(build_request))
        else:
            cancelButton = ""
        return "<font size=\"-1\">(%s, waiting %s)</font>%s%s" % (when, delay, cancelButton, reason)
Example #9
0
    def content(self, req, cxt):
        b = self.builder_status

        cxt['name'] = b.getName()
        
        slaves = b.getSlaves()
        connected_slaves = [s for s in slaves if s.isConnected()]

        cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()]

        cxt['pending'] = []
        for pb in b.getPendingBuilds():
            source = pb.getSourceStamp()
            changes = []

            if source.changes:
                for c in source.changes:
                    changes.append({ 'url' : path_to_change(req, c),
                                            'who' : c.who})
            if source.revision:
                reason = source.revision
            else:
                reason = "no changes specified"

            cxt['pending'].append({
                'when': time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())),
                'delay': util.formatInterval(util.now() - pb.getSubmitTime()),
                'reason': reason,
                'id': pb.brid,
                'changes' : changes
                })

        numbuilds = int(req.args.get('numbuilds', ['5'])[0])
        recent = cxt['recent'] = []
        for build in b.generateFinishedBuilds(num_builds=int(numbuilds)):
            recent.append(self.get_line_values(req, build, False))

        sl = cxt['slaves'] = []
        connected_slaves = 0
        for slave in slaves:
            s = {}
            sl.append(s)
            s['link'] = path_to_slave(req, slave)
            s['name'] = slave.getName()
            c = s['connected'] = slave.isConnected()
            if c:
                s['admin'] = slave.getAdmin()
                connected_slaves += 1
        cxt['connected_slaves'] = connected_slaves

        cxt['authz'] = self.getAuthz(req)
        cxt['builder_url'] = path_to_builder(req, b)

        template = req.site.buildbot_service.templates.get_template("builder.html")
        return template.render(**cxt)
Example #10
0
    def content(self, req, cxt):
        b = self.builder_status

        cxt["name"] = b.getName()

        slaves = b.getSlaves()
        connected_slaves = [s for s in slaves if s.isConnected()]

        cxt["current"] = [self.builder(x, req) for x in b.getCurrentBuilds()]

        cxt["pending"] = []
        for pb in b.getPendingBuilds():
            changes = []

            if pb.source.changes:
                for c in pb.source.changes:
                    changes.append({"url": path_to_change(req, c), "who": c.who})
            if pb.source.revision:
                reason = pb.source.revision
            else:
                reason = "no changes specified"

            cxt["pending"].append(
                {
                    "when": time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())),
                    "delay": util.formatInterval(util.now() - pb.getSubmitTime()),
                    "reason": reason,
                    "id": id(pb),
                    "changes": changes,
                }
            )

        numbuilds = int(req.args.get("numbuilds", ["5"])[0])
        recent = cxt["recent"] = []
        for build in b.generateFinishedBuilds(num_builds=int(numbuilds)):
            recent.append(self.get_line_values(req, build, False))

        sl = cxt["slaves"] = []
        connected_slaves = 0
        for slave in slaves:
            s = {}
            sl.append(s)
            s["link"] = path_to_slave(req, slave)
            s["name"] = slave.getName()
            c = s["connected"] = slave.isConnected()
            if c:
                s["admin"] = slave.getAdmin()
                connected_slaves += 1
        cxt["connected_slaves"] = connected_slaves

        cxt["authz"] = self.getAuthz(req)
        cxt["builder_url"] = path_to_builder(req, b)

        template = req.site.buildbot_service.templates.get_template("builder.html")
        return template.render(**cxt)
Example #11
0
    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
Example #12
0
  def finishStep(self, section, status=None, reason=None):
    """Mark the specified step as 'finished.'"""

    # The initial section will be closed by self.finished when runCommand
    # completes, so finishStep should not close it.
    assert not self.sectionIsPreamble(section), ('The initial section cannot '
                                                 'be finalized at annotator '
                                                 'level.')

    status_map = {
        builder.SUCCESS: 'SUCCESS',
        builder.WARNINGS: 'WARNINGS',
        builder.FAILURE: 'FAILURE',
        builder.EXCEPTION: 'EXCEPTION',
        builder.RETRY: 'RETRY',
        builder.SKIPPED: 'SKIPPED',
    }

    # Update status if set as an argument.
    if status is not None:
      section['status'] = status
    else:
      # Wasn't set as an argument, so we know it came from annotations.
      if not reason:
        if section['status'] == builder.SUCCESS:
          reason = 'step finished normally.'
        else:
          reason = 'parsed annotations marked step as %s.' % status_map[
              section['status']]

    self.ensureStepIsStarted(section)
    # Final update of text.
    updateText(section)
    # Add timing info.
    section['ended'] = section.get('ended', util.now())
    started = section['started']
    ended = section['ended']

    msg = '\n\n' + '-' * 80 + '\n'
    msg += '\n'.join([
        'started: %s' % time.ctime(started),
        'ended: %s' % time.ctime(ended),
        'duration: %s' % util.formatInterval(ended - started),
        'status: %s' % status_map[section['status']],
        'status reason: %s' % reason,
        '',  # So we get a final \n
    ])
    section['log'].addHeader(msg)
    # Change status (unless handling the preamble).
    if len(self.sections) != 1:
      section['step'].stepFinished(section['status'])
    # Finish log.
    section['log'].finish()
Example #13
0
    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
Example #14
0
    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
Example #15
0
    def getPending(self, request):
        nr = self.build_status.getNumber()

        status = self.getStatus(request)
        job = status.getBuilder(self.build_status.getBuilder().getName() + "-job")

        builds = []
        pending = yield job.getPendingBuildRequestStatuses()

        for b in pending:
            source = yield b.getSourceStamp()
            submitTime = yield b.getSubmitTime()
            bsid = yield b.getBsid()
            properties = yield \
                b.master.db.buildsets.getBuildsetProperties(bsid)

            if properties["spawned_by"][0] != nr:
                continue

            info = {}

            info['number'] = "?"

            env = info['environment'] = {}
            for name, value in properties.items():
                value, source = value
                if source != ".travis.yml":
                    continue
                env[name] = value

            # How long has it been pending?
            info['start'] = time.strftime("%b %d %H:%M:%S",
                                      time.localtime(submitTime))
            info['elapsed'] = util.formatInterval(util.now() - submitTime)

            info['result_css'] = "pending"

            builds.append(info)

        defer.returnValue(builds)
Example #16
0
    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)))
Example #17
0
    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([str(txt) for txt in 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)
Example #18
0
    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)
Example #19
0
    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))
Example #20
0
    def content(self, req, cxt):
        b = self.builder_status

        cxt['name'] = b.getName()

        slaves = b.getSlaves()
        connected_slaves = [s for s in slaves if s.isConnected()]

        cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()]

        cxt['pending'] = []
        for pb in b.getPendingBuilds():
            source = pb.getSourceStamp()
            changes = []

            if source.changes:
                for c in source.changes:
                    changes.append({
                        'url': path_to_change(req, c),
                        'who': c.who
                    })
            if source.revision:
                reason = source.revision
            else:
                reason = "no changes specified"

            cxt['pending'].append({
                'when':
                time.strftime("%b %d %H:%M:%S",
                              time.localtime(pb.getSubmitTime())),
                'delay':
                util.formatInterval(util.now() - pb.getSubmitTime()),
                'reason':
                reason,
                'id':
                pb.brid,
                'changes':
                changes
            })

        numbuilds = int(req.args.get('numbuilds', ['5'])[0])
        recent = cxt['recent'] = []
        for build in b.generateFinishedBuilds(num_builds=int(numbuilds)):
            recent.append(self.get_line_values(req, build, False))

        sl = cxt['slaves'] = []
        connected_slaves = 0
        for slave in slaves:
            s = {}
            sl.append(s)
            s['link'] = path_to_slave(req, slave)
            s['name'] = slave.getName()
            c = s['connected'] = slave.isConnected()
            if c:
                s['admin'] = slave.getAdmin()
                connected_slaves += 1
        cxt['connected_slaves'] = connected_slaves

        cxt['authz'] = self.getAuthz(req)
        cxt['builder_url'] = path_to_builder(req, b)

        template = req.site.buildbot_service.templates.get_template(
            "builder.html")
        return template.render(**cxt)
Example #21
0
def formatSteps(logFile, build):
    """
    Writes the steps of build to the logfile
    """
    # Steps
    total_master_lag = 0.0
    for step in build.getSteps():
        times = step.getTimes()
        if not times or not times[0]:
            elapsed = "not started"
        elif not times[1]:
            elapsed = "not finished"
        else:
            elapsed = util.formatInterval(times[1] - times[0])

        results = step.getResults()[0]
        if results == (None, []):
            results = "not started"

        shortText = ' '.join(step.getText(
        )) + ' (results: %s, elapsed: %s)' % (results, elapsed)
        if times and times[0]:
            logFile.write("========= Started %s (at %s) =========\n" %
                          (shortText, datetime.fromtimestamp(times[0])))
        else:
            logFile.write("========= Skipped %s =========\n" % shortText)
            continue

        slave_time = None
        for log in step.getLogs():
            data = log.getTextWithHeaders()
            logFile.write(data)
            if not data.endswith("\n"):
                logFile.write("\n")

            # Look for if the slave reported its elapsedTime
            m = re.search("^elapsedTime=([.0-9]+)$", data, re.M)
            if m:
                try:
                    slave_time = float(m.group(1))
                except ValueError:
                    pass

        if times and times[0] and times[1] and slave_time:
            master_lag = times[1] - times[0] - slave_time
            total_master_lag += master_lag
            logFile.write("========= master_lag: %.2f =========\n" %
                          master_lag)
            if STATSD:
                # statsd expects milliseconds
                STATSD.timing('master_lag', master_lag * 1000.0)

        if times and times[1]:
            logFile.write("========= Finished %s (at %s) =========\n\n" %
                          (shortText, datetime.fromtimestamp(times[1])))
        else:
            logFile.write("========= Finished %s =========\n\n" % shortText)

    if STATSD:
        STATSD.timing('total_master_lag', total_master_lag * 1000.0)
    logFile.write("========= Total master_lag: %.2f =========\n\n" %
                  total_master_lag)
Example #22
0
 def test_seconds_singular(self):
     self.assertEqual(util.formatInterval(1), "1 secs")
Example #23
0
 def test_minutes(self):
     self.assertEqual(util.formatInterval(300), "5 mins, 0 secs")
Example #24
0
 def test_hours_over_one_sec(self):
     self.assertEqual(util.formatInterval(3601), "1 hrs, 1 secs")
Example #25
0
 def test_seconds_singular(self):
     self.assertEqual(util.formatInterval(1), "1 secs")
Example #26
0
 def test_minutes_one(self):
     self.assertEqual(util.formatInterval(60), "60 secs")
Example #27
0
    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)
Example #28
0
 def test_minutes_one(self):
     self.assertEqual(util.formatInterval(60), "60 secs")
Example #29
0
 def test_seconds(self):
     self.assertEqual(util.formatInterval(7), "7 secs")
Example #30
0
    def content(self, req, cxt):
        b = self.builder_status

        # Grab all the parameters which are prefixed with 'property.'.
        # We'll use these to filter the builds and build requests we
        # show below.
        props = {}
        prop_prefix = 'property.'
        for arg, val in req.args.iteritems():
            if arg.startswith(prop_prefix):
                props[arg[len(prop_prefix):]] = val[0]
        def prop_match(oprops):
            for key, val in props.iteritems():
                if key not in oprops or val != str(oprops[key]):
                    return False
            return True

        cxt['name'] = b.getName()
        cxt['description'] = b.getDescription()
        req.setHeader('Cache-Control', 'no-cache')
        slaves = b.getSlaves()
        connected_slaves = [s for s in slaves if s.isConnected()]

        cxt['current'] = [
            self.builder(x, req) for x in b.getCurrentBuilds()
                if prop_match(x.getProperties())]

        cxt['pending'] = []
        statuses = yield b.getPendingBuildRequestStatuses()
        for pb in statuses:
            changes = []

            source = yield pb.getSourceStamp()
            submitTime = yield pb.getSubmitTime()
            bsid = yield pb.getBsid()

            properties = yield \
                    pb.master.db.buildsets.getBuildsetProperties(bsid)
            if not prop_match(properties):
                continue

            if source.changes:
                for c in source.changes:
                    changes.append({ 'url' : path_to_change(req, c),
                                     'who' : c.who,
                                     'revision' : c.revision,
                                     'repo' : c.repository })

            cxt['pending'].append({
                'when': time.strftime("%b %d %H:%M:%S",
                                      time.localtime(submitTime)),
                'delay': util.formatInterval(util.now() - submitTime),
                'id': pb.brid,
                'changes' : changes,
                'num_changes' : len(changes),
                'properties' : properties,
                })

        numbuilds = cxt['numbuilds'] = int(req.args.get('numbuilds', [self.numbuilds])[0])
        maxsearch = int(req.args.get('maxsearch', [200])[0])
        recent = cxt['recent'] = []
        for build in b.generateFinishedBuilds(
                num_builds=int(numbuilds),
                max_search=maxsearch,
                filter_fn=lambda b: prop_match(b.getProperties())):
            recent.append(self.get_line_values(req, build, False))

        sl = cxt['slaves'] = []
        connected_slaves = 0
        for slave in slaves:
            s = {}
            sl.append(s)
            s['link'] = path_to_slave(req, slave)
            s['name'] = slave.getName()
            c = s['connected'] = slave.isConnected()
            s['paused'] = slave.isPaused()
            s['admin'] = slave.getAdmin() or u''
            if c:
                connected_slaves += 1
        cxt['connected_slaves'] = connected_slaves

        cxt['authz'] = self.getAuthz(req)
        cxt['builder_url'] = path_to_builder(req, b)
        buildForceContext(cxt, req, self.getBuildmaster(req), b.getName())
        template = req.site.buildbot_service.templates.get_template("builder.html")
        defer.returnValue(template.render(**cxt))
Example #31
0
 def test_hours(self):
     self.assertEqual(util.formatInterval(7200), "2 hrs, 0 secs")
Example #32
0
    def body(self, req):
        b = self.build_status
        status = self.getStatus(req)
        projectURL = status.getProjectURL()
        projectName = status.getProjectName()
        data = ('<div class="title"><a href="%s">%s</a></div>\n' %
                (self.path_to_root(req), projectName))
        # the color in the following line gives python-mode trouble
        builder_name = b.getBuilder().getName()
        data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" %
                 (path_to_builder(
                     req, b.getBuilder()), builder_name, b.getNumber()))

        if not b.isFinished():
            data += "<h2>Build In Progress</h2>"
            when = b.getETA()
            if when is not None:
                when_time = time.strftime("%H:%M:%S",
                                          time.localtime(time.time() + when))
                data += "<div>ETA %ds (%s)</div>\n" % (when, when_time)

            if self.build_control is not None:
                stopURL = urllib.quote(req.childLink("stop"))
                data += make_stop_form(stopURL)

        if b.isFinished():
            results = b.getResults()
            data += "<h2>Results:</h2>\n"
            text = " ".join(b.getText())
            data += '<span class="%s">%s</span>\n' % (css_classes[results],
                                                      text)
            if b.getTestResults():
                url = req.childLink("tests")
                data += "<h3><a href=\"%s\">test results</a></h3>\n" % url

        ss = b.getSourceStamp()
        data += "<h2>SourceStamp:</h2>\n"
        data += " <ul>\n"
        if ss.branch:
            data += "  <li>Branch: %s</li>\n" % html.escape(ss.branch)
        if ss.revision:
            data += "  <li>Revision: %s</li>\n" % html.escape(str(ss.revision))
        if ss.patch:
            data += "  <li>Patch: YES</li>\n"  # TODO: provide link to .diff
        if ss.changes:
            data += "  <li>Changes: see below</li>\n"
        if (ss.branch is None and ss.revision is None and ss.patch is None
                and not ss.changes):
            data += "  <li>build of most recent revision</li>\n"
        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]"
            data += "  <li>Got Revision: %s</li>\n" % got_revision
        data += " </ul>\n"

        # TODO: turn this into a table, or some other sort of definition-list
        # that doesn't take up quite so much vertical space
        try:
            slaveurl = path_to_slave(req, status.getSlave(b.getSlavename()))
            data += "<h2>Buildslave:</h2>\n <a href=\"%s\">%s</a>\n" % (
                html.escape(slaveurl), html.escape(b.getSlavename()))
        except KeyError:
            data += "<h2>Buildslave:</h2>\n %s\n" % html.escape(
                b.getSlavename())
        data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason())

        data += "<h2>Steps and Logfiles:</h2>\n"
        # TODO:
        #        urls = self.original.getURLs()
        #        ex_url_class = "BuildStep external"
        #        for name, target in urls.items():
        #            text.append('[<a href="%s" class="%s">%s</a>]' %
        #                        (target, ex_url_class, html.escape(name)))
        if b.getLogs():
            data += "<ol>\n"
            for s in b.getSteps():
                name = s.getName()
                data += (" <li><a href=\"%s\">%s</a> [%s]\n" %
                         (req.childLink("steps/%s" % urllib.quote(name)), name,
                          " ".join(s.getText())))
                if s.getLogs():
                    data += "  <ol>\n"
                    for logfile in s.getLogs():
                        logname = logfile.getName()
                        logurl = req.childLink(
                            "steps/%s/logs/%s" %
                            (urllib.quote(name), urllib.quote(logname)))
                        data += ("   <li><a href=\"%s\">%s</a></li>\n" %
                                 (logurl, logfile.getName()))
                    data += "  </ol>\n"
                data += " </li>\n"
            data += "</ol>\n"

        data += "<h2>Build Properties:</h2>\n"
        data += "<table><tr><th valign=\"left\">Name</th><th valign=\"left\">Value</th><th valign=\"left\">Source</th></tr>\n"
        for name, value, source in b.getProperties().asList():
            value = str(value)
            if len(value) > 500:
                value = value[:500] + " .. [property value too long]"
            data += "<tr>"
            data += "<td>%s</td>" % html.escape(name)
            data += "<td>%s</td>" % html.escape(value)
            data += "<td>%s</td>" % html.escape(source)
            data += "</tr>\n"
        data += "</table>"

        data += "<h2>Blamelist:</h2>\n"
        if list(b.getResponsibleUsers()):
            data += " <ol>\n"
            for who in b.getResponsibleUsers():
                data += "  <li>%s</li>\n" % html.escape(who)
            data += " </ol>\n"
        else:
            data += "<div>no responsible users</div>\n"

        (start, end) = b.getTimes()
        data += "<h2>Timing</h2>\n"
        data += "<table>\n"
        data += "<tr><td>Start</td><td>%s</td></tr>\n" % time.ctime(start)
        if end:
            data += "<tr><td>End</td><td>%s</td></tr>\n" % time.ctime(end)
            data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval(
                end - start)
        data += "</table>\n"

        if ss.changes:
            data += "<h2>All Changes</h2>\n"
            data += "<ol>\n"
            for c in ss.changes:
                data += "<li>" + c.asHTML() + "</li>\n"
            data += "</ol>\n"
            #data += html.PRE(b.changesText()) # TODO

        if b.isFinished() and self.builder_control is not None:
            data += "<h3>Resubmit Build:</h3>\n"
            # can we rebuild it exactly?
            exactly = (ss.revision is not None) or b.getChanges()
            if exactly:
                data += ("<p>This tree was built from a specific set of \n"
                         "source files, and can be rebuilt exactly</p>\n")
            else:
                data += ("<p>This tree was built from the most recent "
                         "revision")
                if ss.branch:
                    data += " (along some branch)"
                data += (" and thus it might not be possible to rebuild it \n"
                         "exactly. Any changes that have been committed \n"
                         "after this build was started <b>will</b> be \n"
                         "included in a rebuild.</p>\n")
            rebuildURL = urllib.quote(req.childLink("rebuild"))
            data += ('<form action="%s" class="command rebuild">\n' %
                     rebuildURL)
            data += make_row("Your name:",
                             "<input type='text' name='username' />")
            data += make_row("Reason for re-running build:",
                             "<input type='text' name='comments' />")
            data += '<input type="submit" value="Rebuild" />\n'
            data += '</form>\n'

        # TODO: this stuff should be generated by a template of some sort
        data += '<hr /><div class="footer">\n'

        welcomeurl = self.path_to_root(req) + "index.html"
        data += '[<a href="%s">welcome</a>]\n' % welcomeurl
        data += "<br />\n"

        data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>'
        data += "-%s " % version
        if projectName:
            data += "working for the "
            if projectURL:
                data += "<a href=\"%s\">%s</a> project." % (projectURL,
                                                            projectName)
            else:
                data += "%s project." % projectName
        data += "<br />\n"
        data += ("Page built: " + time.strftime(
            "%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n")
        data += '</div>\n'

        return data
Example #33
0
    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)
Example #34
0
 def test_minutes_over_one(self):
     self.assertEqual(util.formatInterval(61), "1 mins, 1 secs")
Example #35
0
 def test_zero(self):
     self.assertEqual(util.formatInterval(0), "0 secs")
Example #36
0
 def test_zero(self):
     self.assertEqual(util.formatInterval(0), "0 secs")
Example #37
0
 def test_minutes(self):
     self.assertEqual(util.formatInterval(300), "5 mins, 0 secs")
Example #38
0
 def test_seconds(self):
     self.assertEqual(util.formatInterval(7), "7 secs")
Example #39
0
 def test_hours_one(self):
     self.assertEqual(util.formatInterval(3600), "60 mins, 0 secs")
Example #40
0
 def test_minutes_over_one(self):
     self.assertEqual(util.formatInterval(61), "1 mins, 1 secs")
Example #41
0
 def test_hours_over_one_sec(self):
     self.assertEqual(util.formatInterval(3601), "1 hrs, 1 secs")
Example #42
0
 def test_hours_one(self):
     self.assertEqual(util.formatInterval(3600), "60 mins, 0 secs")
Example #43
0
 def test_hours_over_one_min(self):
     self.assertEqual(util.formatInterval(3660), "1 hrs, 60 secs")
Example #44
0
 def test_hours_over_one_min(self):
     self.assertEqual(util.formatInterval(3660), "1 hrs, 60 secs")
Example #45
0
def formatLog(tmpdir, build, builder_suffix=''):
    """
    Returns a filename with the contents of the build log
    written to it.
    """
    builder_name = build.builder.name
    build_name = "%s%s-build%s.txt.gz" % (builder_name, builder_suffix, build_number)

    logFile = gzip.GzipFile(os.path.join(tmpdir, build_name), "w")

    # Header information
    logFile.write("builder: %s\n" % builder_name)
    logFile.write("slave: %s\n" % build.getSlavename())
    logFile.write("starttime: %s\n" % build.started)

    results = build.getResults()
    try:
        results_str = Results[results]
    except:
        results_str = "Unknown"
    logFile.write("results: %s (%s)\n" % (results_str, results))

    props = build.getProperties()
    if props.getProperty('buildid') is not None:
        logFile.write("buildid: %s\n" % props['buildid'])

    if props.getProperty('builduid') is not None:
        logFile.write("builduid: %s\n" % props['builduid'])

    if props.getProperty('got_revision') is not None:
        logFile.write("revision: %s\n" % props['got_revision'])
    elif props.getProperty('revision') is not None:
        logFile.write("revision: %s\n" % props['revision'])

    logFile.write("\n")


    # Steps
    for step in build.getSteps():
        times = step.getTimes()
        if not times or not times[0]:
            elapsed = "not started"
        elif not times[1]:
            elapsed = "not started"
        else:
            elapsed = util.formatInterval(times[1] - times[0])

        results = step.getResults()[0]
        if results == (None, []):
            results = "not started"

        shortText = ' '.join(step.getText()) + ' (results: %s, elapsed: %s)' % (results, elapsed)
        logFile.write("========= Started %s ==========\n" % shortText)

        for log in step.getLogs():
            data = log.getTextWithHeaders()
            logFile.write(data)
            if not data.endswith("\n"):
                logFile.write("\n")

        logFile.write("======== Finished %s ========\n\n" % shortText)
    logFile.close()
    return os.path.join(tmpdir, build_name)
Example #46
0
 def test_mixed(self):
     self.assertEqual(util.formatInterval(7392), "2 hrs, 3 mins, 12 secs")
Example #47
0
    def content(self, req, cxt):
        b = self.builder_status

        cxt['name'] = b.getName()
        req.setHeader('Cache-Control', 'no-cache')
        slaves = b.getSlaves()
        connected_slaves = [s for s in slaves if s.isConnected()]

        cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()]

        cxt['pending'] = []
        wfd = defer.waitForDeferred(b.getPendingBuildRequestStatuses())
        yield wfd
        statuses = wfd.getResult()
        for pb in statuses:
            changes = []

            wfd = defer.waitForDeferred(pb.getSourceStamp())
            yield wfd
            source = wfd.getResult()

            wfd = defer.waitForDeferred(pb.getSubmitTime())
            yield wfd
            submitTime = wfd.getResult()

            wfd = defer.waitForDeferred(pb.getBsid())
            yield wfd
            bsid = wfd.getResult()

            wfd = defer.waitForDeferred(
                pb.master.db.buildsets.getBuildsetProperties(bsid))
            yield wfd
            properties = wfd.getResult()

            if source.changes:
                for c in source.changes:
                    changes.append({
                        'url': path_to_change(req, c),
                        'who': c.who,
                        'revision': c.revision,
                        'repo': c.repository
                    })

            cxt['pending'].append({
                'when':
                time.strftime("%b %d %H:%M:%S", time.localtime(submitTime)),
                'delay':
                util.formatInterval(util.now() - submitTime),
                'id':
                pb.brid,
                'changes':
                changes,
                'num_changes':
                len(changes),
                'properties':
                properties,
            })

        numbuilds = int(req.args.get('numbuilds', ['5'])[0])
        recent = cxt['recent'] = []
        for build in b.generateFinishedBuilds(num_builds=int(numbuilds)):
            recent.append(self.get_line_values(req, build, False))

        sl = cxt['slaves'] = []
        connected_slaves = 0
        for slave in slaves:
            s = {}
            sl.append(s)
            s['link'] = path_to_slave(req, slave)
            s['name'] = slave.getName()
            c = s['connected'] = slave.isConnected()
            if c:
                s['admin'] = unicode(slave.getAdmin() or '', 'utf-8')
                connected_slaves += 1
        cxt['connected_slaves'] = connected_slaves

        cxt['authz'] = self.getAuthz(req)
        cxt['builder_url'] = path_to_builder(req, b)
        buildForceContext(cxt, req, self.getBuildmaster(req), b.getName())
        template = req.site.buildbot_service.templates.get_template(
            "builder.html")
        yield template.render(**cxt)
Example #48
0
 def test_hours(self):
     self.assertEqual(util.formatInterval(7200), "2 hrs, 0 secs")
    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 })

            step['aliases'] = {}
            seen_aliases = set()
            for base, aliases in s.getAliases().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(**cxt)
Example #50
0
    def content(self, req, cxt):
        b = self.builder_status

        cxt['name'] = b.getName()
        cxt['description'] = b.getDescription()
        req.setHeader('Cache-Control', 'no-cache')
        slaves = b.getSlaves()
        connected_slaves = [s for s in slaves if s.isConnected()]

        cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()]

        cxt['pending'] = []
        statuses = yield b.getPendingBuildRequestStatuses()
        for pb in statuses:
            changes = []

            source = yield pb.getSourceStamp()
            submitTime = yield pb.getSubmitTime()
            bsid = yield pb.getBsid()

            properties = yield \
                    pb.master.db.buildsets.getBuildsetProperties(bsid)

            if source.changes:
                for c in source.changes:
                    changes.append({ 'url' : path_to_change(req, c),
                                     'who' : c.who,
                                     'revision' : c.revision,
                                     'repo' : c.repository })

            cxt['pending'].append({
                'when': time.strftime("%b %d %H:%M:%S",
                                      time.localtime(submitTime)),
                'delay': util.formatInterval(util.now() - submitTime),
                'id': pb.brid,
                'changes' : changes,
                'num_changes' : len(changes),
                'properties' : properties,
                })

        numbuilds = int(req.args.get('numbuilds', [self.numbuilds])[0])
        recent = cxt['recent'] = []
        for build in b.generateFinishedBuilds(num_builds=int(numbuilds)):
            recent.append(self.get_line_values(req, build, False))

        sl = cxt['slaves'] = []
        connected_slaves = 0
        for slave in slaves:
            s = {}
            sl.append(s)
            s['link'] = path_to_slave(req, slave)
            s['name'] = slave.getName()
            c = s['connected'] = slave.isConnected()
            if c:
                s['admin'] = unicode(slave.getAdmin() or '', 'utf-8')
                connected_slaves += 1
        cxt['connected_slaves'] = connected_slaves

        cxt['authz'] = self.getAuthz(req)
        cxt['builder_url'] = path_to_builder(req, b)
        buildForceContext(cxt, req, self.getBuildmaster(req), b.getName())
        template = req.site.buildbot_service.templates.get_template("builder.html")
        defer.returnValue(template.render(**cxt))
Example #51
0
 def test_mixed(self):
     self.assertEqual(util.formatInterval(7392), "2 hrs, 3 mins, 12 secs")