示例#1
0
文件: webhooks.py 项目: lmy0429/dpxdt
def send_ready_for_review(build_id, release_name, release_number):
    build = models.Build.query.get(build_id)

    if not build.webhook_url:
        logging.debug(
            'Not sending ready for review webhook because build does not have '
            'webhook_url. build_id=%r', build.id)
        return

    ops = operations.BuildOps(build_id)
    release, run_list, stats_dict, _ = ops.get_release(release_name,
                                                       release_number)

    if not run_list:
        logging.debug(
            'Not sending ready for review email because there are '
            ' no runs. build_id=%r, release_name=%r, release_number=%d',
            build.id, release.name, release.number)
        return

    view_build_url = url_for('view_build', id=build.id, _external=True)
    title = '%s: %s - Ready for review at %r' % (build.name, release.name,
                                                 view_build_url)
    logging.info('Sending ready_for_review webhook. build_id=%r, url=%s',
                 build.id, build.webhook_url)

    # Arbitrarily chose Slack payload format.
    # See https://api.slack.com/incoming-webhooks
    payload = {
        'text': title,
        'icon_url': url_for('static',
                            filename='img/logo_big.png',
                            _external=True)
    }
    return _send_webhook(build.webhook_url, payload)
示例#2
0
def view_release():
    """Page for viewing all tests runs in a release."""
    build = g.build
    if request.method == 'POST':
        form = forms.ReleaseForm(request.form)
    else:
        form = forms.ReleaseForm(request.args)

    form.validate()

    ops = operations.BuildOps(build.id)
    release, run_list, stats_dict, approval_log = ops.get_release(
        form.name.data, form.number.data)

    if not release:
        abort(404)

    if request.method == 'POST':
        decision_states = (models.Release.REVIEWING, models.Release.RECEIVING,
                           models.Release.PROCESSING)

        if form.good.data and release.status in decision_states:
            release.status = models.Release.GOOD
            auth.save_admin_log(build, release_good=True, release=release)
        elif form.bad.data and release.status in decision_states:
            release.status = models.Release.BAD
            auth.save_admin_log(build, release_bad=True, release=release)
        elif form.reviewing.data and release.status in (models.Release.GOOD,
                                                        models.Release.BAD):
            release.status = models.Release.REVIEWING
            auth.save_admin_log(build, release_reviewing=True, release=release)
        else:
            logging.warning(
                'Bad state transition for name=%r, number=%r, form=%r',
                release.name, release.number, form.data)
            abort(400)

        db.session.add(release)
        db.session.commit()

        ops.evict()

        return redirect(
            url_for('view_release',
                    id=build.id,
                    name=release.name,
                    number=release.number))

    # Update form values for rendering
    form.good.data = True
    form.bad.data = True
    form.reviewing.data = True

    return render_template('view_release.html',
                           build=build,
                           release=release,
                           run_list=run_list,
                           release_form=form,
                           approval_log=approval_log,
                           stats_dict=stats_dict)
示例#3
0
def get_test_result():
    site = request.args['site']
    build = models.Build.query.filter_by(name=site).first()
    id = build.id
    try:
        with open(
                os.path.dirname(os.path.dirname(__file__)) +
                '\\test_run_status.txt', 'r') as f:
            excute_result = f.read()
        os.remove(
            os.path.dirname(os.path.dirname(__file__)) +
            '\\test_run_status.txt')
        if excute_result == "finished":
            pass
    except:
        return "excute don't finished"
    page_size = 10
    offset = request.args.get('offset', 0, type=int)

    ops = operations.BuildOps(id)
    has_next_page, candidate_list, stats_counts = ops.get_candidates(
        page_size, offset)

    # Collate by release name, order releases by latest creation. Init stats.
    release_dict = {}
    created_dict = {}
    for candidate in candidate_list:
        release_list = release_dict.setdefault(candidate.name, [])
        release_list.append(candidate)
        max_created = created_dict.get(candidate.name, candidate.created)
        created_dict[candidate.name] = max(candidate.created, max_created)

    # Sort all releases by created time descending
    release_age_list = [(value, key)
                        for key, value in created_dict.iteritems()]
    release_age_list.sort(reverse=True)
    release_name_list = [key for _, key in release_age_list]

    # Count totals for each run state within that release.
    candidate_id_list = []
    stats_counts_index = []
    for candidate_id, status, count in stats_counts:
        candidate_id_list.append(candidate_id)
    count_candidate_id = candidate_id_list.count(max(candidate_id_list))
    for i in range(count_candidate_id):
        stats_counts_index.append(
            candidate_id_list.index(max(candidate_id_list)))
        candidate_id_list.remove(max(candidate_id_list))
    for count_status in range(len(stats_counts_index)):
        candidate_id, status, count = stats_counts[
            stats_counts_index[count_status]]
        logging.info(stats_counts_index)
        if status == "diff_found":
            return 'Test Failed : {0} have {1} different'.format(
                release_name_list[0], count)
    return 'Test Success : {0} have {1} is {2}'.format(release_name_list[0],
                                                       count, status)
示例#4
0
def view_build():
    """Page for viewing all releases in a build."""
    build = g.build
    page_size = 20
    offset = request.args.get('offset', 0, type=int)

    ops = operations.BuildOps(build.id)
    has_next_page, candidate_list, stats_counts = ops.get_candidates(
        page_size, offset)

    # Collate by release name, order releases by latest creation. Init stats.
    release_dict = {}
    created_dict = {}
    run_stats_dict = {}
    for candidate in candidate_list:
        release_list = release_dict.setdefault(candidate.name, [])
        release_list.append(candidate)
        max_created = created_dict.get(candidate.name, candidate.created)
        created_dict[candidate.name] = max(candidate.created, max_created)
        run_stats_dict[candidate.id] = dict(
            runs_total=0,
            runs_complete=0,
            runs_successful=0,
            runs_failed=0,
            runs_baseline=0,
            runs_pending=0)

    # Sort each release by candidate number descending
    for release_list in release_dict.itervalues():
        release_list.sort(key=lambda x: x.number, reverse=True)

    # Sort all releases by created time descending
    release_age_list = [
        (value, key) for key, value in created_dict.iteritems()]
    release_age_list.sort(reverse=True)
    release_name_list = [key for _, key in release_age_list]

    # Count totals for each run state within that release.
    for candidate_id, status, count in stats_counts:
        stats_dict = run_stats_dict[candidate_id]
        for key in ops.get_stats_keys(status):
            stats_dict[key] += count

    return render_template(
        'view_build.html',
        build=build,
        release_name_list=release_name_list,
        release_dict=release_dict,
        run_stats_dict=run_stats_dict,
        has_next_page=has_next_page,
        current_offset=offset,
        next_offset=offset + page_size,
        last_offset=max(0, offset -  page_size))
示例#5
0
def send_ready_for_review(build_id, release_name, release_number):
    """Sends an email indicating that the release is ready for review."""
    build = models.Build.query.get(build_id)

    if not build.send_email:
        logging.debug(
            'Not sending ready for review email because build does not have '
            'email enabled. build_id=%r', build.id)
        return

    ops = operations.BuildOps(build_id)
    release, run_list, stats_dict, _ = ops.get_release(release_name,
                                                       release_number)

    if not run_list:
        logging.debug(
            'Not sending ready for review email because there are '
            ' no runs. build_id=%r, release_name=%r, release_number=%d',
            build.id, release.name, release.number)
        return

    title = '%s: %s - Ready for review' % (build.name, release.name)

    email_body = render_template('email_ready_for_review.html',
                                 build=build,
                                 release=release,
                                 run_list=run_list,
                                 stats_dict=stats_dict)

    recipients = []
    if build.email_alias:
        recipients.append(build.email_alias)
    else:
        for user in build.owners:
            recipients.append(user.email_address)

    if not recipients:
        logging.debug(
            'Not sending ready for review email because there are no '
            'recipients. build_id=%r, release_name=%r, release_number=%d',
            build.id, release.name, release.number)
        return

    message = Message(title, recipients=recipients)
    message.html = email_body

    logging.info(
        'Sending ready for review email for build_id=%r, '
        'release_name=%r, release_number=%d to %r', build.id, release.name,
        release.number, recipients)

    return render_or_send(send_ready_for_review, message)
示例#6
0
def view_run():
    """Page for viewing before/after for a specific test run."""
    build = g.build
    if request.method == 'POST':
        form = forms.RunForm(request.form)
    else:
        form = forms.RunForm(request.args)

    form.validate()

    ops = operations.BuildOps(build.id)
    run, next_run, previous_run, approval_log = ops.get_run(
        form.name.data, form.number.data, form.test.data)

    if not run:
        abort(404)

    file_type = form.type.data
    image_file, log_file, config_file, sha1sum = (_get_artifact_context(
        run, file_type))

    if request.method == 'POST':
        if form.approve.data and run.status == models.Run.DIFF_FOUND:
            run.status = models.Run.DIFF_APPROVED
            auth.save_admin_log(build, run_approved=True, run=run)
        elif form.disapprove.data and run.status == models.Run.DIFF_APPROVED:
            run.status = models.Run.DIFF_FOUND
            auth.save_admin_log(build, run_rejected=True, run=run)
        else:
            abort(400)

        db.session.add(run)
        db.session.commit()

        ops.evict()

        return redirect(
            url_for(request.endpoint,
                    id=build.id,
                    name=run.release.name,
                    number=run.release.number,
                    test=run.name,
                    type=file_type))

    # Update form values for rendering
    form.approve.data = True
    form.disapprove.data = True

    context = dict(build=build,
                   release=run.release,
                   run=run,
                   run_form=form,
                   previous_run=previous_run,
                   next_run=next_run,
                   file_type=file_type,
                   image_file=image_file,
                   log_file=log_file,
                   config_file=config_file,
                   sha1sum=sha1sum,
                   approval_log=approval_log)

    if file_type:
        template_name = 'view_artifact.html'
    else:
        template_name = 'view_run.html'

    response = flask.Response(render_template(template_name, **context))

    return response