1#!/usr/bin/python 2 3import os 4import poplib 5import imaplib 6import thread 7import time 8import sys 9import mailbox 10import random 11from optparse import OptionParser 12 13 14# default number of concurrent clients to create 15CLIENTS = 20 16 17# default number of fetch commands per client 18MESSAGES = 100 19 20# default mailbox to append from 21MAILBOX = os.path.join(os.path.dirname(__file__), "testbox") 22 23# username 24USERNAME = "testuser1" 25 26# password 27PASSWORD = "test" 28 29# number of messages to send per session 30RECONNECT = 5 31 32DEBUG = False 33 34tlocks = {} 35tdict = {} 36 37 38class IMAPClient: 39 def __init__(self, hostname, port): 40 self.conn = imaplib.IMAP4(hostname, port) 41 self.conn.debug = DEBUG 42 self.conn.login(USERNAME, PASSWORD) 43 44 def append(self, message): 45 self.conn.append("INBOX", (), "", message) 46 47 def logout(self): 48 return self.conn.logout() 49 50 51class POPClient: 52 def __init__(self, hostname, port): 53 self.conn = poplib.POP3(hostname, port) 54 self.conn.set_debuglevel(DEBUG) 55 self.conn.user(USERNAME) 56 self.conn.pass_(PASSWORD) 57 58 def check(self): 59 self.conn.stat() 60 self.conn.list() 61 self.conn.uidl() 62 63 def fetch(self): 64 count, size = self.conn.stat() 65 which = int(random.random() * count) + 1 66 self.conn.list(which) 67 self.conn.uidl(which) 68 self.conn.retr(which) 69 self.conn.top(which, 1) 70 71 def logout(self): 72 self.conn.rset() 73 self.conn.quit() 74 75 76def fillmailbox(*args): 77 c = IMAPClient('localhost', 10143) 78 mb = mailbox.mbox(MAILBOX, factory=None, create=False) 79 for msg in mb.values(): 80 c.append(msg.as_string()) 81 sys.stdout.write('.') 82 sys.stdout.flush() 83 sys.stdout.write('\n') 84 sys.stdout.flush() 85 c.logout() 86 87 88def frontloader(*args): 89 tid = args[0] 90 tlocks[tid].acquire() 91 c = POPClient('localhost', 10110) 92 i = 1 93 while i < MESSAGES: 94 c.check() 95 c.fetch() 96 if not i % RECONNECT: 97 c.logout() 98 c = POPClient('localhost', 10110) 99 sys.stdout.write('_') 100 else: 101 sys.stdout.write('.') 102 sys.stdout.flush() 103 i = i + 1 104 if i >= MESSAGES: 105 break 106 107 c.logout() 108 tlocks[tid].release() 109 110 111if __name__ == '__main__': 112 113 parser = OptionParser() 114 parser.add_option("-c", "--clients", dest="CLIENTS", 115 help="Number of concurrent clients [default: %default]", 116 default=CLIENTS) 117 parser.add_option("-m", "--mailbox", dest="MAILBOX", 118 help="mailbox to feed to dbmail-deliver", 119 default=MAILBOX) 120 parser.add_option("-n", "--messages", dest="MESSAGES", 121 default=MESSAGES, 122 help="number of messages to fetch [default: %default]") 123 parser.add_option("-u", "--username", dest="USERNAME", 124 default=USERNAME, 125 help="deliver to username [default: %default]") 126 parser.add_option("-r", "--reconnect", dest="RECONNECT", 127 default=RECONNECT, 128 help="Number of messages to fetch before " 129 "reconnecting [default: %default]") 130 131 (options, args) = parser.parse_args() 132 133 CLIENTS = int(options.CLIENTS) 134 MESSAGES = int(options.MESSAGES) 135 MAILBOX = options.MAILBOX 136 USERNAME = options.USERNAME 137 RECONNECT = int(options.RECONNECT) 138 139 # start the client threads 140 for i in range(0, CLIENTS): 141 tlocks[i] = thread.allocate_lock() 142 143 if MAILBOX: 144 print "Add messages from file %s to INBOX" % ( 145 MAILBOX) 146 fillmailbox() 147 148 print "Doing %d fetches per client as %s" % (MESSAGES, USERNAME) 149 print "Starting %d clients" % CLIENTS 150 for i in range(0, CLIENTS): 151 id = thread.start_new_thread(frontloader, (i,)) 152 tdict[i] = id 153 time.sleep(1) 154 155 time.sleep(5) 156 # wait for the clients to finish 157 while 1: 158 for i in range(0, CLIENTS): 159 done = [] 160 if i in tdict: 161 r = tlocks[i].acquire(0) 162 if r: 163 sys.stdout.write('Q') 164 sys.stdout.flush() 165 tlocks[i].release() 166 done.append(i) 167 for x in done: 168 del(tlocks[x]) 169 del(tdict[x]) 170 if len(tdict.items()) == 0: 171 break 172 time.sleep(1) 173 174 175#EOF 176