Exemplo n.º 1
0
 def template_data(self):
     failed_steps = BuildStep.select(self.env, build=self.build.id,
                                     status=BuildStep.FAILURE)
     platform = TargetPlatform.fetch(self.env, id=self.build.platform)
     reposname, repos, change = self.get_change()
     return {
         'build': {
             'id': self.build.id,
             'status': self.readable_states[self.build.status],
             'link': self.build_link(),
             'config': self.build.config,
             'platform': getattr(platform, 'name', 'unknown'),
             'slave': self.build.slave,
             'failed_steps': [{
                 'name': step.name,
                 'description': step.description,
                 'errors': step.errors,
                 'log_messages': self.get_all_log_messages_for_step(step),
             } for step in failed_steps],
         },
         'change': {
             'rev': display_rev(repos, change.rev),
             'link': self.env.abs_href.changeset(change.rev,
                         reposname != '(default)' and reposname or None),
             'author': change.author,
         },
     }
Exemplo n.º 2
0
    def get_timeline_events(self, req, start, stop, filters):
        if 'build' not in filters:
            return

        # Attachments (will be rendered by attachment module)
        for event in AttachmentModule(self.env).get_timeline_events(
            req, Resource('build'), start, stop):
            yield event

        start = to_timestamp(start)
        stop = to_timestamp(stop)

        add_stylesheet(req, 'bitten/bitten.css')

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("SELECT b.id,b.config,c.label,c.path, b.rev,p.name,"
                       "b.stopped,b.status FROM bitten_build AS b"
                       "  INNER JOIN bitten_config AS c ON (c.name=b.config) "
                       "  INNER JOIN bitten_platform AS p ON (p.id=b.platform) "
                       "WHERE b.stopped>=%s AND b.stopped<=%s "
                       "AND b.status IN (%s, %s) ORDER BY b.stopped",
                       (start, stop, Build.SUCCESS, Build.FAILURE))

        event_kinds = {Build.SUCCESS: 'successbuild',
                       Build.FAILURE: 'failedbuild'}

        for id_, config, label, path, rev, platform, stopped, status in cursor:
            config_object = BuildConfig.fetch(self.env, config, db=db)
            repos_name, repos, repos_path = get_repos(self.env,
                                                      config_object.path,
                                                      req.authname)
            if not _has_permission(req.perm, repos, repos_path, rev=rev):
                continue
            errors = []
            if status == Build.FAILURE:
                for step in BuildStep.select(self.env, build=id_,
                                             status=BuildStep.FAILURE,
                                             db=db):
                    errors += [(step.name, error) for error
                               in step.errors]
            yield (event_kinds[status], to_datetime(stopped, utc), None,
                        (id_, config, label, display_rev(repos, rev), platform,
                            status, errors))
Exemplo n.º 3
0
 def template_data(self):
     failed_steps = BuildStep.select(self.env,
                                     build=self.build.id,
                                     status=BuildStep.FAILURE)
     platform = TargetPlatform.fetch(self.env, id=self.build.platform)
     reposname, repos, change = self.get_change()
     return {
         'build': {
             'id':
             self.build.id,
             'status':
             self.readable_states[self.build.status],
             'link':
             self.build_link(),
             'config':
             self.build.config,
             'platform':
             getattr(platform, 'name', 'unknown'),
             'slave':
             self.build.slave,
             'failed_steps': [{
                 'name':
                 step.name,
                 'description':
                 step.description,
                 'errors':
                 step.errors,
                 'log_messages':
                 self.get_all_log_messages_for_step(step),
             } for step in failed_steps],
         },
         'change': {
             'rev':
             display_rev(repos, change.rev),
             'link':
             self.env.abs_href.changeset(
                 change.rev, reposname != '(default)' and reposname
                 or None),
             'author':
             change.author,
         },
     }
Exemplo n.º 4
0
 def test_using_normalize(self):
     repos = Mock(normalize_rev=lambda x: '123456')
     rev = '1234567890'
     self.assertEquals('123456', display_rev(repos, rev))
Exemplo n.º 5
0
 def test_using_normalize(self):
     repos = Mock(normalize_rev=lambda x: '123456')
     rev = '1234567890'
     self.assertEquals('123456', display_rev(repos, rev))
Exemplo n.º 6
0
    def process_request(self, req):
        req.perm.require('BUILD_VIEW')

        db = self.env.get_db_cnx()
        build_id = int(req.args.get('id'))
        build = Build.fetch(self.env, build_id, db=db)
        if not build:
            raise HTTPNotFound("Build '%s' does not exist." \
                                % build_id)

        if req.method == 'POST':
            if req.args.get('action') == 'invalidate':
                self._do_invalidate(req, build, db)
            req.redirect(req.href.build(build.config, build.id))

        add_link(req, 'up', req.href.build(build.config),
                 'Build Configuration')
        data = {'title': 'Build %s - %s' % (build_id,
                                            _status_title[build.status]),
                'page_mode': 'view_build',
                'build': {}}
        config = BuildConfig.fetch(self.env, build.config, db=db)
        data['build']['config'] = {
            'name': config.label or config.name,
            'href': req.href.build(config.name)
        }

        context = Context.from_request(req, build.resource)
        data['context'] = context
        data['build']['attachments'] = AttachmentModule(self.env).attachment_data(context)

        formatters = []
        for formatter in self.log_formatters:
            formatters.append(formatter.get_formatter(req, build))

        summarizers = {} # keyed by report type
        for summarizer in self.report_summarizers:
            categories = summarizer.get_supported_categories()
            summarizers.update(dict([(cat, summarizer) for cat in categories]))

        repos_name, repos, repos_path = get_repos(self.env, config.path,
                                                  req.authname)

        _has_permission(req.perm, repos, repos_path, rev=build.rev, raise_error=True)

        data['build'].update(_get_build_data(self.env, req, build, repos_name))
        steps = []
        for step in BuildStep.select(self.env, build=build.id, db=db):
            steps.append({
                'name': step.name, 'description': step.description,
                'duration': pretty_timedelta(step.started, step.stopped or int(time.time())),
                'status': _step_status_label[step.status],
                'cls': _step_status_label[step.status].replace(' ', '-'),
                'errors': step.errors,
                'log': self._render_log(req, build, formatters, step),
                'reports': self._render_reports(req, config, build, summarizers,
                                                step)
            })
        data['build']['steps'] = steps
        data['build']['can_delete'] = ('BUILD_DELETE' in req.perm \
                                   and build.status != build.PENDING)

        chgset = repos.get_changeset(build.rev)
        data['build']['chgset_author'] = chgset.author
        data['build']['display_rev'] = display_rev(repos, build.rev)

        add_script(req, 'common/js/folding.js')
        add_script(req, 'bitten/tabset.js')
        add_script(req, 'bitten/jquery.flot.js')
        add_stylesheet(req, 'bitten/bitten.css')
        return 'bitten_build.html', data, None
Exemplo n.º 7
0
    def _render_config(self, req, config_name):
        db = self.env.get_db_cnx()

        config = BuildConfig.fetch(self.env, config_name, db=db)
        if not config:
            raise HTTPNotFound("Build configuration '%s' does not exist." \
                                % config_name)

        repos_name, repos, repos_path = get_repos(self.env, config.path,
                                                  req.authname)

        rev = config.max_rev or repos.youngest_rev
        try:
            _has_permission(req.perm, repos, repos_path, rev=rev,
                                                        raise_error=True)
        except NoSuchNode:
            raise TracError("Permission checking against repository path %s "
                "at revision %s failed." % (config.path, rev))

        data = {'title': 'Build Configuration "%s"' \
                          % config.label or config.name,
                'page_mode': 'view_config'}
        add_link(req, 'up', req.href.build(), 'Build Status')
        description = config.description
        if description:
            description = wiki_to_html(description, self.env, req)

        pending_builds = list(Build.select(self.env,
                                config=config.name, status=Build.PENDING))
        inprogress_builds = list(Build.select(self.env,
                                config=config.name, status=Build.IN_PROGRESS))

        min_chgset_url = ''
        if config.min_rev:
            min_chgset_resource = get_chgset_resource(self.env, repos_name,
                                                      config.min_rev)
            min_chgset_url = get_resource_url(self.env, min_chgset_resource,
                                              req.href),
        max_chgset_url = ''
        if config.max_rev:
            max_chgset_resource = get_chgset_resource(self.env, repos_name,
                                                      config.max_rev)
            max_chgset_url = get_resource_url(self.env, max_chgset_resource,
                                              req.href),

        data['config'] = {
            'name': config.name, 'label': config.label, 'path': config.path,
            'min_rev': config.min_rev,
            'min_rev_href': min_chgset_url,
            'max_rev': config.max_rev,
            'max_rev_href': max_chgset_url,
            'active': config.active, 'description': description,
            'browser_href': req.href.browser(config.path),
            'builds_pending' : len(pending_builds),
            'builds_inprogress' : len(inprogress_builds)
        }

        context = Context.from_request(req, config.resource)
        data['context'] = context
        data['config']['attachments'] = AttachmentModule(self.env).attachment_data(context)

        platforms = list(TargetPlatform.select(self.env, config=config_name,
                                               db=db))
        data['config']['platforms'] = [
            { 'name': platform.name,
              'id': platform.id,
              'builds_pending': len(list(Build.select(self.env,
                                                    config=config.name,
                                                    status=Build.PENDING,
                                                    platform=platform.id))),
              'builds_inprogress': len(list(Build.select(self.env,
                                                    config=config.name,
                                                    status=Build.IN_PROGRESS,
                                                    platform=platform.id)))
              }
            for platform in platforms
        ]

        has_reports = False
        for report in Report.select(self.env, config=config.name, db=db):
            has_reports = True
            break

        if has_reports:
            chart_generators = []
            report_categories = list(self._report_categories_for_config(config))
            for generator in ReportChartController(self.env).generators:
                for category in generator.get_supported_categories():
                    if category in report_categories:
                        chart_generators.append({
                            'href': req.href.build(config.name, 'chart/' + category),
                            'category': category,
                            'style': self.config.get('bitten', 'chart_style'),
                        })
            data['config']['charts'] = chart_generators

        page = max(1, int(req.args.get('page', 1)))
        more = False
        data['page_number'] = page

        builds_per_page = 12 * len(platforms)
        idx = 0
        builds = {}
        revisions = []
        build_order = []
        for platform, rev, build in collect_changes(config,authname=req.authname):
            if idx >= page * builds_per_page:
                more = True
                break
            elif idx >= (page - 1) * builds_per_page:
                if rev not in builds:
                    revisions.append(rev)
                builds.setdefault(rev, {})
                chgset_resource = get_chgset_resource(self.env, repos_name, rev)
                builds[rev].setdefault('href', get_resource_url(self.env,
                                                    chgset_resource, req.href))
                build_order.append((rev, repos.get_changeset(rev).date))
                builds[rev].setdefault('display_rev', display_rev(repos, rev))
                if build and build.status != Build.PENDING:
                    build_data = _get_build_data(self.env, req, build)
                    build_data['steps'] = []
                    for step in BuildStep.select(self.env, build=build.id,
                                                 db=db):
                        build_data['steps'].append({
                            'name': step.name,
                            'description': step.description,
                            'duration': to_datetime(step.stopped or int(time.time()), utc) - \
                                        to_datetime(step.started, utc),
                            'status': _step_status_label[step.status],
                            'cls': _step_status_label[step.status].replace(' ', '-'),

                            'errors': step.errors,
                            'href': build_data['href'] + '#step_' + step.name
                        })
                    builds[rev][platform.id] = build_data
            idx += 1
        data['config']['build_order'] = [r[0] for r in sorted(build_order,
                                                            key=lambda x: x[1],
                                                            reverse=True)]
        data['config']['builds'] = builds
        data['config']['revisions'] = revisions

        if page > 1:
            if page == 2:
                prev_href = req.href.build(config.name)
            else:
                prev_href = req.href.build(config.name, page=page - 1)
            add_link(req, 'prev', prev_href, 'Previous Page')
        if more:
            next_href = req.href.build(config.name, page=page + 1)
            add_link(req, 'next', next_href, 'Next Page')
        if arity(prevnext_nav) == 4: # Trac 0.12 compat, see #450
            prevnext_nav(req, 'Previous Page', 'Next Page')
        else:
            prevnext_nav (req, 'Page')
        return data
Exemplo n.º 8
0
    def _render_overview(self, req):
        data = {'title': 'Build Status'}
        show_all = False
        if req.args.get('show') == 'all':
            show_all = True
        data['show_all'] = show_all

        configs = []
        for config in BuildConfig.select(self.env, include_inactive=show_all):
            repos_name, repos, repos_path = get_repos(self.env, config.path,
                                                      req.authname)
            rev = config.max_rev or repos.youngest_rev
            try:
                if not _has_permission(req.perm, repos, repos_path, rev=rev):
                    continue
            except NoSuchNode:
                add_warning(req, "Configuration '%s' points to non-existing "
                        "path '/%s' at revision '%s'. Configuration skipped." \
                                    % (config.name, config.path, rev))
                continue

            description = config.description
            if description:
                description = wiki_to_html(description, self.env, req)

            platforms_data = []
            for platform in TargetPlatform.select(self.env, config=config.name):
                pd = { 'name': platform.name,
                       'id': platform.id,
                       'builds_pending': len(list(Build.select(self.env,
                                config=config.name, status=Build.PENDING,
                                platform=platform.id))),
                       'builds_inprogress': len(list(Build.select(self.env,
                                config=config.name, status=Build.IN_PROGRESS,
                                platform=platform.id)))
                }
                platforms_data.append(pd)

            config_data = {
                'name': config.name, 'label': config.label or config.name,
                'active': config.active, 'path': config.path,
                'description': description,
                'builds_pending' : len(list(Build.select(self.env,
                                                config=config.name,
                                                status=Build.PENDING))),
                'builds_inprogress' : len(list(Build.select(self.env,
                                                config=config.name,
                                                status=Build.IN_PROGRESS))),
                'href': req.href.build(config.name),
                'builds': [],
                'platforms': platforms_data
            }
            configs.append(config_data)
            if not config.active:
                continue

            prev_rev = None
            for platform, rev, build in collect_changes(config, req.authname):
                if rev != prev_rev:
                    if prev_rev is None:
                        chgset = repos.get_changeset(rev)
                        chgset_resource = get_chgset_resource(self.env, 
                                repos_name, rev)
                        config_data['youngest_rev'] = {
                            'id': rev,
                            'href': get_resource_url(self.env, chgset_resource,
                                                     req.href),
                            'display_rev': display_rev(repos, rev),
                            'author': chgset.author or 'anonymous',
                            'date': format_datetime(chgset.date),
                            'message': wiki_to_oneliner(
                                shorten_line(chgset.message), self.env, req=req)
                        }
                    else:
                        break
                    prev_rev = rev
                if build:
                    build_data = _get_build_data(self.env, req, build, repos_name)
                    build_data['platform'] = platform.name
                    config_data['builds'].append(build_data)
                else:
                    config_data['builds'].append({
                        'platform': platform.name, 'status': 'pending'
                    })

        data['configs'] = sorted(configs, key=lambda x:x['label'].lower())
        data['page_mode'] = 'overview'

        in_progress_builds = Build.select(self.env, status=Build.IN_PROGRESS)
        pending_builds = Build.select(self.env, status=Build.PENDING)

        data['builds_pending'] = len(list(pending_builds))
        data['builds_inprogress'] = len(list(in_progress_builds))

        add_link(req, 'views', req.href.build(view='inprogress'),
                 'In Progress Builds')
        add_ctxtnav(req, 'In Progress Builds',
                    req.href.build(view='inprogress'))
        return data