Пример #1
0
 def get_build_result(self, bldcfg):
     n = buildcfg_name(bldcfg)
     r = self._get_build_results()
     if isinstance(r, str):
         return r
     return ([
         BuilderResult(
             buildname=n,
             nrtotal=get_or_show(e, 'nrtotal'),
             nrsucceeded=get_or_show(e, 'nrsucceeded'),
             nrfailed=get_or_show(e, 'nrfailed'),
             nrscheduled=get_or_show(e, 'nrscheduled'),
             cfgerror=get_or_show(e, 'haserrormsg')
             or bool(get_or_show(e, "fetcherrormsg")),
         ) for e in r if e['name'] == n
     ] + ['No results available for jobset ' + n])[0]
Пример #2
0
 def _ghr(build_results, prior, reporting_logic_defs=''):
     starttime = datetime.now()
     inp_desc, repo_info = generated_repo_info
     builder_cfgs, build_cfgs = generated_hydra_builder_output
     anarep = AnaRep.AnaRep(verbose=True, actor_system=actor_system)
     # n.b. the name values for build_results come from
     # buildcfg_name, which is revealed by this print loop.
     builder = BldSys.HydraBuilder(None)
     for each in build_cfgs.cfg_build_configs:
         print(buildcfg_name(each))
     builder._build_results = build_results
     report = anarep.report_on(
         [AnaRep.ResultSet(builder, inp_desc, repo_info, build_cfgs)],
         prior,
         reporting_logic_defs=reporting_logic_defs)
     assert report[0] == 'report'
     endtime = datetime.now()
     # This should be a proper test: checks the amount of time to run run the logic process.
     if hasattr(request.module, 'analysis_time_budget'):
         assert endtime - starttime < request.module.analysis_time_budget
     return (builder_cfgs, report[1])
Пример #3
0
def html_summary(repdata, base_builder_url=None):
    section_hdrfun = lambda msg: '<br/><hr class="section_line"/><br/><h2>' + msg + '</h2><br/>'
    subsection_hdrfun = lambda msg: '<br/><h3>' + msg + '</h3>'
    entshow_fun = tcell_entshow(base_builder_url)

    projects = set(
        [sr.project for sr in repdata if isinstance(sr, StatusReport)])

    summary = KVITable(default_factory=int, valuecol_name='Total')
    summary.add(len(projects), Element='Projects')
    summary.add(len(
        set([
            sr.branch for sr in repdata
            if isinstance(sr, StatusReport) and sr.branchtype == 'pullreq'
        ])),
                Element='Pull Requests')

    projtable = KVITable(
        {
            'Project':
            sorted(
                list(
                    set([
                        sr.project
                        for sr in repdata if isinstance(sr, StatusReport)
                    ]))),
            'Status': ['TOTAL', 'ok', 'FAIL', 'pending'],
        },
        valuecol_name='Number',
        kv_frozen=False,
        default_factory=int)

    fulltable = KVITable(
        {
            'Branch': [],
            'system': ['x86-64_linux'],
            'Strategy': ['regular', 'submodules', 'HEADs'],
            'Project': [],
        },
        valuecol_name='Build Status',
        default_factory=lambda: None,
        keyval_factory=lambda key: 'x86_64-linux'
        if key == 'system' else 'n/a',
        kv_frozen=False)

    mkDetailTable = lambda: KVITable(
        {
            'system': ['x86-64_linux'],
            'Branch': [],
            'Strategy': ['regular', 'submodules', 'HEADs'],
        },
        valuecol_name='Build Status',
        default_factory=lambda: None,
        keyval_factory=lambda key: 'x86_64-linux' if key == 'system' else '',
        kv_frozen=False)
    detailtables = defaultdict(mkDetailTable)
    projtable_sts = lambda s: {
        'initial_success': 'ok',
        'succeeded': 'ok',
        # 'pending': 'pending',
    }.get(s, 'FAIL')

    for sr in repdata:

        if isinstance(sr, Notify):
            summary.add(_inc, Element='Notifications')

        elif isinstance(sr, PendingStatus):
            prev = [
                r for r in repdata if isinstance(r, StatusReport)
                and r.project == sr.project and r.buildname == sr.buildname
            ]
            if not prev:
                summary.add(_inc, Element='Builds')
                projtable.add(_inc, Project=sr.project, Status="TOTAL")
            else:
                projtable.add(_dec,
                              Project=sr.project,
                              Status=projtable_sts(prev[0].status))
            projtable.add(_inc, Project=sr.project, Status="pending")
            vars = tuple([(v.varname, v.varvalue) for v in sr.bldvars])

            fulltable.add(TCell_PendingBld(sr.project, sr.buildname),
                          *vars,
                          Project=sr.project,
                          Branch=tbl_branch(sr),
                          Strategy=sr.strategy)
            detailtables[sr.project].add(TCell_PendingBld(
                sr.project, sr.buildname),
                                         *vars,
                                         Branch=tbl_branch(sr),
                                         Strategy=sr.strategy)

        elif isinstance(sr, NewPending):
            summary.add(_inc, Element='Builds')
            projectname = sr.bldcfg.projectname
            buildname = buildcfg_name(sr.bldcfg)
            tbl_brname = tbl_branch_(buildname, sr.bldcfg.branchname)
            projtable.add(_inc, Project=projectname, Status="TOTAL")
            projtable.add(_inc, Project=projectname, Status="pending")
            vars = tuple([(v.varname, v.varvalue) for v in sr.bldcfg.bldvars])

            fulltable.add(TCell_PendingBld(projectname, buildname),
                          *vars,
                          Project=projectname,
                          Branch=tbl_brname,
                          Strategy=sr.bldcfg.strategy)
            detailtables[sr.bldcfg.projectname].add(
                TCell_PendingBld(projectname, buildname),
                *vars,
                Branch=tbl_brname,
                Strategy=sr.bldcfg.strategy)

        elif isinstance(sr, StatusReport):
            summary.add(_inc, Element='Builds')

            projtable.add(_inc,
                          Project=sr.project,
                          Status=projtable_sts(sr.status))
            projtable.add(_inc, Project=sr.project, Status='TOTAL')

            bldres = {
                'initial_success': TCell_GoodBld,
                'succeeded': TCell_GoodBld,
                'fixed': TCell_GoodBld,
                'bad_config': TCell_BadCfgBld,
            }.get(sr.status,
                  lambda proj, name: TCell_FailBld(proj, name, sr.status))(
                      sr.project, sr.buildname)

            fulltable.add(bldres,
                          *tuple([(v.varname, v.varvalue)
                                  for v in sr.bldvars]),
                          Project=sr.project,
                          Branch=tbl_branch(sr),
                          Strategy=sr.strategy)

            detailtables[sr.project].add(bldres,
                                         *tuple([(v.varname, v.varvalue)
                                                 for v in sr.bldvars]),
                                         Branch=tbl_branch(sr),
                                         Strategy=sr.strategy)

    return '\n\n'.join([
        summary.render(as_format='html', sort_vals=True),
        section_hdrfun('Per-project Build Status Summary ::'),
        projtable.render(row_group=['Project'],
                         row_repeat=False,
                         sort_vals=False,
                         as_format='html',
                         caption='Per-project Build Status Summary',
                         colstack_at='Status'),
        section_hdrfun('Combined Details ::'),
        fulltable.render(
            row_group=['system', 'Branch', 'Strategy'],
            row_repeat=False,
            sort_vals=True,
            entrystr=entshow_fun,
            as_format='html',
            caption='Combined Details',
            colstack_at=(list(fulltable.keyvals().keys()) + [None])[4],
        ),
        section_hdrfun('Individual Project Summaries ::'), '\n\n'.join([
            subsection_hdrfun('Project %s:\n' % p) + detailtables[p].render(
                row_repeat=False,
                as_format='html',
                caption='Project %s' % p,
                sort_vals=True,
                colstack_at=(list(detailtables[p].keyvals().keys()) +
                             [None])[3],
                row_group=['system', 'Branch'],
                entrystr=entshow_fun,
            ) for p in sorted(projects)
        ])
    ])
Пример #4
0
    def output_build_configurations(self,
                                    input_desc,
                                    bldcfgs,
                                    bldcfg_fname=None):
        """Given an input description and the set of build configurations
           generated from the BCGen logic, return the Hydra-specific
           configuration of those build configurations, along with any
           auxiliary files as a dictionary, where the key is the
           filename and the value is the contents; the key should be
           None for the primary output file, which is named in the
           input specification.

           For the Hydra builder, an auxiliary file is generated that
           can be used as the declarative project description (used
           for defining the Project in Hydra), along with a helper
           function to move that auxiliary file into the nix store on
           Hydra invocation.

           input_desc :: is the Briareus.Input.Description.InpDesc
                         object describing the repos, the branches,
                         and the variables.

           bldcfgs :: is the set of bldcfgs generated by the BCGen logic.

           bldcfg_fname :: is the filepath where the output build
                            configurations will be written.  This
                            routine does *not* write to that file, but
                            it uses the filepath in the output of
                            auxiliary files, like the project
                            configuration file.  If this argument is
                            None, then the project declarative
                            description and corresponding installation
                            nix file are not generated.

        """
        input_cfg = (json.loads(open(self._conf_file, 'r').read())
                     if self._conf_file else {})
        project_name = input_cfg.get('project_name', 'unnamed')
        out_bldcfg_json = json.dumps(
            # Sort by key for output stability
            {
                buildcfg_name(each): self._jobset(input_desc, bldcfgs,
                                                  input_cfg, each)
                for each in bldcfgs.cfg_build_configs
            },
            sort_keys=True)
        if not bldcfg_fname:
            return {None: out_bldcfg_json}
        copy_hh_src_path = os.path.abspath(
            os.path.join(os.path.dirname(bldcfg_fname), 'hydra'))
        return {
            None:
            out_bldcfg_json,
            (project_name + '-hydra-project-config.json'):
            json.dumps({
                'checkinterval':
                300,
                'keepnr':
                3,
                'schedulingshares':
                1,
                'emailoverride':
                '',
                'description':
                "Briareus-generated %s Project declaration" % project_name,
                'nixexprinput':
                "copy_hh_src",
                'nixexprpath':
                "copy_hh.nix",
                'enabled':
                1,
                'hidden':
                False,
                'enableemail':
                True,
                'inputs': {
                    'hh_output': {
                        'type': "path",
                        'value': os.path.abspath(bldcfg_fname),
                        'emailresponsible': False,
                    },
                    'copy_hh_src': {
                        'type': 'path',
                        'value': copy_hh_src_path,
                        'emailresponsible': False,
                    },
                    'nixpkgs': {
                        'type': "git",
                        'value':
                        "https://github.com/NixOS/nixpkgs-channels nixos-unstable",
                        'emailresponsible': False,
                    },
                },
            }),
            os.path.join(copy_hh_src_path, 'copy_hh.nix'):
            '\n'.join([
                '{ nixpkgs, hh_output }:',
                'let pkgs = import <nixpkgs> {}; in',
                '{ jobsets = pkgs.stdenv.mkDerivation {',
                '    name = "copy_hh";',
                '    phases = [ "installPhase" ];',
                '    installPhase = "cp ${hh_output} $out";',
                '  };',
                '}',
                '',
            ]),
        }
Пример #5
0
def text_summary(repdata):
    sepline = '=' * 60
    hashline = '#' * 60
    banner = '\n\n%(sepline)s\n%(hashline)s\n%(sepline)s\n\n' % locals()
    section_hdrfun = lambda msg: banner + msg
    subsection_hdrfun = lambda msg: msg + '\n'
    entshow_fun = _show_with_fail

    projects = set(
        [sr.project for sr in repdata if isinstance(sr, StatusReport)])

    summary = KVITable(default_factory=int, valuecol_name='Total')
    summary.add(len(projects), Element='Projects')
    summary.add(len(
        set([
            sr.branch for sr in repdata
            if isinstance(sr, StatusReport) and sr.branchtype == 'pullreq'
        ])),
                Element='Pull Requests')

    projtable = KVITable(
        {
            'Project':
            sorted(
                list(
                    set([
                        sr.project
                        for sr in repdata if isinstance(sr, StatusReport)
                    ]))),
            'Status': ['TOTAL', 'ok', 'FAIL', 'pending'],
        },
        valuecol_name='Number',
        kv_frozen=False,
        default_factory=int)

    fulltable = KVITable(
        {
            'Branch': [],
            'system': ['x86-64_linux'],
            'Strategy': ['regular', 'submodules', 'HEADs'],
            'Project': [],
        },
        valuecol_name='Build Status',
        default_factory=FailCount,
        keyval_factory=lambda key: 'x86_64-linux'
        if key == 'system' else 'n/a',
        kv_frozen=False)

    mkDetailTable = lambda: KVITable(
        {
            'system': ['x86-64_linux'],
            'Branch': [],
            'Strategy': ['regular', 'submodules', 'HEADs'],
        },
        valuecol_name='Build Status',
        default_factory=FailCount,
        keyval_factory=lambda key: 'x86_64-linux' if key == 'system' else '',
        kv_frozen=False)
    detailtables = defaultdict(mkDetailTable)
    projtable_sts = lambda s: {
        'initial_success': 'ok',
        'succeeded': 'ok',
        # 'pending': 'pending',
    }.get(s, 'FAIL')

    for sr in repdata:

        if isinstance(sr, Notify):
            summary.add(_inc, Element='Notifications')

        elif isinstance(sr, PendingStatus):
            prev = [
                r for r in repdata if isinstance(r, StatusReport)
                and r.project == sr.project and r.buildname == sr.buildname
            ]
            if not prev:
                summary.add(_inc, Element='Builds')
                projtable.add(_inc, Project=sr.project, Status="TOTAL")
            else:
                projtable.add(_dec,
                              Project=sr.project,
                              Status=projtable_sts(prev[0].status))
            projtable.add(_inc, Project=sr.project, Status="pending")
            vars = tuple([(v.varname, v.varvalue) for v in sr.bldvars])

            fulltable.add(PendingBld,
                          *vars,
                          Project=sr.project,
                          Branch=tbl_branch(sr),
                          Strategy=sr.strategy)
            detailtables[sr.project].add(PendingBld,
                                         *vars,
                                         Branch=tbl_branch(sr),
                                         Strategy=sr.strategy)

        elif isinstance(sr, NewPending):
            summary.add(_inc, Element='Builds')
            projtable.add(_inc, Project=sr.bldcfg.projectname, Status="TOTAL")
            projtable.add(_inc,
                          Project=sr.bldcfg.projectname,
                          Status="pending")
            vars = tuple([(v.varname, v.varvalue) for v in sr.bldcfg.bldvars])
            buildname = buildcfg_name(sr.bldcfg)
            tbl_brname = tbl_branch_(buildname, sr.bldcfg.branchname)

            fulltable.add(PendingBld,
                          *vars,
                          Project=sr.bldcfg.projectname,
                          Branch=tbl_brname,
                          Strategy=sr.bldcfg.strategy)
            detailtables[sr.bldcfg.projectname].add(
                PendingBld,
                *vars,
                Branch=tbl_brname,
                Strategy=sr.bldcfg.strategy)

        elif isinstance(sr, StatusReport):
            summary.add(_inc, Element='Builds')

            projtable.add(_inc,
                          Project=sr.project,
                          Status=projtable_sts(sr.status))
            projtable.add(_inc, Project=sr.project, Status='TOTAL')

            bldres = _add_if_int({
                'initial_success': '+',
                'succeeded': '+',
                'fixed': '+',
                'bad_config': '-CFG',
            }.get(sr.status, sr.status))
            vars = tuple([(v.varname, v.varvalue) for v in sr.bldvars])

            fulltable.add(bldres,
                          *vars,
                          Project=sr.project,
                          Branch=tbl_branch(sr),
                          Strategy=sr.strategy)

            detailtables[sr.project].add(bldres,
                                         *vars,
                                         Branch=tbl_branch(sr),
                                         Strategy=sr.strategy)

    keytable = KVITable({'Symbol': []},
                        valuecol_name='Meaning',
                        kv_frozen=False)
    keytable.add('Success', Symbol='+')
    keytable.add("'n' build components failed", Symbol='FAIL*n')
    keytable.add('Build configuration error', Symbol='-CFG')
    keytable.add('Pending, no previous builds', Symbol='??')
    keytable.add('Pending, previously suceeding', Symbol='(+)?')
    keytable.add('Pending, previous config error', Symbol='(-CFG)?')
    keytable.add("Pending, previously 'n' components failed", Symbol='(-n)?')

    return '\n\n'.join([
        summary.render(
            as_format='ascii',
            sort_vals=True,
        ),
        section_hdrfun('Per-project Build Status Summary ::'),
        projtable.render(row_group=['Project'],
                         row_repeat=False,
                         sort_vals=False,
                         as_format='ascii',
                         colstack_at='Status'),
        section_hdrfun('Combined Details ::'),
        fulltable.render(
            row_group=['system', 'Branch', 'Strategy'],
            row_repeat=False,
            sort_vals=True,
            entrystr=entshow_fun,
            as_format='ascii',
            colstack_at=(list(fulltable.keyvals().keys()) + [None])[4],
        ),
        section_hdrfun('Individual Project Summaries ::'),
        '\n\n'.join([
            subsection_hdrfun('Project %s:\n' % p) + detailtables[p].render(
                row_repeat=False,
                sort_vals=True,
                as_format='ascii',
                colstack_at=(list(detailtables[p].keyvals().keys()) +
                             [None])[3],
                row_group=['system', 'Branch'],
                entrystr=entshow_fun,
            ) for p in sorted(projects)
        ]),
        section_hdrfun('KEY ::'),
        keytable.render(as_format='ascii'),
    ])