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