def test_with_result(result): revision_id = "revision_id" revision_url = "revision_url" source = self.create_source( project, data={"phabricator.revisionID": revision_id, "phabricator.revisionURL": revision_url} ) build = self.create_build( project, label="Test diff", date_started=datetime.utcnow(), result=result, source=source ) job = self.create_job(build=build, result=Result.failed) phase = self.create_jobphase(job=job) step = self.create_jobstep(phase=phase) logsource = self.create_logsource(step=step, name="console") self.create_logchunk(source=logsource, text="hello world") context = build_context_lib.get_collection_context([build]) if result is not Result.passed and result is not Result.failed: result = Result.unknown assert context["title"] == "%s %s - %s" % ("D{}".format(revision_id), str(result).lower(), job.build.label) assert len(context["builds"]) == 1 assert context["result"] == result assert context["target_uri"] == revision_url assert context["target"] == "D{}".format(revision_id) assert context["label"] == build.label assert context["date_created"] == build.date_created assert context["author"] == build.author assert context["commit_message"] == "" assert context["failing_tests_count"] == 0 assert context["total_failing_tests_count"] == 0
def build_finished_handler(build_id, **kwargs): build = Build.query.get(build_id) if build is None: return target = build.target is_diff_build = target and target.startswith(u'D') if not is_diff_build: # Not a diff build return options = get_options(build.project_id) if options.get('phabricator.notify', '0') != '1': return builds = list( Build.query.filter(Build.collection_id == build.collection_id)) # Exit if there are no builds for the given build_id, or any build hasn't # finished. if not builds or any(map(lambda b: b.status != Status.finished, builds)): return # if comment has already been posted for this set of builds, don't do anything if _comment_posted_for_collection_of_build(build): return context = build_context_lib.get_collection_context(builds) message = '\n\n'.join([_get_message_for_build_context(x) for x in context['builds']]) post_comment(target, message)
def build_finished_handler(build_id, **kwargs): build = Build.query.get(build_id) if build is None: return if build.tags and 'arc test' in build.tags: # 'arc test' builds have an associated Phabricator diff, but # aren't necessarily for the diff under review, so we don't # want to notify with them. return options = get_options(build.project_id) if options.get('phabricator.notify', '0') != '1': return target = build.target is_diff_build = target and target.startswith(u'D') is_commit_build = (build.source is not None and build.source.is_commit() and build.tags and 'commit' in build.tags) phab = PhabricatorClient() if options.get('phabricator.coverage', '0') == '1' and (is_diff_build or is_commit_build): coverage = merged_coverage_data(get_coverage_by_build_id(build_id)) if coverage: if is_diff_build: logger.info("Posting coverage to %s", target) post_diff_coverage(target[1:], coverage, phab) elif is_commit_build: # commits update diffs in phabricator, so post the coverage there too revision_id = parse_revision_id(build.message) if revision_id: post_diff_coverage(revision_id, coverage, phab) callsign, branch, commit = commit_details(build.source) if callsign and commit: logger.info("Posting coverage to %s, %s, %s", callsign, branch, commit) post_commit_coverage(callsign, branch, commit, coverage, phab) if not is_diff_build: # Not a diff build return builds = list( Build.query.filter(Build.collection_id == build.collection_id)) # Exit if there are no builds for the given build_id, or any build hasn't # finished. if not builds or any(map(lambda b: b.status != Status.finished, builds)): return # if comment has already been posted for this set of builds, don't do anything if _comment_posted_for_collection_of_build(build): return context = build_context_lib.get_collection_context(builds) message = '\n\n'.join([_get_message_for_build_context(x) for x in context['builds']]) post_comment(target, message, phab)
def build_finished_handler(build_id, **kwargs): build = Build.query.get(build_id) if build is None: return target = build.target is_diff_build = target and target.startswith(u'D') if not is_diff_build: # Not a diff build return options = get_options(build.project_id) if options.get('phabricator.notify', '0') != '1': return builds = list( Build.query.filter(Build.collection_id == build.collection_id)) # Exit if there are no builds for the given build_id, or any build hasn't # finished. if not builds or any(map(lambda b: b.status != Status.finished, builds)): return # if comment has already been posted for this set of builds, don't do anything if _comment_posted_for_collection_of_build(build): return context = build_context_lib.get_collection_context(builds) message = '\n\n'.join( [_get_message_for_build_context(x) for x in context['builds']]) post_comment(target, message)
def get_msg(self, builds): # type: (List[Build]) -> Message context = build_context_lib.get_collection_context( builds) # type: CollectionContext if context.result == Result.passed: return None max_shown = current_app.config.get('MAX_SHOWN_ITEMS_PER_BUILD_MAIL', 3) context_dict = context._asdict() context_dict.update({ 'MAX_SHOWN_ITEMS_PER_BUILD': max_shown, 'showing_failing_tests_count': sum([ min(b['failing_tests_count'], max_shown) for b in context.builds ]) }) recipients = self.get_collection_recipients(context) msg = Message(context.title, recipients=recipients, extra_headers={ 'Reply-To': ', '.join(sanitize_address(r) for r in recipients), }) msg.body = render_template('listeners/mail/notification.txt', **context_dict) msg.html = Markup( toronado.from_string( render_template('listeners/mail/notification.html', **context_dict))) return msg
def test_multiple_builds(self): project = self.create_project(name='test', slug='test') revision_id = 'revision_id' revision_url = 'revision_url' source = self.create_source(project, data={ 'phabricator.revisionID': revision_id, 'phabricator.revisionURL': revision_url }) def create_build(result): build = self.create_build( project, label='test diff', date_started=datetime.utcnow(), result=result, source=source ) job = self.create_job(build=build, result=Result.failed) phase = self.create_jobphase(job=job) step = self.create_jobstep(phase=phase) logsource = self.create_logsource( step=step, name='console', ) self.create_logchunk( source=logsource, text='hello world', ) return build build1 = create_build(Result.failed) build2 = create_build(Result.infra_failed) build3 = create_build(Result.aborted) build4 = create_build(Result.unknown) build5 = create_build(Result.skipped) build6 = create_build(Result.passed) builds_wrong_order = [build2, build3, build1, build4, build6, build5] builds_correct_order = [build1, build2, build3, build4, build5, build6] context = build_context_lib.get_collection_context(builds_wrong_order) first_build = builds_correct_order[0] assert context['title'] == '%s failed - %s' % ( 'D{}'.format(revision_id), first_build.label) for i in range(len(context['builds'])): assert context['builds'][i]['build'] == builds_correct_order[i] assert context['result'] == Result.failed assert context['target_uri'] == revision_url assert context['target'] == 'D{}'.format(revision_id) assert context['label'] == first_build.label assert context['date_created'] == build1.date_created assert context['author'] == first_build.author assert context['commit_message'] == '' assert context['failing_tests_count'] == 0
def test_multiple_builds(self): project = self.create_project(name='test', slug='test') revision_id = 'revision_id' revision_url = 'revision_url' source = self.create_source(project, data={ 'phabricator.revisionID': revision_id, 'phabricator.revisionURL': revision_url }) def create_build(result): build = self.create_build(project, label='test diff', date_started=datetime.utcnow(), result=result, source=source) job = self.create_job(build=build, result=Result.failed) phase = self.create_jobphase(job=job) step = self.create_jobstep(phase=phase) logsource = self.create_logsource( step=step, name='console', ) self.create_logchunk( source=logsource, text='hello world', ) return build build1 = create_build(Result.failed) build2 = create_build(Result.infra_failed) build3 = create_build(Result.aborted) build4 = create_build(Result.unknown) build5 = create_build(Result.skipped) build6 = create_build(Result.passed) builds_wrong_order = [build2, build3, build1, build4, build6, build5] builds_correct_order = [build1, build2, build3, build4, build5, build6] context = build_context_lib.get_collection_context(builds_wrong_order) first_build = builds_correct_order[0] assert context.title == '%s failed - %s' % ('D{}'.format(revision_id), first_build.label) for i in range(len(context.builds)): assert context.builds[i]['build'] == builds_correct_order[i] assert context.result == Result.failed assert context.target_uri == revision_url assert context.target == 'D{}'.format(revision_id) assert context.label == first_build.label assert context.date_created == build1.date_created assert context.author == first_build.author assert context.commit_message == '' assert context.failing_tests_count == 0
def get_msg(self, builds): context = build_context_lib.get_collection_context(builds) if context['result'] == Result.passed: return None recipients = self.get_collection_recipients(context) msg = Message(context['title'], recipients=recipients, extra_headers={ 'Reply-To': ', '.join(sanitize_address(r) for r in recipients), }) msg.body = render_template('listeners/mail/notification.txt', **context) msg.html = Markup(toronado.from_string( render_template('listeners/mail/notification.html', **context) )) return msg
def test_multiple_builds(self): project = self.create_project(name="test", slug="test") revision_id = "revision_id" revision_url = "revision_url" source = self.create_source( project, data={"phabricator.revisionID": revision_id, "phabricator.revisionURL": revision_url} ) def create_build(result): build = self.create_build( project, label="test diff", date_started=datetime.utcnow(), result=result, source=source ) job = self.create_job(build=build, result=Result.failed) phase = self.create_jobphase(job=job) step = self.create_jobstep(phase=phase) logsource = self.create_logsource(step=step, name="console") self.create_logchunk(source=logsource, text="hello world") return build build1 = create_build(Result.failed) build2 = create_build(Result.infra_failed) build3 = create_build(Result.aborted) build4 = create_build(Result.unknown) build5 = create_build(Result.skipped) build6 = create_build(Result.passed) builds_wrong_order = [build2, build3, build1, build4, build6, build5] builds_correct_order = [build1, build2, build3, build4, build5, build6] context = build_context_lib.get_collection_context(builds_wrong_order) first_build = builds_correct_order[0] assert context["title"] == "%s failed - %s" % ("D{}".format(revision_id), first_build.label) for i in range(len(context["builds"])): assert context["builds"][i]["build"] == builds_correct_order[i] assert context["result"] == Result.failed assert context["target_uri"] == revision_url assert context["target"] == "D{}".format(revision_id) assert context["label"] == first_build.label assert context["date_created"] == build1.date_created assert context["author"] == first_build.author assert context["commit_message"] == "" assert context["failing_tests_count"] == 0 assert context["total_failing_tests_count"] == 0
def test_with_result(result): revision_id = 'revision_id' revision_url = 'revision_url' source = self.create_source(project, data={ 'phabricator.revisionID': revision_id, 'phabricator.revisionURL': revision_url }) build = self.create_build(project, label='Test diff', date_started=datetime.utcnow(), result=result, source=source) job = self.create_job(build=build, result=Result.failed) phase = self.create_jobphase(job=job) step = self.create_jobstep(phase=phase) logsource = self.create_logsource( step=step, name='console', ) self.create_logchunk( source=logsource, text='hello world', ) context = build_context_lib.get_collection_context([build]) if result is not Result.passed and result is not Result.failed: result = Result.unknown assert context.title == '%s %s - %s' % ('D{}'.format(revision_id), str(result).lower(), job.build.label) assert len(context.builds) == 1 assert context.result == result assert context.target_uri == revision_url assert context.target == 'D{}'.format(revision_id) assert context.label == build.label assert context.date_created == build.date_created assert context.author == build.author assert context.commit_message == '' assert context.failing_tests_count == 0
def test_with_result(result): revision_id = 'revision_id' revision_url = 'revision_url' source = self.create_source(project, data={ 'phabricator.revisionID': revision_id, 'phabricator.revisionURL': revision_url }) build = self.create_build( project, label='Test diff', date_started=datetime.utcnow(), result=result, source=source ) job = self.create_job(build=build, result=Result.failed) phase = self.create_jobphase(job=job) step = self.create_jobstep(phase=phase) logsource = self.create_logsource( step=step, name='console', ) self.create_logchunk( source=logsource, text='hello world', ) context = build_context_lib.get_collection_context([build]) if result is not Result.passed and result is not Result.failed: result = Result.unknown assert context['title'] == '%s %s - %s' % ( 'D{}'.format(revision_id), str(result).lower(), job.build.label) assert len(context['builds']) == 1 assert context['result'] == result assert context['target_uri'] == revision_url assert context['target'] == 'D{}'.format(revision_id) assert context['label'] == build.label assert context['date_created'] == build.date_created assert context['author'] == build.author assert context['commit_message'] == '' assert context['failing_tests_count'] == 0
def get_msg(self, builds): context = build_context_lib.get_collection_context(builds) if context['result'] == Result.passed: return None max_shown = current_app.config.get('MAX_SHOWN_ITEMS_PER_BUILD_MAIL', 3) context.update({ 'MAX_SHOWN_ITEMS_PER_BUILD': max_shown, 'showing_failing_tests_count': sum([min(b['failing_tests_count'], max_shown) for b in context['builds']]) }) recipients = self.get_collection_recipients(context) msg = Message(context['title'], recipients=recipients, extra_headers={ 'Reply-To': ', '.join(sanitize_address(r) for r in recipients), }) msg.body = render_template('listeners/mail/notification.txt', **context) msg.html = Markup(toronado.from_string( render_template('listeners/mail/notification.html', **context) )) return msg
def build_finished_handler(build_id, **kwargs): build = Build.query.get(build_id) if build is None: return if build.tags and 'arc test' in build.tags: # 'arc test' builds have an associated Phabricator diff, but # aren't necessarily for the diff under review, so we don't # want to notify with them. return options = get_options(build.project_id) if options.get('phabricator.notify', '0') != '1': return target = build.target is_diff_build = target and target.startswith(u'D') is_commit_build = (build.source is not None and build.source.is_commit() and build.tags and 'commit' in build.tags) phab = PhabricatorClient() if options.get('phabricator.coverage', '0') == '1' and (is_diff_build or is_commit_build): coverage = merged_coverage_data(get_coverage_by_build_id(build_id)) if coverage: if is_diff_build: logger.info("Posting coverage to %s", target) post_diff_coverage(target[1:], coverage, phab) elif is_commit_build: # commits update diffs in phabricator, so post the coverage there too revision_id = parse_revision_id(build.message) if revision_id: post_diff_coverage(revision_id, coverage, phab) callsign, branch, commit = commit_details(build.source) if callsign and commit: logger.info("Posting coverage to %s, %s, %s", callsign, branch, commit) post_commit_coverage(callsign, branch, commit, coverage, phab) if not is_diff_build: # Not a diff build return builds = list( Build.query.filter(Build.collection_id == build.collection_id)) # Exit if there are no builds for the given build_id, or any build hasn't # finished. if not builds or any(map(lambda b: b.status != Status.finished, builds)): return # if comment has already been posted for this set of builds, don't do anything if _comment_posted_for_collection_of_build(build): return context = build_context_lib.get_collection_context(builds) message = '\n\n'.join( [_get_message_for_build_context(x) for x in context['builds']]) post_comment(target, message, phab)
def build_finished_handler(build_id, **kwargs): build = Build.query.get(build_id) if build is None: return if build_type.is_arc_test_build(build): # 'arc test' builds have an associated Phabricator diff, but # aren't necessarily for the diff under review, so we don't # want to notify with them. return options = get_options(build.project_id) if options.get('phabricator.notify', '0') != '1': return target = build.target is_diff_build = build_type.is_phabricator_diff_build(build) is_commit_build = build_type.is_initial_commit_build(build) phab = PhabricatorClient() if options.get('phabricator.coverage', '0') == '1' and (is_diff_build or is_commit_build): coverage = merged_coverage_data(get_coverage_by_build_id(build_id)) if coverage: if is_diff_build: logger.info("Posting coverage to %s", target) post_diff_coverage(target[1:], coverage, phab) elif is_commit_build: # commits update diffs in phabricator, so post the coverage there too revision_id = parse_revision_id(build.message) if revision_id: post_diff_coverage(revision_id, coverage, phab) callsign, branch, commit = commit_details(build.source) if callsign and commit: logger.info("Posting coverage to %s, %s, %s", callsign, branch, commit) post_commit_coverage(callsign, branch, commit, coverage, phab) if not is_diff_build: # Not a diff build return builds = list( Build.query.filter(Build.collection_id == build.collection_id)) # Filter collection of builds down to only consider/report builds for # projects with phabricator.notify set. options = ProjectOptionsHelper.get_options([b.project for b in builds], ['phabricator.notify']) builds = [b for b in builds if options[b.project.id].get('phabricator.notify', '0') == '1'] # Exit if there are no builds for the given build_id, or any build hasn't # finished. if not builds or any(map(lambda b: b.status != Status.finished, builds)): return # if comment has already been posted for this set of builds, don't do anything if _comment_posted_for_collection_of_build(build): return context = build_context_lib.get_collection_context(builds) good_builds = [b for b in context.builds if b['build'].result == Result.passed] bad_builds = [b for b in context.builds if b['build'].result != Result.passed] message = "" if bad_builds: message += '(IMPORTANT) Failing builds!\n\n' message += '\n'.join([_get_message_for_build_context(x) for x in bad_builds]) if good_builds: if bad_builds: message += '\n\n' message += '(NOTE) Passing builds:\n\n' message += '\n'.join([_get_message_for_build_context(x) for x in good_builds]) post_comment(target, message, phab)
def build_finished_handler(build_id, **kwargs): build = Build.query.get(build_id) if build is None: return if build_type.is_arc_test_build(build): # 'arc test' builds have an associated Phabricator diff, but # aren't necessarily for the diff under review, so we don't # want to notify with them. return options = get_options(build.project_id) if options.get('phabricator.notify', '0') != '1': return target = build.target is_diff_build = build_type.is_phabricator_diff_build(build) is_commit_build = build_type.is_initial_commit_build(build) phab = PhabricatorClient() if options.get('phabricator.coverage', '0') == '1' and (is_diff_build or is_commit_build): coverage = merged_coverage_data(get_coverage_by_build_id(build_id)) if coverage: if is_diff_build: logger.info("Posting coverage to %s", target) post_diff_coverage(target[1:], coverage, phab) elif is_commit_build: # commits update diffs in phabricator, so post the coverage there too revision_id = parse_revision_id(build.message) if revision_id: post_diff_coverage(revision_id, coverage, phab) callsign, branch, commit = commit_details(build.source) if callsign and commit: logger.info("Posting coverage to %s, %s, %s", callsign, branch, commit) post_commit_coverage(callsign, branch, commit, coverage, phab) if not is_diff_build: # Not a diff build return builds = list( Build.query.filter(Build.collection_id == build.collection_id)) # Filter collection of builds down to only consider/report builds for # projects with phabricator.notify set. options = ProjectOptionsHelper.get_options([b.project for b in builds], ['phabricator.notify']) builds = [ b for b in builds if options[b.project.id].get('phabricator.notify', '0') == '1' ] # Exit if there are no builds for the given build_id, or any build hasn't # finished. if not builds or any(map(lambda b: b.status != Status.finished, builds)): return # if comment has already been posted for this set of builds, don't do anything if _comment_posted_for_collection_of_build(build): return context = build_context_lib.get_collection_context(builds) good_builds = [ b for b in context.builds if b['build'].result == Result.passed ] bad_builds = [ b for b in context.builds if b['build'].result != Result.passed ] message = "" if bad_builds: message += '(IMPORTANT) Failing builds!\n\n' message += '\n'.join( [_get_message_for_build_context(x) for x in bad_builds]) if good_builds: if bad_builds: message += '\n\n' message += '(NOTE) Passing builds:\n\n' message += '\n'.join( [_get_message_for_build_context(x) for x in good_builds]) post_comment(target, message, phab)