Permalink
Browse files

Add experimental comet suport

  • Loading branch information...
1 parent cd2ca9f commit 30369194b02c5a0d8557cc996b9652f7cf0ebd65 @bdelbosc bdelbosc committed Nov 24, 2011
Showing with 55 additions and 7 deletions.
  1. +21 −0 CHANGES.txt
  2. +2 −2 doc/source/faq.rst
  3. +18 −2 src/funkload/FunkLoadTestCase.py
  4. +14 −3 src/funkload/PatchWebunit.py
View
@@ -29,6 +29,27 @@ New Features
Then the `response.body` will be uncompressed when needed.
+* Experimental comet request support, handle stream request in a separate
+ thread, the server input is send to a consumer method::
+
+ # async request
+ thread = self.comet(server_url + "/comet?t=1234&c=1",
+ self.consumer, description="Comet connection")
+ # do some requests
+ ...
+ # stop comet request
+ self.stop_consumer = True
+ thread.join()
+
+ The consumer get the server input character by character and stop the
+ can stop the connection by returning 0 value::
+
+ def consumer(self, string):
+ trace(string)
+ if self.stop_consumer:
+ self.logd('Stop consumer')
+ return 0
+
Bug Fixes
~~~~~~~~~~
View
@@ -48,8 +48,8 @@ How to accept invalid Cookies ?
How to share a counter between concurrent users ?
--------------------------------------------------
-* The credential server can serve a sequence. Using ``xmlrpc_get_seq``
- threads can share a sequence::
+The credential server can serve a sequence. Using ``xmlrpc_get_seq``
+threads can share a sequence::
from funkload.utils import xmlrpc_get_seq
...
@@ -26,6 +26,7 @@
import re
import logging
import gzip
+import threading
from StringIO import StringIO
from warnings import warn
from socket import error as SocketError
@@ -193,7 +194,7 @@ def clearContext(self):
#------------------------------------------------------------
# browser simulation
#
- def _connect(self, url, params, ok_codes, rtype, description, redirect=False):
+ def _connect(self, url, params, ok_codes, rtype, description, redirect=False, consumer=None):
"""Handle fetching, logging, errors and history."""
if params is None and rtype in ('post','put'):
# enable empty put/post
@@ -202,7 +203,7 @@ def _connect(self, url, params, ok_codes, rtype, description, redirect=False):
try:
response = self._browser.fetch(url, params, ok_codes=ok_codes,
key_file=self._keyfile_path,
- cert_file=self._certfile_path, method=rtype)
+ cert_file=self._certfile_path, method=rtype, consumer=consumer)
except:
etype, value, tback = sys.exc_info()
t_stop = time.time()
@@ -519,6 +520,21 @@ def waitUntilAvailable(self, url, time_out=20, sleep_time=2):
return
time.sleep(sleep_time)
+ def comet(self, url, consumer, description=None):
+ """Initiate a comet request and process the input in a separate thread.
+ This call is async and return a thread object.
+
+ The consumer method takes as parameter an input string, it can
+ close the comet connection by returning 0."""
+ self.steps += 1
+ self.page_responses = 0
+ thread = threading.Thread(target=self._cometFetcher, args=(url, consumer, description))
+ thread.start()
+ return thread
+
+ def _cometFetcher(self, url, consumer, description):
+ self._connect(url, None, self.ok_codes, 'GET', description, consumer=consumer)
+
def setBasicAuth(self, login, password):
"""Set HTTP basic authentication for the following requests."""
self._browser.setBasicAuth(login, password)
@@ -181,7 +181,7 @@ def WTC_pageImages(self, url, page, testcase=None):
# WebFetcher fetch
def WF_fetch(self, url, postdata=None, server=None, port=None, protocol=None,
- ok_codes=None, key_file=None, cert_file=None, method="GET"):
+ ok_codes=None, key_file=None, cert_file=None, method="GET", consumer=None):
'''Run a single test request to the indicated url. Use the POST data
if supplied. Accepts key and certificate file paths for https (ssl/tls)
connections.
@@ -390,10 +390,21 @@ def WF_fetch(self, url, postdata=None, server=None, port=None, protocol=None,
else:
f = h.getfile()
g = cStringIO.StringIO()
- d = f.read()
+ if consumer is None:
+ d = f.read()
+ else:
+ d = f.readline(1)
while d:
g.write(d)
- d = f.read()
+ if consumer is None:
+ d = f.read()
+ else:
+ ret = consumer(d)
+ if ret == 0:
+ # consumer close connection
+ d = None
+ else:
+ d = f.readline(1)
response = HTTPResponse(self.cookies, protocol, server, port, url,
errcode, errmsg, headers, g.getvalue(),
self.error_content)

0 comments on commit 3036919

Please sign in to comment.