Commit d7e92149 authored by Denis Bilenko's avatar Denis Bilenko

update test__server*.py

parent c666e418
...@@ -20,7 +20,7 @@ class SimpleStreamServer(StreamServer): ...@@ -20,7 +20,7 @@ class SimpleStreamServer(StreamServer):
raise raise
if path == '/ping': if path == '/ping':
client_socket.sendall('HTTP/1.0 200 OK\r\n\r\nPONG') client_socket.sendall('HTTP/1.0 200 OK\r\n\r\nPONG')
elif path == '/long': elif path in ['/long', '/short']:
client_socket.sendall('hello') client_socket.sendall('hello')
while True: while True:
data = client_socket.recv(1) data = client_socket.recv(1)
...@@ -34,13 +34,16 @@ class Settings: ...@@ -34,13 +34,16 @@ class Settings:
ServerClass = StreamServer ServerClass = StreamServer
ServerSubClass = SimpleStreamServer ServerSubClass = SimpleStreamServer
restartable = True restartable = True
close_socket_detected = True
@staticmethod @staticmethod
def assert500(self): def assertAcceptedConnectionError(self):
conn = self.makefile() conn = self.makefile()
result = conn.read() result = conn.read()
assert not result, repr(result) assert not result, repr(result)
assert500 = assertAcceptedConnectionError
@staticmethod @staticmethod
def assert503(self): def assert503(self):
# regular reads timeout # regular reads timeout
...@@ -52,6 +55,10 @@ class Settings: ...@@ -52,6 +55,10 @@ class Settings:
if ex[0] != errno.ECONNRESET: if ex[0] != errno.ECONNRESET:
raise raise
@staticmethod
def assertPoolFull(self):
self.assertRaises(socket.timeout, self.assertRequestSucceeded, timeout=0.01)
class TestCase(greentest.TestCase): class TestCase(greentest.TestCase):
...@@ -91,6 +98,12 @@ class TestCase(greentest.TestCase): ...@@ -91,6 +98,12 @@ class TestCase(greentest.TestCase):
def assert503(self): def assert503(self):
Settings.assert503(self) Settings.assert503(self)
def assertAcceptedConnectionError(self):
Settings.assertAcceptedConnectionError(self)
def assertPoolFull(self):
Settings.assertPoolFull(self)
def assertNotAccepted(self): def assertNotAccepted(self):
conn = self.makefile() conn = self.makefile()
conn.write('GET / HTTP/1.0\r\n\r\n') conn.write('GET / HTTP/1.0\r\n\r\n')
...@@ -107,16 +120,16 @@ class TestCase(greentest.TestCase): ...@@ -107,16 +120,16 @@ class TestCase(greentest.TestCase):
return return
assert result.startswith('HTTP/1.0 500 Internal Server Error'), repr(result) assert result.startswith('HTTP/1.0 500 Internal Server Error'), repr(result)
def assertConnectionSucceed(self): def assertRequestSucceeded(self, timeout=0.1):
conn = self.makefile() conn = self.makefile(timeout=timeout)
conn.write('GET /ping HTTP/1.0\r\n\r\n') conn.write('GET /ping HTTP/1.0\r\n\r\n')
result = conn.read() result = conn.read()
assert result.endswith('\r\n\r\nPONG'), repr(result) assert result.endswith('\r\n\r\nPONG'), repr(result)
def start_server(self): def start_server(self):
self.server.start() self.server.start()
self.assertConnectionSucceed() self.assertRequestSucceeded()
self.assertConnectionSucceed() self.assertRequestSucceeded()
def stop_server(self): def stop_server(self):
self.server.stop() self.server.stop()
...@@ -138,9 +151,9 @@ class TestCase(greentest.TestCase): ...@@ -138,9 +151,9 @@ class TestCase(greentest.TestCase):
return self.server.socket return self.server.socket
def _test_invalid_callback(self): def _test_invalid_callback(self):
self.hook_stderr()
self.server = self.ServerClass(('127.0.0.1', 0), lambda : None) self.server = self.ServerClass(('127.0.0.1', 0), lambda : None)
self.server.start() self.server.start()
self.hook_stderr()
self.assert500() self.assert500()
self.assert_stderr_traceback('TypeError') self.assert_stderr_traceback('TypeError')
self.assert_stderr(self.invalid_callback_message) self.assert_stderr(self.invalid_callback_message)
...@@ -171,7 +184,7 @@ class TestDefaultSpawn(TestCase): ...@@ -171,7 +184,7 @@ class TestDefaultSpawn(TestCase):
self.assertNotAccepted() self.assertNotAccepted()
self.server.start_accepting() self.server.start_accepting()
self.report_netstat('after start_accepting') self.report_netstat('after start_accepting')
self.assertConnectionSucceed() self.assertRequestSucceeded()
else: else:
self.assertRaises(Exception, self.server.start) # XXX which exception exactly? self.assertRaises(Exception, self.server.start) # XXX which exception exactly?
self.stop_server() self.stop_server()
...@@ -203,7 +216,7 @@ class TestDefaultSpawn(TestCase): ...@@ -203,7 +216,7 @@ class TestDefaultSpawn(TestCase):
g = gevent.spawn_link_exception(self.server.serve_forever) g = gevent.spawn_link_exception(self.server.serve_forever)
try: try:
gevent.sleep(0.01) gevent.sleep(0.01)
self.assertConnectionSucceed() self.assertRequestSucceeded()
self.server.stop() self.server.stop()
assert not self.server.started assert not self.server.started
self.assertConnectionRefused() self.assertConnectionRefused()
...@@ -233,7 +246,8 @@ class TestDefaultSpawn(TestCase): ...@@ -233,7 +246,8 @@ class TestDefaultSpawn(TestCase):
try: try:
try: try:
result = conn.read() result = conn.read()
assert result.startswith('HTTP/1.0 500 Internal Server Error'), repr(result) if result:
assert result.startswith('HTTP/1.0 500 Internal Server Error'), repr(result)
except socket.error, ex: except socket.error, ex:
if ex[0] != errno.ECONNRESET: if ex[0] != errno.ECONNRESET:
raise raise
...@@ -256,10 +270,10 @@ class TestDefaultSpawn(TestCase): ...@@ -256,10 +270,10 @@ class TestDefaultSpawn(TestCase):
self.hook_stderr() self.hook_stderr()
error = ExpectedError('test_error_in_spawn') error = ExpectedError('test_error_in_spawn')
self.server.spawn = lambda *args: gevent.getcurrent().throw(error) self.server.spawn = lambda *args: gevent.getcurrent().throw(error)
self.assert500() self.assertAcceptedConnectionError()
self.assert_stderr_traceback(error) self.assert_stderr_traceback(error)
#self.assert_stderr('^WARNING: <SimpleStreamServer .*?>: ignoring test_error_in_spawn \\(sleeping \d.\d+ seconds\\)\n$') #self.assert_stderr('^WARNING: <SimpleStreamServer .*?>: ignoring test_error_in_spawn \\(sleeping \d.\d+ seconds\\)\n$')
self.assert_stderr('Failed to handle...') self.assert_stderr('<.*?>: Failed to handle...')
return return
if Settings.restartable: if Settings.restartable:
assert not self.server.started assert not self.server.started
...@@ -282,26 +296,24 @@ class TestPoolSpawn(TestDefaultSpawn): ...@@ -282,26 +296,24 @@ class TestPoolSpawn(TestDefaultSpawn):
def get_spawn(self): def get_spawn(self):
return 2 return 2
def test_pull_full(self): def test_pool_full(self):
self.init_server() self.init_server()
pool = [] short_request = self.send_request('/short')
for _ in xrange(2): long_request = self.send_request('/long')
pool.append(self.send_request('/long'))
gevent.sleep(0.01) gevent.sleep(0.01)
print len(self.server.pool) self.assertPoolFull()
self.assert503() self.assertPoolFull()
self.assert503() self.assertPoolFull()
self.assert503() short_request._sock.close()
pool[0]._sock.close() # gevent.http and gevent.wsgi cannot detect socket close, so sleep a little
pool[0].close() # to let /short request finish
gevent.sleep(0.1) gevent.sleep(0.1)
print len(self.server.pool) self.assertRequestSucceeded()
self.assertConnectionSucceed()
class TestNoneSpawn(TestCase): class TestNoneSpawn(TestCase):
invalid_callback_message = 'Failed to handle' invalid_callback_message = '<.*?>: Failed to handle'
def get_spawn(self): def get_spawn(self):
return None return None
......
...@@ -23,7 +23,7 @@ class Test(unittest.TestCase): ...@@ -23,7 +23,7 @@ class Test(unittest.TestCase):
except socket.error, ex: except socket.error, ex:
self.assertEqual(ex[0], errno.ECONNREFUSED) self.assertEqual(ex[0], errno.ECONNREFUSED)
def assertConnectionSucceed(self): def assertRequestSucceeded(self):
conn = self.makefile() conn = self.makefile()
conn.write('GET /ping HTTP/1.0\r\n\r\n') conn.write('GET /ping HTTP/1.0\r\n\r\n')
result = conn.read() result = conn.read()
......
...@@ -4,13 +4,8 @@ from gevent import http ...@@ -4,13 +4,8 @@ from gevent import http
import test__server import test__server
from test__server import * from test__server import *
internal_error = '''HTTP/1.0 500 Internal Server Error internal_error_start = 'HTTP/1.0 500 Internal Server Error\n'.replace('\n', '\r\n')
Connection: close internal_error_end = '\n\nInternal Server Error'.replace('\n', '\r\n')
Content-type: text/plain
Content-length: 21
Internal Server Error'''.replace('\n', '\r\n')
internal_error503 = '''HTTP/1.0 503 Service Unavailable internal_error503 = '''HTTP/1.0 503 Service Unavailable
Connection: close Connection: close
...@@ -24,27 +19,31 @@ class SimpleHTTPServer(http.HTTPServer): ...@@ -24,27 +19,31 @@ class SimpleHTTPServer(http.HTTPServer):
def handle(self, request): def handle(self, request):
if request.uri == '/ping': if request.uri == '/ping':
request.send_reply(200, "OK", "PONG") request.send_reply(200, "OK", "PONG")
elif request.uri == '/short':
gevent.sleep(0.1)
request.send_reply(200, "OK", 'hello')
elif request.uri == '/long': elif request.uri == '/long':
request.send_reply_start(200, "OK") gevent.sleep(10)
request.send_reply_chunk("hello") request.send_reply(200, "OK", 'hello')
while request:
print request
gevent.sleep(0.01)
else: else:
request.send_reply(404, "what?", "") request.send_reply(404, "gevent.http", "")
class Settings: class Settings:
ServerClass = http.HTTPServer ServerClass = http.HTTPServer
ServerSubClass = SimpleHTTPServer ServerSubClass = SimpleHTTPServer
restartable = False restartable = False
close_socket_detected = False
@staticmethod @staticmethod
def assert500(self): def assert500(self):
conn = self.makefile() conn = self.makefile()
conn.write('GET / HTTP/1.0\r\n\r\n') conn.write('GET / HTTP/1.0\r\n\r\n')
result = conn.read() result = conn.read()
assert result == internal_error, (result, internal_error) assert result.startswith(internal_error_start), (result, internal_error_start)
assert result.endswith(internal_error_end), (result, internal_error_end)
assertAcceptedConnectionError = assert500
@staticmethod @staticmethod
def assert503(self): def assert503(self):
...@@ -53,6 +52,8 @@ class Settings: ...@@ -53,6 +52,8 @@ class Settings:
result = conn.read() result = conn.read()
assert result == internal_error503, (result, internal_error503) assert result == internal_error503, (result, internal_error503)
assertPoolFull = assert503
test__server.Settings = Settings test__server.Settings = Settings
......
...@@ -3,15 +3,27 @@ import gevent ...@@ -3,15 +3,27 @@ import gevent
from gevent import pywsgi from gevent import pywsgi
import test__server import test__server
from test__server import * from test__server import *
from test__server import Settings as server_Settings
from test__server_http import Settings as http_Settings from test__server_http import Settings as http_Settings
import gevent.wsgi; gevent.wsgi.WSGIServer.__init__ = None import gevent.wsgi; gevent.wsgi.WSGIServer.__init__ = None
def application(self, environ, start_response): def application(self, environ, start_response):
if environ['PATH_INFO'] == '/':
start_response("200 OK", [])
return ["PONG"]
if environ['PATH_INFO'] == '/ping': if environ['PATH_INFO'] == '/ping':
start_response("200 OK", []) start_response("200 OK", [])
return ["PONG"] return ["PONG"]
elif environ['PATH_INFO'] == '/short':
gevent.sleep(0.5)
start_response("200 OK", [])
return []
elif environ['PATH_INFO'] == '/long':
gevent.sleep(10)
start_response("200 OK", [])
return []
else: else:
start_response("404 pywsgi WTF?", []) start_response("404 pywsgi WTF?", [])
return [] return []
...@@ -24,14 +36,36 @@ class SimpleWSGIServer(pywsgi.WSGIServer): ...@@ -24,14 +36,36 @@ class SimpleWSGIServer(pywsgi.WSGIServer):
class Settings(http_Settings): class Settings(http_Settings):
ServerClass = pywsgi.WSGIServer ServerClass = pywsgi.WSGIServer
ServerSubClass = SimpleWSGIServer ServerSubClass = SimpleWSGIServer
close_socket_detected = True
@staticmethod
def assertPoolFull(self):
self.assertRaises(socket.timeout, self.assertRequestSucceeded)
@staticmethod
def assertAcceptedConnectionError(self):
conn = self.makefile()
result = conn.read()
assert not result, repr(result)
# @staticmethod
# def assert500(self):
# conn = self.makefile()
# result = conn.read()
# assert not result, repr(result)
test__server.Settings = Settings test__server.Settings = Settings
TestNoneSpawn.invalid_callback_message = 'Failed to handle...' msg = '<.*?>: Failed to handle...'
TestRawSpawn.invalid_callback_message = 'Failed to handle...'
TestPoolSpawn.invalid_callback_message = 'Failed to handle...' TestNoneSpawn.invalid_callback_message = msg
TestDefaultSpawn.invalid_callback_message = 'Failed to handle...' TestRawSpawn.invalid_callback_message = msg
TestPoolSpawn.invalid_callback_message = msg
TestDefaultSpawn.invalid_callback_message = msg
del TestNoneSpawn
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
......
...@@ -12,6 +12,14 @@ def application(self, environ, start_response): ...@@ -12,6 +12,14 @@ def application(self, environ, start_response):
if environ['PATH_INFO'] == '/ping': if environ['PATH_INFO'] == '/ping':
start_response("200 OK", []) start_response("200 OK", [])
return ["PONG"] return ["PONG"]
elif environ['PATH_INFO'] == '/short':
gevent.sleep(0.1)
start_response("200 after 0.1 seconds", [])
return ["hello"]
elif environ['PATH_INFO'] == '/long':
gevent.sleep(10)
start_response("200 after 10 seconds", [])
return ["hello"]
else: else:
start_response("404 wsgi WTF?", []) start_response("404 wsgi WTF?", [])
return [] return []
...@@ -28,10 +36,12 @@ class Settings(http_Settings): ...@@ -28,10 +36,12 @@ class Settings(http_Settings):
test__server.Settings = Settings test__server.Settings = Settings
TestNoneSpawn.invalid_callback_message = 'Failed to handle...' msg = '<.*?>: Failed to handle...'
TestRawSpawn.invalid_callback_message = 'Failed to handle...'
TestPoolSpawn.invalid_callback_message = 'Failed to handle...' TestNoneSpawn.invalid_callback_message = msg
TestDefaultSpawn.invalid_callback_message = 'Failed to handle...' TestRawSpawn.invalid_callback_message = msg
TestPoolSpawn.invalid_callback_message = msg
TestDefaultSpawn.invalid_callback_message = msg
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment