Skip to content

Commit c7cef56

Browse files
authored
C# parity tests for payloads (#1677)
* payload_tests * blackcheck
1 parent 2bd4d42 commit c7cef56

File tree

4 files changed

+424
-0
lines changed

4 files changed

+424
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
from typing import List
2+
from unittest import TestCase
3+
from uuid import uuid4, UUID
4+
5+
import pytest
6+
from botframework.streaming.payloads import HeaderSerializer
7+
from botframework.streaming.payloads.models import Header, PayloadTypes
8+
from botframework.streaming.transport import TransportConstants
9+
10+
11+
class TestHeaderSerializer(TestCase):
12+
def test_can_round_trip(self):
13+
header = Header()
14+
header.type = PayloadTypes.REQUEST
15+
header.payload_length = 168
16+
header.id = uuid4()
17+
header.end = True
18+
19+
buffer: List[int] = [None] * TransportConstants.MAX_PAYLOAD_LENGTH
20+
offset: int = 0
21+
22+
length = HeaderSerializer.serialize(header, buffer, offset)
23+
result = HeaderSerializer.deserialize(buffer, 0, length)
24+
25+
self.assertEqual(header.type, result.type)
26+
self.assertEqual(header.payload_length, result.payload_length)
27+
self.assertEqual(header.id, result.id)
28+
self.assertEqual(header.end, result.end)
29+
30+
def test_serializes_to_ascii(self):
31+
header = Header()
32+
header.type = PayloadTypes.REQUEST
33+
header.payload_length = 168
34+
header.id = uuid4()
35+
header.end = True
36+
37+
buffer: List[int] = [None] * TransportConstants.MAX_PAYLOAD_LENGTH
38+
offset: int = 0
39+
40+
length = HeaderSerializer.serialize(header, buffer, offset)
41+
decoded = bytes(buffer[offset:length]).decode("ascii")
42+
43+
self.assertEqual(f"A.000168.{str(header.id)}.1\n", decoded)
44+
45+
def test_deserializes_from_ascii(self):
46+
header_id: UUID = uuid4()
47+
header: str = f"A.000168.{str(header_id)}.1\n"
48+
buffer: List[int] = list(bytes(header, "ascii"))
49+
50+
result = HeaderSerializer.deserialize(buffer, 0, len(buffer))
51+
52+
self.assertEqual("A", result.type)
53+
self.assertEqual(168, result.payload_length)
54+
self.assertEqual(header_id, result.id)
55+
self.assertTrue(result.end)
56+
57+
def test_deserialize_unknown_type(self):
58+
header_id: UUID = uuid4()
59+
header: str = f"Z.000168.{str(header_id)}.1\n"
60+
buffer: List[int] = list(bytes(header, "ascii"))
61+
62+
result = HeaderSerializer.deserialize(buffer, 0, len(buffer))
63+
64+
self.assertEqual("Z", result.type)
65+
self.assertEqual(168, result.payload_length)
66+
67+
def test_deserialize_length_too_short_throws(self):
68+
header_id: UUID = uuid4()
69+
header: str = f"A.000168.{str(header_id)}.1\n"
70+
buffer: List[int] = list(bytes(header, "ascii"))
71+
72+
with pytest.raises(ValueError):
73+
HeaderSerializer.deserialize(buffer, 0, 5)
74+
75+
def test_deserialize_length_too_long_throws(self):
76+
header_id: UUID = uuid4()
77+
header: str = f"A.000168.{str(header_id)}.1\n"
78+
buffer: List[int] = list(bytes(header, "ascii"))
79+
80+
with pytest.raises(ValueError):
81+
HeaderSerializer.deserialize(buffer, 0, 55)
82+
83+
def test_deserialize_bad_type_delimiter_throws(self):
84+
header_id: UUID = uuid4()
85+
header: str = f"Ax000168.{str(header_id)}.1\n"
86+
buffer: List[int] = list(bytes(header, "ascii"))
87+
88+
with pytest.raises(ValueError):
89+
HeaderSerializer.deserialize(buffer, 0, len(buffer))
90+
91+
def test_deserialize_bad_length_delimiter_throws(self):
92+
header_id: UUID = uuid4()
93+
header: str = f"A.000168x{str(header_id)}.1\n"
94+
buffer: List[int] = list(bytes(header, "ascii"))
95+
96+
with pytest.raises(ValueError):
97+
HeaderSerializer.deserialize(buffer, 0, len(buffer))
98+
99+
def test_deserialize_bad_id_delimiter_throws(self):
100+
header_id: UUID = uuid4()
101+
header: str = f"A.000168.{str(header_id)}x1\n"
102+
buffer: List[int] = list(bytes(header, "ascii"))
103+
104+
with pytest.raises(ValueError):
105+
HeaderSerializer.deserialize(buffer, 0, len(buffer))
106+
107+
def test_deserialize_bad_terminator_throws(self):
108+
header_id: UUID = uuid4()
109+
header: str = f"A.000168.{str(header_id)}.1c"
110+
buffer: List[int] = list(bytes(header, "ascii"))
111+
112+
with pytest.raises(ValueError):
113+
HeaderSerializer.deserialize(buffer, 0, len(buffer))
114+
115+
def test_deserialize_bad_length_throws(self):
116+
header_id: UUID = uuid4()
117+
header: str = f"A.00p168.{str(header_id)}.1\n"
118+
buffer: List[int] = list(bytes(header, "ascii"))
119+
120+
with pytest.raises(ValueError):
121+
HeaderSerializer.deserialize(buffer, 0, len(buffer))
122+
123+
def test_deserialize_bad_id_throws(self):
124+
header: str = "A.000168.68e9p9ca-a651-40f4-ad8f-3aaf781862b4.1\n"
125+
buffer: List[int] = list(bytes(header, "ascii"))
126+
127+
with pytest.raises(ValueError):
128+
HeaderSerializer.deserialize(buffer, 0, len(buffer))
129+
130+
def test_deserialize_bad_end_throws(self):
131+
header_id: UUID = uuid4()
132+
header: str = f"A.000168.{str(header_id)}.z\n"
133+
buffer: List[int] = list(bytes(header, "ascii"))
134+
135+
with pytest.raises(ValueError):
136+
HeaderSerializer.deserialize(buffer, 0, len(buffer))
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from unittest import TestCase
2+
from uuid import UUID, uuid4
3+
4+
from botframework.streaming.payloads import StreamManager
5+
from botframework.streaming.payloads.assemblers import PayloadStreamAssembler
6+
from botframework.streaming.payloads.models import Header
7+
8+
9+
class TestPayloadAssembler(TestCase):
10+
def test_ctor_id(self):
11+
identifier: UUID = uuid4()
12+
stream_manager = StreamManager()
13+
assembler = PayloadStreamAssembler(stream_manager, identifier)
14+
self.assertEqual(identifier, assembler.identifier)
15+
16+
def test_ctor_end_false(self):
17+
identifier: UUID = uuid4()
18+
stream_manager = StreamManager()
19+
assembler = PayloadStreamAssembler(stream_manager, identifier)
20+
self.assertFalse(assembler.end)
21+
22+
def test_get_stream(self):
23+
identifier: UUID = uuid4()
24+
stream_manager = StreamManager()
25+
assembler = PayloadStreamAssembler(stream_manager, identifier)
26+
stream = assembler.get_payload_as_stream()
27+
self.assertIsNotNone(stream)
28+
29+
def test_get_stream_does_not_make_new_each_time(self):
30+
identifier: UUID = uuid4()
31+
stream_manager = StreamManager()
32+
assembler = PayloadStreamAssembler(stream_manager, identifier)
33+
stream1 = assembler.get_payload_as_stream()
34+
stream2 = assembler.get_payload_as_stream()
35+
self.assertEqual(stream1, stream2)
36+
37+
def test_on_receive_sets_end(self):
38+
identifier: UUID = uuid4()
39+
stream_manager = StreamManager()
40+
assembler = PayloadStreamAssembler(stream_manager, identifier)
41+
42+
header = Header()
43+
header.end = True
44+
45+
assembler.get_payload_as_stream()
46+
assembler.on_receive(header, [], 100)
47+
48+
self.assertTrue(assembler.end)
49+
50+
def test_close_does_not_set_end(self):
51+
identifier: UUID = uuid4()
52+
stream_manager = StreamManager()
53+
assembler = PayloadStreamAssembler(stream_manager, identifier)
54+
55+
assembler.close()
56+
57+
self.assertFalse(assembler.end)
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import asyncio
2+
from asyncio import Future, ensure_future
3+
from typing import Dict
4+
from uuid import UUID, uuid4
5+
6+
import aiounittest
7+
from botframework.streaming import ReceiveResponse
8+
from botframework.streaming.payloads import RequestManager
9+
10+
11+
class TestRequestManager(aiounittest.AsyncTestCase):
12+
def test_ctor_empty_dictionary(self):
13+
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
14+
_ = RequestManager(pending_requests=pending_requests)
15+
16+
self.assertEqual(0, len(pending_requests))
17+
18+
async def test_signal_response_returns_false_when_no_uuid(self):
19+
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
20+
manager = RequestManager(pending_requests=pending_requests)
21+
request_id: UUID = uuid4()
22+
response = ReceiveResponse()
23+
signal = await manager.signal_response(request_id=request_id, response=response)
24+
25+
self.assertFalse(signal)
26+
27+
async def test_signal_response_returns_true_when_uuid(self):
28+
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
29+
request_id: UUID = uuid4()
30+
pending_requests[request_id] = Future()
31+
32+
manager = RequestManager(pending_requests=pending_requests)
33+
34+
response = ReceiveResponse()
35+
signal = await manager.signal_response(request_id=request_id, response=response)
36+
37+
self.assertTrue(signal)
38+
39+
async def test_signal_response_null_response_is_ok(self):
40+
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
41+
request_id: UUID = uuid4()
42+
pending_requests[request_id] = Future()
43+
44+
manager = RequestManager(pending_requests=pending_requests)
45+
46+
# noinspection PyTypeChecker
47+
_ = await manager.signal_response(request_id=request_id, response=None)
48+
49+
self.assertIsNone(pending_requests[request_id].result())
50+
51+
async def test_signal_response_response(self):
52+
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
53+
request_id: UUID = uuid4()
54+
pending_requests[request_id] = Future()
55+
56+
manager = RequestManager(pending_requests=pending_requests)
57+
response = ReceiveResponse()
58+
59+
_ = await manager.signal_response(request_id=request_id, response=response)
60+
61+
self.assertEqual(response, pending_requests[request_id].result())
62+
63+
async def test_get_response_returns_null_on_duplicate_call(self):
64+
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
65+
request_id: UUID = uuid4()
66+
pending_requests[request_id] = Future()
67+
68+
manager = RequestManager(pending_requests=pending_requests)
69+
70+
response = await manager.get_response(request_id)
71+
72+
self.assertIsNone(response)
73+
74+
async def test_get_response_returns_response(self):
75+
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
76+
request_id: UUID = uuid4()
77+
78+
manager = RequestManager(pending_requests=pending_requests)
79+
test_response = ReceiveResponse()
80+
81+
async def set_response():
82+
nonlocal manager
83+
nonlocal request_id
84+
nonlocal test_response
85+
86+
while True:
87+
signal = await manager.signal_response(
88+
request_id, response=test_response
89+
)
90+
if signal:
91+
break
92+
await asyncio.sleep(2)
93+
94+
ensure_future(set_response())
95+
response = await manager.get_response(request_id)
96+
97+
self.assertEqual(test_response, response)
98+
99+
async def test_get_response_returns_null_response(self):
100+
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
101+
request_id: UUID = uuid4()
102+
103+
manager = RequestManager(pending_requests=pending_requests)
104+
105+
async def set_response():
106+
nonlocal manager
107+
nonlocal request_id
108+
109+
while True:
110+
# noinspection PyTypeChecker
111+
signal = await manager.signal_response(request_id, response=None)
112+
if signal:
113+
break
114+
await asyncio.sleep(2)
115+
116+
ensure_future(set_response())
117+
response = await manager.get_response(request_id)
118+
119+
self.assertIsNone(response)

0 commit comments

Comments
 (0)