Skip to content

Commit

Permalink
Client sleep unittesting.
Browse files Browse the repository at this point in the history
  • Loading branch information
arobenko committed Aug 8, 2024
1 parent 344f610 commit 23b934a
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 11 deletions.
4 changes: 2 additions & 2 deletions client/lib/src/ClientImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ op::ConnectOp* ClientImpl::connectPrepare(CC_MqttsnErrorCode* ec)

if (!m_disconnectOps.empty()) {
// Already allocated
errorLog("Another disconnect operation is in progress.");
errorLog("Another disconnect or sleep operation is in progress.");
updateEc(ec, CC_MqttsnErrorCode_Busy);
break;
}
Expand Down Expand Up @@ -308,7 +308,7 @@ op::DisconnectOp* ClientImpl::disconnectPrepare(CC_MqttsnErrorCode* ec)
}

if (!m_disconnectOps.empty()) {
errorLog("Another disconnect operation is in progress.");
errorLog("Another disconnect or sleep operation is in progress.");
updateEc(ec, CC_MqttsnErrorCode_Busy);
break;
}
Expand Down
4 changes: 4 additions & 0 deletions client/lib/src/SessionState.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@

#pragma once

#include "ProtocolDefs.h"

namespace cc_mqttsn_client
{

struct SessionState
{
using ClientIdStr = ConnectMsg::Field_clientId::ValueType;
static constexpr unsigned DefaultKeepAlive = 60;

ClientIdStr m_clientId;
unsigned m_keepAliveMs = 0U;
CC_MqttsnConnectionStatus m_connectionStatus = CC_MqttsnConnectionStatus_Disconnected;
bool m_disconnecting = false;
Expand Down
2 changes: 2 additions & 0 deletions client/lib/src/op/ConnectOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ CC_MqttsnErrorCode ConnectOp::send(CC_MqttsnConnectCompleteCb cb, void* cbData)
return ec;
}

client().sessionState().m_clientId.clear();
if (m_connectMsg.field_flags().field_mid().getBitValue_CleanSession()) {
// Don't wait for acknowledgement, assume state cleared upon send
client().reuseState() = ReuseState();
Expand Down Expand Up @@ -250,6 +251,7 @@ void ConnectOp::handle(ConnackMsg& msg)
#endif // #if CC_MQTTSN_CLIENT_HAS_WILL

if (info.m_returnCode == CC_MqttsnReturnCode_Accepted) {
client().sessionState().m_clientId = m_connectMsg.field_clientId().value();
client().sessionState().m_keepAliveMs = comms::units::getMilliseconds<unsigned>(m_connectMsg.field_duration());
client().gatewayConnected();
}
Expand Down
2 changes: 1 addition & 1 deletion client/lib/src/op/DisconnectOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ CC_MqttsnErrorCode DisconnectOp::sendInternal()
void DisconnectOp::timeoutInternal()
{
if (getRetryCount() == 0U) {
errorLog("All retries of the disconnect operation have been exhausted.");
errorLog("All retries of the disconnect or sleep operation have been exhausted.");
completeOpInternal(CC_MqttsnAsyncOpStatus_Timeout);
return;
}
Expand Down
9 changes: 8 additions & 1 deletion client/lib/src/op/KeepAliveOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,15 @@ void KeepAliveOp::sendPing()
return; // Ping has already been sent, waiting for response
}

auto& cl = client();
auto& st = cl.sessionState();

PingreqMsg msg;
client().sendMessage(msg);
if (st.m_connectionStatus == CC_MqttsnConnectionStatus_Asleep) {
msg.field_clientId().setValue(st.m_clientId);
}

cl.sendMessage(msg);
restartRespTimer();
}

Expand Down
1 change: 1 addition & 0 deletions client/lib/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ if (TARGET cc::cc_mqttsn_client)
cc_mqttsn_client_add_unit_test(UnitTestSubscribe ${DEFAULT_BASE_LIB_NAME})
cc_mqttsn_client_add_unit_test(UnitTestUnsubscribe ${DEFAULT_BASE_LIB_NAME})
cc_mqttsn_client_add_unit_test(UnitTestWill ${DEFAULT_BASE_LIB_NAME})
cc_mqttsn_client_add_unit_test(UnitTestSleep ${DEFAULT_BASE_LIB_NAME})
endif ()

# TODO
Expand Down
77 changes: 75 additions & 2 deletions client/lib/test/UnitTestCommonBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ UnitTestCommonBase::UnitTestCommonBase(const LibFuncs& funcs) :
test_assert(m_funcs.m_get_outgoing_topic_id_storage_limit != nullptr);
test_assert(m_funcs.m_set_incoming_topic_id_storage_limit != nullptr);
test_assert(m_funcs.m_get_incoming_topic_id_storage_limit != nullptr);
test_assert(m_funcs.m_asleep_check_messages != nullptr);
test_assert(m_funcs.m_search_prepare != nullptr);
test_assert(m_funcs.m_search_set_retry_period != nullptr);
test_assert(m_funcs.m_search_get_retry_period != nullptr);
Expand Down Expand Up @@ -124,8 +125,17 @@ UnitTestCommonBase::UnitTestCommonBase(const LibFuncs& funcs) :
test_assert(m_funcs.m_will_config != nullptr);
test_assert(m_funcs.m_will_send != nullptr);
test_assert(m_funcs.m_will_cancel != nullptr);
test_assert(m_funcs.m_will != nullptr);

test_assert(m_funcs.m_will != nullptr);
test_assert(m_funcs.m_sleep_prepare != nullptr);
test_assert(m_funcs.m_sleep_set_retry_period != nullptr);
test_assert(m_funcs.m_sleep_get_retry_period != nullptr);
test_assert(m_funcs.m_sleep_set_retry_count != nullptr);
test_assert(m_funcs.m_sleep_get_retry_count != nullptr);
test_assert(m_funcs.m_sleep_init_config != nullptr);
test_assert(m_funcs.m_sleep_config != nullptr);
test_assert(m_funcs.m_sleep_send != nullptr);
test_assert(m_funcs.m_sleep_cancel != nullptr);
test_assert(m_funcs.m_sleep != nullptr);
test_assert(m_funcs.m_set_next_tick_program_callback != nullptr);
test_assert(m_funcs.m_set_cancel_next_tick_wait_callback != nullptr);
test_assert(m_funcs.m_set_send_output_data_callback != nullptr);
Expand Down Expand Up @@ -800,6 +810,28 @@ CC_MqttsnErrorCode UnitTestCommonBase::unitTestWillSend(CC_MqttsnWillHandle will
return m_funcs.m_will_send(will, &UnitTestCommonBase::unitTestWillCompleteCb, this);
}

bool UnitTestCommonBase::unitTestHasSleepCompleteReport() const
{
return !m_data.m_sleepCompleteReports.empty();
}

UnitTestCommonBase::UnitTestSleepCompleteReportPtr UnitTestCommonBase::unitTestSleepCompleteReport(bool mustExist)
{
if (!unitTestHasSleepCompleteReport()) {
test_assert(!mustExist);
return UnitTestSleepCompleteReportPtr();
}

auto ptr = std::move(m_data.m_sleepCompleteReports.front());
m_data.m_sleepCompleteReports.pop_front();
return ptr;
}

CC_MqttsnErrorCode UnitTestCommonBase::unitTestSleepSend(CC_MqttsnSleepHandle sleep)
{
return m_funcs.m_sleep_send(sleep, &UnitTestCommonBase::unitTestSleepCompleteCb, this);
}

bool UnitTestCommonBase::unitTestHasReceivedMessage() const
{
return !m_data.m_recvMsgs.empty();
Expand Down Expand Up @@ -827,11 +859,21 @@ CC_MqttsnErrorCode UnitTestCommonBase::apiSetDefaultRetryPeriod(CC_MqttsnClient*
return m_funcs.m_set_default_retry_period(client, value);
}

unsigned UnitTestCommonBase::apiGetDefaultRetryPeriod(CC_MqttsnClientHandle client)
{
return m_funcs.m_get_default_retry_period(client);
}

CC_MqttsnErrorCode UnitTestCommonBase::apiSetDefaultRetryCount(CC_MqttsnClient* client, unsigned value)
{
return m_funcs.m_set_default_retry_count(client, value);
}

unsigned UnitTestCommonBase::apiGetDefaultRetryCount(CC_MqttsnClientHandle client)
{
return m_funcs.m_get_default_retry_count(client);
}

CC_MqttsnErrorCode UnitTestCommonBase::apiSetVerifyIncomingMsgSubscribed(CC_MqttsnClient* client, bool enabled)
{
return m_funcs.m_set_verify_incoming_msg_subscribed(client, enabled);
Expand Down Expand Up @@ -1060,6 +1102,31 @@ CC_MqttsnErrorCode UnitTestCommonBase::apiWillCancel(CC_MqttsnWillHandle will)
return m_funcs.m_will_cancel(will);
}

CC_MqttsnSleepHandle UnitTestCommonBase::apiSleepPrepare(CC_MqttsnClient* client, CC_MqttsnErrorCode* ec)
{
return m_funcs.m_sleep_prepare(client, ec);
}

CC_MqttsnErrorCode UnitTestCommonBase::apiSleepSetRetryCount(CC_MqttsnSleepHandle sleep, unsigned count)
{
return m_funcs.m_sleep_set_retry_count(sleep, count);
}

void UnitTestCommonBase::apiSleepInitConfig(CC_MqttsnSleepConfig* config)
{
m_funcs.m_sleep_init_config(config);
}

CC_MqttsnErrorCode UnitTestCommonBase::apiSleepConfig(CC_MqttsnSleepHandle sleep, const CC_MqttsnSleepConfig* config)
{
return m_funcs.m_sleep_config(sleep, config);
}

CC_MqttsnErrorCode UnitTestCommonBase::apiSleepCancel(CC_MqttsnSleepHandle sleep)
{
return m_funcs.m_sleep_cancel(sleep);
}

void UnitTestCommonBase::unitTestMessageReportCb(void* data, const CC_MqttsnMessageInfo* msgInfo)
{
test_assert(msgInfo != nullptr);
Expand Down Expand Up @@ -1143,4 +1210,10 @@ void UnitTestCommonBase::unitTestWillCompleteCb(void* data, CC_MqttsnAsyncOpStat
{
auto* thisPtr = asThis(data);
thisPtr->m_data.m_willCompleteReports.push_back(std::make_unique<UnitTestWillCompleteReport>(status, info));
}

void UnitTestCommonBase::unitTestSleepCompleteCb(void* data, CC_MqttsnAsyncOpStatus status)
{
auto* thisPtr = asThis(data);
thisPtr->m_data.m_sleepCompleteReports.push_back(std::make_unique<UnitTestSleepCompleteReport>(status));
}
39 changes: 36 additions & 3 deletions client/lib/test/UnitTestCommonBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class UnitTestCommonBase
unsigned long long (*m_get_outgoing_topic_id_storage_limit)(CC_MqttsnClientHandle) = nullptr;
CC_MqttsnErrorCode (*m_set_incoming_topic_id_storage_limit)(CC_MqttsnClientHandle, unsigned long long) = nullptr;
unsigned long long (*m_get_incoming_topic_id_storage_limit)(CC_MqttsnClientHandle) = nullptr;
CC_MqttsnErrorCode (*m_asleep_check_messages)(CC_MqttsnClientHandle client) = nullptr;
CC_MqttsnSearchHandle (*m_search_prepare)(CC_MqttsnClientHandle, CC_MqttsnErrorCode*) = nullptr;
CC_MqttsnErrorCode (*m_search_set_retry_period)(CC_MqttsnSearchHandle, unsigned) = nullptr;
unsigned (*m_search_get_retry_period)(CC_MqttsnSearchHandle) = nullptr;
Expand Down Expand Up @@ -115,7 +116,16 @@ class UnitTestCommonBase
CC_MqttsnErrorCode (*m_will_send)(CC_MqttsnWillHandle, CC_MqttsnWillCompleteCb, void*) = nullptr;
CC_MqttsnErrorCode (*m_will_cancel)(CC_MqttsnWillHandle) = nullptr;
CC_MqttsnErrorCode (*m_will)(CC_MqttsnClientHandle, const CC_MqttsnWillConfig*, CC_MqttsnWillCompleteCb, void* cbData) = nullptr;

CC_MqttsnSleepHandle (*m_sleep_prepare)(CC_MqttsnClientHandle, CC_MqttsnErrorCode*) = nullptr;
CC_MqttsnErrorCode (*m_sleep_set_retry_period)(CC_MqttsnSleepHandle, unsigned) = nullptr;
unsigned (*m_sleep_get_retry_period)(CC_MqttsnSleepHandle) = nullptr;
CC_MqttsnErrorCode (*m_sleep_set_retry_count)(CC_MqttsnSleepHandle, unsigned) = nullptr;
unsigned (*m_sleep_get_retry_count)(CC_MqttsnSleepHandle) = nullptr;
void (*m_sleep_init_config)(CC_MqttsnSleepConfig*) = nullptr;
CC_MqttsnErrorCode (*m_sleep_config)(CC_MqttsnSleepHandle, const CC_MqttsnSleepConfig*) = nullptr;
CC_MqttsnErrorCode (*m_sleep_send)(CC_MqttsnSleepHandle, CC_MqttsnSleepCompleteCb, void*) = nullptr;
CC_MqttsnErrorCode (*m_sleep_cancel)(CC_MqttsnSleepHandle) = nullptr;
CC_MqttsnErrorCode (*m_sleep)(CC_MqttsnClientHandle, const CC_MqttsnSleepConfig*, CC_MqttsnSleepCompleteCb, void* cbData) = nullptr;
void (*m_set_next_tick_program_callback)(CC_MqttsnClientHandle, CC_MqttsnNextTickProgramCb, void*) = nullptr;
void (*m_set_cancel_next_tick_wait_callback)(CC_MqttsnClientHandle, CC_MqttsnCancelNextTickWaitCb, void*) = nullptr;
void (*m_set_send_output_data_callback)(CC_MqttsnClientHandle, CC_MqttsnSendOutputDataCb, void*) = nullptr;
Expand Down Expand Up @@ -272,7 +282,6 @@ class UnitTestCommonBase
CC_MqttsnTopicId m_topicId = 0U;
};


struct UnitTestUnsubscribeCompleteReport
{
CC_MqttsnUnsubscribeHandle m_handle = nullptr;
Expand Down Expand Up @@ -335,6 +344,15 @@ class UnitTestCommonBase
using UnitTestWillCompleteReportPtr = std::unique_ptr<UnitTestWillCompleteReport>;
using UnitTestWillCompleteReportList = std::list<UnitTestWillCompleteReportPtr>;

struct UnitTestSleepCompleteReport
{
CC_MqttsnAsyncOpStatus m_status = CC_MqttsnAsyncOpStatus_ValuesLimit;

UnitTestSleepCompleteReport(CC_MqttsnAsyncOpStatus status) : m_status(status) {};
};

using UnitTestSleepCompleteReportPtr = std::unique_ptr<UnitTestSleepCompleteReport>;
using UnitTestSleepCompleteReportList = std::list<UnitTestSleepCompleteReportPtr>;

struct UnitTestMessageInfo
{
Expand Down Expand Up @@ -422,12 +440,19 @@ class UnitTestCommonBase

CC_MqttsnErrorCode unitTestWillSend(CC_MqttsnWillHandle will);

bool unitTestHasSleepCompleteReport() const;
UnitTestSleepCompleteReportPtr unitTestSleepCompleteReport(bool mustExist = true);

CC_MqttsnErrorCode unitTestSleepSend(CC_MqttsnSleepHandle sleep);

bool unitTestHasReceivedMessage() const;
UnitTestMessageInfoPtr unitTestReceivedMessage(bool mustExist = true);

void apiProcessData(CC_MqttsnClient* client, const unsigned char* buf, unsigned bufLen);
CC_MqttsnErrorCode apiSetDefaultRetryPeriod(CC_MqttsnClient* client, unsigned value);
unsigned apiGetDefaultRetryPeriod(CC_MqttsnClientHandle client);
CC_MqttsnErrorCode apiSetDefaultRetryCount(CC_MqttsnClient* client, unsigned value);
unsigned apiGetDefaultRetryCount(CC_MqttsnClientHandle client);
CC_MqttsnErrorCode apiSetVerifyIncomingMsgSubscribed(CC_MqttsnClient* client, bool enabled);
void apiInitGatewayInfo(CC_MqttsnGatewayInfo* info);
CC_MqttsnErrorCode apiSetAvailableGatewayInfo(CC_MqttsnClient* client, const CC_MqttsnGatewayInfo* info);
Expand Down Expand Up @@ -472,7 +497,13 @@ class UnitTestCommonBase
CC_MqttsnErrorCode apiWillSetRetryCount(CC_MqttsnWillHandle will, unsigned count);
void apiWillInitConfig(CC_MqttsnWillConfig* config);
CC_MqttsnErrorCode apiWillConfig(CC_MqttsnWillHandle will, const CC_MqttsnWillConfig* config);
CC_MqttsnErrorCode apiWillCancel(CC_MqttsnWillHandle will);
CC_MqttsnErrorCode apiWillCancel(CC_MqttsnWillHandle will);

CC_MqttsnSleepHandle apiSleepPrepare(CC_MqttsnClient* client, CC_MqttsnErrorCode* ec = nullptr);
CC_MqttsnErrorCode apiSleepSetRetryCount(CC_MqttsnSleepHandle sleep, unsigned count);
void apiSleepInitConfig(CC_MqttsnSleepConfig* config);
CC_MqttsnErrorCode apiSleepConfig(CC_MqttsnSleepHandle sleep, const CC_MqttsnSleepConfig* config);
CC_MqttsnErrorCode apiSleepCancel(CC_MqttsnSleepHandle sleep);


protected:
Expand All @@ -494,6 +525,7 @@ class UnitTestCommonBase
UnitTestUnsubscribeCompleteReportList m_unsubscribeCompleteReports;
UnitTestPublishCompleteReportList m_publishCompleteReports;
UnitTestWillCompleteReportList m_willCompleteReports;
UnitTestSleepCompleteReportList m_sleepCompleteReports;
UnitTestMessageInfosList m_recvMsgs;
};

Expand All @@ -512,6 +544,7 @@ class UnitTestCommonBase
static void unitTestUnsubscribeCompleteCb(void* data, CC_MqttsnUnsubscribeHandle handle, CC_MqttsnAsyncOpStatus status);
static void unitTestPublishCompleteCb(void* data, CC_MqttsnPublishHandle handle, CC_MqttsnAsyncOpStatus status, const CC_MqttsnPublishInfo* info);
static void unitTestWillCompleteCb(void* data, CC_MqttsnAsyncOpStatus status, const CC_MqttsnWillInfo* info);
static void unitTestSleepCompleteCb(void* data, CC_MqttsnAsyncOpStatus status);

LibFuncs m_funcs;
ClientData m_data;
Expand Down
14 changes: 12 additions & 2 deletions client/lib/test/UnitTestDefaultBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const UnitTestDefaultBase::LibFuncs& UnitTestDefaultBase::getFuncs()
funcs.m_get_outgoing_topic_id_storage_limit = &cc_mqttsn_client_get_outgoing_topic_id_storage_limit;
funcs.m_set_incoming_topic_id_storage_limit = &cc_mqttsn_client_set_incoming_topic_id_storage_limit;
funcs.m_get_incoming_topic_id_storage_limit = &cc_mqttsn_client_get_incoming_topic_id_storage_limit;
funcs.m_asleep_check_messages = &cc_mqttsn_client_asleep_check_messages;
funcs.m_search_prepare = &cc_mqttsn_client_search_prepare;
funcs.m_search_set_retry_period = &cc_mqttsn_client_search_set_retry_period;
funcs.m_search_get_retry_period = &cc_mqttsn_client_search_get_retry_period;
Expand Down Expand Up @@ -105,8 +106,17 @@ const UnitTestDefaultBase::LibFuncs& UnitTestDefaultBase::getFuncs()
funcs.m_will_config = &cc_mqttsn_client_will_config;
funcs.m_will_send = &cc_mqttsn_client_will_send;
funcs.m_will_cancel = &cc_mqttsn_client_will_cancel;
funcs.m_will = &cc_mqttsn_client_will;

funcs.m_will = &cc_mqttsn_client_will;
funcs.m_sleep_prepare = &cc_mqttsn_client_sleep_prepare;
funcs.m_sleep_set_retry_period = &cc_mqttsn_client_sleep_set_retry_period;
funcs.m_sleep_get_retry_period = &cc_mqttsn_client_sleep_get_retry_period;
funcs.m_sleep_set_retry_count = &cc_mqttsn_client_sleep_set_retry_count;
funcs.m_sleep_get_retry_count = &cc_mqttsn_client_sleep_get_retry_count;
funcs.m_sleep_init_config = &cc_mqttsn_client_sleep_init_config;
funcs.m_sleep_config = &cc_mqttsn_client_sleep_config;
funcs.m_sleep_send = &cc_mqttsn_client_sleep_send;
funcs.m_sleep_cancel = &cc_mqttsn_client_sleep_cancel;
funcs.m_sleep = &cc_mqttsn_client_sleep;
funcs.m_set_next_tick_program_callback = &cc_mqttsn_client_set_next_tick_program_callback;
funcs.m_set_cancel_next_tick_wait_callback = &cc_mqttsn_client_set_cancel_next_tick_wait_callback;
funcs.m_set_send_output_data_callback = &cc_mqttsn_client_set_send_output_data_callback;
Expand Down
Loading

0 comments on commit 23b934a

Please sign in to comment.