Przeglądaj źródła

Send information about broken platforms to platform maintainers and the Boost testing list

[SVN r42013]
Douglas Gregor 18 lat temu
rodzic
commit
3ccac9c942
1 zmienionych plików z 205 dodań i 2 usunięć
  1. 205 2
      tools/regression/xsl_reports/email_maintainers.py

+ 205 - 2
tools/regression/xsl_reports/email_maintainers.py

@@ -16,6 +16,7 @@ import sys
 
 report_author = "Douglas Gregor <dgregor@osl.iu.edu>"
 boost_dev_list = "Boost Developer List <boost@lists.boost.org>"
+boost_testing_list = "Boost Testing List <boost-testing@lists.boost.org>"
 
 def sorted_keys( dict ):
     result = dict.keys()
@@ -30,6 +31,7 @@ class Platform:
     def __init__(self, name):
         self.name = name
         self.failures = list()
+        self.maintainers = list()
         return
 
     def addFailure(self, failure):
@@ -39,6 +41,13 @@ class Platform:
     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 @@ There are failures in these libraries you maintain:
 
         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@osl.iu.edu>
+To: """
+        message += self.name + ' <' + self.email + '>'
+        message += """
+Reply-To: boost@lists.boost.org
+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 @@ class Report:
         self.libraries = dict()
         self.platforms = dict()
         self.maintainers = dict()
+        self.platform_maintainers = dict()
         return
 
     def getPlatform(self, name):
@@ -233,6 +304,17 @@ class Report:
             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 @@ class Report:
             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 @@ class Report:
         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 @@ class Report:
             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 @@ To: boost@lists.boost.org
 Reply-To: boost@lists.boost.org
 Subject: [Report] """
         message += str(self.numFailures()) + " failures on " + branch
+        if branch != 'trunk':
+            message += ' branch'
         message += " (" + str(datetime.date.today()) + ")"
         message += """
 
@@ -455,6 +576,54 @@ Please see the full report for information about these failures.
 
         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@osl.iu.edu>
+To: boost-testing@lists.boost.org
+Reply-To: boost-testing@lists.boost.org
+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 @@ if not okay:
 
 # 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 @@ for maintainer_name in report.maintainers:
         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 @@ if '--debug' in sys.argv:
     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.'

粤ICP备19079148号