Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions libraries/botframework-streaming/tests/test_header_serializer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
from typing import List
from unittest import TestCase
from uuid import uuid4, UUID

import pytest
from botframework.streaming.payloads import HeaderSerializer
from botframework.streaming.payloads.models import Header, PayloadTypes
from botframework.streaming.transport import TransportConstants


class TestHeaderSerializer(TestCase):
def test_can_round_trip(self):
header = Header()
header.type = PayloadTypes.REQUEST
header.payload_length = 168
header.id = uuid4()
header.end = True

buffer: List[int] = [None] * TransportConstants.MAX_PAYLOAD_LENGTH
offset: int = 0

length = HeaderSerializer.serialize(header, buffer, offset)
result = HeaderSerializer.deserialize(buffer, 0, length)

self.assertEqual(header.type, result.type)
self.assertEqual(header.payload_length, result.payload_length)
self.assertEqual(header.id, result.id)
self.assertEqual(header.end, result.end)

def test_serializes_to_ascii(self):
header = Header()
header.type = PayloadTypes.REQUEST
header.payload_length = 168
header.id = uuid4()
header.end = True

buffer: List[int] = [None] * TransportConstants.MAX_PAYLOAD_LENGTH
offset: int = 0

length = HeaderSerializer.serialize(header, buffer, offset)
decoded = bytes(buffer[offset:length]).decode("ascii")

self.assertEqual(f"A.000168.{str(header.id)}.1\n", decoded)

def test_deserializes_from_ascii(self):
header_id: UUID = uuid4()
header: str = f"A.000168.{str(header_id)}.1\n"
buffer: List[int] = list(bytes(header, "ascii"))

result = HeaderSerializer.deserialize(buffer, 0, len(buffer))

self.assertEqual("A", result.type)
self.assertEqual(168, result.payload_length)
self.assertEqual(header_id, result.id)
self.assertTrue(result.end)

def test_deserialize_unknown_type(self):
header_id: UUID = uuid4()
header: str = f"Z.000168.{str(header_id)}.1\n"
buffer: List[int] = list(bytes(header, "ascii"))

result = HeaderSerializer.deserialize(buffer, 0, len(buffer))

self.assertEqual("Z", result.type)
self.assertEqual(168, result.payload_length)

def test_deserialize_length_too_short_throws(self):
header_id: UUID = uuid4()
header: str = f"A.000168.{str(header_id)}.1\n"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, 5)

def test_deserialize_length_too_long_throws(self):
header_id: UUID = uuid4()
header: str = f"A.000168.{str(header_id)}.1\n"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, 55)

def test_deserialize_bad_type_delimiter_throws(self):
header_id: UUID = uuid4()
header: str = f"Ax000168.{str(header_id)}.1\n"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, len(buffer))

def test_deserialize_bad_length_delimiter_throws(self):
header_id: UUID = uuid4()
header: str = f"A.000168x{str(header_id)}.1\n"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, len(buffer))

def test_deserialize_bad_id_delimiter_throws(self):
header_id: UUID = uuid4()
header: str = f"A.000168.{str(header_id)}x1\n"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, len(buffer))

def test_deserialize_bad_terminator_throws(self):
header_id: UUID = uuid4()
header: str = f"A.000168.{str(header_id)}.1c"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, len(buffer))

def test_deserialize_bad_length_throws(self):
header_id: UUID = uuid4()
header: str = f"A.00p168.{str(header_id)}.1\n"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, len(buffer))

def test_deserialize_bad_id_throws(self):
header: str = "A.000168.68e9p9ca-a651-40f4-ad8f-3aaf781862b4.1\n"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, len(buffer))

def test_deserialize_bad_end_throws(self):
header_id: UUID = uuid4()
header: str = f"A.000168.{str(header_id)}.z\n"
buffer: List[int] = list(bytes(header, "ascii"))

with pytest.raises(ValueError):
HeaderSerializer.deserialize(buffer, 0, len(buffer))
57 changes: 57 additions & 0 deletions libraries/botframework-streaming/tests/test_payload_assembler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from unittest import TestCase
from uuid import UUID, uuid4

from botframework.streaming.payloads import StreamManager
from botframework.streaming.payloads.assemblers import PayloadStreamAssembler
from botframework.streaming.payloads.models import Header


class TestPayloadAssembler(TestCase):
def test_ctor_id(self):
identifier: UUID = uuid4()
stream_manager = StreamManager()
assembler = PayloadStreamAssembler(stream_manager, identifier)
self.assertEqual(identifier, assembler.identifier)

def test_ctor_end_false(self):
identifier: UUID = uuid4()
stream_manager = StreamManager()
assembler = PayloadStreamAssembler(stream_manager, identifier)
self.assertFalse(assembler.end)

def test_get_stream(self):
identifier: UUID = uuid4()
stream_manager = StreamManager()
assembler = PayloadStreamAssembler(stream_manager, identifier)
stream = assembler.get_payload_as_stream()
self.assertIsNotNone(stream)

def test_get_stream_does_not_make_new_each_time(self):
identifier: UUID = uuid4()
stream_manager = StreamManager()
assembler = PayloadStreamAssembler(stream_manager, identifier)
stream1 = assembler.get_payload_as_stream()
stream2 = assembler.get_payload_as_stream()
self.assertEqual(stream1, stream2)

def test_on_receive_sets_end(self):
identifier: UUID = uuid4()
stream_manager = StreamManager()
assembler = PayloadStreamAssembler(stream_manager, identifier)

header = Header()
header.end = True

assembler.get_payload_as_stream()
assembler.on_receive(header, [], 100)

self.assertTrue(assembler.end)

def test_close_does_not_set_end(self):
identifier: UUID = uuid4()
stream_manager = StreamManager()
assembler = PayloadStreamAssembler(stream_manager, identifier)

assembler.close()

self.assertFalse(assembler.end)
119 changes: 119 additions & 0 deletions libraries/botframework-streaming/tests/test_request_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import asyncio
from asyncio import Future, ensure_future
from typing import Dict
from uuid import UUID, uuid4

import aiounittest
from botframework.streaming import ReceiveResponse
from botframework.streaming.payloads import RequestManager


class TestRequestManager(aiounittest.AsyncTestCase):
def test_ctor_empty_dictionary(self):
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
_ = RequestManager(pending_requests=pending_requests)

self.assertEqual(0, len(pending_requests))

async def test_signal_response_returns_false_when_no_uuid(self):
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
manager = RequestManager(pending_requests=pending_requests)
request_id: UUID = uuid4()
response = ReceiveResponse()
signal = await manager.signal_response(request_id=request_id, response=response)

self.assertFalse(signal)

async def test_signal_response_returns_true_when_uuid(self):
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
request_id: UUID = uuid4()
pending_requests[request_id] = Future()

manager = RequestManager(pending_requests=pending_requests)

response = ReceiveResponse()
signal = await manager.signal_response(request_id=request_id, response=response)

self.assertTrue(signal)

async def test_signal_response_null_response_is_ok(self):
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
request_id: UUID = uuid4()
pending_requests[request_id] = Future()

manager = RequestManager(pending_requests=pending_requests)

# noinspection PyTypeChecker
_ = await manager.signal_response(request_id=request_id, response=None)

self.assertIsNone(pending_requests[request_id].result())

async def test_signal_response_response(self):
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
request_id: UUID = uuid4()
pending_requests[request_id] = Future()

manager = RequestManager(pending_requests=pending_requests)
response = ReceiveResponse()

_ = await manager.signal_response(request_id=request_id, response=response)

self.assertEqual(response, pending_requests[request_id].result())

async def test_get_response_returns_null_on_duplicate_call(self):
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
request_id: UUID = uuid4()
pending_requests[request_id] = Future()

manager = RequestManager(pending_requests=pending_requests)

response = await manager.get_response(request_id)

self.assertIsNone(response)

async def test_get_response_returns_response(self):
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
request_id: UUID = uuid4()

manager = RequestManager(pending_requests=pending_requests)
test_response = ReceiveResponse()

async def set_response():
nonlocal manager
nonlocal request_id
nonlocal test_response

while True:
signal = await manager.signal_response(
request_id, response=test_response
)
if signal:
break
await asyncio.sleep(2)

ensure_future(set_response())
response = await manager.get_response(request_id)

self.assertEqual(test_response, response)

async def test_get_response_returns_null_response(self):
pending_requests: Dict[UUID, Future[ReceiveResponse]] = {}
request_id: UUID = uuid4()

manager = RequestManager(pending_requests=pending_requests)

async def set_response():
nonlocal manager
nonlocal request_id

while True:
# noinspection PyTypeChecker
signal = await manager.signal_response(request_id, response=None)
if signal:
break
await asyncio.sleep(2)

ensure_future(set_response())
response = await manager.get_response(request_id)

self.assertIsNone(response)
Loading