Skip to content

Commit

Permalink
add unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-du-car committed Nov 22, 2023
1 parent c72ecc9 commit 383bafd
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 35 deletions.
4 changes: 3 additions & 1 deletion src/v2i-hub/TelematicBridgePlugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ TARGET_LINK_LIBRARIES ( ${PROJECT_NAME} tmxutils jsoncpp nats)
####################################################
################## Testing #######################
####################################################
add_library(${PROJECT_NAME}_lib src/TelematicUnit.cpp)
target_link_libraries(${PROJECT_NAME}_lib PUBLIC tmxutils jsoncpp nats)
enable_testing()
include_directories(${PROJECT_SOURCE_DIR}/src)
file(GLOB_RECURSE TEST_SOURCES LIST_DIRECTORIES false test/*.h test/*.cpp)
add_executable(${PROJECT_NAME}_test ${TEST_SOURCES})
target_link_libraries(${PROJECT_NAME}_test PRIVATE gtest tmxutils jsoncpp nats)
target_link_libraries(${PROJECT_NAME}_test PRIVATE gtest ${PROJECT_NAME}_lib)
45 changes: 22 additions & 23 deletions src/v2i-hub/TelematicBridgePlugin/src/TelematicUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace TelematicBridge
void TelematicUnit::registerUnitRequestor()
{
// Reset registration status
setRegistered(false);
_isRegistered = false;

while (!_isRegistered)
{
Expand All @@ -39,13 +39,13 @@ namespace TelematicBridge
_eventName = root[EVENT_NAME].asString();

// Unit is registered when server responds with event information (location, testing_type, event_name)
setRegistered(true);
_isRegistered = true;
}
natsMsg_Destroy(reply);
}
else
{
PLOG(logERROR) << "NATS regsiter Error: " << s << "-" << natsStatus_GetText(s);
throw TelematicBridgeException(natsStatus_GetText(s));
}
sleep(1);
}
Expand All @@ -66,7 +66,7 @@ namespace TelematicBridge
PLOG(logDEBUG2) << "Inside available topic replier";
stringstream topic;
topic << _unit.unitId << AVAILABLE_TOPICS;
auto s = natsConnection_Subscribe(&_subAvailableTopic, _conn, topic.str().c_str(), onAvailableTopicsCallback, this);
natsConnection_Subscribe(&_subAvailableTopic, _conn, topic.str().c_str(), onAvailableTopicsCallback, this);
}
}

Expand All @@ -77,7 +77,7 @@ namespace TelematicBridge
PLOG(logDEBUG2) << "Inside selected topic replier";
stringstream topic;
topic << _unit.unitId << PUBLISH_TOPICS;
auto s = natsConnection_Subscribe(&_subSelectedTopic, _conn, topic.str().c_str(), onSelectedTopicsCallback, this);
natsConnection_Subscribe(&_subSelectedTopic, _conn, topic.str().c_str(), onSelectedTopicsCallback, this);
}
}

Expand All @@ -88,7 +88,7 @@ namespace TelematicBridge
PLOG(logDEBUG2) << "Inside check status replier";
stringstream topic;
topic << _unit.unitId << CHECK_STATUS;
auto s = natsConnection_Subscribe(&_subCheckStatus, _conn, topic.str().c_str(), onCheckStatusCallback, this);
natsConnection_Subscribe(&_subCheckStatus, _conn, topic.str().c_str(), onCheckStatusCallback, this);
}
}

Expand All @@ -113,10 +113,13 @@ namespace TelematicBridge
// Sends a reply
if (natsMsg_GetReply(msg) != nullptr)
{
TelematicUnit *obj = (TelematicUnit *)object;
auto reply = constructAvailableTopicsReplyString(obj->_unit, obj->_availableTopics, obj->_excludedTopics);
PLOG(logDEBUG3) << "Available topics replied! " << reply;
natsConnection_PublishString(nc, natsMsg_GetReply(msg), reply.c_str());
const auto obj = (TelematicUnit *)object;
if (obj)
{
auto reply = constructAvailableTopicsReplyString(obj->_unit, obj->_availableTopics, obj->_excludedTopics);
PLOG(logDEBUG3) << "Available topics replied! " << reply;
natsConnection_PublishString(nc, natsMsg_GetReply(msg), reply.c_str());
}
natsMsg_Destroy(msg);
}
}
Expand All @@ -131,7 +134,7 @@ namespace TelematicBridge
auto root = parseJson(msgStr);
if (root.isMember(TOPICS) && root[TOPICS].isArray())
{
TelematicUnit *obj = (TelematicUnit *)object;
auto obj = (TelematicUnit *)object;
// clear old selected topics
obj->_selectedTopics.clear();

Expand All @@ -144,8 +147,8 @@ namespace TelematicBridge
string reply = "request received!";
PLOG(logDEBUG3) << "Selected topics replied: " << reply;
natsConnection_PublishString(nc, natsMsg_GetReply(msg), reply.c_str());
natsMsg_Destroy(msg);
}
natsMsg_Destroy(msg);
}

void TelematicUnit::onCheckStatusCallback(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *object)
Expand All @@ -160,20 +163,21 @@ namespace TelematicBridge
}
}

string TelematicUnit::constructPublishedDataString(const unit_st &unit, const string &_eventLocation, const string &_testingType, const string &_eventName, const string &topicName, const Json::Value payload)
string TelematicUnit::constructPublishedDataString(const unit_st &unit, const string &eventLocation, const string &testingType, const string &eventName, const string &topicName, const Json::Value& payload) const
{
Json::Value message;
message[UNIT_ID] = unit.unitId;
message[UNIT_NAME] = unit.unitName;
message[UNIT_TYPE] = unit.unitType;
message[LOCATION] = _eventLocation;
message[TESTING_TYPE] = _testingType;
message[EVENT_NAME] = _eventName;
message[LOCATION] = eventLocation;
message[TESTING_TYPE] = testingType;
message[EVENT_NAME] = eventName;
message[TOPIC_NAME] = topicName;
message[TIMESTAMP] = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
message[TIMESTAMP] = payload.isMember("timestamp") ? payload["timestamp"].asUInt64() : duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
message[PAYLOAD] = payload;
Json::FastWriter fasterWirter;
string jsonStr = fasterWirter.write(message);
return jsonStr;
}

Json::Value TelematicUnit::parseJson(const string &jsonStr)
Expand Down Expand Up @@ -211,12 +215,7 @@ namespace TelematicBridge
return reply;
}

void TelematicUnit::setRegistered(bool isRegistered)
{
_isRegistered = isRegistered;
}

void TelematicUnit::setUnit(unit_st unit)
void TelematicUnit::setUnit(const unit_st& unit)
{
lock_guard<mutex> lock(_unitMutex);
_unit = unit;
Expand Down
30 changes: 19 additions & 11 deletions src/v2i-hub/TelematicBridgePlugin/src/TelematicUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ namespace TelematicBridge
explicit TelematicUnit() = default;
/**
* @brief A function for telematic unit to connect to NATS server. Throw exception is connection failed. *
* @param const string NATS server URL
* @param string string NATS server URL
*/
void connect(const string &natsURL);

Expand All @@ -77,7 +77,8 @@ namespace TelematicBridge
void registerUnitRequestor();

/**
* @brief A NATS replier to publish available topics upon receiving a request for a list of available topics.
* @brief A NATS replier to subscribe to NATS server and receive available topics request.
* Publish list of available topics after receiving/processing the request.
*/
void availableTopicsReplier();

Expand All @@ -89,7 +90,8 @@ namespace TelematicBridge
void selectedTopicsReplier();

/**
* @brief A NATS replier to publish unit status upon receiving a request for status check from telematic server.
* @brief A NATS replier to subscribe to NATS server and receive request for status check from telematic server.
* Publish unit status upon receiving a request.
*/
void checkStatusReplier();

Expand All @@ -113,11 +115,6 @@ namespace TelematicBridge
*/
static string constructAvailableTopicsReplyString(const unit_st &unit, const vector<string> &availableTopicList, const string &excludedTopics);

/**
* @brief Update isregisterd indicator
*/
void setRegistered(bool isRegistered);

/**
* @brief A function to update available topics global variables when discovering a new topic.
*/
Expand All @@ -130,15 +127,15 @@ namespace TelematicBridge
* @param string Testing type
* @param string Event name
* @param string Topic name is a combination of type_subtype_source from TMX IVPMessage
* @param string Payload is the actual data generated by V2xHub plugin
* @param Json::Value Payload is the actual data generated by V2xHub plugin
*/
string constructPublishedDataString(const unit_st &unit, const string &_eventLocation, const string &_testingType, const string &_eventName, const string &topicName, const Json::Value payload);
string constructPublishedDataString(const unit_st &unit, const string &eventLocation, const string &testingType, const string &eventName, const string &topicName, const Json::Value& payload) const;

/**
* @brief A function to update global unit variable
* @param unit_st object that has the unit id, type and name information
*/
void setUnit(unit_st unit);
void setUnit(const unit_st& unit);

/**
* @brief A function to update excluded topics.
Expand All @@ -153,8 +150,19 @@ namespace TelematicBridge
*/
bool inSelectedTopics(const string &topic);

/**
* @brief A callback function for available topic replier
*/
static void onAvailableTopicsCallback(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *object);

/**
* @brief A callback function for selected topic replier
*/
static void onSelectedTopicsCallback(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *object);

/**
* @brief A callback function for check status replier
*/
static void onCheckStatusCallback(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *object);

~TelematicUnit();
Expand Down
117 changes: 117 additions & 0 deletions src/v2i-hub/TelematicBridgePlugin/test/test_TelematicUnit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include <gtest/gtest.h>
#include "TelematicUnit.h"

namespace TelematicBridge
{
class test_TelematicUnit : public ::testing::Test
{
public:
shared_ptr<TelematicUnit> _telematicUnitPtr = make_shared<TelematicUnit>();
unit_st unit =
{
"test_id",
"test_name",
"infrastructure"};
};

TEST_F(test_TelematicUnit, setUnit)
{
ASSERT_NO_THROW(_telematicUnitPtr->setUnit(unit));
}

TEST_F(test_TelematicUnit, updateExcludedTopics)
{
ASSERT_NO_THROW(_telematicUnitPtr->updateExcludedTopics("test_topic"));
}

TEST_F(test_TelematicUnit, inSelectedTopics)
{
ASSERT_FALSE(_telematicUnitPtr->inSelectedTopics("test_topic"));
}

TEST_F(test_TelematicUnit, updateAvailableTopics)
{
ASSERT_NO_THROW(_telematicUnitPtr->updateAvailableTopics("test_topic"));
}

TEST_F(test_TelematicUnit, constructAvailableTopicsReplyString)
{
vector<string> topics = {"test_topic", "excluded_topic"};
string excluded_topic = "excluded_topic";
auto reply = TelematicUnit::constructAvailableTopicsReplyString(unit, topics, excluded_topic);
auto json = TelematicUnit::parseJson(reply);
ASSERT_EQ("test_topic", json["topics"][0]["name"].asString());
}

TEST_F(test_TelematicUnit, constructPublishedDataString)
{
string eventLocation = "location";
string testingType = "unit_test";
string eventName = "testing";
string topicName = "test_topic";
Json::Value payload;
payload["body"] = "test_body";
auto reply = _telematicUnitPtr->constructPublishedDataString(unit, eventLocation, testingType, eventName, topicName, payload);
auto json = TelematicUnit::parseJson(reply);
ASSERT_EQ(eventLocation, json["location"].asString());
ASSERT_EQ(testingType, json["testing_type"].asString());
ASSERT_EQ(eventName, json["event_name"].asString());
}

TEST_F(test_TelematicUnit, onCheckStatusCallback)
{
natsMsg *msg;
string data = "{\"data\":\"test\"}";
natsMsg_Create(&msg, "test_subject", "Test_reply", data.c_str(), data.size());
ASSERT_NO_THROW(TelematicUnit::onCheckStatusCallback(nullptr, nullptr, msg, nullptr));
}

TEST_F(test_TelematicUnit, onSelectedTopicsCallback)
{
natsMsg *msg;
string data = "{\"data\":\"test\"}";
natsMsg_Create(&msg, "test_subject", "Test_reply", data.c_str(), data.size());
ASSERT_NO_THROW(TelematicUnit::onSelectedTopicsCallback(nullptr, nullptr, msg, nullptr));
}

TEST_F(test_TelematicUnit, onAvailableTopicsCallback)
{
natsMsg *msg;
string data = "{\"data\":\"test\"}";
natsMsg_Create(&msg, "test_subject", "Test_reply", data.c_str(), data.size());
ASSERT_NO_THROW(TelematicUnit::onAvailableTopicsCallback(nullptr, nullptr, msg, _telematicUnitPtr.get()));
}

TEST_F(test_TelematicUnit, publishMessage)
{
string topicName = "test_topic";
Json::Value payload;
payload["body"] = "test_body";
ASSERT_THROW(_telematicUnitPtr->publishMessage(topicName, payload), TelematicBridgeException);
}

TEST_F(test_TelematicUnit, checkStatusReplier)
{
_telematicUnitPtr->checkStatusReplier();
}

TEST_F(test_TelematicUnit, selectedTopicsReplier)
{
_telematicUnitPtr->selectedTopicsReplier();
}

TEST_F(test_TelematicUnit, availableTopicsReplier)
{
_telematicUnitPtr->availableTopicsReplier();
}

TEST_F(test_TelematicUnit, registerUnitRequestor)
{
ASSERT_THROW(_telematicUnitPtr->registerUnitRequestor(), TelematicBridgeException);
}

TEST_F(test_TelematicUnit, connect)
{
ASSERT_THROW(_telematicUnitPtr->connect("nats://127.0.0.1:4222"), TelematicBridgeException);
}
}

0 comments on commit 383bafd

Please sign in to comment.