示例#1
0
def build_email_body(ctx, stack, sleep_time_sec):
    email_template_path = os.path.dirname(__file__) + \
            '/templates/email-sleep-before-teardown.jinja2'

    with open(email_template_path) as f:
        template_text = f.read()

    email_template = jinja2.Template(template_text)
    archive_path = ctx.config.get('archive_path')
    job_id = ctx.config.get('job_id')
    status = get_status(ctx.summary)
    stack_path = '/'.join(task for task, _ in stack)
    suite_name = ctx.config.get('suite')
    sleep_date = time.time()
    sleep_date_str = time.strftime('%Y-%m-%d %H:%M:%S',
                                   time.gmtime(sleep_date))

    body = email_template.render(
        sleep_time=format_timespan(sleep_time_sec),
        sleep_time_sec=sleep_time_sec,
        sleep_date=sleep_date_str,
        owner=ctx.owner,
        run_name=ctx.name,
        job_id=ctx.config.get('job_id'),
        job_info=get_results_url(ctx.name),
        job_logs=get_http_log_path(archive_path, job_id),
        suite_name=suite_name,
        status=status,
        task_stack=stack_path,
    )
    subject = ('teuthology job {run}/{job} has fallen asleep at {date}'.format(
        run=ctx.name, job=job_id, date=sleep_date_str))
    return (subject.strip(), body.strip())
示例#2
0
def build_rocketchat_message(ctx, stack, sleep_time_sec, template_path=None):
    message_template_path = template_path or os.path.dirname(__file__) + \
            '/templates/rocketchat-sleep-before-teardown.jinja2'

    with open(message_template_path) as f:
        template_text = f.read()

    template = jinja2.Template(template_text)
    archive_path = ctx.config.get('archive_path')
    job_id = ctx.config.get('job_id')
    status = get_status(ctx.summary)
    stack_path = ' -> '.join(task for task, _ in stack)
    suite_name = ctx.config.get('suite')
    sleep_date = time.time()
    sleep_date_str = time.strftime('%Y-%m-%d %H:%M:%S',
                                   time.gmtime(sleep_date))

    message = template.render(
        sleep_time=format_timespan(sleep_time_sec),
        sleep_time_sec=sleep_time_sec,
        sleep_date=sleep_date_str,
        owner=ctx.owner,
        run_name=ctx.name,
        job_id=ctx.config.get('job_id'),
        job_desc=ctx.config.get('description'),
        job_info=get_results_url(ctx.name, job_id),
        job_logs=get_http_log_path(archive_path, job_id),
        suite_name=suite_name,
        status=status,
        task_stack=stack_path,
    )
    return message
示例#3
0
def build_email_body(name, _reporter=None):
    stanzas = OrderedDict([
        ('fail', dict()),
        ('dead', dict()),
        ('running', dict()),
        ('waiting', dict()),
        ('queued', dict()),
        ('pass', dict()),
    ])
    reporter = _reporter or ResultsReporter()
    fields = ('job_id', 'status', 'description', 'duration', 'failure_reason',
              'sentry_event', 'log_href')
    jobs = reporter.get_jobs(name, fields=fields)
    jobs.sort(key=lambda job: job['job_id'])

    for job in jobs:
        job_stanza = format_job(name, job)
        stanzas[job['status']][job['job_id']] = job_stanza

    sections = OrderedDict.fromkeys(stanzas.keys(), '')
    subject_fragments = []
    for status in sections.keys():
        stanza = stanzas[status]
        if stanza:
            subject_fragments.append('%s %s' % (len(stanza), status))
            sections[status] = email_templates['sect_templ'].format(
                title=status.title(),
                jobs=''.join(stanza.values()),
            )
    subject = ', '.join(subject_fragments) + ' '

    if config.archive_server:
        log_root = os.path.join(config.archive_server, name, '')
    else:
        log_root = None

    body = email_templates['body_templ'].format(
        name=name,
        info_root=misc.get_results_url(name),
        log_root=log_root,
        fail_count=len(stanzas['fail']),
        dead_count=len(stanzas['dead']),
        running_count=len(stanzas['running']),
        waiting_count=len(stanzas['waiting']),
        queued_count=len(stanzas['queued']),
        pass_count=len(stanzas['pass']),
        fail_sect=sections['fail'],
        dead_sect=sections['dead'],
        running_sect=sections['running'],
        waiting_sect=sections['waiting'],
        queued_sect=sections['queued'],
        pass_sect=sections['pass'],
    )

    subject += 'in {suite}'.format(suite=name)
    return (subject.strip(), body.strip())
示例#4
0
def build_email_body(name, _reporter=None):
    stanzas = OrderedDict([
        ('fail', dict()),
        ('dead', dict()),
        ('running', dict()),
        ('waiting', dict()),
        ('queued', dict()),
        ('pass', dict()),
    ])
    reporter = _reporter or ResultsReporter()
    fields = ('job_id', 'status', 'description', 'duration', 'failure_reason',
              'sentry_event', 'log_href')
    jobs = reporter.get_jobs(name, fields=fields)
    jobs.sort(key=lambda job: job['job_id'])

    for job in jobs:
        job_stanza = format_job(name, job)
        stanzas[job['status']][job['job_id']] = job_stanza

    sections = OrderedDict.fromkeys(stanzas.keys(), '')
    subject_fragments = []
    for status in sections.keys():
        stanza = stanzas[status]
        if stanza:
            subject_fragments.append('%s %s' % (len(stanza), status))
            sections[status] = email_templates['sect_templ'].format(
                title=status.title(),
                jobs=''.join(stanza.values()),
            )
    subject = ', '.join(subject_fragments) + ' '

    if config.archive_server:
        log_root = os.path.join(config.archive_server, name, '')
    else:
        log_root = None

    body = email_templates['body_templ'].format(
        name=name,
        info_root=misc.get_results_url(name),
        log_root=log_root,
        fail_count=len(stanzas['fail']),
        dead_count=len(stanzas['dead']),
        running_count=len(stanzas['running']),
        waiting_count=len(stanzas['waiting']),
        queued_count=len(stanzas['queued']),
        pass_count=len(stanzas['pass']),
        fail_sect=sections['fail'],
        dead_sect=sections['dead'],
        running_sect=sections['running'],
        waiting_sect=sections['waiting'],
        queued_sect=sections['queued'],
        pass_sect=sections['pass'],
    )

    subject += 'in {suite}'.format(suite=name)
    return (subject.strip(), body.strip())
示例#5
0
 def write_result(self):
     arg = copy.deepcopy(self.base_args)
     arg.append('--last-in-suite')
     if self.base_config.email:
         arg.extend(['--email', self.base_config.email])
     if self.args.timeout:
         arg.extend(['--timeout', self.args.timeout])
     util.teuthology_schedule(args=arg,
                              dry_run=self.args.dry_run,
                              verbose=self.args.verbose,
                              log_prefix="Results: ")
     results_url = get_results_url(self.base_config.name)
     if results_url:
         log.info("Test results viewable at %s", results_url)
示例#6
0
def format_job(run_name, job):
    job_id = job['job_id']
    status = job['status']
    description = job['description']
    duration = seconds_to_hms(int(job['duration'] or 0))

    # Every job gets a link to e.g. pulpito's pages
    info_url = misc.get_results_url(run_name, job_id)
    if info_url:
        info_line = email_templates['info_url_templ'].format(info=info_url)
    else:
        info_line = ''

    if status in UNFINISHED_STATUSES:
        format_args = dict(
            job_id=job_id,
            desc=description,
            time=duration,
            info_line=info_line,
        )
        return email_templates['running_templ'].format(**format_args)

    if status == 'pass':
        return email_templates['pass_templ'].format(
            job_id=job_id,
            desc=description,
            time=duration,
            info_line=info_line,
        )
    else:
        log_dir_url = job['log_href'].rstrip('teuthology.yaml')
        if log_dir_url:
            log_line = email_templates['fail_log_templ'].format(
                log=log_dir_url)
        else:
            log_line = ''
        sentry_event = job.get('sentry_event')
        if sentry_event:
            sentry_line = email_templates['fail_sentry_templ'].format(
                sentry_event=sentry_event)
        else:
            sentry_line = ''

        if job['failure_reason']:
            # 'fill' is from the textwrap module and it collapses a given
            # string into multiple lines of a maximum width as specified.
            # We want 75 characters here so that when we indent by 4 on the
            # next line, we have 79-character exception paragraphs.
            reason = fill(job['failure_reason'] or '', 75)
            reason = \
                '\n'.join(('    ') + line for line in reason.splitlines())
            reason_lines = email_templates['fail_reason_templ'].format(
                reason=reason).rstrip()
        else:
            reason_lines = ''

        format_args = dict(
            job_id=job_id,
            desc=description,
            time=duration,
            info_line=info_line,
            log_line=log_line,
            sentry_line=sentry_line,
            reason_lines=reason_lines,
        )
        return email_templates['fail_templ'].format(**format_args)
示例#7
0
def build_email_body(name, archive_dir, timeout):
    failed = {}
    hung = {}
    passed = {}

    for job in ls.get_jobs(archive_dir):
        job_dir = os.path.join(archive_dir, job)
        summary_file = os.path.join(job_dir, 'summary.yaml')

        # Every job gets a link to e.g. pulpito's pages
        info_url = misc.get_results_url(name, job)
        if info_url:
            info_line = email_templates['info_url_templ'].format(info=info_url)
        else:
            info_line = ''

        # Unfinished jobs will have no summary.yaml
        if not os.path.exists(summary_file):
            info_file = os.path.join(job_dir, 'info.yaml')

            desc = ''
            if os.path.exists(info_file):
                with file(info_file) as f:
                    info = yaml.safe_load(f)
                    desc = info['description']

            hung[job] = email_templates['hung_templ'].format(
                job_id=job,
                desc=desc,
                info_line=info_line,
            )
            continue

        with file(summary_file) as f:
            summary = yaml.safe_load(f)

        if summary['success']:
            passed[job] = email_templates['pass_templ'].format(
                job_id=job,
                desc=summary.get('description'),
                time=int(summary.get('duration', 0)),
                info_line=info_line,
            )
        else:
            log = misc.get_http_log_path(archive_dir, job)
            if log:
                log_line = email_templates['fail_log_templ'].format(log=log)
            else:
                log_line = ''
            # Transitioning from sentry_events -> sentry_event
            sentry_events = summary.get('sentry_events')
            if sentry_events:
                sentry_event = sentry_events[0]
            else:
                sentry_event = summary.get('sentry_event', '')
            if sentry_event:
                sentry_line = email_templates['fail_sentry_templ'].format(
                    sentry_event=sentry_event)
            else:
                sentry_line = ''

            # 'fill' is from the textwrap module and it collapses a given
            # string into multiple lines of a maximum width as specified. We
            # want 75 characters here so that when we indent by 4 on the next
            # line, we have 79-character exception paragraphs.
            reason = fill(summary.get('failure_reason'), 75)
            reason = '\n'.join(('    ') + line for line in reason.splitlines())

            failed[job] = email_templates['fail_templ'].format(
                job_id=job,
                desc=summary.get('description'),
                time=int(summary.get('duration', 0)),
                reason=reason,
                info_line=info_line,
                log_line=log_line,
                sentry_line=sentry_line,
            )

    maybe_comma = lambda s: ', ' if s else ' '

    subject = ''
    fail_sect = ''
    hung_sect = ''
    pass_sect = ''
    if failed:
        subject += '{num_failed} failed{sep}'.format(
            num_failed=len(failed),
            sep=maybe_comma(hung or passed)
        )
        fail_sect = email_templates['sect_templ'].format(
            title='Failed',
            jobs=''.join(failed.values())
        )
    if hung:
        subject += '{num_hung} hung{sep}'.format(
            num_hung=len(hung),
            sep=maybe_comma(passed),
        )
        hung_sect = email_templates['sect_templ'].format(
            title='Hung',
            jobs=''.join(hung.values()),
        )
    if passed:
        subject += '%s passed ' % len(passed)
        pass_sect = email_templates['sect_templ'].format(
            title='Passed',
            jobs=''.join(passed.values()),
        )

    body = email_templates['body_templ'].format(
        name=name,
        info_root=misc.get_results_url(name),
        log_root=misc.get_http_log_path(archive_dir),
        fail_count=len(failed),
        hung_count=len(hung),
        pass_count=len(passed),
        fail_sect=fail_sect,
        hung_sect=hung_sect,
        pass_sect=pass_sect,
    )

    subject += 'in {suite}'.format(suite=name)
    return (subject.strip(), body.strip())
示例#8
0
def format_job(run_name, job):
    job_id = job['job_id']
    status = job['status']
    description = job['description']
    duration = seconds_to_hms(int(job['duration'] or 0))

    # Every job gets a link to e.g. pulpito's pages
    info_url = misc.get_results_url(run_name, job_id)
    if info_url:
        info_line = email_templates['info_url_templ'].format(info=info_url)
    else:
        info_line = ''

    if status in UNFINISHED_STATUSES:
        format_args = dict(
            job_id=job_id,
            desc=description,
            time=duration,
            info_line=info_line,
        )
        return email_templates['running_templ'].format(**format_args)

    if status == 'pass':
        return email_templates['pass_templ'].format(
            job_id=job_id,
            desc=description,
            time=duration,
            info_line=info_line,
        )
    else:
        log_dir_url = job['log_href'].rstrip('teuthology.yaml')
        if log_dir_url:
            log_line = email_templates['fail_log_templ'].format(
                log=log_dir_url)
        else:
            log_line = ''
        sentry_event = job.get('sentry_event')
        if sentry_event:
            sentry_line = email_templates['fail_sentry_templ'].format(
                sentry_event=sentry_event)
        else:
            sentry_line = ''

        if job['failure_reason']:
            # 'fill' is from the textwrap module and it collapses a given
            # string into multiple lines of a maximum width as specified.
            # We want 75 characters here so that when we indent by 4 on the
            # next line, we have 79-character exception paragraphs.
            reason = fill(job['failure_reason'] or '', 75)
            reason = \
                '\n'.join(('    ') + line for line in reason.splitlines())
            reason_lines = email_templates['fail_reason_templ'].format(
                reason=reason).rstrip()
        else:
            reason_lines = ''

        format_args = dict(
            job_id=job_id,
            desc=description,
            time=duration,
            info_line=info_line,
            log_line=log_line,
            sentry_line=sentry_line,
            reason_lines=reason_lines,
        )
        return email_templates['fail_templ'].format(**format_args)
示例#9
0
def build_email_body(name, archive_dir):
    failed = {}
    hung = {}
    passed = {}

    for job in ls.get_jobs(archive_dir):
        job_dir = os.path.join(archive_dir, job)
        summary_file = os.path.join(job_dir, 'summary.yaml')

        # Every job gets a link to e.g. pulpito's pages
        info_url = misc.get_results_url(name, job)
        if info_url:
            info_line = email_templates['info_url_templ'].format(info=info_url)
        else:
            info_line = ''

        # Unfinished jobs will have no summary.yaml
        if not os.path.exists(summary_file):
            info_file = os.path.join(job_dir, 'info.yaml')

            desc = ''
            if os.path.exists(info_file):
                with file(info_file) as f:
                    info = yaml.safe_load(f)
                    desc = info['description']

            hung[job] = email_templates['hung_templ'].format(
                job_id=job,
                desc=desc,
                info_line=info_line,
            )
            continue

        with file(summary_file) as f:
            summary = yaml.safe_load(f)

        if get_status(summary) == 'pass':
            passed[job] = email_templates['pass_templ'].format(
                job_id=job,
                desc=summary.get('description'),
                time=int(summary.get('duration', 0)),
                info_line=info_line,
            )
        else:
            log = misc.get_http_log_path(archive_dir, job)
            if log:
                log_line = email_templates['fail_log_templ'].format(log=log)
            else:
                log_line = ''
            # Transitioning from sentry_events -> sentry_event
            sentry_events = summary.get('sentry_events')
            if sentry_events:
                sentry_event = sentry_events[0]
            else:
                sentry_event = summary.get('sentry_event', '')
            if sentry_event:
                sentry_line = email_templates['fail_sentry_templ'].format(
                    sentry_event=sentry_event)
            else:
                sentry_line = ''

            # 'fill' is from the textwrap module and it collapses a given
            # string into multiple lines of a maximum width as specified. We
            # want 75 characters here so that when we indent by 4 on the next
            # line, we have 79-character exception paragraphs.
            reason = fill(summary.get('failure_reason'), 75)
            reason = '\n'.join(('    ') + line for line in reason.splitlines())

            failed[job] = email_templates['fail_templ'].format(
                job_id=job,
                desc=summary.get('description'),
                time=int(summary.get('duration', 0)),
                reason=reason,
                info_line=info_line,
                log_line=log_line,
                sentry_line=sentry_line,
            )

    maybe_comma = lambda s: ', ' if s else ' '

    subject = ''
    fail_sect = ''
    hung_sect = ''
    pass_sect = ''
    if failed:
        subject += '{num_failed} failed{sep}'.format(num_failed=len(failed),
                                                     sep=maybe_comma(
                                                         hung or passed))
        fail_sect = email_templates['sect_templ'].format(title='Failed',
                                                         jobs=''.join(
                                                             failed.values()))
    if hung:
        subject += '{num_hung} hung{sep}'.format(
            num_hung=len(hung),
            sep=maybe_comma(passed),
        )
        hung_sect = email_templates['sect_templ'].format(
            title='Hung',
            jobs=''.join(hung.values()),
        )
    if passed:
        subject += '%s passed ' % len(passed)
        pass_sect = email_templates['sect_templ'].format(
            title='Passed',
            jobs=''.join(passed.values()),
        )

    body = email_templates['body_templ'].format(
        name=name,
        info_root=misc.get_results_url(name),
        log_root=misc.get_http_log_path(archive_dir),
        fail_count=len(failed),
        hung_count=len(hung),
        pass_count=len(passed),
        fail_sect=fail_sect,
        hung_sect=hung_sect,
        pass_sect=pass_sect,
    )

    subject += 'in {suite}'.format(suite=name)
    return (subject.strip(), body.strip())