Changeset 32 for branches

Show
Ignore:
Timestamp:
10/16/07 03:51:19 (1 year ago)
Author:
amcgregor
Message:

Applied smtpfrom_fix.patch and smtpfrom_test.patch as per ticket #12, and fixed indentation style in several files.

Location:
branches/2.0.5
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • branches/2.0.5/tests/basic_tests.py

    r31 r32  
    7777                assert 'Hello World' in msg.get_payload()  
    7878 
    79     def test_add_custom_headers_dict(self): 
    80         "Test that custom headers (dict type) can be attached." 
    81         extra_headers = {'Precendence': 'bulk', 'X-User': 'Alice'} 
    82         message = turbomail.Message('sender@foo.example',  
    83                                     'recipient@foo.example', 'foo bar') 
    84         message.plain = 'Hello World!' 
    85         message.headers = extra_headers 
    86         turbomail.enqueue(message) 
    87         msginfo = get_received_mail(self.sink) 
    88         msg = email.message_from_string(msginfo['mail'])  
    89         for header_name in extra_headers.keys(): 
    90             self.failUnless(msg.has_key(header_name)) 
    91             self.assertEquals(extra_headers[header_name], msg[header_name]) 
     79        def test_smtpfrom(self): 
     80                "Test that smtpfrom is being honored and used as envelope sender." 
     81                sender = 'sender@foo.example' 
     82                recipient = 'recipient@foo.example' 
     83                subject = 'foo bar' 
     84                smtpfrom = 'devnull@foo.example' 
     85                message = turbomail.Message(sender, recipient, subject,  
     86                                                                        smtpfrom=smtpfrom) 
     87                message.plain = 'Hello World!'             
     88                turbomail.enqueue(message) 
     89                msginfo = get_received_mail(self.sink) 
     90                self.assertEqual(smtpfrom, msginfo['from']) 
     91                self.assertEqual([recipient], msginfo['recipients']) 
    9292 
    93     def test_add_custom_headers_tuple(self): 
    94         "Test that a custom header (tuple type) can be attached." 
    95         extra_headers = (('Precendence', 'bulk'), ('X-User', 'Alice')) 
    96         message = turbomail.Message('sender@foo.example',  
    97                                     'recipient@foo.example', 'foo bar') 
    98         message.plain = 'Hello World!' 
    99         message.headers = extra_headers 
    100         turbomail.enqueue(message) 
    101         msginfo = get_received_mail(self.sink) 
    102         msg = email.message_from_string(msginfo['mail'])  
    103         for name, value in extra_headers: 
    104             self.failUnless(msg.has_key(name)) 
    105             self.assertEquals(value, msg[name]) 
     93        def test_add_custom_headers_dict(self): 
     94                "Test that custom headers (dict type) can be attached." 
     95                extra_headers = {'Precendence': 'bulk', 'X-User': 'Alice'} 
     96                message = turbomail.Message('sender@foo.example',  
     97                                                                        'recipient@foo.example', 'foo bar') 
     98                message.plain = 'Hello World!' 
     99                message.headers = extra_headers 
     100                turbomail.enqueue(message) 
     101                msginfo = get_received_mail(self.sink) 
     102                msg = email.message_from_string(msginfo['mail'])  
     103                for header_name in extra_headers.keys(): 
     104                        self.failUnless(msg.has_key(header_name)) 
     105                        self.assertEquals(extra_headers[header_name], msg[header_name]) 
    106106 
    107     def test_add_custom_headers_list(self): 
    108         "Test that a custom header (list type) can be attached." 
    109         extra_headers = [('Precendence', 'bulk'), ('X-User', 'Alice')] 
    110         message = turbomail.Message('sender@foo.example',  
    111                                     'recipient@foo.example', 'foo bar') 
    112         message.plain = 'Hello World!' 
    113         message.headers = extra_headers 
    114         turbomail.enqueue(message) 
    115         msginfo = get_received_mail(self.sink) 
    116         msg = email.message_from_string(msginfo['mail'])  
    117         for name, value in extra_headers: 
    118             self.failUnless(msg.has_key(name)) 
    119             self.assertEquals(value, msg[name]) 
     107        def test_add_custom_headers_tuple(self): 
     108                "Test that a custom header (tuple type) can be attached." 
     109                extra_headers = (('Precendence', 'bulk'), ('X-User', 'Alice')) 
     110                message = turbomail.Message('sender@foo.example',  
     111                                                                        'recipient@foo.example', 'foo bar') 
     112                message.plain = 'Hello World!' 
     113                message.headers = extra_headers 
     114                turbomail.enqueue(message) 
     115                msginfo = get_received_mail(self.sink) 
     116                msg = email.message_from_string(msginfo['mail'])  
     117                for name, value in extra_headers: 
     118                        self.failUnless(msg.has_key(name)) 
     119                        self.assertEquals(value, msg[name]) 
    120120 
     121        def test_add_custom_headers_list(self): 
     122                "Test that a custom header (list type) can be attached." 
     123                extra_headers = [('Precendence', 'bulk'), ('X-User', 'Alice')] 
     124                message = turbomail.Message('sender@foo.example',  
     125                                                                        'recipient@foo.example', 'foo bar') 
     126                message.plain = 'Hello World!' 
     127                message.headers = extra_headers 
     128                turbomail.enqueue(message) 
     129                msginfo = get_received_mail(self.sink) 
     130                msg = email.message_from_string(msginfo['mail'])  
     131                for name, value in extra_headers: 
     132                        self.failUnless(msg.has_key(name)) 
     133                        self.assertEquals(value, msg[name]) 
     134 
  • branches/2.0.5/tests/lib/smtp_mailsink.py

    r25 r32  
    1818# You should have received a copy of the GNU Lesser General Public 
    1919# License along with this library; if not, write to the Free Software 
    20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA  
     20# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301      USA  
    2121 
    2222 
     
    3939# sink.start() 
    4040# while not sink.has_message(): 
    41 #     time.sleep(1) 
     41#         time.sleep(1) 
    4242# print "received message: " + str(sink.get_messages()) 
    4343# sink.stop() 
     
    5151 
    5252class SMTPMailsinkServer(smtpd.SMTPServer): 
    53     """This is the actual mailsink server which stores all received messages in 
    54     an internal queue. Do not access the queue directly. All accessor methods 
    55     in this object are sufficiently guarded against race conditions.""" 
    56      
    57     def __init__( self, *args, **kwargs): 
    58         smtpd.SMTPServer.__init__( self, *args, **kwargs ) 
    59         self.queued_mails = [] 
    60         self.lock = threading.Lock() 
     53        """This is the actual mailsink server which stores all received messages in 
     54        an internal queue. Do not access the queue directly. All accessor methods 
     55        in this object are sufficiently guarded against race conditions.""" 
     56         
     57        def __init__( self, *args, **kwargs): 
     58                smtpd.SMTPServer.__init__( self, *args, **kwargs ) 
     59                self.queued_mails = [] 
     60                self.lock = threading.Lock() 
    6161 
    62     def has_message(self): 
    63         """Return True if at least one message was received successfully. The  
    64         access to the internal queue is synchronized so the caller will be  
    65         blocked until the necessary lock was aquired.""" 
    66         self.lock.acquire() 
    67         number_messages = len(self.queued_mails) 
    68         self.lock.release() 
    69         return number_messages > 0 
     62        def has_message(self): 
     63                """Return True if at least one message was received successfully. The  
     64                access to the internal queue is synchronized so the caller will be  
     65                blocked until the necessary lock was aquired.""" 
     66                self.lock.acquire() 
     67                number_messages = len(self.queued_mails) 
     68                self.lock.release() 
     69                return number_messages > 0 
    7070 
    71     def get_messages(self): 
    72         """Return a copy of the internal queue with all received messages. The  
    73         access to the internal queue is synchronized so the caller will be  
    74         blocked until the necessary lock was aquired.""" 
    75         self.lock.acquire() 
    76         messages = copy.copy(self.queued_mails) 
    77         self.lock.release() 
    78         return messages 
     71        def get_messages(self): 
     72                """Return a copy of the internal queue with all received messages. The  
     73                access to the internal queue is synchronized so the caller will be  
     74                blocked until the necessary lock was aquired.""" 
     75                self.lock.acquire() 
     76                messages = copy.copy(self.queued_mails) 
     77                self.lock.release() 
     78                return messages 
    7979 
    80     def pop(self, index=None): 
    81         """Return the index'th message in the queue (default=last) which is 
    82         removed from the queue afterwards. Throws IndexError if index is bigger  
    83         than the number of messages in the queue.""" 
    84         item = None 
    85         self.lock.acquire() 
    86         if index == None: 
    87             index = len(self.queued_mails) - 1 
    88         try: 
    89             item = self.queued_mails.pop(index) 
    90         except Exception: 
    91             print 'pop: before lock release' 
    92             self.lock.release() 
    93             raise 
    94         self.lock.release() 
    95         return item 
     80        def pop(self, index=None): 
     81                """Return the index'th message in the queue (default=last) which is 
     82                removed from the queue afterwards. Throws IndexError if index is bigger  
     83                than the number of messages in the queue.""" 
     84                item = None 
     85                self.lock.acquire() 
     86                if index == None: 
     87                        index = len(self.queued_mails) - 1 
     88                try: 
     89                        item = self.queued_mails.pop(index) 
     90                except Exception: 
     91                        print 'pop: before lock release' 
     92                        self.lock.release() 
     93                        raise 
     94                self.lock.release() 
     95                return item 
    9696 
    9797 
    98     def process_message(self, peer, mailfrom, rcpttos, data): 
    99         "Store a received message in the internal queue. For internal use only!" 
    100         msg = {'client': peer, 'from': mailfrom, 'recipients': rcpttos,  
    101                'mail': data} 
    102         self.lock.acquire() 
    103         self.queued_mails.append(msg) 
    104         self.lock.release() 
     98        def process_message(self, peer, mailfrom, rcpttos, data): 
     99                "Store a received message in the internal queue. For internal use only!" 
     100                msg = {'client': peer, 'from': mailfrom, 'recipients': rcpttos,  
     101                           'mail': data} 
     102                self.lock.acquire() 
     103                self.queued_mails.append(msg) 
     104                self.lock.release() 
    105105 
    106106 
    107107class SMTPMailsink(threading.Thread): 
    108     """This class is responsible for controlling the actual mailsink server  
    109     class."""    
     108        """This class is responsible for controlling the actual mailsink server  
     109        class."""        
    110110 
    111     def __init__(self, host='localhost', port=25): 
    112         threading.Thread.__init__(self) 
    113         self.stop_event = threading.Event() 
    114         self.server = SMTPMailsinkServer((host, port), None) 
     111        def __init__(self, host='localhost', port=25): 
     112                threading.Thread.__init__(self) 
     113                self.stop_event = threading.Event() 
     114                self.server = SMTPMailsinkServer((host, port), None) 
    115115 
    116     def run(self): 
    117         "Just run in a loop until stop() is called." 
    118         while not self.stop_event.isSet(): 
    119             asyncore.loop(timeout=0.1) 
     116        def run(self): 
     117                "Just run in a loop until stop() is called." 
     118                while not self.stop_event.isSet(): 
     119                        asyncore.loop(timeout=0.1) 
    120120 
    121     def stop(self, timeout_seconds=5.0): 
    122         """Stop the mailsink and shut down this thread. timeout_seconds  
    123         specifies how long the caller should wait for the mailsink server to  
    124         close down (default: 5 seconds). If the server did not stop in time, a 
    125         warning message is printed.""" 
    126         self.stop_event.set() 
    127         self.server.close() 
    128         threading.Thread.join(self, timeout=timeout_seconds) 
    129         if self.isAlive(): 
    130             print "WARNING: Thread still alive. Timeout while waiting for " + \ 
    131                   "termination!" 
    132          
    133     def has_message(self): 
    134         "Return True if at least one message was received successfully." 
    135         return self.server.has_message() 
    136          
    137     def get_messages(self): 
    138         "Return a copy of the internal queue with all received messages." 
    139         return self.server.get_messages() 
     121        def stop(self, timeout_seconds=5.0): 
     122                """Stop the mailsink and shut down this thread. timeout_seconds  
     123                specifies how long the caller should wait for the mailsink server to  
     124                close down (default: 5 seconds). If the server did not stop in time, a 
     125                warning message is printed.""" 
     126                self.stop_event.set() 
     127                self.server.close() 
     128                threading.Thread.join(self, timeout=timeout_seconds) 
     129                if self.isAlive(): 
     130                        print "WARNING: Thread still alive. Timeout while waiting for " + \ 
     131                                  "termination!" 
     132                 
     133        def has_message(self): 
     134                "Return True if at least one message was received successfully." 
     135                return self.server.has_message() 
     136                 
     137        def get_messages(self): 
     138                "Return a copy of the internal queue with all received messages." 
     139                return self.server.get_messages() 
    140140 
    141     def pop(self, index=None): 
    142         """Return the index'th message in the queue (default=last) which is 
    143         removed from the queue afterwards. Throws IndexError if index is bigger  
    144         than the number of messages in the queue.""" 
    145         return self.server.pop(index) 
     141        def pop(self, index=None): 
     142                """Return the index'th message in the queue (default=last) which is 
     143                removed from the queue afterwards. Throws IndexError if index is bigger  
     144                than the number of messages in the queue.""" 
     145                return self.server.pop(index) 
  • branches/2.0.5/tests/lib/utils.py

    r25 r32  
    2929 
    3030class TimeoutException(Exception): 
    31     "A timeout occured!" 
    32     pass 
     31        "A timeout occured!" 
     32        pass 
    3333 
    3434 
    3535def get_received_mail(sink): 
    36     """Return the first mail received (which is removed from the TurboMail 
    37     queue) in the following format {'client': ...., 'from': ...,  
    38     'recipients': ..., 'mail': ...}. Blocks the caller until a message was  
    39     received but no longer than 10 seconds (in this case, a TimeoutException 
    40     is thrown).""" 
    41     for i in range(10 * 10): 
    42         if not sink.has_message(): 
    43             time.sleep(0.1) 
    44         else: 
    45             break 
    46     if not sink.has_message(): 
    47         raise TimeoutException() 
    48     return sink.pop(index=0) 
     36        """Return the first mail received (which is removed from the TurboMail 
     37        queue) in the following format {'client': ...., 'from': ...,  
     38        'recipients': ..., 'mail': ...}. Blocks the caller until a message was  
     39        received but no longer than 10 seconds (in this case, a TimeoutException 
     40        is thrown).""" 
     41        for i in range(10 * 10): 
     42                if not sink.has_message(): 
     43                        time.sleep(0.1) 
     44                else: 
     45                        break 
     46        if not sink.has_message(): 
     47                raise TimeoutException() 
     48        return sink.pop(index=0) 
    4949 
    5050 
    5151def save_config(keys): 
    52     """Return a dictionary with the original configuration for the specified 
    53     keys.""" 
    54     original_config = {} 
    55     for key in keys: 
    56         original_config[key] = turbogears.config.get(key) 
    57     return original_config 
     52        """Return a dictionary with the original configuration for the specified 
     53        keys.""" 
     54        original_config = {} 
     55        for key in keys: 
     56                original_config[key] = turbogears.config.get(key) 
     57        return original_config 
    5858 
    5959 
  • branches/2.0.5/tests/test_message_as_string.py

    r27 r32  
    3838 
    3939class TestMessageAsString(unittest.TestCase): 
    40     "Test cases for sending emails as plain strings with TurboMail." 
     40        "Test cases for sending emails as plain strings with TurboMail." 
    4141 
    42     def setUp(self): 
    43         server_port = 42042 
    44         test_config = {'mail.on': True, 'mail.timeout': 1, 
    45                        'mail.server': 'localhost:%d' % server_port} 
    46         self._original_config = save_config(test_config.keys()) 
    47         turbogears.config.update(test_config) 
    48          
    49         self.sink = SMTPMailsink(host='localhost', port=server_port) 
    50         self.sink.start() 
    51         turbogears.startup.startTurboGears() 
     42        def setUp(self): 
     43                server_port = 42042 
     44                test_config = {'mail.on': True, 'mail.timeout': 1, 
     45                                           'mail.server': 'localhost:%d' % server_port} 
     46                self._original_config = save_config(test_config.keys()) 
     47                turbogears.config.update(test_config) 
     48                 
     49                self.sink = SMTPMailsink(host='localhost', port=server_port) 
     50                self.sink.start() 
     51                turbogears.startup.startTurboGears() 
    5252 
    5353 
    54     def tearDown(self): 
    55         turbogears.startup.stopTurboGears() 
    56         turbogears.config.update(self._original_config) 
    57         self.sink.stop() 
     54        def tearDown(self): 
     55                turbogears.startup.stopTurboGears() 
     56                turbogears.config.update(self._original_config) 
     57                self.sink.stop() 
    5858 
    5959 
    60     def test_message_string(self): 
    61         """Test that a message can be submitted as string (not as  
    62         turbomail.Message). This is important when existing (e.g. from a  
    63         mailbox) or digitally signed messages should be sent through  
    64         TurboMail.""" 
    65         msg_string = """From: bar@xams.example 
     60        def test_message_string(self): 
     61                """Test that a message can be submitted as string (not as  
     62                turbomail.Message). This is important when existing (e.g. from a  
     63                mailbox) or digitally signed messages should be sent through  
     64                TurboMail.""" 
     65                msg_string = """From: bar@xams.example 
    6666To: foo@xams.example 
    6767Subject: foo bar 
     
    7171 
    7272Hello World!""" 
    73         sender = 'sender@foobar.example' 
    74         recipient = 'recipient@foo.example' 
    75         msginfo = dict(sender=sender, recipients=[recipient], message=msg_string) 
    76         turbomail.enqueue(msginfo) 
     73                sender = 'sender@foobar.example' 
     74                recipient = 'recipient@foo.example' 
     75                msginfo = dict(sender=sender, recipients=[recipient], message=msg_string) 
     76                turbomail.enqueue(msginfo) 
    7777 
    78         msginfo = get_received_mail(self.sink) 
    79         self.assertEqual(sender, msginfo['from']) 
    80         self.assertEqual([recipient], msginfo['recipients']) 
    81         self.assertEqual(msg_string, msginfo['mail']) 
     78                msginfo = get_received_mail(self.sink) 
     79                self.assertEqual(sender, msginfo['from']) 
     80                self.assertEqual([recipient], msginfo['recipients']) 
     81                self.assertEqual(msg_string, msginfo['mail']) 
    8282 
  • branches/2.0.5/turbomail/dispatch.py

    r27 r32  
    148148                        packUpdate['smtpfrom'] = pack['sender'] 
    149149                 
    150                 if 'smtpfrom' in pack: 
     150                if 'smtpfrom' in pack and pack['smtpfrom'] != None: 
    151151                        if isinstance(pack['smtpfrom'], tuple): 
    152152                                packUpdate['smtpfrom'] = pack['smtpfrom'][1] 
  • branches/2.0.5/turbomail/message.py

    r31 r32  
    354354                return dict( 
    355355                                sender=self.sender, 
     356                                smtpfrom = self.smtpfrom, 
    356357                                to=[[self.recipient], self.recipient][isinstance(self.recipient, list)], 
    357358                                recipients=[i[1] for i in recipients if isinstance(i, tuple)] + [i for i in recipients if not isinstance(i, tuple)],