mirror of https://github.com/opencardev/aasdk
228 lines
9.7 KiB
C++
228 lines
9.7 KiB
C++
/*
|
|
* This file is part of aasdk library project.
|
|
* Copyright (C) 2018 f1x.studio (Michal Szwaj)
|
|
*
|
|
* aasdk is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
|
|
* aasdk is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with aasdk. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
#include <aasdk/Transport/UT/Transport.mock.hpp>
|
|
#include <aasdk/Messenger/UT/Cryptor.mock.hpp>
|
|
#include <aasdk/Messenger/UT/SendPromiseHandler.mock.hpp>
|
|
#include <aasdk/Messenger/Promise.hpp>
|
|
#include <aasdk/Messenger/MessageOutStream.hpp>
|
|
|
|
|
|
namespace aasdk
|
|
{
|
|
namespace messenger
|
|
{
|
|
namespace ut
|
|
{
|
|
|
|
using ::testing::_;
|
|
using ::testing::SaveArg;
|
|
using ::testing::SetArgReferee;
|
|
using ::testing::Return;
|
|
|
|
class MessageOutStreamUnitTest
|
|
{
|
|
protected:
|
|
MessageOutStreamUnitTest()
|
|
: transport_(&transportMock_, [](auto*) {})
|
|
, cryptor_(&cryptorMock_, [](auto*) {})
|
|
, sendPromise_(SendPromise::defer(ioService_))
|
|
{
|
|
sendPromise_->then(std::bind(&SendPromiseHandlerMock::onResolve, &sendPromiseHandlerMock_),
|
|
std::bind(&SendPromiseHandlerMock::onReject, &sendPromiseHandlerMock_, std::placeholders::_1));
|
|
}
|
|
|
|
boost::asio::io_service ioService_;
|
|
transport::ut::TransportMock transportMock_;
|
|
transport::ITransport::Pointer transport_;
|
|
CryptorMock cryptorMock_;
|
|
ICryptor::Pointer cryptor_;
|
|
SendPromiseHandlerMock sendPromiseHandlerMock_;
|
|
SendPromise::Pointer sendPromise_;
|
|
};
|
|
|
|
ACTION(ThrowSSLWriteException)
|
|
{
|
|
throw error::Error(error::ErrorCode::SSL_WRITE, 32);
|
|
}
|
|
|
|
BOOST_FIXTURE_TEST_CASE(MessageOutStream_SendPlainMessage, MessageOutStreamUnitTest)
|
|
{
|
|
const FrameHeader frameHeader(ChannelId::INPUT, FrameType::BULK, EncryptionType::PLAIN, MessageType::CONTROL);
|
|
const common::Data payload(1000, 0x5E);
|
|
const FrameSize frameSize(payload.size());
|
|
|
|
const auto& frameHeaderData = frameHeader.getData();
|
|
common::Data expectedData(frameHeaderData.begin(), frameHeaderData.end());
|
|
|
|
const auto& frameSizeData = frameSize.getData();
|
|
expectedData.insert(expectedData.end(), frameSizeData.begin(), frameSizeData.end());
|
|
expectedData.insert(expectedData.end(), payload.begin(), payload.end());
|
|
|
|
transport::ITransport::SendPromise::Pointer transportSendPromise;
|
|
EXPECT_CALL(transportMock_, send(expectedData, _)).WillOnce(SaveArg<1>(&transportSendPromise));
|
|
|
|
Message::Pointer message(std::make_shared<Message>(ChannelId::INPUT, EncryptionType::PLAIN, MessageType::CONTROL));
|
|
message->insertPayload(payload);
|
|
MessageOutStream::Pointer messageOutStream(std::make_shared<MessageOutStream>(ioService_, transport_, cryptor_));
|
|
messageOutStream->stream(message, std::move(sendPromise_));
|
|
|
|
ioService_.run();
|
|
ioService_.reset();
|
|
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0);
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onResolve());
|
|
transportSendPromise->resolve();
|
|
ioService_.run();
|
|
}
|
|
|
|
BOOST_FIXTURE_TEST_CASE(MessageOutStream_SendEncryptedMessage, MessageOutStreamUnitTest)
|
|
{
|
|
const FrameHeader frameHeader(ChannelId::VIDEO, FrameType::BULK, EncryptionType::ENCRYPTED, MessageType::CONTROL);
|
|
const common::Data encryptedPayload(2000, 0x5F);
|
|
const FrameSize frameSize(encryptedPayload.size());
|
|
|
|
const auto& frameHeaderData = frameHeader.getData();
|
|
common::Data expectedData(frameHeaderData.begin(), frameHeaderData.end());
|
|
|
|
const auto& frameSizeData = frameSize.getData();
|
|
expectedData.insert(expectedData.end(), frameSizeData.begin(), frameSizeData.end());
|
|
expectedData.insert(expectedData.end(), encryptedPayload.begin(), encryptedPayload.end());
|
|
|
|
common::Data encryptedData(expectedData.begin(), expectedData.begin() + FrameHeader::getSizeOf() + FrameSize::getSizeOf(FrameSizeType::SHORT));
|
|
encryptedData.insert(encryptedData.end(), encryptedPayload.begin(), encryptedPayload.end());
|
|
transport::ITransport::SendPromise::Pointer transportSendPromise;
|
|
EXPECT_CALL(cryptorMock_, encrypt(_, _)).WillOnce(DoAll(SetArgReferee<0>(encryptedData), Return(encryptedPayload.size())));
|
|
EXPECT_CALL(transportMock_, send(expectedData, _)).WillOnce(SaveArg<1>(&transportSendPromise));
|
|
|
|
Message::Pointer message(std::make_shared<Message>(ChannelId::VIDEO, EncryptionType::ENCRYPTED, MessageType::CONTROL));
|
|
const common::Data payload(1000, 0x5E);
|
|
message->insertPayload(payload);
|
|
MessageOutStream::Pointer messageOutStream(std::make_shared<MessageOutStream>(ioService_, transport_, cryptor_));
|
|
messageOutStream->stream(message, std::move(sendPromise_));
|
|
|
|
ioService_.run();
|
|
ioService_.reset();
|
|
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0);
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onResolve());
|
|
transportSendPromise->resolve();
|
|
ioService_.run();
|
|
}
|
|
|
|
BOOST_FIXTURE_TEST_CASE(MessageOutStream_MessageEncryptionFailed, MessageOutStreamUnitTest)
|
|
{
|
|
Message::Pointer message(std::make_shared<Message>(ChannelId::VIDEO, EncryptionType::ENCRYPTED, MessageType::CONTROL));
|
|
const common::Data payload(1000, 0x5E);
|
|
message->insertPayload(payload);
|
|
MessageOutStream::Pointer messageOutStream(std::make_shared<MessageOutStream>(ioService_, transport_, cryptor_));
|
|
|
|
EXPECT_CALL(cryptorMock_, encrypt(_, _)).WillOnce(ThrowSSLWriteException());
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onReject(error::Error(error::ErrorCode::SSL_WRITE, 32)));
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onResolve()).Times(0);
|
|
messageOutStream->stream(message, std::move(sendPromise_));
|
|
|
|
ioService_.run();
|
|
}
|
|
|
|
BOOST_FIXTURE_TEST_CASE(MessageOutStream_SendError, MessageOutStreamUnitTest)
|
|
{
|
|
Message::Pointer message(std::make_shared<Message>(ChannelId::VIDEO, EncryptionType::PLAIN, MessageType::CONTROL));
|
|
const common::Data payload(1000, 0x5E);
|
|
message->insertPayload(payload);
|
|
MessageOutStream::Pointer messageOutStream(std::make_shared<MessageOutStream>(ioService_, transport_, cryptor_));
|
|
|
|
transport::ITransport::SendPromise::Pointer transportSendPromise;
|
|
EXPECT_CALL(transportMock_, send(_, _)).WillOnce(SaveArg<1>(&transportSendPromise));
|
|
messageOutStream->stream(message, std::move(sendPromise_));
|
|
|
|
ioService_.run();
|
|
ioService_.reset();
|
|
|
|
const error::Error e(error::ErrorCode::USB_TRANSFER, 513);
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onReject(e));
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onResolve()).Times(0);
|
|
|
|
transportSendPromise->reject(e);
|
|
ioService_.run();
|
|
}
|
|
|
|
BOOST_FIXTURE_TEST_CASE(MessageOutStream_SendSplittedMessage, MessageOutStreamUnitTest)
|
|
{
|
|
const size_t maxFramePayloadSize = 0x4000;
|
|
|
|
const common::Data frame1Payload(maxFramePayloadSize, 0x5E);
|
|
const common::Data frame2Payload(maxFramePayloadSize, 0x5E);
|
|
|
|
const FrameHeader frame1Header(ChannelId::VIDEO, FrameType::FIRST, EncryptionType::PLAIN, MessageType::CONTROL);
|
|
const auto& frame1HeaderData = frame1Header.getData();
|
|
|
|
const FrameSize frame1Size(frame1Payload.size(), frame1Payload.size() + frame2Payload.size());
|
|
const auto& frame1SizeData = frame1Size.getData();
|
|
|
|
const FrameHeader frame2Header(ChannelId::VIDEO, FrameType::LAST, EncryptionType::PLAIN, MessageType::CONTROL);
|
|
const auto& frame2HeaderData = frame2Header.getData();
|
|
|
|
const FrameSize frame2Size(frame2Payload.size());
|
|
const auto& frame2SizeData = frame2Size.getData();
|
|
|
|
Message::Pointer message(std::make_shared<Message>(ChannelId::VIDEO, EncryptionType::PLAIN, MessageType::CONTROL));
|
|
message->insertPayload(frame1Payload);
|
|
message->insertPayload(frame2Payload);
|
|
|
|
transport::ITransport::SendPromise::Pointer transportSendPromise;
|
|
common::Data expectedData1(frame1HeaderData.begin(), frame1HeaderData.end());
|
|
expectedData1.insert(expectedData1.end(), frame1SizeData.begin(), frame1SizeData.end());
|
|
expectedData1.insert(expectedData1.end(), frame1Payload.begin(), frame1Payload.end());
|
|
EXPECT_CALL(transportMock_, send(expectedData1, _)).WillOnce(SaveArg<1>(&transportSendPromise));
|
|
|
|
MessageOutStream::Pointer messageOutStream(std::make_shared<MessageOutStream>(ioService_, transport_, cryptor_));
|
|
messageOutStream->stream(message, std::move(sendPromise_));
|
|
|
|
ioService_.run();
|
|
ioService_.reset();
|
|
|
|
common::Data expectedData2(frame2HeaderData.begin(), frame2HeaderData.end());
|
|
expectedData2.insert(expectedData2.end(), frame2SizeData.begin(), frame2SizeData.end());
|
|
expectedData2.insert(expectedData2.end(), frame2Payload.begin(), frame2Payload.end());
|
|
EXPECT_CALL(transportMock_, send(expectedData2, _)).WillOnce(SaveArg<1>(&transportSendPromise));
|
|
|
|
auto secondSendPromise = SendPromise::defer(ioService_);
|
|
SendPromiseHandlerMock secondSendPromiseHandlerMock;
|
|
secondSendPromise->then(std::bind(&SendPromiseHandlerMock::onResolve, &secondSendPromiseHandlerMock),
|
|
std::bind(&SendPromiseHandlerMock::onReject, &secondSendPromiseHandlerMock, std::placeholders::_1));
|
|
|
|
EXPECT_CALL(secondSendPromiseHandlerMock, onResolve()).Times(0);
|
|
EXPECT_CALL(secondSendPromiseHandlerMock, onReject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS)));
|
|
messageOutStream->stream(message, std::move(secondSendPromise));
|
|
|
|
transportSendPromise->resolve();
|
|
ioService_.run();
|
|
ioService_.reset();
|
|
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0);
|
|
EXPECT_CALL(sendPromiseHandlerMock_, onResolve());
|
|
transportSendPromise->resolve();
|
|
ioService_.run();
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|