Blame tests/functionality/iomux/client.py

Packit 6d2c1b
#!/usr/bin/python 
Packit 6d2c1b
# Written By: Avner BenHanoch
Packit 6d2c1b
# Date: 2011-01-11
Packit 6d2c1b
#
Packit 6d2c1b
"""
Packit 6d2c1b
A client that use ctrl socket for instructing server to sleep than it send
Packit 6d2c1b
payload on data socket during sleep time.
Packit 6d2c1b
It compares the time the TCP window was blocked to the requested sleep time
Packit 6d2c1b
It exit with success iff these times are close enough
Packit 6d2c1b
In addition, this code tests select on 1 write fd using zero/fixed/infinity timeout
Packit 6d2c1b
"""
Packit 6d2c1b
import socket
Packit 6d2c1b
import select
Packit 6d2c1b
import time
Packit 6d2c1b
import sys
Packit 6d2c1b
Packit 6d2c1b
HOST = 'alf6'     # The remote host
Packit 6d2c1b
if len (sys.argv) > 1: HOST = sys.argv[1]
Packit 6d2c1b
PPORT = 50007     # pyload port
Packit 6d2c1b
CPORT = PPORT + 1 # ctrl port
Packit 6d2c1b
SIZE = 1024      # size of send buf
Packit 6d2c1b
PAYLOAD = '0' * SIZE # payload for send
Packit 6d2c1b
SECSLEEP = 2      # seconds for requesting server to sleep without recveing data
Packit 6d2c1b
SECGRACE = 0.2    # seconds GRACE for mismatch in sleep request vs. actual blocking time
Packit 6d2c1b
WRITEABLE_INDICATION = 100 * 1024 # see block_till_writeable() function below
Packit 6d2c1b
Packit 6d2c1b
def print_info (msg):
Packit 6d2c1b
	print "INFO: ", msg
Packit 6d2c1b
Packit 6d2c1b
readfds=[]
Packit 6d2c1b
Packit 6d2c1b
# for the sake of this test, socket is defined writeable if we could
Packit 6d2c1b
# successfully use it for sending 'WRITEABLE_INDICATION' bytes of data
Packit 6d2c1b
def block_till_writeable (sock):
Packit 6d2c1b
	sent = 0
Packit 6d2c1b
	ret = 0
Packit 6d2c1b
	while sent < WRITEABLE_INDICATION:
Packit 6d2c1b
		print_info(">>> before select infinity (send-ret=%d, sent=%d)" % (ret, sent))
Packit 6d2c1b
		readready,writeready,exceptready = select.select(readfds,[sock],[])
Packit 6d2c1b
		if sock in writeready:
Packit 6d2c1b
			print_info("<<< after select infinity, sock is writeable (sent=%d)" % sent)
Packit 6d2c1b
			ret = sock.send(PAYLOAD)
Packit 6d2c1b
			sent += ret
Packit 6d2c1b
		else:
Packit 6d2c1b
			raise Exception("no writeable socket after select infinity")
Packit 6d2c1b
			#sys.stdin.read(1)
Packit 6d2c1b
	return sent
Packit 6d2c1b
Packit 6d2c1b
#ctrl socket
Packit 6d2c1b
csocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Packit 6d2c1b
csocket.connect((HOST, CPORT))
Packit 6d2c1b
Packit 6d2c1b
#payload socket
Packit 6d2c1b
psocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Packit 6d2c1b
psocket.connect((HOST, PPORT))
Packit 6d2c1b
psocket.setblocking(0)
Packit 6d2c1b
Packit 6d2c1b
#instruct peer to sleep
Packit 6d2c1b
print_info("instructing peer to sleep %f seconds and flooding it with data" % SECSLEEP)
Packit 6d2c1b
csocket.send(str(SECSLEEP)) #ctrl
Packit 6d2c1b
# flood sleeping peer with data
Packit 6d2c1b
size = 0
Packit 6d2c1b
Packit 6d2c1b
print_info(">>> before select (size=%d)" % size)
Packit 6d2c1b
readready,writeready,exceptready = select.select(readfds,[psocket],[], 0)
Packit 6d2c1b
print_info("<<< after  select (size=%d)" % size)
Packit 6d2c1b
while psocket in writeready:
Packit 6d2c1b
	ret = psocket.send(PAYLOAD)
Packit 6d2c1b
	size += ret
Packit 6d2c1b
	if size > 300*1024:
Packit 6d2c1b
		raise Exception("socket is always writeable (size=%d)" % size)
Packit 6d2c1b
	print_info(">>> before select (send-ret=%d, size=%d)" % (ret, size))
Packit 6d2c1b
	readready,writeready,exceptready = select.select(readfds,[psocket],[], 0)
Packit 6d2c1b
	print_info("<<< after  select (size=%d)" % size)
Packit 6d2c1b
Packit 6d2c1b
#wait till payload socket is ready for write
Packit 6d2c1b
t1 = time.time()
Packit 6d2c1b
print_info("---->>> TCP window was closed after sending %d bytes.  Waiting till window is open..." % size )
Packit 6d2c1b
res = block_till_writeable(psocket)
Packit 6d2c1b
t2 = time.time()
Packit 6d2c1b
Packit 6d2c1b
#check results
Packit 6d2c1b
blocked = t2 - t1
Packit 6d2c1b
diff = abs(SECSLEEP - blocked)
Packit 6d2c1b
print_info ("<<<---- blocked time=%f; requested block=%f" % (blocked, SECSLEEP) )
Packit 6d2c1b
if SECGRACE >= diff:
Packit 6d2c1b
	print_info("SUCCESS in test: grace of %f >= diff of %f" % (SECGRACE,diff) )
Packit 6d2c1b
	ret = 0
Packit 6d2c1b
else:
Packit 6d2c1b
	print_info("FAIL in test: grace of %f < diff of %f" % (SECGRACE,diff) )
Packit 6d2c1b
	ret = 255
Packit 6d2c1b
print_info ("[total bytes sent = %d]" % (size + res) )
Packit 6d2c1b
Packit 6d2c1b
psocket.close()
Packit 6d2c1b
csocket.close()
Packit 6d2c1b
sys.exit (ret)