Boost logo

Boost-Commit :

From: dgregor_at_[hidden]
Date: 2007-12-13 14:20:24


Author: dgregor
Date: 2007-12-13 14:20:23 EST (Thu, 13 Dec 2007)
New Revision: 42013
URL: http://svn.boost.org/trac/boost/changeset/42013

Log:
Send information about broken platforms to platform maintainers and the Boost testing list
Text files modified:
   trunk/tools/regression/xsl_reports/email_maintainers.py | 207 +++++++++++++++++++++++++++++++++++++++
   1 files changed, 205 insertions(+), 2 deletions(-)

Modified: trunk/tools/regression/xsl_reports/email_maintainers.py
==============================================================================
--- trunk/tools/regression/xsl_reports/email_maintainers.py (original)
+++ trunk/tools/regression/xsl_reports/email_maintainers.py 2007-12-13 14:20:23 EST (Thu, 13 Dec 2007)
@@ -16,6 +16,7 @@
 
 report_author = "Douglas Gregor <dgregor_at_[hidden]>"
 boost_dev_list = "Boost Developer List <boost_at_[hidden]>"
+boost_testing_list = "Boost Testing List <boost-testing_at_[hidden]>"
 
 def sorted_keys( dict ):
     result = dict.keys()
@@ -30,6 +31,7 @@
     def __init__(self, name):
         self.name = name
         self.failures = list()
+ self.maintainers = list()
         return
 
     def addFailure(self, failure):
@@ -39,6 +41,13 @@
     def isBroken(self):
         return len(self.failures) > 300
 
+ def addMaintainer(self, maintainer):
+ """
+ Add a new maintainer for this platform.
+ """
+ self.maintainers.append(maintainer)
+ return
+
 class Failure:
     """
     A single test case failure in the report.
@@ -200,6 +209,67 @@
 
         return message
 
+class PlatformMaintainer:
+ """
+ Information about the platform maintainer of a library
+ """
+ def __init__(self, name, email):
+ self.name = name
+ self.email = email
+ self.platforms = list()
+ return
+
+ def addPlatform(self, runner, platform):
+ self.platforms.append(platform)
+ return
+
+ def composeEmail(self, report):
+ """
+ Composes an e-mail to this platform maintainer if one or more of
+ the platforms s/he maintains has a large number of failures.
+ Returns the e-mail text if a message needs to be sent, or None
+ otherwise.
+ """
+
+ # Determine if we need to send a message to this developer.
+ requires_message = False
+ for platform in self.platforms:
+ if platform.isBroken():
+ requires_message = True
+ break
+
+ if not requires_message:
+ return None
+
+ # Build the message header
+ message = """From: Douglas Gregor <dgregor_at_[hidden]>
+To: """
+ message += self.name + ' <' + self.email + '>'
+ message += """
+Reply-To: boost_at_[hidden]
+Subject: Large number of Boost failures on a platform you maintain as of """
+ message += str(datetime.date.today()) + " [" + report.branch + "]"
+ message += """
+
+You are receiving this report because one or more of the testing
+platforms that you maintain has a large number of Boost failures that
+are not accounted for. A full version of the report is sent to the
+Boost developer's mailing list.
+
+Detailed report:
+"""
+ message += ' ' + report.url + """
+
+The following platforms have a large number of failures:
+"""
+
+ for platform in self.platforms:
+ if platform.isBroken():
+ message += (' ' + platform.name + ' ('
+ + str(len(platform.failures)) + ' failures)\n')
+
+ return message
+
 class Report:
     """
     The complete report of all failing test cases.
@@ -211,6 +281,7 @@
         self.libraries = dict()
         self.platforms = dict()
         self.maintainers = dict()
+ self.platform_maintainers = dict()
         return
 
     def getPlatform(self, name):
@@ -233,6 +304,17 @@
             self.maintainers[name] = Maintainer(name, email)
             return self.maintainers[name]
 
+ def getPlatformMaintainer(self, name, email):
+ """
+ Retrieve the platform maintainer with the given name and
+ e-mail address.
+ """
+ if self.platform_maintainers.has_key(name):
+ return self.platform_maintainers[name]
+ else:
+ self.platform_maintainers[name] = PlatformMaintainer(name, email)
+ return self.platform_maintainers[name]
+
     def parseIssuesEmail(self):
         """
         Try to parse the issues e-mail file. Returns True if everything was
@@ -317,7 +399,7 @@
             time.sleep (30)
 
         return False
-
+
     # Parses the file $BOOST_ROOT/libs/maintainers.txt to create a hash
     # mapping from the library name to the list of maintainers.
     def parseLibraryMaintainersFile(self):
@@ -329,6 +411,8 @@
         name_email_regex = re.compile('\s*(\w*(\s*\w+)+)\s*<\s*(\S*(\s*\S+)+)\S*>')
         at_regex = re.compile('\s*-\s*at\s*-\s*')
         for line in file('../../../libs/maintainers.txt', 'r'):
+ if line.startswith('#'):
+ continue
             m = lib_maintainer_regex.match (line)
             if m:
                 libname = m.group(1)
@@ -350,6 +434,41 @@
             pass
         pass
 
+ # Parses the file $BOOST_ROOT/libs/platform_maintainers.txt to
+ # create a hash mapping from the platform name to the list of
+ # maintainers.
+ def parsePlatformMaintainersFile(self):
+ """
+ Parse the platform maintainers file in
+ ../../../libs/platform_maintainers.txt to collect information
+ about the maintainers of the various platforms.
+ """
+ platform_maintainer_regex = re.compile('([A-Za-z0-9_.-]*|"[^"]*")\s+(\S+)\s+(.*)')
+ name_email_regex = re.compile('\s*(\w*(\s*\w+)+)\s*<\s*(\S*(\s*\S+)+)\S*>')
+ at_regex = re.compile('\s*-\s*at\s*-\s*')
+ for line in file('../../../libs/platform_maintainers.txt', 'r'):
+ if line.startswith('#'):
+ continue
+ m = platform_maintainer_regex.match (line)
+ if m:
+ platformname = m.group(2)
+ if self.platforms.has_key(platformname):
+ platform = self.platforms[platformname]
+ for person in re.split('\s*,\s*', m.group(3)):
+ nmm = name_email_regex.match(person)
+ if nmm:
+ name = nmm.group(1)
+ email = nmm.group(3)
+ email = at_regex.sub('@', email)
+ maintainer = self.getPlatformMaintainer(name, email)
+ maintainer.addPlatform(m.group(1), platform)
+ platform.addMaintainer(maintainer)
+ pass
+ pass
+ pass
+ pass
+ pass
+
     def numFailures(self):
         count = 0
         for library in self.libraries:
@@ -374,6 +493,8 @@
 Reply-To: boost_at_[hidden]
 Subject: [Report] """
         message += str(self.numFailures()) + " failures on " + branch
+ if branch != 'trunk':
+ message += ' branch'
         message += " (" + str(datetime.date.today()) + ")"
         message += """
 
@@ -455,6 +576,54 @@
 
         return message
 
+ def composeTestingSummaryEmail(self):
+ """
+ Compose a message to send to the Boost Testing list. Returns
+ the message text if a message is needed, returns None
+ otherwise.
+ """
+ brokenPlatforms = 0
+ for platform in sorted_keys( self.platforms ):
+ if self.platforms[platform].isBroken():
+ brokenPlatforms = brokenPlatforms + 1
+
+ if brokenPlatforms == 0:
+ return None;
+
+ message = """From: Douglas Gregor <dgregor_at_[hidden]>
+To: boost-testing_at_[hidden]
+Reply-To: boost-testing_at_[hidden]
+Subject: [Report] """
+ message += str(brokenPlatforms) + " potentially broken platforms on " + branch
+ if branch != 'trunk':
+ message += ' branch'
+ message += " (" + str(datetime.date.today()) + ")"
+ message += """
+
+Potentially broken platforms for Boost regression testing
+"""
+ message += "Report time: " + self.date + """
+
+This report lists the high-priority platforms that are exhibiting a
+large number of regresson test failures, which might indicate a problem
+with the test machines or testing harness.
+
+Detailed report:
+"""
+
+ message += ' ' + self.url + '\n'
+
+ message += """
+Platforms with a large number of failures:
+"""
+ for platform in sorted_keys( self.platforms ):
+ if self.platforms[platform].isBroken():
+ message += (' ' + platform + ' ('
+ + str(len(self.platforms[platform].failures))
+ + ' failures)\n')
+
+ return message
+
 # Send a message to "person" (a maintainer of a library that is
 # failing).
 # maintainers is the result of get_library_maintainers()
@@ -599,7 +768,9 @@
 
 # Try to parse maintainers information
 report.parseLibraryMaintainersFile()
+report.parsePlatformMaintainersFile()
 
+# Generate individualized e-mail for library maintainers
 for maintainer_name in report.maintainers:
     maintainer = report.maintainers[maintainer_name]
 
@@ -618,7 +789,27 @@
         if '--debug' in sys.argv:
             print ('Message text for ' + maintainer.name + ':\n')
             print email
-
+
+# Generate individualized e-mail for platform maintainers
+for maintainer_name in report.platform_maintainers:
+ maintainer = report.platform_maintainers[maintainer_name]
+
+ email = maintainer.composeEmail(report)
+ if email:
+ if '--send' in sys.argv:
+ print ('Sending notification email to ' + maintainer.name + '...')
+ smtp = smtplib.SMTP('milliways.osl.iu.edu')
+ smtp.sendmail(from_addr = report_author,
+ to_addrs = maintainer.email,
+ msg = email)
+ print 'done.\n'
+ else:
+ print 'Would send a notification e-mail to',maintainer.name
+
+ if '--debug' in sys.argv:
+ print ('Message text for ' + maintainer.name + ':\n')
+ print email
+
 email = report.composeSummaryEmail()
 if '--send' in sys.argv:
     print 'Sending summary email to Boost developer list...'
@@ -631,6 +822,18 @@
     print 'Message text for summary:\n'
     print email
 
+email = report.composeTestingSummaryEmail()
+if '--send' in sys.argv:
+ print 'Sending summary email to Boost testing list...'
+ smtp = smtplib.SMTP('milliways.osl.iu.edu')
+ smtp.sendmail(from_addr = report_author,
+ to_addrs = boost_testing_list,
+ msg = email)
+ print 'done.\n'
+if '--debug' in sys.argv:
+ print 'Message text for testing summary:\n'
+ print email
+
 if not ('--send' in sys.argv):
     print 'Chickening out and not sending any e-mail.'
     print 'Use --send to actually send e-mail, --debug to see e-mails.'


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk