[Checkins] SVN: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/ - Incorporating changes after 1st code review by

Matthew Grant grantma at anathoth.gen.nz
Mon Mar 24 18:17:38 EDT 2008


Log message for revision 84908:
  - Incorporating changes after 1st code review by 
    Marius Gedminas
  

Changed:
  U   zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/configure.zcml
  U   zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/delivery.py
  U   zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/interfaces.py
  U   zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/maildir.py
  U   zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/mailer.py
  U   zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/tests/test_delivery.py
  U   zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/tests/test_mailer.py
  U   zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/zcml.py

-=-
Modified: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/configure.zcml
===================================================================
--- zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/configure.zcml	2008-03-24 16:56:14 UTC (rev 84907)
+++ zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/configure.zcml	2008-03-24 22:17:32 UTC (rev 84908)
@@ -16,7 +16,7 @@
     To send mail, uncomment the following directive and be sure to
     create the queue directory. 
     
-    Other parameters sepcify the polling interval, and the retry 
+    Other parameters specify the polling interval, and the retry 
     interval used when a temporary failure is detected.  Lock links
     can also be cleared on server start.
 
@@ -24,8 +24,8 @@
                       queuePath="./queue"
                       retryInterval="300"
                       pollingInterval="3000"
-	              cleanLockLinks="False"
-		      mailer="smtp" />
+                      cleanLockLinks="False"
+                      mailer="smtp" />
    -->
 
   <interface interface="zope.sendmail.interfaces.IMailDelivery" />

Modified: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/delivery.py
===================================================================
--- zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/delivery.py	2008-03-24 16:56:14 UTC (rev 84907)
+++ zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/delivery.py	2008-03-24 22:17:32 UTC (rev 84908)
@@ -22,6 +22,7 @@
 import atexit
 import logging
 import os
+import errno
 import os.path
 import rfc822
 import stat
@@ -36,8 +37,8 @@
 from zope.interface.exceptions import DoesNotImplement
 from zope.sendmail.interfaces import IDirectMailDelivery, IQueuedMailDelivery
 from zope.sendmail.interfaces import ISMTPMailer, IMailer
-from zope.sendmail.interfaces import MailerTemporaryFailureException
-from zope.sendmail.interfaces import MailerPermanentFailureException
+from zope.sendmail.interfaces import MailerTemporaryError
+from zope.sendmail.interfaces import MailerPermanentError
 from zope.sendmail.maildir import Maildir
 from transaction.interfaces import IDataManager
 import transaction
@@ -241,13 +242,12 @@
         self.maildir = Maildir(path, True)
 
     def setMailer(self, mailer):
-        if not(IMailer.providedBy(mailer)):
+        if not IMailer.providedBy(mailer):
             raise (DoesNotImplement)
         self.mailer = mailer
 
     def _parseMessage(self, message):
-        """Extract fromaddr and toaddrs from the first two lines of
-        the `message`.
+        """Extract fromaddr and toaddrs from first two lines of the `message`.
 
         Returns a fromaddr string, a toaddrs tuple and the message
         string.
@@ -277,26 +277,30 @@
         try:
             os.unlink(filename)
         except OSError, e:
-            if e.errno == 2: # file does not exist
+            if e.errno == errno.ENOENT: # file does not exist
                 # someone else unlinked the file; oh well
                 pass
             else:
-                # something bad happend, log it
+                # something bad happened, log it
                 raise
 
     def _queueRetryWait(self, tmp_filename, forever):
-        """Implements Retry Wait if there is an SMTP Connection
-           Failure or error 4xx due to machine load etc
+        """Implements Retry Wait
+        
+        This is can be due to an SMTP Connection Failure or error 4xx
+        due to machine load etc
         """
         # Clean up by unlinking lock link
         self._unlinkFile(tmp_filename)
         # Wait specified retry interval in stages of self.interval
         count = self.retry_interval
-        while(count > 0 and not self.__stopped):
+        while count > 0 and not self.__stopped:
             if forever:
                 time.sleep(self.interval)
             count -= self.interval
         # Plug for test routines so that we know we got here
+        # We want to definitvely test that above count down code is
+        # functioning - can't have unit test code taking 10 minutes!
         if not forever:
             self.test_results['_queueRetryWait'] \
                     = "Retry timeout: %s count: %s" \
@@ -322,7 +326,7 @@
                 head, tail = os.path.split(filename)
                 tmp_filename = os.path.join(head, SENDING_MSG_LOCK_PREFIX + tail)
                 rejected_filename = os.path.join(head, REJECTED_MSG_PREFIX + tail)
-                message_id = os.path.basename(filename)
+                queue_id = os.path.basename(filename)
                 try:
                     # perform a series of operations in an attempt to ensure
                     # that no two threads/processes send this message
@@ -336,7 +340,7 @@
                         mtime = os.stat(tmp_filename)[stat.ST_MTIME]
                         age = time.time() - mtime
                     except OSError, e:
-                        if e.errno == 2: # file does not exist
+                        if e.errno == errno.ENOENT: # file does not exist
                             # the tmp file could not be stated because it
                             # doesn't exist, that's fine, keep going
                             pass
@@ -361,7 +365,7 @@
                             # if we get here, the file existed, but was too
                             # old, so it was unlinked
                         except OSError, e:
-                            if e.errno == 2: # file does not exist
+                            if e.errno == errno.ENOENT: # file does not exist
                                 # it looks like someone else removed the tmp
                                 # file, that's fine, we'll try to deliver the
                                 # message again later
@@ -375,7 +379,7 @@
                     try:
                         os.utime(filename, None)
                     except OSError, e:
-                        if e.errno == 2: # file does not exist
+                        if e.errno == errno.ENOENT: # file does not exist
                             # someone removed the message before we could
                             # touch it, no need to complain, we'll just keep
                             # going
@@ -386,7 +390,7 @@
                     try:
                         os.link(filename, tmp_filename)
                     except OSError, e:
-                        if e.errno == 17: # file exists
+                        if e.errno == errno.EEXIST: # file exists
                             # it looks like someone else is sending this
                             # message too; we'll try again later
                             continue
@@ -400,12 +404,12 @@
                         sentaddrs = self.mailer.send(fromaddr,
                                                      toaddrs,
                                                      message,
-                                                     message_id)
-                    except MailerTemporaryFailureException, e:
+                                                     queue_id)
+                    except MailerTemporaryError, e:
                         self._queueRetryWait(tmp_filename, forever)
                         # We break as we don't want to send message later
-                        break;
-                    except MailerPermanentFailureException, e:
+                        break
+                    except MailerPermanentError, e:
                         os.link(filename, rejected_filename)
                         sentaddrs = []
 
@@ -418,7 +422,7 @@
                     # TODO: maybe log the Message-Id of the message sent
                     if len(sentaddrs) > 0:
                         self.log.info("%s - mail sent, Sender: %s, Rcpt: %s,",
-                                      message_id,
+                                      queue_id,
                                       fromaddr,
                                       ", ".join(sentaddrs))
                     # Blanket except because we don't want
@@ -428,14 +432,14 @@
                         self.log.error(
                             "%s - Error while sending mail, Sender: %s,"
                             " Rcpt: %s,",
-                            message_id,
+                            queue_id,
                             fromaddr,
                             ", ".join(toaddrs),
                             exc_info=True)
                     else:
                         self.log.error(
                             "%s - Error while sending mail.",
-                            message_id,
+                            queue_id,
                             exc_info=True)
             else:
                 if forever:

Modified: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/interfaces.py
===================================================================
--- zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/interfaces.py	2008-03-24 16:56:14 UTC (rev 84907)
+++ zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/interfaces.py	2008-03-24 22:17:32 UTC (rev 84908)
@@ -141,42 +141,46 @@
 #
 class IMailerFailureException(IException):
     """Failure in sending mail"""
-    pass
 
+
 class MailerFailureException(Exception):
     """Failure in sending mail"""
 
     implements(IMailerFailureException)
 
     def __init__(self, message="Failure in sending mail"):
+        """Embeds new default exception message text"""
         self.message = message
         self.args = (message,)
 
 
-class IMailerTemporaryFailureException(IMailerFailureException):
+class IMailerTemporaryError(IMailerFailureException):
     """Temporary failure in sending mail - retry later"""
-    pass
 
-class MailerTemporaryFailureException(MailerFailureException):
+
+class MailerTemporaryError(MailerFailureException):
     """Temporary failure in sending mail - retry later"""
 
-    implements(IMailerTemporaryFailureException)
+    implements(IMailerTemporaryError)
 
     def __init__(self, message="Temporary failure in sending mail - retry later"):
+        """Embeds new default exception message text"""
         self.message = message
         self.args = (message,)
 
 
-class IMailerPermanentFailureException(IMailerFailureException):
+class IMailerPermanentError(IMailerFailureException):
     """Permanent failure in sending mail - take reject action"""
-    pass
 
-class MailerPermanentFailureException(MailerFailureException):
+
+class MailerPermanentError(MailerFailureException):
     """Permanent failure in sending mail - take reject action"""
 
-    implements(IMailerPermanentFailureException)
+    implements(IMailerPermanentError)
 
-    def __init__(self, message="Permanent failure in sending mail - take reject action"):
+    def __init__(self,
+            message="Permanent failure in sending mail - take reject action"):
+        """Embeds new default exception message text"""
         self.message = message
         self.args = (message,)
 
@@ -186,13 +190,13 @@
 
     Mailer can raise the exceptions
 
-        MailerPermanentFailure
-        MailerTemporaryFailure
+        MailerPermanentError
+        MailerTemporaryError
 
     to indicate to sending process what action to take.
     """
 
-    def send(fromaddr, toaddrs, message, message_id):
+    def send(fromaddr, toaddrs, message, queue_id):
         """Send an email message.
 
         `fromaddr` is the sender address (unicode string),
@@ -203,7 +207,7 @@
         2822.  It should contain at least Date, From, To, and Message-Id
         headers.
 
-        `message_id` is an id for the message, typically a filename.
+        `queue_id` is an id for the message, typically a filename.
 
         Messages are sent immediatelly.
 
@@ -212,10 +216,16 @@
         """
 
     def set_logger(logger):
-        """Set the log object for the Mailer - this is for use by
-           QueueProcessorThread to hand a logging object to the mailer
+        """Set the logger for additional messages.
+        
+        The additional messages include information about SMTP
+        errors, connection timeouts, etc.
+        
+        The logger should be a logging.Logger object.  If you pass None,
+        no messages will be logged.
         """
 
+
 class ISMTPMailer(IMailer):
     """A mailer that delivers mail to a relay host via SMTP."""
 

Modified: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/maildir.py
===================================================================
--- zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/maildir.py	2008-03-24 16:56:14 UTC (rev 84907)
+++ zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/maildir.py	2008-03-24 22:17:32 UTC (rev 84908)
@@ -91,7 +91,7 @@
             try:
                 os.unlink(link)
             except OSError, e:
-                if e.errno == 2: # file does not exist
+                if e.errno == errno.ENOENT: # file does not exist
                     # someone else unlinked the file; oh well
                     pass
                 else:

Modified: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/mailer.py
===================================================================
--- zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/mailer.py	2008-03-24 16:56:14 UTC (rev 84907)
+++ zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/mailer.py	2008-03-24 22:17:32 UTC (rev 84908)
@@ -25,9 +25,9 @@
 
 from zope.interface import implements
 from zope.interface.exceptions import DoesNotImplement
-from zope.sendmail.interfaces import (ISMTPMailer, 
-                                      MailerTemporaryFailureException,
-                                      MailerPermanentFailureException)
+from zope.sendmail.interfaces import (ISMTPMailer,
+                                      MailerTemporaryError,
+                                      MailerPermanentError)
 
 SMTP_ERR_MEDIUM_LOG_MSG = '%s - SMTP Error: %s - %s, %s'
 SMTP_ERR_SERVER_LOG_MSG = '%s - SMTP server %s:%s - %s'
@@ -35,6 +35,7 @@
 
 have_ssl = hasattr(socket, 'ssl')
 
+
 class SMTPMailer(object):
 
     implements(ISMTPMailer)
@@ -52,102 +53,118 @@
         self.logger = None
 
     def set_logger(self, logger):
-        if not isinstance(logger, logging.Logger):
-            raise DoesNotImplement('Invalid logger given')
         self.logger = logger
 
     def _log(self, log_level, *args):
         if self.logger is None:
             return
-        # This is not elegant, but it can be fixed later
-        if log_level == 'debug':
-            self.logger.debug(*args)
-        elif log_level =='info':
-            self.logger.info(*args)
-        elif log_level =='error':
-            self.logger.error(*args)
-        elif log_level =='warning':
-            self.logger.warning(*args)
+        self.logger.log(log_level, *args)
 
     def _handle_smtp_error(self,
                            smtp_code,
                            smtp_error,
                            fromaddr,
                            toaddrs,
-                           message_id):
-        """Process results of an SMTP error
-           returns True to indicate break needed"""
+                           queue_id):
+        """
+        Process results of an SMTP error
+
+        Returns True to indicate break needed
+        """
         if 500 <= smtp_code <= 599:
             # permanent error, ditch the message
-            self._log('warning',
+            self._log(logging.WARNING,
                 SMTP_ERR_LOG_MSG,
-                message_id,
+                queue_id,
                 str(smtp_code),
                 smtp_error,
                 fromaddr,
                 ", ".join(toaddrs))
-            raise MailerPermanentFailureException()
+            raise MailerPermanentError()
         elif 400 <= smtp_code <= 499:
             # Temporary error
-            self._log('warning',
+            self._log(logging.WARNING,
                 SMTP_ERR_LOG_MSG,
-                message_id,
+                queue_id,
                 str(smtp_code),
                 smtp_error,
                 fromaddr,
                 ", ".join(toaddrs))
             # temporary failure, go and sleep for 
             # retry_interval
-            raise MailerTemporaryFailureException()
+            raise MailerTemporaryError()
         else:
-            self._log('warning',
+            self._log(logging.WARNING,
                 SMTP_ERR_LOG_MSG,
-                message_id,
+                queue_id,
                 str(smtp_code),
                 smtp_error,
                 fromaddr,
                 ", ".join(toaddrs))
-            raise MailerTemporaryFailureException()
+            raise MailerTemporaryError()
 
-    def send(self, fromaddr, toaddrs, message, message_id):
+    def _handle_smtp_recipients_refused(self, e, fromaddr,
+                                        toaddrs, queue_id):
+            # This exception is raised because no recipients
+            # were acceptable - lets take the most common error
+            # code and proceed with that
+            freq = {}
+            for result in e.recipients.values():
+                if freq.has_key(result):
+                    freq[result] += 1
+                else:
+                    freq[result] = 1
+            max_ = 0
+            for result in freq.keys():
+                if freq[result] > max_:
+                    most_common = result
+                    max_ = freq[result]
+            (smtp_code, smtp_error) = most_common
+            self._handle_smtp_error(smtp_code,
+                                      smtp_error,
+                                      fromaddr,
+                                      toaddrs,
+                                      queue_id)
+
+    def send(self, fromaddr, toaddrs, message, queue_id):
         try:
             connection = self.smtp(self.hostname, str(self.port))
         except socket.error, e:
-            self._log('info',
+            self._log(logging.INFO,
                 "%s - SMTP server %s:%s - could not connect(),"
                 " %s.",
-                message_id,
+                queue_id,
                 self.hostname,
                 str(self.port),
                 str(e),)
             # temporary failure, go and sleep for 
             # retry_interval
-            raise MailerTemporaryFailureException()
+            raise MailerTemporaryError()
 
         # send EHLO
         code, response = connection.ehlo()
         if code < 200 or code >= 300:
             code, response = connection.helo()
             if code < 200 or code >= 300:
-                self._log('warning',
+                self._log(logging.WARNING,
                           SMTP_ERR_MEDIUM_LOG_MSG,
-                          message_id,
+                          queue_id,
                           code,
                           str(response),
                           'error sending HELO')
-                raise MailerTemporaryFailureException()
+                raise MailerTemporaryError()
 
         # encryption support
         have_tls = connection.has_extn('starttls')
         if not have_tls and self.force_tls:
             error_str = 'TLS is not available but TLS is required'
-            self._log('warning',
+            self._log(logging.WARNING,
                       SMTP_ERR_SERVER_LOG_MSG,
-                      message_id,
+                      queue_id,
                       self.hostname,
                       self.port,
                       error_str)
-            raise MaileriTemporaryFailure(error_str)
+            raise MailerTemporaryFailure(error_str)
 
         if have_tls and have_ssl and not self.no_tls:
             connection.starttls()
@@ -159,27 +176,28 @@
         elif self.username:
             error_str = 'Mailhost does not support ESMTP but a username ' \
                         'is configured'
-            self._log('warning',
+            self._log(logging.WARNING,
                       SMTP_ERR_SERVER_LOG_MSG,
-                      message_id,
+                      queue_id,
                       self.hostname,
                       self.port,
                       error_str)
-            raise MailerTemporaryFailureException(error_str)
+            raise MailerTemporaryError(error_str)
 
+        send_errors = None
         try:
             send_errors = connection.sendmail(fromaddr, toaddrs, message)
         except smtplib.SMTPSenderRefused, e:
-            self._log('warning',
+            self._log(logging.WARNING,
                 SMTP_ERR_LOG_MSG,
-                message_id,
+                queue_id,
                 str(e.smtp_code),
                 e.smtp_error,
                 e.sender,
                 ", ".join(toaddrs))
             # temporary failure, go and sleep for 
             # retry_interval
-            raise MailerTemporaryFailureException()
+            raise MailerTemporaryError()
         except (smtplib.SMTPAuthenticationError,
                 smtplib.SMTPConnectError,
                 smtplib.SMTPDataError,
@@ -189,58 +207,40 @@
                                       e.smtp_error,
                                       fromaddr,
                                       toaddrs,
-                                      message_id)
+                                      queue_id)
         except smtplib.SMTPServerDisconnected, e:
-            self._log('info',
+            self._log(logging.INFO,
                 SMTP_ERR_SERVER_LOG_MSG,
-                message_id,
+                queue_id,
                 self.hostname,
                 str(self.port),
                 str(e))
             # temporary failure, go and sleep for 
             # retry_interval
-            raise MailerTemporaryFailureException()
+            raise MailerTemporaryError()
         except smtplib.SMTPRecipientsRefused, e:
-            # This exception is raised because no recipients
-            # were acceptable - lets take the most common error
-            # code and proceed with that
-            freq = {}
-            for result in e.recipients.values():
-                if freq.has_key(result):
-                    freq[result] += 1
-                else:
-                    freq[result] = 1
-            max_ = 0
-            for result in freq.keys():
-                if freq[result] > max_:
-                    most_common = result
-                    max_ = freq[result]
-            (smtp_code, smtp_error) = most_common
-            self._handle_smtp_error(smtp_code,
-                                      smtp_error,
-                                      fromaddr,
-                                      toaddrs,
-                                      message_id)
+            self._handle_smtp_recipients_refused(e, fromaddr,
+                                                 toaddrs, queue_id)
         except smtplib.SMTPException, e:
             # Permanent SMTP failure
-            self._log('warning',
+            self._log(logging.WARNING,
                 '%s - SMTP failure: %s',
-                message_id,
+                queue_id,
                 str(e))
-            raise MailerPermanentFailureException()
+            raise MailerPermanentError()
 
         connection.quit()
 
         # Log ANY errors
         if send_errors is not None:
             sentaddrs = [x for x in toaddrs
-                         if x not in send_errors.keys()]
-            for address in send_errors.keys():
-                self._log('warning',
+                         if x not in send_errors]
+            for address, (smtp_code, smtp_error) in send_errors.items():
+                self._log(logging.WARNING,
                     SMTP_ERR_LOG_MSG,
-                    message_id,
-                    str(send_errors[address][0]),
-                    send_errors[address][1],
+                    queue_id,
+                    str(smtp_code),
+                    smtp_error,
                     fromaddr,
                     address)
         else:

Modified: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/tests/test_delivery.py
===================================================================
--- zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/tests/test_delivery.py	2008-03-24 16:56:14 UTC (rev 84907)
+++ zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/tests/test_delivery.py	2008-03-24 22:17:32 UTC (rev 84908)
@@ -21,7 +21,7 @@
 import os.path
 import shutil
 import smtplib
-from socket import error as socket_error
+import logging
 from tempfile import mkdtemp
 from unittest import TestCase, TestSuite, makeSuite
 
@@ -30,8 +30,8 @@
 from zope.interface import implements
 from zope.interface.verify import verifyObject
 from zope.sendmail.interfaces import IMailer, ISMTPMailer
-from zope.sendmail.interfaces import MailerTemporaryFailureException
-from zope.sendmail.interfaces import MailerPermanentFailureException
+from zope.sendmail.interfaces import MailerTemporaryError
+from zope.sendmail.interfaces import MailerPermanentError
 
 
 class MailerStub(object):
@@ -40,7 +40,7 @@
     def __init__(self, *args, **kw):
         self.sent_messages = []
 
-    def send(self, fromaddr, toaddrs, message, message_id):
+    def send(self, fromaddr, toaddrs, message, queue_id):
         self.sent_messages.append((fromaddr, toaddrs, message))
         return toaddrs
 
@@ -223,7 +223,15 @@
     def info(self, msg, *args, **kwargs):
         self.infos.append((msg, args, kwargs))
 
+    def log(self, level, msg, *args, **kwargs):
+        if level == logging.ERROR:
+                self.errors.append((msg, args, kwargs)),
+        elif level == logging.WARNING:
+                self.warnings.append((msg, args, kwargs))
+        elif level ==logging.INFO:
+                self.infos.append((msg, args, kwargs))
 
+
 class BizzarreMailError(IOError):
     pass
 
@@ -234,28 +242,28 @@
     def __init__(self, *args, **kw):
         pass
 
-    def send(self, fromaddr, toaddrs, message, message_id):
+    def send(self, fromaddr, toaddrs, message, queue_id):
         raise BizzarreMailError("bad things happened while sending mail")
 
 
-class MailerPermanentFailureExceptionMailerStub(object):
+class MailerPermanentErrorMailerStub(object):
 
     implements(IMailer)
     def __init__(self, msg='Permanent failure'):
         self.msg = msg
 
-    def send(self, fromaddr, toaddrs, message, message_id):
-        raise MailerPermanentFailureException(self.msg)
+    def send(self, fromaddr, toaddrs, message, queue_id):
+        raise MailerPermanentError(self.msg)
 
 
-class MailerTemporaryFailureExceptionMailerStub(object):
+class MailerTemporaryErrorMailerStub(object):
 
     implements(IMailer)
     def __init__(self, msg='Temporary failure'):
         self.msg = msg
 
-    def send(self, fromaddr, toaddrs, message, message_id):
-        raise MailerTemporaryFailureException(self.msg)
+    def send(self, fromaddr, toaddrs, message, queue_id):
+        raise MailerTemporaryError(self.msg)
 
 
 class TestQueuedMailDelivery(TestCase):
@@ -430,7 +438,7 @@
     def test_mailer_temporary_failure(self):
         # Test a transient error
         self.thread.log = LoggerStub()          # Clean log
-        self.thread.setMailer(MailerTemporaryFailureExceptionMailerStub())
+        self.thread.setMailer(MailerTemporaryErrorMailerStub())
         self.filename = os.path.join(self.dir, 'message')
         self.tmp_filename = os.path.join(self.dir, '.sending-message')
         temp = open(self.filename, "w+b")
@@ -451,7 +459,7 @@
     def test_mailer_permanent_failure(self):
         # Test a permanent error
         self.thread.log = LoggerStub()          # Clean log
-        self.thread.setMailer(MailerPermanentFailureExceptionMailerStub())
+        self.thread.setMailer(MailerPermanentErrorMailerStub())
         self.filename = os.path.join(self.dir, 'message')
         self.tmp_filename = os.path.join(self.dir, '.sending-message')
         temp = open(self.filename, "w+b")

Modified: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/tests/test_mailer.py
===================================================================
--- zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/tests/test_mailer.py	2008-03-24 16:56:14 UTC (rev 84907)
+++ zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/tests/test_mailer.py	2008-03-24 22:17:32 UTC (rev 84908)
@@ -25,8 +25,8 @@
 from zope.interface.verify import verifyObject
 
 from zope.sendmail.interfaces import (ISMTPMailer,
-                                      MailerTemporaryFailureException,
-                                      MailerPermanentFailureException)
+                                      MailerTemporaryError,
+                                      MailerPermanentError)
 from zope.sendmail.mailer import SMTPMailer
 from zope.sendmail.tests.test_delivery import LoggerStub
 
@@ -38,7 +38,7 @@
         self.test_kwargs = {'fromaddr': 'me at example.com',
                           'toaddrs': ('you at example.com', 'him at example.com'),
                           'message': 'Headers: headers\n\nbodybodybody\n-- \nsig\n',
-                          'message_id': 'dummy_file_name_XXX345YZ'}
+                          'queue_id': 'dummy_file_name_XXX345YZ'}
 
     def setUp(self, port=None, exception=None, exception_args=None, 
               send_errors=None):
@@ -61,6 +61,8 @@
                 self.fromaddr = f
                 self.toaddrs = t
                 self.msgtext = m
+                # This code is like this so that multiple classes are 
+                # not neeeded
                 if hasattr(self, '_exception'):
                     if self._exception and issubclass(self._exception, Exception):
                         if hasattr(self, '_exception_args') \
@@ -107,10 +109,12 @@
         test_mailer = SMTPMailer()
         log_object = logging.getLogger('test_logger')
         test_mailer.set_logger(log_object)
-        self.assertEquals(isinstance(test_mailer.logger, logging.Logger), True)
+        self.assertTrue(isinstance(test_mailer.logger, logging.Logger))
 
     def test_send(self):
         for run in (1,2):
+            # run self.setUp() to reinitialise target host and port
+            # as required by this test, other tests MAY have messed with things
             if run == 2:
                 self.setUp(u'25')
             else:
@@ -126,10 +130,8 @@
     def test_mailer_no_connect(self):
         # set up test value to raise socket.error exception
         self.setUp('0')
-        try:
-            self.mailer.send(**self.test_kwargs)
-        except MailerTemporaryFailureException:
-            pass
+        self.assertRaises(MailerTemporaryError,
+                             self.mailer.send, **self.test_kwargs)
         self.assertEquals(self.mailer.logger.infos,
                          [('%s - SMTP server %s:%s - could not connect(), %s.',
                            ('dummy_file_name_XXX345YZ', u'localhost', '0',
@@ -138,10 +140,8 @@
     def test_mailer_smtp_data_error(self):
         self.setUp(exception=smtplib.SMTPDataError,
                    exception_args=(471, 'SMTP Data Error'))
-        try:
-            self.mailer.send(**self.test_kwargs)
-        except MailerTemporaryFailureException:
-            pass
+        self.assertRaises(MailerTemporaryError,
+                             self.mailer.send, **self.test_kwargs)
         self.assertEquals(self.mailer.logger.warnings,
                 [('%s - SMTP Error: %s - %s, Sender: %s, Rcpt: %s',
                   ('dummy_file_name_XXX345YZ', '471', 'SMTP Data Error',
@@ -152,10 +152,8 @@
     def test_mailer_smtp_really_bad_error(self):
         self.setUp(exception=smtplib.SMTPResponseException,
                    exception_args=(550, 'SMTP Really Bad Error'))
-        try:
-            self.mailer.send(**self.test_kwargs)
-        except MailerPermanentFailureException:
-            pass
+        self.assertRaises(MailerPermanentError,
+                             self.mailer.send, **self.test_kwargs)
         self.assertEquals(self.mailer.logger.warnings,
                 [('%s - SMTP Error: %s - %s, Sender: %s, Rcpt: %s',
                   ('dummy_file_name_XXX345YZ', '550', 'SMTP Really Bad Error',
@@ -165,10 +163,8 @@
     def test_mailer_smtp_crazy_error(self):
         self.setUp(exception=smtplib.SMTPResponseException,
                    exception_args=(200, 'SMTP Crazy Error'))
-        try:
-            self.mailer.send(**self.test_kwargs)
-        except MailerTemporaryFailureException:
-            pass
+        self.assertRaises(MailerTemporaryError,
+                             self.mailer.send, **self.test_kwargs)
         self.assertEquals(self.mailer.logger.warnings,
                 [('%s - SMTP Error: %s - %s, Sender: %s, Rcpt: %s',
                   ('dummy_file_name_XXX345YZ', '200', 'SMTP Crazy Error',
@@ -178,10 +174,8 @@
     def test_mailer_smtp_server_disconnected(self):
         self.setUp(exception=smtplib.SMTPServerDisconnected,
                    exception_args=('TCP RST - unexpected dissconnection',))
-        try:
-            self.mailer.send(**self.test_kwargs)
-        except MailerTemporaryFailureException:
-            pass
+        self.assertRaises(MailerTemporaryError,
+                             self.mailer.send, **self.test_kwargs)
         self.assertEquals(self.mailer.logger.infos,
             [('%s - SMTP server %s:%s - %s',
               ('dummy_file_name_XXX345YZ',
@@ -193,10 +187,8 @@
         self.setUp(exception=smtplib.SMTPSenderRefused,
                    exception_args=(550, 'SMTP Sender Refused',
                                    'iamasender at bogus.com'))
-        try:
-            self.mailer.send(**self.test_kwargs)
-        except MailerTemporaryFailureException:
-            pass
+        self.assertRaises(MailerTemporaryError,
+                             self.mailer.send, **self.test_kwargs)
         self.assertEquals(self.mailer.logger.warnings,
             [('%s - SMTP Error: %s - %s, Sender: %s, Rcpt: %s',
               ('dummy_file_name_XXX345YZ', '550', 'SMTP Sender Refused',
@@ -207,10 +199,8 @@
         self.setUp(exception=smtplib.SMTPRecipientsRefused,
          exception_args=({'you at example.com': (451, 'SMTP Recipient A Refused'),
                      'him at example.com': (450, 'SMTP Recipient B Refused')},))
-        try:
-            self.mailer.send(**self.test_kwargs)
-        except MailerTemporaryFailureException:
-            pass
+        self.assertRaises(MailerTemporaryError,
+                             self.mailer.send, **self.test_kwargs)
         self.assertEquals(self.mailer.logger.warnings,
             [('%s - SMTP Error: %s - %s, Sender: %s, Rcpt: %s',
               ('dummy_file_name_XXX345YZ', '450', 'SMTP Recipient B Refused',
@@ -220,10 +210,8 @@
     def test_mailer_smtp_exception(self):
         self.setUp(exception=smtplib.SMTPException,
                    exception_args=('SMTP Permanent Failure',))
-        try:
-            self.mailer.send(**self.test_kwargs)
-        except MailerPermanentFailureException:
-            pass
+        self.assertRaises(MailerPermanentError,
+                             self.mailer.send, **self.test_kwargs)
         self.assertEquals(self.mailer.logger.warnings,
             [('%s - SMTP failure: %s',
               ('dummy_file_name_XXX345YZ',

Modified: zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/zcml.py
===================================================================
--- zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/zcml.py	2008-03-24 16:56:14 UTC (rev 84907)
+++ zope.sendmail/branches/grantma-retryfixes/src/zope/sendmail/zcml.py	2008-03-24 22:17:32 UTC (rev 84908)
@@ -110,7 +110,7 @@
         if mailerObject is None:
             raise ConfigurationError("Mailer %r is not defined" % mailer)
 
-        thread = QueueProcessorThread(interval=pollingInterval/1000,
+        thread = QueueProcessorThread(interval=pollingInterval/1000.0,
                                       retry_interval=retryInterval,
                                       clean_lock_links=cleanLockLinks)
         thread.setMailer(mailerObject)



More information about the Checkins mailing list