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]
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])
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) ]) ])
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";', ' };', '}', '', ]), }
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'), ])