Ticket #12089: 0001-Tests-12089.patch

File 0001-Tests-12089.patch, 6.6 KB (added by trygve, 5 years ago)
  • lib/bridgedb/test/test_smtp.py

    From 87375acd74a7cc2248fa145f39a5a1f8a5389bc5 Mon Sep 17 00:00:00 2001
    From: trygve <nothing@nowhere>
    Date: Sat, 9 Aug 2014 22:28:49 +0000
    Subject: [PATCH] Tests #12089
    
    Added test to check sequence of events described in ticket #12089 i.e. sending an SMTP message with the 'MAIL FROM' differing to the 'From' in the mail header. The test as written currently fails because it reproduces the bug described in the ticket.
    ---
     lib/bridgedb/test/test_smtp.py |   48 +++++++++++++++++++++++++++++-----------
     1 file changed, 35 insertions(+), 13 deletions(-)
    
    diff --git a/lib/bridgedb/test/test_smtp.py b/lib/bridgedb/test/test_smtp.py
    index 5e8b5c9..210be91 100644
    a b LOCAL_SMTP_SERVER_PORT = 2525 # Must be the same as bridgedb's EMAIL_SMTP_PORT 
    3535class EmailServer(SMTPServer):
    3636    def process_message(self, peer, mailfrom, rcpttos, data):
    3737        ''' Overridden from SMTP server, called whenever a message is received'''
    38         self.message_queue.put(data)
     38        self.message_queue.put((data, rcpttos[0]))
    3939
    4040    def thread_proc(self):
    4141        ''' This function runs in thread, and will continue looping
    class EmailServer(SMTPServer): 
    6666        self._thread.join()       
    6767        assert self._thread.is_alive() == False, "Thread is alive and kicking"
    6868
    69     def getAndCheckMessageContains(self, text, timeoutInSecs=2.0):
     69    def getAndCheckMessageContains(self, text, rcpt, timeoutInSecs=2.0):
    7070        #print("Checking for reponse")
    71         message = self.message_queue.get(block=True, timeout=timeoutInSecs)
     71        message, rcpttos = self.message_queue.get(block=True, timeout=timeoutInSecs)
     72        #print(message)
    7273        assert message.find(text) != -1, "Message did not contain text \"%s\". Full message is:\n %s" % (text, message)
     74        if rcpt != None:
     75            assert rcpt == rcpttos, "Expected recipient %s, found %s" % (rcpt, rcpttos)
    7376
    7477    def checkNoMessageReceived(self, timeoutInSecs=2.0):
    7578        try:
    class EmailServer(SMTPServer): 
    7881            return True         
    7982        assert False, "Found a message in the queue, but expected none"
    8083
    81 def sendMail(fromAddress):
     84def sendMail(fromAddress, headerFromAddress=None):
    8285    #print("Connecting to %s:%d" % (BRIDGEDB_SMTP_SERVER_ADDRESS, BRIDGEDB_SMTP_SERVER_PORT))
    8386    client = smtplib.SMTP(BRIDGEDB_SMTP_SERVER_ADDRESS, BRIDGEDB_SMTP_SERVER_PORT)
    8487    client.set_debuglevel(SMTP_DEBUG_LEVEL)
    8588
    8689    #print("Sending mail TO:%s, FROM:%s" % (TO_ADDRESS, fromAddress))
    87     result = client.sendmail(fromAddress, TO_ADDRESS, MESSAGE_TEMPLATE % (fromAddress, TO_ADDRESS))
     90    if headerFromAddress == None:
     91        headerFromAddress = fromAddress
     92    result = client.sendmail(fromAddress, TO_ADDRESS, MESSAGE_TEMPLATE % (headerFromAddress, TO_ADDRESS))
    8893    assert result == {}, "Failed to send mail"
    8994    client.quit()
    9095
    class SMTPTests(unittest.TestCase): 
    99104
    100105    def test_getBridges(self):
    101106        # send the mail to bridgedb, choosing a random email address
    102         sendMail(fromAddress=FROM_ADDRESS_TEMPLATE % random.randint(MIN_FROM_ADDRESS, MAX_FROM_ADDRESS))
     107        FROM_ADDRESS = FROM_ADDRESS_TEMPLATE % random.randint(MIN_FROM_ADDRESS, MAX_FROM_ADDRESS)
     108        sendMail(fromAddress=FROM_ADDRESS)
    103109
    104110        # then check that our local SMTP server received a response
    105111        # and that response contained some bridges
    106         self.server.getAndCheckMessageContains("Here are your bridges")
     112        self.server.getAndCheckMessageContains("Here are your bridges", rcpt=FROM_ADDRESS)
    107113
    108114    def test_getBridges_rateLimitExceeded(self):
    109115        # send the mail to bridgedb, choosing a random email address
    110116        FROM_ADDRESS = FROM_ADDRESS_TEMPLATE % random.randint(MIN_FROM_ADDRESS, MAX_FROM_ADDRESS)
    111         sendMail(FROM_ADDRESS)
     117        sendMail(fromAddress=FROM_ADDRESS)
    112118
    113119        # then check that our local SMTP server received a response
    114120        # and that response contained some bridges
    115         self.server.getAndCheckMessageContains("Here are your bridges")
     121        self.server.getAndCheckMessageContains("Here are your bridges", rcpt=FROM_ADDRESS)
    116122
    117123        # send another request from the same email address
    118124        sendMail(FROM_ADDRESS)
    119125
    120126        # this time, the email response should not contain any bridges
    121         self.server.getAndCheckMessageContains("You have exceeded the rate limit. Please slow down!")
     127        self.server.getAndCheckMessageContains("You have exceeded the rate limit. Please slow down!", rcpt=FROM_ADDRESS)
    122128
    123129        # then we send another request from the same email address
    124130        sendMail(FROM_ADDRESS)
    class SMTPTests(unittest.TestCase): 
    130136        ''' Sends a large number of emails in a short period of time, and checks that
    131137            a response is received for each message '''
    132138        NUM_MAILS = 100
     139        fromAddresses = []
    133140        for i in range(NUM_MAILS):
    134141            # Note: if by chance two emails with the same FROM_ADDRESS are generated, this test will fail
    135142            # Setting 'MAX_FROM_ADDRESS' to be a high value reduces the probability of this occuring, but does not rule it out
    136             sendMail(fromAddress=FROM_ADDRESS_TEMPLATE % random.randint(MIN_FROM_ADDRESS, MAX_FROM_ADDRESS))
     143            FROM_ADDRESS = FROM_ADDRESS_TEMPLATE % random.randint(MIN_FROM_ADDRESS, MAX_FROM_ADDRESS)
     144            sendMail(fromAddress=FROM_ADDRESS)
     145            fromAddresses.append(FROM_ADDRESS)
    137146
    138         for i in range(NUM_MAILS):
    139             self.server.getAndCheckMessageContains("Here are your bridges")
     147        for fromAddress in fromAddresses:
     148            # It would be nice to check that the RCPT address is the same as fromAddress, but we can't
     149            # guarantee that they get sent in the same order
     150            self.server.getAndCheckMessageContains("Here are your bridges", rcpt=None)
     151
     152    def test_trac_12089(self):
     153        # send an email with the FROM address different to the one in the HEADER
     154        FROM_ADDRESS = FROM_ADDRESS_TEMPLATE % random.randint(MIN_FROM_ADDRESS, MAX_FROM_ADDRESS)
     155        HEADER_FROM_ADDRESS = FROM_ADDRESS_TEMPLATE % random.randint(MIN_FROM_ADDRESS, MAX_FROM_ADDRESS)
     156        self.assertTrue(FROM_ADDRESS != HEADER_FROM_ADDRESS, "Both addresses were equal. This was *very* unlikely. Try again")
     157        sendMail(fromAddress=FROM_ADDRESS, headerFromAddress=HEADER_FROM_ADDRESS)
     158
     159        # now there should be no response at all (wait 1 second to make sure)
     160        # Note to isis: is this the correct behaviour?
     161        self.server.checkNoMessageReceived(timeoutInSecs=1.0)
    140162