4 Run the test suite and send the result as an email message.
6 The code for sending of the directory is copied from
7 http://docs.python.org/library/email-examples.html.
14 # For guessing MIME type based on file name extension
17 from optparse import OptionParser
19 from email import encoders
20 from email.message import Message
21 from email.mime.audio import MIMEAudio
22 from email.mime.base import MIMEBase
23 from email.mime.image import MIMEImage
24 from email.mime.multipart import MIMEMultipart
25 from email.mime.text import MIMEText
28 def runTestsuite(testDir, sessDir, envs=None):
29 """Run the testsuite and return a (summary, output) tuple."""
42 command_line = "./dotest.py -w -s %s" % sessDir
43 # Apply correct tokenization for subprocess.Popen().
44 args = shlex.split(command_line)
46 # Use subprocess module to spawn a new process.
47 process = subprocess.Popen(args,
48 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
49 # Wait for subprocess to terminate.
50 stdout, stderr = process.communicate()
52 # This will be used as the subject line of our email about this test.
53 cmd = "%s %s" % (' '.join(envs) if envs else "", command_line)
62 parser = OptionParser(usage="""\
63 Run lldb test suite and send the results as a MIME message.
65 Usage: %prog [options]
67 Unless the -o option is given, the email is sent by forwarding to the specified
68 SMTP server, which then does the normal delivery process.
70 parser.add_option('-d', '--directory',
71 type='string', action='store',
73 help="""The LLDB test directory directly under the top dir.
74 Otherwise use the current directory.""")
76 # This is similar to TestBase.getRunSpec(self) from lldbtest.py.
78 parser.add_option('-e', '--environment',
79 type='string', action='append', metavar='ENVIRONMENT',
80 default=[], dest='environments',
81 help="""The environment setting as prefix to the test driver.
82 Example: -e 'CC=clang' -e 'ARCH=x86_64'""")
83 parser.add_option('-m', '--mailserver',
84 type='string', action='store', metavar='MAILSERVER',
86 help="""The outgoing SMTP server.""")
87 parser.add_option('-o', '--output',
88 type='string', action='store', metavar='FILE',
89 help="""Print the composed message to FILE instead of
90 sending the message to the SMTP server.""")
91 parser.add_option('-s', '--sender',
92 type='string', action='store', metavar='SENDER',
93 help='The value of the From: header (required)')
94 parser.add_option('-r', '--recipient',
95 type='string', action='append', metavar='RECIPIENT',
96 default=[], dest='recipients',
97 help='A To: header value (at least one required)')
98 opts, args = parser.parse_args()
99 if not opts.sender or not opts.recipients:
102 testDir = opts.testDir
106 sessDir = 'tmp-lldb-session'
107 if os.path.exists(sessDir):
108 shutil.rmtree(sessDir)
109 # print "environments:", opts.environments
110 summary, output = runTestsuite(testDir, sessDir, opts.environments)
112 # Create the enclosing (outer) message
113 outer = MIMEMultipart()
114 outer['Subject'] = summary
115 outer['To'] = COMMASPACE.join(opts.recipients)
116 outer['From'] = opts.sender
117 outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
119 # The sessDir contains all the session logs for failed/errored tests.
120 # Attach them all if it exists!
122 if not os.path.exists(sessDir):
123 outer.attach(MIMEText(output, 'plain'))
128 (output, "Session logs of test failures/errors:"), 'plain'))
130 for filename in (os.listdir(sessDir) if os.path.exists(sessDir) else []):
131 path = os.path.join(sessDir, filename)
132 if not os.path.isfile(path):
134 # Guess the content type based on the file's extension. Encoding
135 # will be ignored, although we should check for simple things like
136 # gzip'd or compressed files.
137 ctype, encoding = mimetypes.guess_type(path)
138 if ctype is None or encoding is not None:
139 # No guess could be made, or the file is encoded (compressed), so
140 # use a generic bag-of-bits type.
141 ctype = 'application/octet-stream'
142 maintype, subtype = ctype.split('/', 1)
143 if maintype == 'text':
145 # Note: we should handle calculating the charset
146 msg = MIMEText(fp.read(), _subtype=subtype)
148 elif maintype == 'image':
149 fp = open(path, 'rb')
150 msg = MIMEImage(fp.read(), _subtype=subtype)
152 elif maintype == 'audio':
153 fp = open(path, 'rb')
154 msg = MIMEAudio(fp.read(), _subtype=subtype)
157 fp = open(path, 'rb')
158 msg = MIMEBase(maintype, subtype)
159 msg.set_payload(fp.read())
161 # Encode the payload using Base64
162 encoders.encode_base64(msg)
163 # Set the filename parameter
164 msg.add_header('Content-Disposition', 'attachment', filename=filename)
167 # Now send or store the message
168 composed = outer.as_string()
170 fp = open(opts.output, 'w')
174 s = smtplib.SMTP(opts.mailserver)
175 s.sendmail(opts.sender, opts.recipients, composed)
179 if __name__ == '__main__':