mirror of
https://github.com/ammaraskar/pyCraft.git
synced 2024-11-21 17:56:30 +01:00
Add test case reproducing #146 (fixed to behave consistently)
This commit is contained in:
parent
7693961fb9
commit
93db454cb5
@ -479,6 +479,8 @@ class Connection(object):
|
||||
self.write_packet(handshake)
|
||||
|
||||
def _handle_exception(self, exc, exc_info):
|
||||
final_handler = self.handle_exception
|
||||
|
||||
# Call the current PacketReactor's exception handler.
|
||||
try:
|
||||
if self.reactor.handle_exception(exc, exc_info):
|
||||
@ -499,9 +501,9 @@ class Connection(object):
|
||||
caught = False
|
||||
|
||||
# Call the user-specified final exception handler.
|
||||
if self.handle_exception not in (None, False):
|
||||
if final_handler not in (None, False):
|
||||
try:
|
||||
self.handle_exception(exc, exc_info)
|
||||
final_handler(exc, exc_info)
|
||||
except Exception as new_exc:
|
||||
exc, exc_info = new_exc, sys.exc_info()
|
||||
|
||||
@ -516,7 +518,7 @@ class Connection(object):
|
||||
self.disconnect(immediate=True)
|
||||
|
||||
# If allowed by the final exception handler, re-raise the exception.
|
||||
if self.handle_exception is None and not caught:
|
||||
if final_handler is None and not caught:
|
||||
exc_value, exc_tb = exc_info[1:]
|
||||
raise exc_value.with_traceback(exc_tb)
|
||||
|
||||
|
@ -70,11 +70,23 @@ class FakeClientHandler(object):
|
||||
# Communicate with the client until disconnected.
|
||||
try:
|
||||
self._run_handshake()
|
||||
self.socket.shutdown(socket.SHUT_RDWR)
|
||||
try:
|
||||
self.socket.shutdown(socket.SHUT_RDWR)
|
||||
except IOError:
|
||||
pass
|
||||
except (FakeClientDisconnect, BrokenPipeError) as exc:
|
||||
if not self.handle_abnormal_disconnect(exc):
|
||||
raise
|
||||
finally:
|
||||
self.socket.close()
|
||||
self.socket_file.close()
|
||||
|
||||
def handle_abnormal_disconnect(self, exc):
|
||||
# Called when the client disconnects in an abnormal fashion. If this
|
||||
# handler returns True, the error is ignored and is treated as a normal
|
||||
# disconnection.
|
||||
return False
|
||||
|
||||
def handle_connection(self):
|
||||
# Called in the handshake state, just after the client connects,
|
||||
# before any packets have been exchanged.
|
||||
@ -363,7 +375,7 @@ class FakeServer(object):
|
||||
'minecraft_version', 'client_handler_type', 'server_type', \
|
||||
'packets_handshake', 'packets_login', 'packets_playing', \
|
||||
'packets_status', 'lock', 'stopping', 'private_key', \
|
||||
'public_key_bytes', 'test_case',
|
||||
'public_key_bytes', 'test_case'
|
||||
|
||||
def __init__(self, minecraft_version=None, compression_threshold=None,
|
||||
client_handler_type=FakeClientHandler, private_key=None,
|
||||
@ -407,7 +419,7 @@ class FakeServer(object):
|
||||
self.listen_socket = socket.socket()
|
||||
self.listen_socket.settimeout(0.1)
|
||||
self.listen_socket.bind(('localhost', 0))
|
||||
self.listen_socket.listen(0)
|
||||
self.listen_socket.listen(1)
|
||||
|
||||
self.lock = threading.Lock()
|
||||
self.stopping = False
|
||||
@ -581,8 +593,6 @@ class _FakeServerTest(unittest.TestCase):
|
||||
if thread is not None and thread.is_alive():
|
||||
errors.append({
|
||||
'msg': 'Thread "%s" timed out.' % thread.name})
|
||||
if client_exc_info[0] is None:
|
||||
client_exc_info[0] = client.exc_info
|
||||
except Exception:
|
||||
errors.insert(0, {
|
||||
'msg': 'Exception in main thread',
|
||||
|
@ -360,6 +360,34 @@ class HandleExceptionTest(ConnectTest):
|
||||
client.connect()
|
||||
|
||||
|
||||
class ExceptionReconnectTest(ConnectTest):
|
||||
class CustomException(Exception):
|
||||
pass
|
||||
|
||||
def setUp(self):
|
||||
self.phase = 0
|
||||
|
||||
def _start_client(self, client):
|
||||
@client.listener(clientbound.play.JoinGamePacket)
|
||||
def handle_join_game(packet):
|
||||
if self.phase == 0:
|
||||
self.phase += 1
|
||||
raise self.CustomException
|
||||
else:
|
||||
raise fake_server.FakeServerTestSuccess
|
||||
|
||||
@client.exception_handler(self.CustomException, early=True)
|
||||
def handle_custom_exception(exc, exc_info):
|
||||
client.disconnect(immediate=True)
|
||||
client.connect()
|
||||
|
||||
client.connect()
|
||||
|
||||
class client_handler_type(ConnectTest.client_handler_type):
|
||||
def handle_abnormal_disconnect(self, exc):
|
||||
return True
|
||||
|
||||
|
||||
class VersionNegotiationEdgeCases(fake_server._FakeServerTest):
|
||||
earliest_version = SUPPORTED_PROTOCOL_VERSIONS[0]
|
||||
latest_version = SUPPORTED_PROTOCOL_VERSIONS[-1]
|
||||
|
Loading…
Reference in New Issue
Block a user