benchmark.py 3.49 KB
Newer Older
1
from __future__ import print_function
2
import argparse
3 4 5 6
import sys
import smtplib
import platform
import datetime
7 8
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

MAIL_SERVER = '127.0.0.1:25'

class AttributeDict(dict):

    def __getattr__(self, item):
        return self.__getitem__(item)

class BenchmarkRunner(object):
    """
        Base class for a command-line benchmark test runner.
    """

    def __init__(self):
        self._successful = True
        self._status = []
25 26
        parser = argparse.ArgumentParser(
            formatter_class=argparse.RawDescriptionHelpFormatter)
27
        # register common options
28 29 30 31 32
        _ = parser.add_argument
        _('--title')
        _('--mail-to', action='append')
        _('--mail-from')
        _('--mail-server')
33 34
        self.add_options(parser)
        # check common arguments
35 36
        args = parser.parse_args()
        if bool(args.mail_to) ^ bool(args.mail_from):
37
            sys.exit('Need a sender and recipients to mail report')
38
        mail_server = args.mail_server or MAIL_SERVER
39 40
        # check specifics arguments
        self._config = AttributeDict()
41
        self._config.update(self.load_options(args))
42
        self._config.update(
43 44 45
            title = args.title or self.__class__.__name__,
            mail_from = args.mail_from,
            mail_to = args.mail_to,
46
            mail_server = mail_server.split(':'),
47
        )
48 49 50 51 52

    def add_status(self, key, value):
        self._status.append((key, value))

    def build_report(self, content):
53
        fmt = "%-25s : %s"
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
        status = "\n".join([fmt % item for item in [
            ('Title', self._config.title),
            ('Date', datetime.date.today().isoformat()),
            ('Node', platform.node()),
            ('Machine', platform.machine()),
            ('System', platform.system()),
            ('Python', platform.python_version()),
        ]])
        status += '\n\n'
        status += "\n".join([fmt % item for item in self._status])
        return "%s\n\n%s" % (status, content)

    def send_report(self, subject, report):
        # build report
        # build email
        msg = MIMEMultipart()
        msg['Subject'] = '%s: %s' % (self._config.title, subject)
        msg['From'] = self._config.mail_from
        msg['To'] = ', '.join(self._config.mail_to)
        msg['X-ERP5-Tests'] = 'NEO'
        if self._successful:
            msg['X-ERP5-Tests-Status'] = 'OK'
        msg.epilogue = ''
        msg.attach(MIMEText(report))

        # send it
        s = smtplib.SMTP()
        s.connect(*self._config.mail_server)
        mail = msg.as_string()
        for recipient in self._config.mail_to:
            try:
                s.sendmail(self._config.mail_from, recipient, mail)
            except smtplib.SMTPRecipientsRefused:
87
                print("Mail for %s fails" % recipient)
88 89 90 91 92 93 94
        s.close()

    def run(self):
        subject, report = self.start()
        report = self.build_report(report)
        if self._config.mail_to:
            self.send_report(subject, report)
95 96 97 98
        print(subject)
        if report:
            print()
            print(report, end='')
99 100 101 102 103 104 105 106

    def was_successful(self):
        return self._successful

    def add_options(self, parser):
        """ Append options to command line parser """
        raise NotImplementedError

107
    def load_options(self, args):
108 109 110 111 112 113 114
        """ Check options and return a configuration dict """
        raise NotImplementedError

    def start(self):
        """ Run the test """
        raise NotImplementedError