def testOnlyHandleAMaximumNrOfRequests(self): codes = [] def handler(**kwargs): yield "OK" def error_handler(**kwargs): codes.append(kwargs['ResponseCode']) yield "FAIL" server = HttpServer(self.reactor, self.port, handler, errorHandler=error_handler, maxConnections=5) server.listen() self.reactor.getOpenConnections = lambda: 10 sock = socket() sock.connect(('localhost', self.port)) self.reactor.step() sock.send("GET / HTTP/1.0\r\n\r\n") self.reactor.step().step().step() server.shutdown() self.assertEquals('FAIL', sock.recv(1024)) self.assertEquals([503], codes) # cleanup sock.close()
def testYieldInHttpServer(self): bucket = [] def handler(RequestURI, **kwargs): yield 'A' while 'continue' not in bucket: yield Yield yield 'B' with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('GET /path/here HTTP/1.0\r\n\r\n') for i in xrange(500): reactor.step() self.assertEquals('A', sok.recv(100)) bucket.append('continue') reactor.step() self.assertEquals('B', sok.recv(100)) # cleanup sok.close() server.shutdown()
def testOnlyHandleAMaximumNrOfRequests(self): codes = [] def handler(**kwargs): yield "OK" def error_handler(**kwargs): codes.append(kwargs['ResponseCode']) yield "FAIL" server = HttpServer(self.reactor, self.port, handler, errorHandler=error_handler, maxConnections=5) server.listen() self.reactor.getOpenConnections = lambda: 10 sock = socket() sock.connect(('localhost', self.port)) self.reactor.step() sock.send("GET / HTTP/1.0\r\n\r\n") self.reactor.step().step().step() server.shutdown() self.assertEquals('FAIL', sock.recv(1024)) self.assertEquals([503], codes)
def sendRequestAndReceiveResponse(self, request, response='The Response', recvSize=4096, compressResponse=False, extraStepAfterCompress=True): self.responseCalled = False @compose def responseGenFunc(**kwargs): yield response yield '' self.responseCalled = True server = HttpServer(self.reactor, self.port, responseGenFunc, recvSize=recvSize, compressResponse=compressResponse) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send(request) mockStdout = None with self.stdout_replaced() as mockStdout: while not self.responseCalled: self.reactor.step() if compressResponse and extraStepAfterCompress: #not everythingSent???: self.reactor.step() stdoutValue = mockStdout.getvalue() if stdoutValue: print stdoutValue server.shutdown() r = sok.recv(4096) sok.close() return r
def testReadMultipartFormEndBoundary(self): httpRequest = open(inmydir('data/multipart-data-04')).read() self.requestData = {} def handler(**kwargs): self.requestData = kwargs return yield with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send(httpRequest) reactor.addTimer(2, lambda: self.fail("Test Stuck")) while self.requestData.get('Form', None) == None: reactor.step() form = self.requestData['Form'] self.assertEquals(1, len(form)) self.assertEquals(3521*'X', form['id'][0]) # cleanup sok.close() server.shutdown()
def testTextFileSeenAsFile(self): httpRequest = open(inmydir('data/multipart-data-03')).read() self.requestData = {} def handler(**kwargs): self.requestData = kwargs return yield with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send(httpRequest) reactor.addTimer(2, lambda: self.fail("Test Stuck")) while self.requestData.get('Form', None) == None: reactor.step() form = self.requestData['Form'] self.assertEquals(4, len(form)) self.assertEquals(['SOME ID'], form['id']) self.assertEquals(1, len(form['somename'])) filename, mimetype, data = form['somename'][0] self.assertEquals('hello.bas', filename) self.assertEquals('text/plain', mimetype) # cleanup sok.close() server.shutdown()
def testPostMethodDeCompressesDeflatedBody_deflate(self): self.requestData = None def handler(**kwargs): self.requestData = kwargs return yield with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler, timeout=0.01) server.listen() sok = socket() sok.connect(('localhost', self.port)) bodyData = 'bodydatabodydata' bodyDataCompressed = compress(bodyData) contentLengthCompressed = len(bodyDataCompressed) sok.send(('POST / HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\nContent-Encoding: deflate\r\n\r\n' % contentLengthCompressed) + bodyDataCompressed) while not self.requestData: reactor.step() self.assertEquals(dict, type(self.requestData)) self.assertTrue('Headers' in self.requestData) headers = self.requestData['Headers'] self.assertEquals('POST', self.requestData['Method']) self.assertEquals('application/x-www-form-urlencoded', headers['Content-Type']) self.assertEquals(contentLengthCompressed, int(headers['Content-Length'])) # TS: is this correct?, maybe decompressed length? self.assertTrue('Body' in self.requestData) self.assertEquals('bodydatabodydata', self.requestData['Body']) # cleanup sok.close() server.shutdown()
def testPostMethodDeCompressesDeflatedBody_unrecognizedEncoding(self): self.requestData = None def handler(**kwargs): self.requestData = kwargs return yield with Reactor() as reactor: server = HttpServer(reactor, self.port, handler, timeout=0.01) server.listen() sok = socket() sok.connect(('localhost', self.port)) bodyData = 'bodydatabodydata' bodyDataCompressed = compress(bodyData) contentLengthCompressed = len(bodyDataCompressed) sok.send(('POST / HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\nContent-Encoding: unknown\r\n\r\n' % contentLengthCompressed) + bodyDataCompressed) while select([sok],[], [], 0) != ([sok], [], []): reactor.step() self.assertTrue(sok.recv(4096).startswith('HTTP/1.0 400 Bad Request')) self.assertEquals(None, self.requestData) # cleanup sok.close() server.shutdown()
def testReadChunkedAndCompressedPost(self): postData = 'AhjBeehCeehAhjBeehCeehAhjBeehCeehAhjBeehCeeh' postDataCompressed = compress(postData) self.assertEquals(20, len(postDataCompressed)) self.assertEquals(15, len(postDataCompressed[:15])) self.assertEquals(5, len(postDataCompressed[15:])) self.requestData = {} def handler(**kwargs): self.requestData = kwargs return yield with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler, timeout=0.01, recvSize=3) server.listen() sok = socket() sok.connect(('localhost', self.port)) postString = 'POST / HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nTransfer-Encoding: chunked\r\nContent-Encoding: deflate\r\n\r\nf\r\n%s\r\n5\r\n%s\r\n0\r\n' % (postDataCompressed[:15], postDataCompressed[15:]) sok.send(postString) reactor.addTimer(0.2, lambda: self.fail("Test Stuck")) while self.requestData.get('Body', None) != postData: reactor.step() # cleanup sok.close() server.shutdown()
def testPutMethodReadsBody(self): self.requestData = None def handler(**kwargs): self.requestData = kwargs return yield with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler, timeout=0.01) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('PUT / HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 8\r\n\r\nbodydata') while not self.requestData: reactor.step() self.assertEquals(dict, type(self.requestData)) self.assertTrue('Headers' in self.requestData) headers = self.requestData['Headers'] self.assertEquals('PUT', self.requestData['Method']) self.assertEquals('application/x-www-form-urlencoded', headers['Content-Type']) self.assertEquals(8, int(headers['Content-Length'])) self.assertTrue('Body' in self.requestData) self.assertEquals('bodydata', self.requestData['Body']) # cleanup sok.close() server.shutdown()
def testInvalidPOSTRequestStartsOnlyOneTimer(self): # problem in found in OAS, timers not removed properly when whole body hasnt been read yet _httpserver.RECVSIZE = 1 with Reactor() as reactor: timers = [] orgAddTimer = reactor.addTimer def addTimerInterceptor(*timer): timers.append(timer) return orgAddTimer(*timer) reactor.addTimer = addTimerInterceptor server = HttpServer(reactor, self.port, lambda **kwargs: (x for x in []), timeout=0.01) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('POST / HTTP/1.0\r\nContent-Length: 10\r\n\r\n') reactor.step() sok.send(".") sleep(0.1) reactor.step() sok.send(".") reactor.step() sleep(0.1) while select([sok],[], [], 0) != ([sok], [], []): reactor.step() self.assertEquals(2, len(timers)) # cleanup sok.close() server.shutdown()
def XXX_testPostMultipartFormCompressed(self): """Not yet""" httpRequest = open(inmydir('data/multipart-data-01-compressed')).read() self.requestData = {} def handler(**kwargs): self.requestData = kwargs return yield with Reactor() as reactor: server = HttpServer(reactor, self.port, handler) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send(httpRequest) reactor.addTimer(2, lambda: self.fail("Test Stuck")) while self.requestData.get('Form', None) == None: reactor.step() form = self.requestData['Form'] self.assertEquals(4, len(form)) self.assertEquals(['SOME ID'], form['id']) # cleanup sok.close() server.shutdown()
def testWindowsPostMultipartForm(self): httpRequest = open(inmydir('data/multipart-data-02')).read() self.requestData = {} def handler(**kwargs): self.requestData = kwargs return yield with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send(httpRequest) reactor.addTimer(2, lambda: self.fail("Test Stuck")) while self.requestData.get('Form', None) == None: reactor.step() form = self.requestData['Form'] self.assertEquals(4, len(form)) self.assertEquals(['SOME ID'], form['id']) self.assertEquals(1, len(form['somename'])) filename, mimetype, data = form['somename'][0] self.assertEquals('Bank Gothic Medium BT.ttf', filename) self.assertEquals('application/octet-stream', mimetype) # cleanup sok.close() server.shutdown()
def testHttpServerEncodesUnicode(self): unicodeString = u'some t\xe9xt' oneStringLength = len(unicodeString.encode(getdefaultencoding())) self.assertTrue(len(unicodeString) != oneStringLength) def response(**kwargs): yield unicodeString * 6000 with Reactor() as reactor: server = HttpServer(reactor, self.port, response, recvSize=3) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('GET /path/here HTTP/1.0\r\nConnection: close\r\nApe-Nut: Mies\r\n\r\n') writers = lambda: [c for c in reactor._fds.values() if c.intent == WRITE_INTENT] while not writers(): reactor.step() reactor.step() reactor.step() fragment = sok.recv(100000) # will read about 49152 chars self.assertEquals(oneStringLength * 6000, len(fragment)) self.assertTrue("some t\xc3\xa9xt" in fragment, fragment) # cleanup sok.close() server.shutdown()
def testSmallFragmentsWhileSendingResponse(self): def response(**kwargs): yield '' # Socket poking here - then try to really send stuff yield 'some text that is longer than ' yield 'the lenght of fragments sent' with Reactor() as reactor: server = HttpServer(reactor, self.port, response, recvSize=3) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('GET /path/here HTTP/1.0\r\nConnection: close\r\nApe-Nut: Mies\r\n\r\n') writerFile = lambda: [context.fileOrFd for context in reactor._fds.values() if context.intent == WRITE_INTENT] while not writerFile(): reactor.step() serverSok = writerFile()[0] originalSend = serverSok.send def sendOnlyManagesToActuallySendThreeBytesPerSendCall(data, *options): originalSend(data[:3], *options) return 3 serverSok.send = sendOnlyManagesToActuallySendThreeBytesPerSendCall for i in range(22): reactor.step() fragment = sok.recv(4096) self.assertEquals('some text that is longer than the lenght of fragments sent', fragment) # cleanup sok.close() server.shutdown()
def testPostMethodTimesOutOnBadBody(self): self.requestData = None def handler(**kwargs): self.requestData = kwargs return yield done = [] def onDone(): fromServer = sok.recv(1024) self.assertTrue('HTTP/1.0 400 Bad Request' in fromServer) done.append(True) with Reactor() as reactor: server = HttpServer(reactor, self.port, handler, timeout=0.01) server.listen() reactor.addTimer(0.02, onDone) sok = socket() sok.connect(('localhost', self.port)) sok.send('POST / HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 8\r\n\r\n') while not done: reactor.step() # cleanup sok.close() server.shutdown()
def testConnectBindAddress(self): reactor = CallTrace() server = HttpServer(reactor, self.port, lambda **kwargs: None, bindAddress='127.0.0.1') server.listen() self.assertEquals(('127.0.0.1', self.port), server._acceptor._sok.getsockname()) # cleanup server.shutdown()
class AsyncReaderTest(WeightlessTestCase): def dispatch(self, *args, **kwargs): return compose(self.handler(*args, **kwargs)) def setUp(self): WeightlessTestCase.setUp(self) self.reactor = Reactor() self.port = randint(2**10, 2**16) self.httpserver = HttpServer(self.reactor, self.port, self.dispatch) self.httpserver.listen() def tearDown(self): self.httpserver.shutdown() self.reactor.shutdown() WeightlessTestCase.tearDown(self) def testHttpRequest(self): self.assertEquals('GET / HTTP/1.0\r\n', _httpRequest('GET', '/')) self.assertEquals('POST / HTTP/1.0\r\n', _httpRequest('POST', '/')) def testPassRequestThruToBackOfficeServer(self): done = [False] backofficeport = self.port + 1 def passthruhandler(*args, **kwargs): request = kwargs['RequestURI'] response = yield httpget('localhost', backofficeport, request) yield response done[0] = True self.handler = passthruhandler expectedrequest = "GET /depot?arg=1&arg=2 HTTP/1.0\r\n\r\n" responses = (i for i in ['hel', 'lo!']) backofficeserver = testserver(backofficeport, responses, expectedrequest) client = clientget('localhost', self.port, '/depot?arg=1&arg=2') while not done[0]: self.reactor.step() response = client.recv(99) self.assertEquals('hello!', response) def testConnectFails(self): exceptions = [] def failingserver(*args, **kwarg): try: response = yield httpget(*target) except Exception, e: exceptions.append(exc_info()) self.handler = failingserver clientget('localhost', self.port, '/') target = ('localhost', 'port', '/') # non-numeric port try: with self.stderr_replaced(): with self.loopingReactor(): while not exceptions: pass except Exception, e: pass
def testValidRequestResetsTimer(self): with Reactor() as reactor: server = HttpServer(reactor, self.port, lambda **kwargs: ('a' for a in range(3)), timeout=0.01, recvSize=3) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('GET / HTTP/1.0\r\n\r\n') sleep(0.02) for i in range(11): reactor.step() response = sok.recv(4096) self.assertEquals('aaa', response) # cleanup sok.close() server.shutdown()
def testDefaultErrorHandler(self): def handler(**kwargs): yield "OK" server = HttpServer(self.reactor, self.port, handler, maxConnections=5) server.listen() self.reactor.getOpenConnections = lambda: 10 sock = socket() sock.connect(('localhost', self.port)) self.reactor.step() sock.send("GET / HTTP/1.0\r\n\r\n") self.reactor.step().step().step() self.assertEquals('HTTP/1.0 503 Service Unavailable\r\n\r\n<html><head></head><body><h1>Service Unavailable</h1></body></html>', sock.recv(1024)) server.shutdown()
def testInvalidRequestWithHalfHeader(self): with Reactor() as reactor: server = HttpServer(reactor, self.port, None, timeout=0.1) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('POST / HTTP/1.0\r\n') sok.send('Expect: something\r\n') sok.send('Content-Length: 5\r\n') sok.send('\r\n1234') sok.close() with self.stderr_replaced() as s: for i in range(4): reactor.step() self.assertEquals(1, len([c for c in reactor._fds.values() if c.intent == READ_INTENT])) # cleanup sok.close() server.shutdown()
def testDefaultErrorHandler(self): def handler(**kwargs): yield "OK" server = HttpServer(self.reactor, self.port, handler, maxConnections=5) server.listen() self.reactor.getOpenConnections = lambda: 10 sock = socket() sock.connect(('localhost', self.port)) self.reactor.step() sock.send("GET / HTTP/1.0\r\n\r\n") self.reactor.step().step().step() self.assertEquals( 'HTTP/1.0 503 Service Unavailable\r\n\r\n<html><head></head><body><h1>Service Unavailable</h1></body></html>', sock.recv(1024)) server.shutdown()
def testSendHeader(self): self.kwargs = None def response(**kwargs): self.kwargs = kwargs yield 'nosense' with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, response) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('GET /path/here HTTP/1.0\r\nConnection: close\r\nApe-Nut: Mies\r\n\r\n') while not self.kwargs: reactor.step() self.assertEquals({'Body': '', 'RequestURI': '/path/here', 'HTTPVersion': '1.0', 'Method': 'GET', 'Headers': {'Connection': 'close', 'Ape-Nut': 'Mies'}, 'Client': ('127.0.0.1', MATCHALL)}, self.kwargs) # cleanup sok.close() server.shutdown()
def testOnlyHandleAMaximumNrOfRequestsBelowBoundary(self): def handler(**kwargs): yield "OK" def error_handler(**kwargs): yield "FAIL" server = HttpServer(self.reactor, self.port, handler, errorHandler=error_handler, maxConnections=10) server.listen() self.reactor.getOpenConnections = lambda: 5 sock = socket() sock.connect(('localhost', self.port)) self.reactor.step() sock.send("GET / HTTP/1.0\r\n\r\n") self.reactor.step().step().step() server.shutdown() self.assertEquals('OK', sock.recv(1024))
def testConnect(self): self.req = False def onRequest(**kwargs): self.req = True yield 'nosens' with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, onRequest) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('GET / HTTP/1.0\r\n\r\n') reactor.step() # connect/accept reactor.step() # read GET request reactor.step() # call onRequest for response data self.assertEquals(True, self.req) # cleanup server.shutdown() sok.close()
def testHandlerExitsWithException(self): exceptions = [] exc_message = "this is not an I/O exception, but an application exception" yielded_data = "a bit of data" def handler(**kwargs): yield yielded_data raise Exception(exc_message) yield server = HttpServer(self.reactor, self.port, handler, maxConnections=5) server.listen() sock = socket() sock.connect(('localhost', self.port)) self.reactor.step() sock.send("GET / HTTP/1.0\r\n\r\n") self.reactor.step() with stderr_replaced() as f: self.reactor.step().step() self.assertFalse(yielded_data in f.getvalue()) self.assertTrue("Exception: %s" % exc_message in f.getvalue()) server.shutdown() sock.close()
def testReadChunkedPost(self): self.requestData = {} def handler(**kwargs): self.requestData = kwargs return yield with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler, timeout=0.01, recvSize=3) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('POST / HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nabcde\r\n5\r\nfghij\r\n0\r\n') reactor.addTimer(0.2, lambda: self.fail("Test Stuck")) while self.requestData.get('Body', None) != 'abcdefghij': reactor.step() # cleanup sok.close() server.shutdown()
def sendRequestAndReceiveResponse(self, request, response='The Response', recvSize=4096, compressResponse=False, extraStepAfterCompress=True): self.responseCalled = False @compose def responseGenFunc(**kwargs): yield response yield '' self.responseCalled = True server = HttpServer(self.reactor, self.port, responseGenFunc, recvSize=recvSize, compressResponse=compressResponse) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send(request) mockStdout = None with self.stdout_replaced() as mockStdout: while not self.responseCalled: self.reactor.step() if compressResponse and extraStepAfterCompress: #not everythingSent???: self.reactor.step() stdoutValue = mockStdout.getvalue() if stdoutValue: print stdoutValue server.shutdown() r = sok.recv(4096) sok.close() return r
def testInvalidGETRequestStartsOnlyOneTimer(self): _httpserver.RECVSIZE = 3 with Reactor() as reactor: timers = [] orgAddTimer = reactor.addTimer def addTimerInterceptor(*timer): timers.append(timer) return orgAddTimer(*timer) reactor.addTimer = addTimerInterceptor server = HttpServer(reactor, self.port, None, timeout=0.01) server.listen() sok = socket() sok.connect(('localhost', self.port)) sok.send('GET HTTP/1.0\r\n\r\n') # no path while select([sok],[], [], 0) != ([sok], [], []): reactor.step() response = sok.recv(4096) self.assertEquals('HTTP/1.0 400 Bad Request\r\n\r\n', response) self.assertEquals(1, len(timers)) # cleanup sok.close() server.shutdown()
def testOnlyHandleAMaximumNrOfRequestsBelowBoundary(self): def handler(**kwargs): yield "OK" def error_handler(**kwargs): yield "FAIL" server = HttpServer(self.reactor, self.port, handler, errorHandler=error_handler, maxConnections=10) server.listen() self.reactor.getOpenConnections = lambda: 5 sock = socket() sock.connect(('localhost', self.port)) self.reactor.step() sock.send("GET / HTTP/1.0\r\n\r\n") self.reactor.step().step().step() server.shutdown() self.assertEquals('OK', sock.recv(1024))
def testPostMethodDeCompressesDeflatedBody_gzip(self): self.requestData = None def handler(**kwargs): self.requestData = kwargs return yield with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler, timeout=0.01) server.listen() sok = socket() sok.connect(('localhost', self.port)) bodyData = 'bodydatabodydata' _sio = StringIO() _gzFileObj = GzipFile(filename=None, mode='wb', compresslevel=6, fileobj=_sio) _gzFileObj.write(bodyData); _gzFileObj.close() bodyDataCompressed = _sio.getvalue() contentLengthCompressed = len(bodyDataCompressed) sok.send(('POST / HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\nContent-Encoding: gzip\r\n\r\n' % contentLengthCompressed) + bodyDataCompressed) while not self.requestData: reactor.step() self.assertEquals(dict, type(self.requestData)) self.assertTrue('Headers' in self.requestData) headers = self.requestData['Headers'] self.assertEquals('POST', self.requestData['Method']) self.assertEquals('application/x-www-form-urlencoded', headers['Content-Type']) self.assertEquals(contentLengthCompressed, int(headers['Content-Length'])) self.assertTrue('Body' in self.requestData) self.assertEquals('bodydatabodydata', self.requestData['Body']) # cleanup sok.close() server.shutdown()
def testYieldPossibleUseCase(self): bucket = [] result = [] ready = [] useYield = [] workDone = [] def handler(RequestURI, **kwargs): name = 'work' if 'aLotOfWork' in RequestURI else 'lazy' bucket.append('%s_START' % name) yield 'START' if '/aLotOfWork' in RequestURI: bucket.append('%s_part_1' % name) if True in useYield: while not workDone: yield Yield bucket.append('%s_part_2' % name) bucket.append('%s_END' % name) ready.append('yes') yield 'END' with stdout_replaced(): with Reactor() as reactor: server = HttpServer(reactor, self.port, handler) server.listen() def loopWithYield(use): del ready[:] del bucket[:] del result[:] del workDone[:] useYield[:] = [use] sok0 = socket() sok0.connect(('localhost', self.port)) sok0.send('GET /aLotOfWork HTTP/1.0\r\n\r\n') sok1 = socket() sok1.connect(('localhost', self.port)) sok1.send('GET /path/here HTTP/1.0\r\n\r\n') sleep(0.02) while ready != ['yes']: reactor.step() if bucket: result.append(set(bucket)) del bucket[:] workDone.append(True) while ready != ['yes', 'yes']: reactor.step() if bucket: result.append(set(bucket)) del bucket[:] sok0.close() sok1.close() return result self.assertEquals([ set(['work_START']), set(['lazy_START', 'work_part_1', 'work_part_2', 'work_END']), set(['lazy_END']) ], loopWithYield(False)) self.assertEquals([ set(['work_START']), set(['lazy_START', 'work_part_1']), set(['lazy_END']), set(['work_part_2', 'work_END']), ], loopWithYield(True)) # cleanup server.shutdown()
class ObservableHttpServer(Observable): def __init__(self, reactor, port, timeout=1, prio=None, sok=None, maxConnections=None, compressResponse=True, bindAddress=None): Observable.__init__(self) self._port = port self._reactor = reactor self._timeout = timeout self._started = False self._prio = prio self._sok = sok self._maxConnections = maxConnections self._compressResponse = compressResponse self._bindAddress = bindAddress def startServer(self): """Starts server, When running a http server on port 80, this method should be called by the root user. In other cases it will be started when initializing all observers, see observer_init() """ self._httpserver = HttpServer(self._reactor, self._port, self._connect, timeout=self._timeout, prio=self._prio, sok=self._sok, maxConnections=self._maxConnections, errorHandler=self._error, compressResponse=self._compressResponse, bindAddress=self._bindAddress) self._httpserver.listen() self._started = True def observer_init(self): if not self._started: self.startServer() def _connect(self, **kwargs): return compose(self.handleRequest(port=self._port, **kwargs)) def _error(self, **kwargs): yield serverUnavailableHtml +\ '<html><head></head><body><h1>Service Unavailable</h1></body></html>' self.do.logHttpError(**kwargs) def handleRequest(self, RequestURI=None, **kwargs): scheme, netloc, path, query, fragments = urlsplit(RequestURI) arguments = parse_qs(str(query, encoding="utf-8"), keep_blank_values=True) requestArguments = { 'scheme': scheme, 'netloc': netloc, 'path': path, 'query': query, 'fragments': fragments, 'arguments': arguments, 'RequestURI': RequestURI } requestArguments.update(kwargs) savedBody = None if 'Body' in requestArguments: savedBody = requestArguments.pop('Body') convertedResult = _convertToStrings(requestArguments) if not savedBody is None: convertedResult['Body'] = savedBody yield self.all.handleRequest(**convertedResult) def setMaxConnections(self, m): self._httpserver.setMaxConnections(m) def shutdown(self): self._httpserver.shutdown()
class AsyncReaderTest(WeightlessTestCase): def setUp(self): WeightlessTestCase.setUp(self) self.port = PortNumberGenerator.next() self.httpserver = HttpServer(self.reactor, self.port, self._dispatch) self.httpserver.listen() def tearDown(self): self.httpserver.shutdown() WeightlessTestCase.tearDown(self) def testRequestLine(self): self.assertEquals('GET / HTTP/1.0\r\n', _requestLine('GET', '/')) self.assertEquals('POST / HTTP/1.0\r\n', _requestLine('POST', '/')) def testEmptyRequestConvenientlyTranslatedToSlash(self): self.assertEquals('GET / HTTP/1.0\r\n', _requestLine('GET', '')) self.assertEquals('POST / HTTP/1.0\r\n', _requestLine('POST', '')) def testPassRequestThruToBackOfficeServer(self): backofficeport = PortNumberGenerator.next() def passthruhandler(*args, **kwargs): request = kwargs['RequestURI'] response = yield httpget('localhost', backofficeport, request) yield response self.handler = passthruhandler expectedrequest = "GET /depot?arg=1&arg=2 HTTP/1.0\r\n\r\n" responses = (i for i in ['hel', 'lo!']) backofficeserver = testserver(backofficeport, responses, expectedrequest) client = clientget('localhost', self.port, '/depot?arg=1&arg=2') self._loopReactorUntilDone() response = client.recv(99) self.assertEquals('hello!', response) def testPassRequestThruToBackOfficeServerWithHttpRequest(self): backofficeport = PortNumberGenerator.next() def passthruhandler(*args, **kwargs): request = kwargs['RequestURI'] response = yield HttpRequest().httprequest(host='localhost', port=backofficeport, request=request) yield response self.handler = passthruhandler expectedrequest = "GET /depot?arg=1&arg=2 HTTP/1.0\r\n\r\n" responses = (i for i in ['hel', 'lo!']) backofficeserver = testserver(backofficeport, responses, expectedrequest) client = clientget('localhost', self.port, '/depot?arg=1&arg=2') self._loopReactorUntilDone() response = client.recv(99) self.assertEquals('hello!', response) @stderr_replaced def testConnectFails(self): def failingserver(*args, **kwarg): response = yield httpget(*target) self.handler = failingserver clientget('localhost', self.port, '/') target = ('localhost', 'port', '/') # non-numeric port self._loopReactorUntilDone() expectedTraceback = ignoreLineNumbers( """Traceback (most recent call last): File "%(__file__)s", line 0, in handle yield self.handler(*args, **kwargs) File "%(__file__)s", line 85, in failingserver response = yield httpget(*target) File "%(httprequest.py)s", line 78, in httprequest result = s.getResult() File "%(suspend.py)s", line 34, in __call__ self._doNext(self) File "%(httprequest.py)s", line 35, in _do sok.connect((host, port)) File "<string>", line 1, in connect TypeError: an integer is required """ % fileDict) if PYVERSION == "2.7": expectedTraceback = ignoreLineNumbers( """Traceback (most recent call last): File "%(__file__)s", line 0, in handle yield self.handler(*args, **kwargs) File "%(__file__)s", line 85, in failingserver response = yield httpget(*target) File "%(httprequest.py)s", line 78, in httprequest result = s.getResult() File "%(suspend.py)s", line 34, in __call__ self._doNext(self) File "%(httprequest.py)s", line 35, in _do sok.connect((host, port)) File "/usr/lib/python2.7/socket.py", line [#], in meth return getattr(self._sock,name)(*args) TypeError: an integer is required """ % fileDict) self.assertEquals(TypeError, self.error[0]) self.assertEqualsWS( expectedTraceback, ignoreLineNumbers(''.join(format_exception(*self.error)))) target = ('localhost', 87, '/') # invalid port clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertEquals(IOError, self.error[0]) target = ('UEYR^$*FD(#>NDJ.khfd9.(*njnd', PortNumberGenerator.next(), '/') # invalid host clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertEquals(SocketGaiError, self.error[0]) target = ('127.0.0.1', PortNumberGenerator.next(), '/' ) # No-one listens clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertEquals(IOError, self.error[0]) self.assertEquals('111', str(self.error[1])) @stdout_replaced def testTracebackPreservedAcrossSuspend(self): backofficeport = PortNumberGenerator.next() expectedrequest = '' testserver(backofficeport, [], expectedrequest) target = ('localhost', backofficeport, '/') exceptions = [] def failingserver(*args, **kwarg): response = yield httpget(*target) self.handler = failingserver def requestLine(self, *args, **kwargs): raise RuntimeError("Boom!") try: originalRequestLine = httpRequestModule._requestLine httpRequestModule._requestLine = requestLine clientget('localhost', self.port, '/') with stderr_replaced(): self._loopReactorUntilDone() expectedTraceback = ignoreLineNumbers( """Traceback (most recent call last): File "%(__file__)s", line 0, in handle yield self.handler(*args, **kwargs) File "%(__file__)s", line 192, in failingserver response = yield httpget(*target) File "%(httprequest.py)s", line 129, in httprequest result = s.getResult() File "%(httprequest.py)s", line 83, in _do yield _sendHttpHeaders(sok, method, request, headers) File "%(httprequest.py)s", line 121, in _sendHttpHeaders data = _requestLine(method, request) File "%(__file__)s", line 198, in requestLine raise RuntimeError("Boom!") RuntimeError: Boom!""" % fileDict) resultingTraceback = ''.join(format_exception(*self.error)) self.assertEqualsWS(expectedTraceback, ignoreLineNumbers(resultingTraceback)) finally: httpRequestModule._requestLine = originalRequestLine def testHttpPost(self): post_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, post_request) body = u"BÖDY" * 20000 responses = [] def posthandler(*args, **kwargs): response = yield httppost('localhost', port, '/path', body, headers={'Content-Type': 'text/plain'}) yield response responses.append(response) self.handler = posthandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("POST RESPONSE" in responses[0], responses[0]) self.assertEquals('POST', post_request[0]['command']) self.assertEquals('/path', post_request[0]['path']) headers = post_request[0]['headers'].headers self.assertEquals( ['Content-Length: 100000\r\n', 'Content-Type: text/plain\r\n'], headers) self.assertEquals(body, post_request[0]['body']) def testHttpPostWithoutHeaders(self): post_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, post_request) body = u"BÖDY" * 20000 responses = [] def posthandler(*args, **kwargs): response = yield httppost('localhost', port, '/path', body) yield response responses.append(response) self.handler = posthandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("POST RESPONSE" in responses[0], responses[0]) self.assertEquals('POST', post_request[0]['command']) self.assertEquals('/path', post_request[0]['path']) headers = post_request[0]['headers'].headers self.assertEquals(['Content-Length: 100000\r\n'], headers) self.assertEquals(body, post_request[0]['body']) def testHttpsPost(self): post_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, post_request, ssl=True) body = u"BÖDY" * 20000 responses = [] def posthandler(*args, **kwargs): response = yield httpspost('localhost', port, '/path', body, headers={'Content-Type': 'text/plain'}) yield response responses.append(response) self.handler = posthandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("POST RESPONSE" in responses[0], responses[0]) self.assertEquals('POST', post_request[0]['command']) self.assertEquals('/path', post_request[0]['path']) headers = post_request[0]['headers'].headers self.assertEquals( ['Content-Length: 100000\r\n', 'Content-Type: text/plain\r\n'], headers) self.assertEquals(body, post_request[0]['body']) @stderr_replaced def testHttpsPostOnIncorrectPort(self): responses = [] def posthandler(*args, **kwargs): response = yield httpspost('localhost', PortNumberGenerator.next(), '/path', "body", headers={'Content-Type': 'text/plain'}) yield response responses.append(response) self.handler = posthandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue(self.error[0] is IOError) self.assertEquals("111", str(self.error[1])) def testHttpGet(self): get_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, get_request) responses = [] def gethandler(*args, **kwargs): response = 'no response yet' try: response = yield httpget('localhost', port, '/path', headers={ 'Content-Type': 'text/plain', 'Content-Length': 0 }, prio=4) finally: responses.append(response) yield 'HTTP/1.0 200 OK\r\n\r\n' self.handler = gethandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("GET RESPONSE" in responses[0], responses[0]) self.assertEquals('GET', get_request[0]['command']) self.assertEquals('/path', get_request[0]['path']) headers = get_request[0]['headers'].headers self.assertEquals( ['Content-Length: 0\r\n', 'Content-Type: text/plain\r\n'], headers) def testHttpRequest(self): get_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, get_request) responses = [] def gethandler(*args, **kwargs): response = 'no response yet' try: response = yield httprequest(method='MYMETHOD', host='localhost', port=port, request='/path', headers={ 'Content-Type': 'text/plain', 'Content-Length': 0 }, prio=4) finally: responses.append(response) yield 'HTTP/1.0 200 OK\r\n\r\n' self.handler = gethandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue( "Message: Unsupported method ('MYMETHOD')" in responses[0], responses[0]) def testHttpRequestWithTimeout(self): # And thus too http(s)get/post/... and friends. get_request = [] port = PortNumberGenerator.next() def slowData(): for i in xrange(5): yield i sleep(0.01) responses = [] def handlerFactory(timeout): def gethandler(*args, **kwargs): try: response = yield httprequest( method='GET', host='localhost', port=port, request='/path', headers={ 'Content-Type': 'text/plain', 'Content-Length': 0, 'Host': 'localhost' }, timeout=timeout, ) responses.append(response) except TimeoutException, e: responses.append(e) finally: assert responses, 'Either a timeout or response should have occurred.'
server.listen() sock = socket() sock.connect(('localhost', self.port)) self.reactor.step() sock.send("GET / HTTP/1.0\r\n\r\n") sock.shutdown(SHUT_RDWR) with stderr_replaced() as f: while not exceptions: self.reactor.step() self.assertTrue("Error while sending data \"%s" % yielded_data[:10] in f.getvalue()) self.assertTrue("Traceback" in f.getvalue()) self.assertTrue("[Errno 32] Broken pipe" in f.getvalue()) self.assertEquals("[Errno 32] Broken pipe", str(exceptions[0])) server.shutdown() sock.close() self.reactor.removeTimer(token=token) def testHandlerExitsWithException(self): exceptions = [] exc_message = "this is not an I/O exception, but an application exception" yielded_data = "a bit of data" def handler(**kwargs): yield yielded_data raise Exception(exc_message) yield server = HttpServer(self.reactor, self.port, handler, maxConnections=5) server.listen() sock = socket()
class AsyncReaderTest(WeightlessTestCase): def setUp(self): WeightlessTestCase.setUp(self) self.port = PortNumberGenerator.next() self.httpserver = HttpServer(self.reactor, self.port, self._dispatch) self.httpserver.listen() def tearDown(self): self.httpserver.shutdown() WeightlessTestCase.tearDown(self) def testRequestLine(self): self.assertEquals('GET / HTTP/1.0\r\n', _requestLine('GET', '/')) self.assertEquals('POST / HTTP/1.0\r\n', _requestLine('POST', '/')) def testEmptyRequestConvenientlyTranslatedToSlash(self): self.assertEquals('GET / HTTP/1.0\r\n', _requestLine('GET', '')) self.assertEquals('POST / HTTP/1.0\r\n', _requestLine('POST', '')) def testPassRequestThruToBackOfficeServer(self): backofficeport = PortNumberGenerator.next() def passthruhandler(*args, **kwargs): request = kwargs['RequestURI'] response = yield httpget('localhost', backofficeport, request) yield response self.handler = passthruhandler expectedrequest = "GET /depot?arg=1&arg=2 HTTP/1.0\r\n\r\n" responses = (i for i in ['hel', 'lo!']) backofficeserver = testserver(backofficeport, responses, expectedrequest) client = clientget('localhost', self.port, '/depot?arg=1&arg=2') self._loopReactorUntilDone() response = client.recv(99) self.assertEquals('hello!', response) def testPassRequestThruToBackOfficeServerWithHttpRequest(self): backofficeport = PortNumberGenerator.next() def passthruhandler(*args, **kwargs): request = kwargs['RequestURI'] response = yield HttpRequest().httprequest(host='localhost', port=backofficeport, request=request) yield response self.handler = passthruhandler expectedrequest = "GET /depot?arg=1&arg=2 HTTP/1.0\r\n\r\n" responses = (i for i in ['hel', 'lo!']) backofficeserver = testserver(backofficeport, responses, expectedrequest) client = clientget('localhost', self.port, '/depot?arg=1&arg=2') self._loopReactorUntilDone() response = client.recv(99) self.assertEquals('hello!', response) @stderr_replaced def testConnectFails(self): def failingserver(*args, **kwarg): response = yield httpget(*target) self.handler = failingserver clientget('localhost', self.port, '/') target = ('localhost', 'port', '/') # non-numeric port self._loopReactorUntilDone() expectedTraceback = ignoreLineNumbers("""Traceback (most recent call last): File "%(__file__)s", line 0, in handle yield self.handler(*args, **kwargs) File "%(__file__)s", line 85, in failingserver response = yield httpget(*target) File "%(httprequest.py)s", line 78, in httprequest result = s.getResult() File "%(suspend.py)s", line 34, in __call__ self._doNext(self) File "%(httprequest.py)s", line 35, in _do sok.connect((host, port)) File "<string>", line 1, in connect TypeError: an integer is required """ % fileDict) if PYVERSION == "2.7": expectedTraceback = ignoreLineNumbers("""Traceback (most recent call last): File "%(__file__)s", line 0, in handle yield self.handler(*args, **kwargs) File "%(__file__)s", line 85, in failingserver response = yield httpget(*target) File "%(httprequest.py)s", line 78, in httprequest result = s.getResult() File "%(suspend.py)s", line 34, in __call__ self._doNext(self) File "%(httprequest.py)s", line 35, in _do sok.connect((host, port)) File "/usr/lib/python2.7/socket.py", line [#], in meth return getattr(self._sock,name)(*args) TypeError: an integer is required """ % fileDict) self.assertEquals(TypeError, self.error[0]) self.assertEqualsWS(expectedTraceback, ignoreLineNumbers(''.join(format_exception(*self.error)))) target = ('localhost', 87, '/') # invalid port clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertEquals(IOError, self.error[0]) target = ('UEYR^$*FD(#>NDJ.khfd9.(*njnd', PortNumberGenerator.next(), '/') # invalid host clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertEquals(SocketGaiError, self.error[0]) target = ('127.0.0.1', PortNumberGenerator.next(), '/') # No-one listens clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertEquals(IOError, self.error[0]) self.assertEquals('111', str(self.error[1])) @stdout_replaced def testTracebackPreservedAcrossSuspend(self): backofficeport = PortNumberGenerator.next() expectedrequest = '' testserver(backofficeport, [], expectedrequest) target = ('localhost', backofficeport, '/') exceptions = [] def failingserver(*args, **kwarg): response = yield httpget(*target) self.handler = failingserver def requestLine(self, *args, **kwargs): raise RuntimeError("Boom!") try: originalRequestLine = httpRequestModule._requestLine httpRequestModule._requestLine = requestLine clientget('localhost', self.port, '/') with stderr_replaced(): self._loopReactorUntilDone() expectedTraceback = ignoreLineNumbers("""Traceback (most recent call last): File "%(__file__)s", line 0, in handle yield self.handler(*args, **kwargs) File "%(__file__)s", line 192, in failingserver response = yield httpget(*target) File "%(httprequest.py)s", line 129, in httprequest result = s.getResult() File "%(httprequest.py)s", line 83, in _do yield _sendHttpHeaders(sok, method, request, headers) File "%(httprequest.py)s", line 121, in _sendHttpHeaders data = _requestLine(method, request) File "%(__file__)s", line 198, in requestLine raise RuntimeError("Boom!") RuntimeError: Boom!""" % fileDict) resultingTraceback = ''.join(format_exception(*self.error)) self.assertEqualsWS(expectedTraceback, ignoreLineNumbers(resultingTraceback)) finally: httpRequestModule._requestLine = originalRequestLine def testHttpPost(self): post_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, post_request) body = u"BÖDY" * 20000 responses = [] def posthandler(*args, **kwargs): response = yield httppost('localhost', port, '/path', body, headers={'Content-Type': 'text/plain'} ) yield response responses.append(response) self.handler = posthandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("POST RESPONSE" in responses[0], responses[0]) self.assertEquals('POST', post_request[0]['command']) self.assertEquals('/path', post_request[0]['path']) headers = post_request[0]['headers'].headers self.assertEquals(['Content-Length: 100000\r\n', 'Content-Type: text/plain\r\n'], headers) self.assertEquals(body, post_request[0]['body']) def testHttpPostWithoutHeaders(self): post_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, post_request) body = u"BÖDY" * 20000 responses = [] def posthandler(*args, **kwargs): response = yield httppost('localhost', port, '/path', body) yield response responses.append(response) self.handler = posthandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("POST RESPONSE" in responses[0], responses[0]) self.assertEquals('POST', post_request[0]['command']) self.assertEquals('/path', post_request[0]['path']) headers = post_request[0]['headers'].headers self.assertEquals(['Content-Length: 100000\r\n'], headers) self.assertEquals(body, post_request[0]['body']) def testHttpsPost(self): post_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, post_request, ssl=True) body = u"BÖDY" * 20000 responses = [] def posthandler(*args, **kwargs): response = yield httpspost('localhost', port, '/path', body, headers={'Content-Type': 'text/plain'} ) yield response responses.append(response) self.handler = posthandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("POST RESPONSE" in responses[0], responses[0]) self.assertEquals('POST', post_request[0]['command']) self.assertEquals('/path', post_request[0]['path']) headers = post_request[0]['headers'].headers self.assertEquals(['Content-Length: 100000\r\n', 'Content-Type: text/plain\r\n'], headers) self.assertEquals(body, post_request[0]['body']) @stderr_replaced def testHttpsPostOnIncorrectPort(self): responses = [] def posthandler(*args, **kwargs): response = yield httpspost('localhost', PortNumberGenerator.next(), '/path', "body", headers={'Content-Type': 'text/plain'} ) yield response responses.append(response) self.handler = posthandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue(self.error[0] is IOError) self.assertEquals("111", str(self.error[1])) def testHttpGet(self): get_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, get_request) responses = [] def gethandler(*args, **kwargs): response = 'no response yet' try: response = yield httpget('localhost', port, '/path', headers={'Content-Type': 'text/plain', 'Content-Length': 0}, prio=4 ) finally: responses.append(response) yield 'HTTP/1.0 200 OK\r\n\r\n' self.handler = gethandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("GET RESPONSE" in responses[0], responses[0]) self.assertEquals('GET', get_request[0]['command']) self.assertEquals('/path', get_request[0]['path']) headers = get_request[0]['headers'].headers self.assertEquals(['Content-Length: 0\r\n', 'Content-Type: text/plain\r\n'], headers) def testHttpRequest(self): get_request = [] port = PortNumberGenerator.next() self.referenceHttpServer(port, get_request) responses = [] def gethandler(*args, **kwargs): response = 'no response yet' try: response = yield httprequest(method='MYMETHOD', host='localhost', port=port, request='/path', headers={'Content-Type': 'text/plain', 'Content-Length': 0}, prio=4 ) finally: responses.append(response) yield 'HTTP/1.0 200 OK\r\n\r\n' self.handler = gethandler clientget('localhost', self.port, '/') self._loopReactorUntilDone() self.assertTrue("Message: Unsupported method ('MYMETHOD')" in responses[0], responses[0]) def testHttpRequestWithTimeout(self): # And thus too http(s)get/post/... and friends. get_request = [] port = PortNumberGenerator.next() def slowData(): for i in xrange(5): yield i sleep(0.01) responses = [] def handlerFactory(timeout): def gethandler(*args, **kwargs): try: response = yield httprequest(method='GET', host='localhost', port=port, request='/path', headers={'Content-Type': 'text/plain', 'Content-Length': 0, 'Host': 'localhost'}, timeout=timeout, ) responses.append(response) except TimeoutException, e: responses.append(e) finally: assert responses, 'Either a timeout or response should have occurred.'
def testSuspendTimingProtocol(self): # happy path for timing out and not timing out def test(expectTimeout): count = [] timedOut = [] @identify def workInSuspendGenF(): this = yield suspend = yield suspend._reactor.addProcess(process=this.next) try: for i in xrange(5): count.append(True) yield while True: sleep(0.0001) if not expectTimeout: break yield suspend.resume('retval') except TimeoutException: timedOut.append(True) finally: suspend._reactor.removeProcess(process=this.next) yield # Wait for GC def workInSuspend(): g = workInSuspendGenF() def doNext(suspend): g.send(suspend) def onTimeout(): g.throw(TimeoutException, TimeoutException(), None) return doNext, onTimeout def suspendWrap(): doNext, onTimeout = workInSuspend() s = Suspend(doNext=doNext, timeout=0.01, onTimeout=onTimeout) yield s result = s.getResult() if expectTimeout: self.fail('Should not have come here') raise StopIteration(result) try: result = yield suspendWrap() if expectTimeout: self.fail() except TimeoutException: self.assertEquals(5, len(count)) self.assertEquals(expectTimeout, bool(timedOut)) if not expectTimeout: self.assertEquals('retval', result) testRun.append(True) # Simple driver - timing out testRun = [] asProcess(test(expectTimeout=True)) self.assertEquals(True, bool(testRun)) # Simple driver - not timing out del testRun[:] asProcess(test(expectTimeout=False)) self.assertEquals(True, bool(testRun)) # http server - timing out reactor0 = self.reactor self.reactor = reactor1 = Reactor() del testRun[:] port = PortNumberGenerator.next() def reqHandler(**whatever): def inner(): yield test(expectTimeout=True) yield 'HTTP/1.0 200 OK\r\n\r\n' return compose(inner()) servert = HttpServer(reactor=self.reactor, port=port, generatorFactory=reqHandler, bindAddress='127.42.42.42') servert.listen() with self.loopingReactor(): sok = self.httpGet(host='127.42.42.42', port=port, path='/ignored') allData = '' try: while allData != 'HTTP/1.0 200 OK\r\n\r\n': allData += sok.recv(4096) finally: servert.shutdown() self.assertEquals(True, bool(testRun)) # http server - not timing out self.reactor = reactor2 = Reactor() del testRun[:] port = PortNumberGenerator.next() def reqHandler(**whatever): def inner(): yield test(expectTimeout=False) yield 'HTTP/1.0 200 OK\r\n\r\n' return compose(inner()) servert = HttpServer(reactor=self.reactor, port=port, generatorFactory=reqHandler, bindAddress='127.42.42.42') servert.listen() with self.loopingReactor(): sok = self.httpGet(host='127.42.42.42', port=port, path='/ignored') allData = '' try: while allData != 'HTTP/1.0 200 OK\r\n\r\n': allData += sok.recv(4096) finally: servert.shutdown() self.assertEquals(True, bool(testRun)) # cleanup (most) stuff reactor0.shutdown() reactor1.shutdown() reactor2.shutdown()