Tests: websockets style fixes.

This commit is contained in:
Andrey Zelenkov
2019-08-30 15:37:44 +03:00
parent 7053a35a60
commit ccd6c0dc05
2 changed files with 213 additions and 245 deletions

View File

@@ -4,6 +4,7 @@ import unittest
from unit.applications.lang.node import TestApplicationNode from unit.applications.lang.node import TestApplicationNode
from unit.applications.websockets import TestApplicationWebsocket from unit.applications.websockets import TestApplicationWebsocket
class TestNodeWebsockets(TestApplicationNode): class TestNodeWebsockets(TestApplicationNode):
prerequisites = ['node'] prerequisites = ['node']
@@ -21,10 +22,7 @@ class TestNodeWebsockets(TestApplicationNode):
) )
self.skip_alerts.extend( self.skip_alerts.extend(
[ [r'last message send failed', r'socket close\(\d+\) failed']
r'last message send failed',
r'socket close\(\d+\) failed',
]
) )
def close_connection(self, sock): def close_connection(self, sock):
@@ -61,9 +59,7 @@ class TestNodeWebsockets(TestApplicationNode):
sock.close() sock.close()
self.assertEqual(resp['status'], 101, 'status') self.assertEqual(resp['status'], 101, 'status')
self.assertEqual( self.assertEqual(resp['headers']['Upgrade'], 'websocket', 'upgrade')
resp['headers']['Upgrade'], 'websocket', 'upgrade'
)
self.assertEqual( self.assertEqual(
resp['headers']['Connection'], 'Upgrade', 'connection' resp['headers']['Connection'], 'Upgrade', 'connection'
) )
@@ -81,16 +77,12 @@ class TestNodeWebsockets(TestApplicationNode):
self.ws.frame_write(sock, self.ws.OP_TEXT, message) self.ws.frame_write(sock, self.ws.OP_TEXT, message)
frame = self.ws.frame_read(sock) frame = self.ws.frame_read(sock)
self.assertEqual( self.assertEqual(message, frame['data'].decode('utf-8'), 'mirror')
message, frame['data'].decode('utf-8'), 'mirror'
)
self.ws.frame_write(sock, self.ws.OP_TEXT, message) self.ws.frame_write(sock, self.ws.OP_TEXT, message)
frame = self.ws.frame_read(sock) frame = self.ws.frame_read(sock)
self.assertEqual( self.assertEqual(message, frame['data'].decode('utf-8'), 'mirror 2')
message, frame['data'].decode('utf-8'), 'mirror 2'
)
sock.close() sock.close()
@@ -176,9 +168,7 @@ class TestNodeWebsockets(TestApplicationNode):
frame = self.ws.frame_read(sock) frame = self.ws.frame_read(sock)
self.assertEqual( self.assertEqual(
message, message, frame['data'].decode('utf-8'), 'partial send'
frame['data'].decode('utf-8'),
'partial send',
) )
sock.close() sock.close()
@@ -276,28 +266,29 @@ class TestNodeWebsockets(TestApplicationNode):
frame1 = self.ws.frame_read(sock1) frame1 = self.ws.frame_read(sock1)
frame2 = self.ws.frame_read(sock2) frame2 = self.ws.frame_read(sock2)
self.assertEqual( self.assertEqual(message1, frame1['data'].decode('utf-8'), 'client 1')
message1, frame1['data'].decode('utf-8'), 'client 1' self.assertEqual(message2, frame2['data'].decode('utf-8'), 'client 2')
)
self.assertEqual(
message2, frame2['data'].decode('utf-8'), 'client 2'
)
sock1.close() sock1.close()
sock2.close() sock2.close()
@unittest.skip('not yet') @unittest.skip('not yet')
def test_node_websockets_handshake_upgrade_absent(self): # FAIL https://tools.ietf.org/html/rfc6455#section-4.2.1 def test_node_websockets_handshake_upgrade_absent(
self
): # FAIL https://tools.ietf.org/html/rfc6455#section-4.2.1
self.load('websockets/mirror') self.load('websockets/mirror')
key = self.ws.key() key = self.ws.key()
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Connection': 'Upgrade', 'Connection': 'Upgrade',
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Key': key,
'Sec-WebSocket-Protocol': 'chat', 'Sec-WebSocket-Protocol': 'chat',
'Sec-WebSocket-Version': 13, 'Sec-WebSocket-Version': 13,
}, read_timeout=1) },
read_timeout=1,
)
self.assertEqual(resp['status'], 400, 'upgrade absent') self.assertEqual(resp['status'], 400, 'upgrade absent')
@@ -305,14 +296,17 @@ class TestNodeWebsockets(TestApplicationNode):
self.load('websockets/mirror') self.load('websockets/mirror')
key = self.ws.key() key = self.ws.key()
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'WEBSOCKET', 'Upgrade': 'WEBSOCKET',
'Connection': 'UPGRADE', 'Connection': 'UPGRADE',
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Key': key,
'Sec-WebSocket-Protocol': 'chat', 'Sec-WebSocket-Protocol': 'chat',
'Sec-WebSocket-Version': 13, 'Sec-WebSocket-Version': 13,
}, read_timeout=1) },
read_timeout=1,
)
self.assertEqual(resp['status'], 101, 'status') self.assertEqual(resp['status'], 101, 'status')
@@ -321,13 +315,16 @@ class TestNodeWebsockets(TestApplicationNode):
self.load('websockets/mirror') self.load('websockets/mirror')
key = self.ws.key() key = self.ws.key()
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'websocket', 'Upgrade': 'websocket',
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Key': key,
'Sec-WebSocket-Protocol': 'chat', 'Sec-WebSocket-Protocol': 'chat',
'Sec-WebSocket-Version': 13, 'Sec-WebSocket-Version': 13,
}, read_timeout=1) },
read_timeout=1,
)
self.assertEqual(resp['status'], 400, 'status') self.assertEqual(resp['status'], 400, 'status')
@@ -335,13 +332,16 @@ class TestNodeWebsockets(TestApplicationNode):
self.load('websockets/mirror') self.load('websockets/mirror')
key = self.ws.key() key = self.ws.key()
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'websocket', 'Upgrade': 'websocket',
'Connection': 'Upgrade', 'Connection': 'Upgrade',
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Key': key,
'Sec-WebSocket-Protocol': 'chat' 'Sec-WebSocket-Protocol': 'chat',
}, read_timeout=1) },
read_timeout=1,
)
self.assertEqual(resp['status'], 426, 'status') self.assertEqual(resp['status'], 426, 'status')
@@ -349,41 +349,52 @@ class TestNodeWebsockets(TestApplicationNode):
def test_node_websockets_handshake_key_invalid(self): def test_node_websockets_handshake_key_invalid(self):
self.load('websockets/mirror') self.load('websockets/mirror')
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'websocket', 'Upgrade': 'websocket',
'Connection': 'Upgrade', 'Connection': 'Upgrade',
'Sec-WebSocket-Key': '!', 'Sec-WebSocket-Key': '!',
'Sec-WebSocket-Protocol': 'chat', 'Sec-WebSocket-Protocol': 'chat',
'Sec-WebSocket-Version': 13 'Sec-WebSocket-Version': 13,
}, read_timeout=1) },
read_timeout=1,
)
self.assertEqual(resp['status'], 400, 'key length') self.assertEqual(resp['status'], 400, 'key length')
key = self.ws.key() key = self.ws.key()
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'websocket', 'Upgrade': 'websocket',
'Connection': 'Upgrade', 'Connection': 'Upgrade',
'Sec-WebSocket-Key': [key, key], 'Sec-WebSocket-Key': [key, key],
'Sec-WebSocket-Protocol': 'chat', 'Sec-WebSocket-Protocol': 'chat',
'Sec-WebSocket-Version': 13 'Sec-WebSocket-Version': 13,
}, read_timeout=1) },
read_timeout=1,
)
self.assertEqual(resp['status'], 400, 'key double') # FAIL https://tools.ietf.org/html/rfc6455#section-11.3.1 self.assertEqual(
resp['status'], 400, 'key double'
) # FAIL https://tools.ietf.org/html/rfc6455#section-11.3.1
def test_node_websockets_handshake_method_invalid(self): def test_node_websockets_handshake_method_invalid(self):
self.load('websockets/mirror') self.load('websockets/mirror')
key = self.ws.key() key = self.ws.key()
resp = self.post(headers={ resp = self.post(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'websocket', 'Upgrade': 'websocket',
'Connection': 'Upgrade', 'Connection': 'Upgrade',
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Key': key,
'Sec-WebSocket-Protocol': 'chat', 'Sec-WebSocket-Protocol': 'chat',
'Sec-WebSocket-Version': 13 'Sec-WebSocket-Version': 13,
}, read_timeout=1) },
read_timeout=1,
)
self.assertEqual(resp['status'], 400, 'status') self.assertEqual(resp['status'], 400, 'status')
@@ -391,14 +402,18 @@ class TestNodeWebsockets(TestApplicationNode):
self.load('websockets/mirror') self.load('websockets/mirror')
key = self.ws.key() key = self.ws.key()
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'websocket', 'Upgrade': 'websocket',
'Connection': 'Upgrade', 'Connection': 'Upgrade',
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Key': key,
'Sec-WebSocket-Protocol': 'chat', 'Sec-WebSocket-Protocol': 'chat',
'Sec-WebSocket-Version': 13 'Sec-WebSocket-Version': 13,
}, http_10=True, read_timeout=1) },
http_10=True,
read_timeout=1,
)
self.assertEqual(resp['status'], 400, 'status') self.assertEqual(resp['status'], 400, 'status')
@@ -406,14 +421,18 @@ class TestNodeWebsockets(TestApplicationNode):
self.load('websockets/mirror') self.load('websockets/mirror')
key = self.ws.key() key = self.ws.key()
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'websocket', 'Upgrade': 'websocket',
'Connection': 'Upgrade', 'Connection': 'Upgrade',
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Key': key,
'Sec-WebSocket-Protocol': 'chat', 'Sec-WebSocket-Protocol': 'chat',
'Sec-WebSocket-Version': 13 'Sec-WebSocket-Version': 13,
}, url='!', read_timeout=1) },
url='!',
read_timeout=1,
)
self.assertEqual(resp['status'], 400, 'status') self.assertEqual(resp['status'], 400, 'status')
@@ -421,18 +440,19 @@ class TestNodeWebsockets(TestApplicationNode):
self.load('websockets/mirror') self.load('websockets/mirror')
key = self.ws.key() key = self.ws.key()
resp = self.get(headers={ resp = self.get(
headers={
'Host': 'localhost', 'Host': 'localhost',
'Upgrade': 'websocket', 'Upgrade': 'websocket',
'Connection': 'Upgrade', 'Connection': 'Upgrade',
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Key': key,
'Sec-WebSocket-Version': 13 'Sec-WebSocket-Version': 13,
}, read_timeout=1) },
read_timeout=1,
)
self.assertEqual(resp['status'], 101, 'status') self.assertEqual(resp['status'], 101, 'status')
self.assertEqual( self.assertEqual(resp['headers']['Upgrade'], 'websocket', 'upgrade')
resp['headers']['Upgrade'], 'websocket', 'upgrade'
)
self.assertEqual( self.assertEqual(
resp['headers']['Connection'], 'Upgrade', 'connection' resp['headers']['Connection'], 'Upgrade', 'connection'
) )
@@ -441,7 +461,7 @@ class TestNodeWebsockets(TestApplicationNode):
) )
# autobahn-testsuite # autobahn-testsuite
#
# Some following tests fail because of Unit does not support UTF-8 # Some following tests fail because of Unit does not support UTF-8
# validation for websocket frames. It should be implemented # validation for websocket frames. It should be implemented
# by application, if necessary. # by application, if necessary.
@@ -621,11 +641,7 @@ class TestNodeWebsockets(TestApplicationNode):
self.check_frame(frame, True, self.ws.OP_TEXT, payload) self.check_frame(frame, True, self.ws.OP_TEXT, payload)
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_TEXT, payload, rsv1=True, rsv2=True
self.ws.OP_TEXT,
payload,
rsv1=True,
rsv2=True,
) )
self.check_close(sock, 1002, no_close=True) self.check_close(sock, 1002, no_close=True)
@@ -639,11 +655,7 @@ class TestNodeWebsockets(TestApplicationNode):
self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1) self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1)
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_TEXT, payload, rsv3=True, chopsize=1
self.ws.OP_TEXT,
payload,
rsv3=True,
chopsize=1
) )
self.ws.frame_write(sock, self.ws.OP_PING, '') self.ws.frame_write(sock, self.ws.OP_PING, '')
@@ -674,11 +686,7 @@ class TestNodeWebsockets(TestApplicationNode):
_, sock, _ = self.ws.upgrade() _, sock, _ = self.ws.upgrade()
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_PING, payload, rsv2=True, rsv3=True
self.ws.OP_PING,
payload,
rsv2=True,
rsv3=True,
) )
self.check_close(sock, 1002) self.check_close(sock, 1002)
@@ -688,12 +696,7 @@ class TestNodeWebsockets(TestApplicationNode):
_, sock, _ = self.ws.upgrade() _, sock, _ = self.ws.upgrade()
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_CLOSE, payload, rsv1=True, rsv2=True, rsv3=True
self.ws.OP_CLOSE,
payload,
rsv1=True,
rsv2=True,
rsv3=True,
) )
self.check_close(sock, 1002) self.check_close(sock, 1002)
@@ -857,18 +860,10 @@ class TestNodeWebsockets(TestApplicationNode):
# 5_5 # 5_5
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_TEXT, 'fragment1', fin=False, chopsize=1
self.ws.OP_TEXT,
'fragment1',
fin=False,
chopsize=1,
) )
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_CONT, 'fragment2', fin=True, chopsize=1
self.ws.OP_CONT,
'fragment2',
fin=True,
chopsize=1,
) )
frame = self.ws.frame_read(sock) frame = self.ws.frame_read(sock)
@@ -910,19 +905,11 @@ class TestNodeWebsockets(TestApplicationNode):
ping_payload = 'ping payload' ping_payload = 'ping payload'
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_TEXT, 'fragment1', fin=False, chopsize=1
self.ws.OP_TEXT,
'fragment1',
fin=False,
chopsize=1,
) )
self.ws.frame_write(sock, self.ws.OP_PING, ping_payload, chopsize=1) self.ws.frame_write(sock, self.ws.OP_PING, ping_payload, chopsize=1)
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_CONT, 'fragment2', fin=True, chopsize=1
self.ws.OP_CONT,
'fragment2',
fin=True,
chopsize=1,
) )
frame = self.ws.frame_read(sock) frame = self.ws.frame_read(sock)
@@ -934,10 +921,7 @@ class TestNodeWebsockets(TestApplicationNode):
# 5_9 # 5_9
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_CONT, 'non-continuation payload', fin=True
self.ws.OP_CONT,
'non-continuation payload',
fin=True,
) )
self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
self.check_close(sock, 1002) self.check_close(sock, 1002)
@@ -947,10 +931,7 @@ class TestNodeWebsockets(TestApplicationNode):
_, sock, _ = self.ws.upgrade() _, sock, _ = self.ws.upgrade()
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_CONT, 'non-continuation payload', fin=True
self.ws.OP_CONT,
'non-continuation payload',
fin=True,
) )
self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
self.check_close(sock, 1002) self.check_close(sock, 1002)
@@ -967,11 +948,7 @@ class TestNodeWebsockets(TestApplicationNode):
chopsize=1, chopsize=1,
) )
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_TEXT, 'Hello, world!', fin=True, chopsize=1
self.ws.OP_TEXT,
'Hello, world!',
fin=True,
chopsize=1,
) )
self.check_close(sock, 1002) self.check_close(sock, 1002)
@@ -980,10 +957,7 @@ class TestNodeWebsockets(TestApplicationNode):
_, sock, _ = self.ws.upgrade() _, sock, _ = self.ws.upgrade()
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_CONT, 'non-continuation payload', fin=False
self.ws.OP_CONT,
'non-continuation payload',
fin=False,
) )
self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
self.check_close(sock, 1002) self.check_close(sock, 1002)
@@ -993,10 +967,7 @@ class TestNodeWebsockets(TestApplicationNode):
_, sock, _ = self.ws.upgrade() _, sock, _ = self.ws.upgrade()
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_CONT, 'non-continuation payload', fin=False
self.ws.OP_CONT,
'non-continuation payload',
fin=False,
) )
self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
self.check_close(sock, 1002) self.check_close(sock, 1002)
@@ -1013,11 +984,7 @@ class TestNodeWebsockets(TestApplicationNode):
chopsize=1, chopsize=1,
) )
self.ws.frame_write( self.ws.frame_write(
sock, sock, self.ws.OP_TEXT, 'Hello, world!', fin=True, chopsize=1
self.ws.OP_TEXT,
'Hello, world!',
fin=True,
chopsize=1,
) )
self.check_close(sock, 1002) self.check_close(sock, 1002)
@@ -1184,7 +1151,7 @@ class TestNodeWebsockets(TestApplicationNode):
self.close_connection(sock) self.close_connection(sock)
# Unit does not support UTF-8 validation # Unit does not support UTF-8 validation
#
# # 6_3_1 FAIL # # 6_3_1 FAIL
# #
# payload_1 = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5' # payload_1 = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5'
@@ -1330,8 +1297,8 @@ class TestNodeWebsockets(TestApplicationNode):
self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
self.check_close(sock, 1002) self.check_close(sock, 1002)
# 7_5_1 FAIL Unit does not support UTF-8 validation # # 7_5_1 FAIL Unit does not support UTF-8 validation
#
# _, sock, _ = self.ws.upgrade() # _, sock, _ = self.ws.upgrade()
# #
# payload = self.ws.serialize_close(reason = '\xce\xba\xe1\xbd\xb9\xcf' \ # payload = self.ws.serialize_close(reason = '\xce\xba\xe1\xbd\xb9\xcf' \
@@ -1581,5 +1548,6 @@ class TestNodeWebsockets(TestApplicationNode):
sock.close() sock.close()
if __name__ == '__main__': if __name__ == '__main__':
TestNodeWebsockets.main() TestNodeWebsockets.main()

View File

@@ -66,9 +66,7 @@ class TestApplicationWebsocket(TestApplicationProto):
data = sock.recv(bytes) data = sock.recv(bytes)
else: else:
data = self.recvall( data = self.recvall(
sock, sock, read_timeout=read_timeout, buff_size=bytes
read_timeout=read_timeout,
buff_size=bytes,
) )
break break
except: except:
@@ -180,7 +178,7 @@ class TestApplicationWebsocket(TestApplicationProto):
else: else:
pos = 0 pos = 0
frame_len = len(frame) frame_len = len(frame)
while (pos < frame_len): while pos < frame_len:
end = min(pos + chopsize, frame_len) end = min(pos + chopsize, frame_len)
sock.sendall(frame[pos:end]) sock.sendall(frame[pos:end])
pos = end pos = end
@@ -197,17 +195,19 @@ class TestApplicationWebsocket(TestApplicationProto):
pos = 0 pos = 0
op_code = type op_code = type
while(pos < message_len): while pos < message_len:
end = min(pos + fragmention_size, message_len) end = min(pos + fragmention_size, message_len)
fin = (end == message_len) fin = end == message_len
self.frame_write(sock, op_code, message[pos:end], fin=fin, **kwargs) self.frame_write(
sock, op_code, message[pos:end], fin=fin, **kwargs
)
op_code = self.OP_CONT op_code = self.OP_CONT
pos = end pos = end
def message_read(self, sock, read_timeout=10): def message_read(self, sock, read_timeout=10):
frame = self.frame_read(sock, read_timeout=read_timeout) frame = self.frame_read(sock, read_timeout=read_timeout)
while(not frame['fin']): while not frame['fin']:
temp = self.frame_read(sock, read_timeout=read_timeout) temp = self.frame_read(sock, read_timeout=read_timeout)
frame['data'] += temp['data'] frame['data'] += temp['data']
frame['fin'] = temp['fin'] frame['fin'] = temp['fin']