]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - utils/test/ras.py
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / utils / test / ras.py
1 #!/usr/bin/env python
2
3 """
4 Run the test suite and send the result as an email message.
5
6 The code for sending of the directory is copied from
7 http://docs.python.org/library/email-examples.html.
8 """
9
10 import os
11 import sys
12 import shutil
13 import smtplib
14 # For guessing MIME type based on file name extension
15 import mimetypes
16
17 from optparse import OptionParser
18
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
26
27
28 def runTestsuite(testDir, sessDir, envs=None):
29     """Run the testsuite and return a (summary, output) tuple."""
30     os.chdir(testDir)
31
32     for env in envs:
33         list = env.split('=')
34         var = list[0].strip()
35         val = list[1].strip()
36         print var + "=" + val
37         os.environ[var] = val
38
39     import shlex
40     import subprocess
41
42     command_line = "./dotest.py -w -s %s" % sessDir
43     # Apply correct tokenization for subprocess.Popen().
44     args = shlex.split(command_line)
45
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()
51
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)
54
55     return (cmd, stderr)
56
57
58 COMMASPACE = ', '
59
60
61 def main():
62     parser = OptionParser(usage="""\
63 Run lldb test suite and send the results as a MIME message.
64
65 Usage: %prog [options]
66
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.
69 """)
70     parser.add_option('-d', '--directory',
71                       type='string', action='store',
72                       dest='testDir',
73                       help="""The LLDB test directory directly under the top dir.
74                       Otherwise use the current directory.""")
75     #
76     # This is similar to TestBase.getRunSpec(self) from lldbtest.py.
77     #
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',
85                       dest='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:
100         parser.print_help()
101         sys.exit(1)
102     testDir = opts.testDir
103     if not testDir:
104         testDir = '.'
105
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)
111
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'
118
119     # The sessDir contains all the session logs for failed/errored tests.
120     # Attach them all if it exists!
121
122     if not os.path.exists(sessDir):
123         outer.attach(MIMEText(output, 'plain'))
124     else:
125         outer.attach(
126             MIMEText(
127                 "%s\n%s\n\n" %
128                 (output, "Session logs of test failures/errors:"), 'plain'))
129
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):
133             continue
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':
144             fp = open(path)
145             # Note: we should handle calculating the charset
146             msg = MIMEText(fp.read(), _subtype=subtype)
147             fp.close()
148         elif maintype == 'image':
149             fp = open(path, 'rb')
150             msg = MIMEImage(fp.read(), _subtype=subtype)
151             fp.close()
152         elif maintype == 'audio':
153             fp = open(path, 'rb')
154             msg = MIMEAudio(fp.read(), _subtype=subtype)
155             fp.close()
156         else:
157             fp = open(path, 'rb')
158             msg = MIMEBase(maintype, subtype)
159             msg.set_payload(fp.read())
160             fp.close()
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)
165         outer.attach(msg)
166
167     # Now send or store the message
168     composed = outer.as_string()
169     if opts.output:
170         fp = open(opts.output, 'w')
171         fp.write(composed)
172         fp.close()
173     else:
174         s = smtplib.SMTP(opts.mailserver)
175         s.sendmail(opts.sender, opts.recipients, composed)
176         s.quit()
177
178
179 if __name__ == '__main__':
180     main()