-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added SerialCommunicationLoopback (#440)
* feat: added SerialCommunicationLoopback * chore: replaced ClockFixture with EventDispatcherFixture * chore: made SerialCommunicationLoopback compatible with <= GCC9 * chore: fixed comments * chore: correct comparing byte ranges for SerialCommunicationLoopbackTest * chore: fix coverage and macos build --------- Co-authored-by: Daan Timmer <[email protected]>
- Loading branch information
1 parent
4b52156
commit 2c87dfb
Showing
5 changed files
with
152 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "services/util/SerialCommunicationLoopback.hpp" | ||
#include "hal/interfaces/SerialCommunication.hpp" | ||
#include "infra/event/EventDispatcher.hpp" | ||
|
||
namespace services | ||
{ | ||
SerialCommunicationLoopback::SerialCommunicationLoopback() | ||
: server(&client) | ||
, client(&server) | ||
{} | ||
|
||
hal::SerialCommunication& SerialCommunicationLoopback::Server() | ||
{ | ||
return server; | ||
} | ||
|
||
hal::SerialCommunication& SerialCommunicationLoopback::Client() | ||
{ | ||
return client; | ||
} | ||
|
||
SerialCommunicationLoopback::SerialCommunicationLoopbackPeer::SerialCommunicationLoopbackPeer(SerialCommunicationLoopbackPeer* other) | ||
: other{ *other } | ||
{} | ||
|
||
void SerialCommunicationLoopback::SerialCommunicationLoopbackPeer::SendData(infra::ConstByteRange data, infra::Function<void()> actionOnCompletion) | ||
{ | ||
this->data = data; | ||
this->actionOnCompletion = actionOnCompletion; | ||
|
||
infra::EventDispatcher::Instance().Schedule([this] | ||
{ | ||
other.dataReceived(this->data); | ||
this->actionOnCompletion(); | ||
}); | ||
} | ||
|
||
void SerialCommunicationLoopback::SerialCommunicationLoopbackPeer::ReceiveData(infra::Function<void(infra::ConstByteRange data)> dataReceived) | ||
{ | ||
this->dataReceived = dataReceived; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#ifndef SERVICES_SERIAL_COMMUNICATION_LOOPBACK_HPP | ||
#define SERVICES_SERIAL_COMMUNICATION_LOOPBACK_HPP | ||
|
||
#include "hal/interfaces/SerialCommunication.hpp" | ||
|
||
namespace services | ||
{ | ||
|
||
class SerialCommunicationLoopback | ||
{ | ||
public: | ||
SerialCommunicationLoopback(); | ||
|
||
hal::SerialCommunication& Server(); | ||
hal::SerialCommunication& Client(); | ||
|
||
private: | ||
class SerialCommunicationLoopbackPeer | ||
: public hal::SerialCommunication | ||
{ | ||
public: | ||
// pointer instead of reference to avoid defining a copy constructor | ||
// pass by reference generates a warning with clang and -Wunitialized | ||
explicit SerialCommunicationLoopbackPeer(SerialCommunicationLoopbackPeer* other); | ||
|
||
void SendData(infra::ConstByteRange data, infra::Function<void()> actionOnCompletion) override; | ||
void ReceiveData(infra::Function<void(infra::ConstByteRange data)> dataReceived) override; | ||
|
||
private: | ||
SerialCommunicationLoopbackPeer& other; | ||
|
||
infra::ConstByteRange data; | ||
infra::Function<void()> actionOnCompletion; | ||
infra::Function<void(infra::ConstByteRange data)> dataReceived; | ||
}; | ||
|
||
private: | ||
SerialCommunicationLoopbackPeer server; | ||
SerialCommunicationLoopbackPeer client; | ||
}; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#include "hal/interfaces/SerialCommunication.hpp" | ||
#include "infra/event/test_helper/EventDispatcherFixture.hpp" | ||
#include "infra/util/ByteRange.hpp" | ||
#include "infra/util/Function.hpp" | ||
#include "infra/util/test_helper/MockCallback.hpp" | ||
#include "services/util/SerialCommunicationLoopback.hpp" | ||
#include "gmock/gmock.h" | ||
#include "gtest/gtest.h" | ||
|
||
class SerialCommunicationLoopbackTest | ||
: public testing::Test | ||
, public infra::EventDispatcherFixture | ||
{ | ||
public: | ||
services::SerialCommunicationLoopback SerialCommunicationLoopback; | ||
hal::SerialCommunication& server{ SerialCommunicationLoopback.Server() }; | ||
hal::SerialCommunication& client{ SerialCommunicationLoopback.Client() }; | ||
}; | ||
|
||
TEST_F(SerialCommunicationLoopbackTest, SendFromServerReceiveByClient) | ||
{ | ||
infra::ConstByteRange data = infra::MakeStringByteRange("hello"); | ||
infra::VerifyingFunctionMock<void(infra::ConstByteRange)> clientReceiveCallback{ data }; | ||
|
||
client.ReceiveData(clientReceiveCallback); | ||
server.SendData(data, infra::emptyFunction); | ||
|
||
ExecuteAllActions(); | ||
} | ||
|
||
TEST_F(SerialCommunicationLoopbackTest, SendFromClientReceiveByServer) | ||
{ | ||
infra::ConstByteRange data = infra::MakeStringByteRange("world"); | ||
infra::VerifyingFunctionMock<void(infra::ConstByteRange)> serverReceiveCallback{ data }; | ||
|
||
server.ReceiveData(serverReceiveCallback); | ||
client.SendData(data, infra::emptyFunction); | ||
|
||
ExecuteAllActions(); | ||
} | ||
|
||
TEST_F(SerialCommunicationLoopbackTest, ActionOnCompletionAfterDataReceivedByOtherPeer) | ||
{ | ||
infra::ConstByteRange data = infra::MakeStringByteRange("Hello World!"); | ||
infra::MockCallback<void(infra::ConstByteRange)> dataReceivedMockCallback; | ||
infra::MockCallback<void()> actionOnCompletionMockCallback; | ||
|
||
server.ReceiveData([&dataReceivedMockCallback](infra::ConstByteRange data) | ||
{ | ||
dataReceivedMockCallback.callback(data); | ||
}); | ||
|
||
client.SendData(data, [&actionOnCompletionMockCallback] | ||
{ | ||
actionOnCompletionMockCallback.callback(); | ||
}); | ||
|
||
testing::InSequence sequence; | ||
EXPECT_CALL(dataReceivedMockCallback, callback(data)); | ||
EXPECT_CALL(actionOnCompletionMockCallback, callback()); | ||
|
||
ExecuteAllActions(); | ||
} |