diff options
author | Youngjae Shin <yj99.shin@samsung.com> | 2023-07-11 17:04:15 +0900 |
---|---|---|
committer | Youngjae Shin <yj99.shin@samsung.com> | 2023-07-12 10:02:20 +0900 |
commit | 694f7b2b42440a9af281dfb62557bc1d9d988d0f (patch) | |
tree | 8d7b280c9581f23f076e6b3c31bd5d9afe395d92 | |
parent | 05d9a1957363bc5687995416cae2d79cde811cbd (diff) | |
download | aitt-accepted/tizen_unified_dev.tar.gz aitt-accepted/tizen_unified_dev.tar.bz2 aitt-accepted/tizen_unified_dev.zip |
revise test casesaccepted/tizen/unified/dev/20230726.115902accepted/tizen/unified/20230713.082748accepted/tizen_unified_dev
- add negative test cases
- Set PublishWithReply return type(exception) same as other API
- Improved invalid parameters and status checks
32 files changed, 1825 insertions, 1059 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b01fb5b..41f814a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,12 @@ if(PLATFORM STREQUAL "android") set(AITT_NEEDS_LIBRARIES ${MOSQUITTO_LIBRARY} ${FLATBUFFERS_LIBRARY} ${LOG_LIBRARIES}) else(PLATFORM STREQUAL "android") if(PLATFORM STREQUAL "tizen") + if(WITH_WEBRTC) + add_definitions(-DWITH_WEBRTC) + endif() + if(WITH_RTSP) + add_definitions(-DWITH_RTSP) + endif() add_definitions(-DTIZEN) set(ADDITIONAL_OPT "-DTIZEN") set(ADDITION_PKG dlog) @@ -107,11 +113,9 @@ endif() if(PLATFORM STREQUAL "tizen") if(WITH_WEBRTC) - add_definitions(-DWITH_WEBRTC) add_subdirectory(modules/webrtc) endif() if(WITH_RTSP) - add_definitions(-DWITH_RTSP) add_subdirectory(modules/rtsp) endif() endif(PLATFORM STREQUAL "tizen") diff --git a/common/AittDiscovery.cc b/common/AittDiscovery.cc index 816f635..b6c1e81 100644 --- a/common/AittDiscovery.cc +++ b/common/AittDiscovery.cc @@ -24,7 +24,8 @@ namespace aitt { -AittDiscovery::AittDiscovery(const std::string &id) : id_(id), callback_handle(nullptr) +AittDiscovery::AittDiscovery(const std::string &id) + : is_running(false), id_(id), callback_handle(nullptr) { } @@ -45,15 +46,18 @@ void AittDiscovery::Start(const std::string &host, int port, const std::string & discovery_mq->SetWillInfo(DISCOVERY_TOPIC_BASE + id_, nullptr, 0, AITT_QOS_EXACTLY_ONCE, true); discovery_mq->SetConnectionCallback([&](int status) { - if (status != AITT_CONNECTED) + if (status != AITT_CONNECTED) { + ERR("Discovery Disconnected"); + is_running = false; return; - + } DBG("Discovery Connected"); - callback_handle = discovery_mq->Subscribe(DISCOVERY_TOPIC_BASE + "+", - DiscoveryMessageCallback, static_cast<void *>(this), AITT_QOS_EXACTLY_ONCE); - discovery_mq->SetConnectionCallback(nullptr); + if (nullptr == callback_handle) + callback_handle = discovery_mq->Subscribe(DISCOVERY_TOPIC_BASE + "+", + DiscoveryMessageCallback, static_cast<void *>(this), AITT_QOS_EXACTLY_ONCE); }); discovery_mq->Connect(host, port, username, password); + is_running = true; } void AittDiscovery::Restart() @@ -64,8 +68,14 @@ void AittDiscovery::Restart() static_cast<void *>(this), AITT_QOS_EXACTLY_ONCE); } +bool AittDiscovery::IsRunning(void) +{ + return is_running; +} + void AittDiscovery::Stop() { + is_running = false; discovery_mq->SetConnectionCallback(nullptr); discovery_mq->Unsubscribe(callback_handle); discovery_mq->Publish(DISCOVERY_TOPIC_BASE + id_, nullptr, 0, AITT_QOS_EXACTLY_ONCE, true); diff --git a/common/AittDiscovery.h b/common/AittDiscovery.h index cbddd6e..ea9ec97 100644 --- a/common/AittDiscovery.h +++ b/common/AittDiscovery.h @@ -37,6 +37,7 @@ class AittDiscovery { void Start(const std::string &host, int port, const std::string &username, const std::string &password); void Restart(); + bool IsRunning(void); void Stop(); void UpdateDiscoveryMsg(const std::string &protocol, const void *msg, int length); int AddDiscoveryCB(const std::string &protocol, const DiscoveryCallback &cb); @@ -59,6 +60,7 @@ class AittDiscovery { void *user_data); void PublishDiscoveryMsg(); + bool is_running; std::string id_; std::unique_ptr<MQ> discovery_mq; void *callback_handle; diff --git a/common/GlibMainLoop.cc b/common/GlibMainLoop.cc index 4a3331c..b21bc71 100644 --- a/common/GlibMainLoop.cc +++ b/common/GlibMainLoop.cc @@ -112,6 +112,11 @@ GlibMainLoop::MainLoopData *GlibMainLoop::RemoveWatch(int fd) unsigned int GlibMainLoop::AddTimeout(int interval, const mainLoopCB &cb, MainLoopData *data) { + if (interval <= 0) { + ERR("Invalid interval(%d)", interval); + return 0; + } + MainLoopCbData *cb_data = new MainLoopCbData(); GMainContext *ctx = g_main_loop_get_context(loop); cb_data->ctx = ctx; diff --git a/common/PosixMainLoop.cc b/common/PosixMainLoop.cc index 6b400a8..b23e77e 100644 --- a/common/PosixMainLoop.cc +++ b/common/PosixMainLoop.cc @@ -165,8 +165,8 @@ unsigned int PosixMainLoop::AddTimeout(int interval, const mainLoopCB &cb, MainL { static int identifier = TIMEOUT_START; - if (interval < 0) { - ERR("Invalid : interval(%d) < 0", interval); + if (interval <= 0) { + ERR("Invalid interval(%d)", interval); return 0; } diff --git a/include/AITT.h b/include/AITT.h index 0b389e8..4599271 100644 --- a/include/AITT.h +++ b/include/AITT.h @@ -53,7 +53,7 @@ class API AITT { void Publish(const std::string &topic, const void *data, const int datalen, AittProtocol protocols = AITT_TYPE_MQTT, AittQoS qos = AITT_QOS_AT_MOST_ONCE, bool retain = false); - int PublishWithReply(const std::string &topic, const void *data, const int datalen, + void PublishWithReply(const std::string &topic, const void *data, const int datalen, AittProtocol protocol, AittQoS qos, bool retain, const SubscribeCallback &cb, void *cbdata, const std::string &correlation); diff --git a/include/AittException.h b/include/AittException.h index 2d2101c..f8b13e8 100644 --- a/include/AittException.h +++ b/include/AittException.h @@ -33,6 +33,7 @@ class AittException : public std::exception { RESOURCE_BUSY_ERR, ALREADY, NOT_SUPPORTED, + INVALID_STATE, }; AittException(ErrCode err_code); diff --git a/modules/tcp/tests/AESEncryptor_test.cc b/modules/tcp/tests/AESEncryptor_test.cc index 7ebad9e..674ee49 100644 --- a/modules/tcp/tests/AESEncryptor_test.cc +++ b/modules/tcp/tests/AESEncryptor_test.cc @@ -67,3 +67,15 @@ TEST_F(AESEncryptorTest, EncryptDecryped_P_Anytime) ASSERT_STREQ(e.what(), strerror(EINVAL)); } } + +TEST_F(AESEncryptorTest, Decryped_N_Anytime) +{ + try { + unsigned char plaintext[crypto.GetCryptogramSize(TEST_MESSAGE.size())]; + int len = + crypto.Decrypt((unsigned char *)TEST_MESSAGE.c_str(), TEST_MESSAGE.size(), plaintext); + EXPECT_EQ(len, -1); + } catch (std::exception &e) { + ASSERT_STREQ(e.what(), strerror(EINVAL)); + } +} diff --git a/modules/tcp/tests/AES_Compatibility_test.cc b/modules/tcp/tests/AES_Compatibility_test.cc index 2969a52..39e9357 100644 --- a/modules/tcp/tests/AES_Compatibility_test.cc +++ b/modules/tcp/tests/AES_Compatibility_test.cc @@ -28,19 +28,6 @@ using namespace AittTCPNamespace; class AESCompatibilityTest : public testing::Test { protected: - void SetUp() override - { - opensslcryptor.Init(TEST_CIPHER_KEY, TEST_CIPHER_IV); - mbedtlscryptor.Init(TEST_CIPHER_KEY, TEST_CIPHER_IV); - memset(ciphertext, 0, sizeof(ciphertext)); - memset(decrypted, 0, sizeof(decrypted)); - - plaintext.resize(20); - std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned char> - random_engine; - std::generate(begin(plaintext), end(plaintext), std::ref(random_engine)); - } - unsigned char TEST_CIPHER_KEY[AITT_TCP_ENCRYPTOR_KEY_LEN] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; @@ -56,6 +43,13 @@ class AESCompatibilityTest : public testing::Test { TEST_F(AESCompatibilityTest, opensslEncrypt_mbedtlsDecrypt_Anytime) { + opensslcryptor.Init(TEST_CIPHER_KEY, TEST_CIPHER_IV); + mbedtlscryptor.Init(TEST_CIPHER_KEY, TEST_CIPHER_IV); + + plaintext.resize(20); + std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned char> random_engine; + std::generate(begin(plaintext), end(plaintext), std::ref(random_engine)); + for (int i = 1; i < static_cast<int>(plaintext.size()); i++) { int ciphertext_len = opensslcryptor.Encrypt(plaintext.data(), i, ciphertext); int decrypted_len = mbedtlscryptor.Decrypt(ciphertext, ciphertext_len, decrypted); @@ -63,10 +57,11 @@ TEST_F(AESCompatibilityTest, opensslEncrypt_mbedtlsDecrypt_Anytime) ASSERT_EQ(i, decrypted_len); ASSERT_EQ(0, memcmp(plaintext.data(), decrypted, decrypted_len)); } -} -TEST_F(AESCompatibilityTest, mbedtlsEncrypt_opensslDecrypt_Anytime) -{ + memset(ciphertext, 0, sizeof(ciphertext)); + memset(decrypted, 0, sizeof(decrypted)); + std::generate(begin(plaintext), end(plaintext), std::ref(random_engine)); + for (int i = 1; i < static_cast<int>(plaintext.size()); i++) { int ciphertext_len = mbedtlscryptor.Encrypt(plaintext.data(), i, ciphertext); int decrypted_len = opensslcryptor.Decrypt(ciphertext, ciphertext_len, decrypted); @@ -74,10 +69,11 @@ TEST_F(AESCompatibilityTest, mbedtlsEncrypt_opensslDecrypt_Anytime) ASSERT_EQ(i, decrypted_len); ASSERT_EQ(0, memcmp(plaintext.data(), decrypted, decrypted_len)); } -} -TEST_F(AESCompatibilityTest, opensslEncrypt_opensslDecrypt_Anytime) -{ + memset(ciphertext, 0, sizeof(ciphertext)); + memset(decrypted, 0, sizeof(decrypted)); + std::generate(begin(plaintext), end(plaintext), std::ref(random_engine)); + for (int i = 1; i < static_cast<int>(plaintext.size()); i++) { int ciphertext_len = opensslcryptor.Encrypt(plaintext.data(), i, ciphertext); int decrypted_len = opensslcryptor.Decrypt(ciphertext, ciphertext_len, decrypted); @@ -85,10 +81,11 @@ TEST_F(AESCompatibilityTest, opensslEncrypt_opensslDecrypt_Anytime) ASSERT_EQ(i, decrypted_len); ASSERT_EQ(0, memcmp(plaintext.data(), decrypted, decrypted_len)); } -} -TEST_F(AESCompatibilityTest, mbedtlsEncrypt_mbedtlsDecrypt_Anytime) -{ + memset(ciphertext, 0, sizeof(ciphertext)); + memset(decrypted, 0, sizeof(decrypted)); + std::generate(begin(plaintext), end(plaintext), std::ref(random_engine)); + for (int i = 1; i < static_cast<int>(plaintext.size()); i++) { int ciphertext_len = mbedtlscryptor.Encrypt(plaintext.data(), i, ciphertext); int decrypted_len = mbedtlscryptor.Decrypt(ciphertext, ciphertext_len, decrypted); diff --git a/modules/tcp/tests/TCPServer_test.cc b/modules/tcp/tests/TCPServer_test.cc index 0e2f571..e1df957 100644 --- a/modules/tcp/tests/TCPServer_test.cc +++ b/modules/tcp/tests/TCPServer_test.cc @@ -30,13 +30,6 @@ using namespace AittTCPNamespace; -TEST(TCPServer, Create_P_Anytime) -{ - unsigned short port = TEST_SERVER_PORT; - std::unique_ptr<TCP::Server> tcp(new TCP::Server(TEST_SERVER_ADDRESS, port)); - ASSERT_NE(tcp, nullptr); -} - TEST(TCPServer, Create_N_Anytime) { try { @@ -55,32 +48,19 @@ TEST(TCPServer, Create_AutoPort_P_Anytime) std::unique_ptr<TCP::Server> tcp(new TCP::Server(TEST_SERVER_ADDRESS, port)); ASSERT_NE(tcp, nullptr); ASSERT_NE(port, 0); + ASSERT_EQ(tcp->GetPort(), port); + ASSERT_GE(tcp->GetHandle(), 0); } -TEST(TCPServer, GetPort_P_Anytime) +TEST(TCPServer, Create_Port_P_Anytime) { unsigned short port = TEST_SERVER_PORT; std::unique_ptr<TCP::Server> tcp(new TCP::Server(TEST_SERVER_ADDRESS, port)); ASSERT_NE(tcp, nullptr); ASSERT_EQ(tcp->GetPort(), TEST_SERVER_PORT); -} - -TEST(TCPServer, GetHandle_P_Anytime) -{ - unsigned short port = TEST_SERVER_PORT; - std::unique_ptr<TCP::Server> tcp(new TCP::Server(TEST_SERVER_ADDRESS, port)); - ASSERT_NE(tcp, nullptr); ASSERT_GE(tcp->GetHandle(), 0); } -TEST(TCPServer, GetPort_AutoPort_P_Anytime) -{ - unsigned short port = TEST_SERVER_AVAILABLE_PORT; - std::unique_ptr<TCP::Server> tcp(new TCP::Server(TEST_SERVER_ADDRESS, port)); - ASSERT_NE(tcp, nullptr); - ASSERT_EQ(tcp->GetPort(), port); -} - TEST(TCPServer, AcceptPeer_P_Anytime) { std::mutex m; @@ -93,6 +73,7 @@ TEST(TCPServer, AcceptPeer_P_Anytime) std::thread serverThread( [serverPort, &m, &ready, &connected, &ready_cv, &connected_cv](void) mutable -> void { std::unique_ptr<TCP::Server> tcp(new TCP::Server(TEST_SERVER_ADDRESS, serverPort)); + ASSERT_NE(tcp, nullptr); { std::lock_guard<std::mutex> lk(m); ready = true; @@ -113,6 +94,7 @@ TEST(TCPServer, AcceptPeer_P_Anytime) TCP::ConnectInfo info; info.port = serverPort; std::unique_ptr<TCP> tcp(new TCP(TEST_SERVER_ADDRESS, info)); + ASSERT_NE(tcp, nullptr); connected_cv.wait(lk, [&connected] { return connected; }); } diff --git a/modules/tcp/tests/TCP_test.cc b/modules/tcp/tests/TCP_test.cc index 5a76c92..1e6db87 100644 --- a/modules/tcp/tests/TCP_test.cc +++ b/modules/tcp/tests/TCP_test.cc @@ -103,7 +103,7 @@ TEST(TCP, Create_InvalidAddress_N_Anytime) } } -TEST_F(TCPTest, GetPeerInfo_P_Anytime) +TEST_F(TCPTest, Get_P_Anytime) { std::string peerHost; unsigned short peerPort = 0; @@ -113,18 +113,10 @@ TEST_F(TCPTest, GetPeerInfo_P_Anytime) peer->GetPeerInfo(peerHost, peerPort); ASSERT_STREQ(peerHost.c_str(), TEST_SERVER_ADDRESS); ASSERT_GT(peerPort, 0); -} -TEST_F(TCPTest, GetHandle_P_Anytime) -{ - RunServer(); int handle = peer->GetHandle(); - ASSERT_GE(handle, 0); -} + ASSERT_GT(handle, 0); -TEST_F(TCPTest, GetPort_P_Anytime) -{ - RunServer(); unsigned short port = peer->GetPort(); ASSERT_GT(port, 0); } diff --git a/src/AITT.cc b/src/AITT.cc index e98b98c..8e723d4 100644 --- a/src/AITT.cc +++ b/src/AITT.cc @@ -101,7 +101,7 @@ void AITT::Publish(const std::string &topic, const void *data, const int datalen return pImpl->Publish(topic, data, datalen, protocols, qos, retain); } -int AITT::PublishWithReply(const std::string &topic, const void *data, const int datalen, +void AITT::PublishWithReply(const std::string &topic, const void *data, const int datalen, AittProtocol protocol, AittQoS qos, bool retain, const SubscribeCallback &cb, void *cbdata, const std::string &correlation) { diff --git a/src/AITTImpl.cc b/src/AITTImpl.cc index f054c19..0d49e6f 100644 --- a/src/AITTImpl.cc +++ b/src/AITTImpl.cc @@ -163,14 +163,18 @@ void AITT::Impl::UnsubscribeAll() subscribed_list.clear(); } -void AITT::Impl::ConfigureTransportModule(const std::string &key, const std::string &value, - AittProtocol protocols) -{ -} - void AITT::Impl::Publish(const std::string &topic, const void *data, const int datalen, AittProtocol protocols, AittQoS qos, bool retain) { + if (discovery.IsRunning() == false) { + ERR("Not connected"); + throw AittException(AittException::INVALID_STATE); + } + if ((protocols & ~(AITT_TYPE_MQTT | AITT_TYPE_TCP | AITT_TYPE_TCP_SECURE)) != 0) { + ERR("Unknown Protocol(%d)", protocols); + throw AittException(AittException::INVALID_ARG); + } + if ((protocols & AITT_TYPE_MQTT) == AITT_TYPE_MQTT) mq->Publish(topic, data, datalen, qos, retain); @@ -199,7 +203,7 @@ AittSubscribeID AITT::Impl::Subscribe(const std::string &topic, const AITT::Subs default: ERR("Unknown AittProtocol(%d)", protocol); delete info; - throw std::runtime_error("Unknown AittProtocol"); + throw AittException(AittException::INVALID_ARG); } info->second = subscribe_handle; { @@ -284,14 +288,14 @@ void *AITT::Impl::Unsubscribe(AittSubscribeID subscribe_id) return user_data; } -// It's not supported with multiple protocols -int AITT::Impl::PublishWithReply(const std::string &topic, const void *data, const int datalen, +// It's not supported with multiple protocols like subscribe. +void AITT::Impl::PublishWithReply(const std::string &topic, const void *data, const int datalen, AittProtocol protocol, AittQoS qos, bool retain, const SubscribeCallback &cb, void *user_data, const std::string &correlation) { std::string replyTopic = topic + RESPONSE_POSTFIX + std::to_string(reply_id++); - Subscribe( + auto id = Subscribe( replyTopic, [this, cb](AittMsg *sub_msg, const void *sub_data, const int sub_datalen, void *sub_cbdata) { @@ -317,9 +321,9 @@ int AITT::Impl::PublishWithReply(const std::string &topic, const void *data, con break; default: ERR("Unknown AittProtocol(%d)", protocol); - return -1; + Unsubscribe(id); + throw AittException(AittException::INVALID_ARG); } - return 0; } int AITT::Impl::PublishWithReplySync(const std::string &topic, const void *data, const int datalen, @@ -444,24 +448,20 @@ void AITT::Impl::DestroyStream(AittStream *aitt_stream) int AITT::Impl::CountSubscriber(const std::string &topic, AittProtocol protocols) { - int total = 0; - if (topic.find("+") != std::string::npos || topic.find("#") != std::string::npos) { ERR("Not Support Wildcard in CountSubscriber"); return AITT_ERROR_NOT_SUPPORTED; } - if ((protocols & AITT_TYPE_MQTT) == AITT_TYPE_MQTT) { + int total = 0; + if (protocols & AITT_TYPE_MQTT) total += mq_discovery_handler.CountSubscriber(topic); - } - if ((protocols & AITT_TYPE_TCP) == AITT_TYPE_TCP) { + if (protocols & AITT_TYPE_TCP) total += modules.Get(AITT_TYPE_TCP).CountSubscriber(topic); - } - if ((protocols & AITT_TYPE_TCP_SECURE) == AITT_TYPE_TCP_SECURE) { + if (protocols & AITT_TYPE_TCP_SECURE) total += modules.Get(AITT_TYPE_TCP_SECURE).CountSubscriber(topic); - } return total; } diff --git a/src/AITTImpl.h b/src/AITTImpl.h index 6932173..954e3a8 100644 --- a/src/AITTImpl.h +++ b/src/AITTImpl.h @@ -44,12 +44,9 @@ class AITT::Impl { const std::string &password); void Disconnect(void); - void ConfigureTransportModule(const std::string &key, const std::string &value, - AittProtocol protocols); - void Publish(const std::string &topic, const void *data, const int datalen, AittProtocol protocols, AittQoS qos, bool retain); - int PublishWithReply(const std::string &topic, const void *data, const int datalen, + void PublishWithReply(const std::string &topic, const void *data, const int datalen, AittProtocol protocol, AittQoS qos, bool retain, const AITT::SubscribeCallback &cb, void *cbdata, const std::string &correlation); int PublishWithReplySync(const std::string &topic, const void *data, const int datalen, diff --git a/src/ModuleManager.cc b/src/ModuleManager.cc index 40000a6..6fa09f5 100644 --- a/src/ModuleManager.cc +++ b/src/ModuleManager.cc @@ -190,6 +190,8 @@ std::unique_ptr<MQ> ModuleManager::NewCustomMQ(const std::string &id, const Aitt AittStream *ModuleManager::CreateStream(AittStreamProtocol type, const std::string &topic, AittStreamRole role) { + RETV_IF(type < 0 || AITT_STREAM_TYPE_MAX <= type, nullptr); + AittStreamModule *stream = nullptr; try { stream = NewStreamModule(type, topic, role); diff --git a/tests/AITT_TCP_test.cc b/tests/AITT_TCP_test.cc index 6ef36e2..edc5fff 100644 --- a/tests/AITT_TCP_test.cc +++ b/tests/AITT_TCP_test.cc @@ -25,7 +25,7 @@ using AITT = aitt::AITT; -class AITTTCPTest : public testing::Test, public AittTests { +class AittTcpTest : public testing::Test, public AittTests { protected: void SetUp() override { Init(); } void TearDown() override { Deinit(); } @@ -46,13 +46,14 @@ class AITTTCPTest : public testing::Test, public AittTests { AITT aitt(clientId, LOCAL_IP); int cnt = 0; + ready = false; aitt.SetConnectionCallback([&](AITT &handle, int status, void *user_data) { if (status != AITT_CONNECTED) return; aitt.Subscribe( sub_topic, [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTCPTest *test = static_cast<AITTTCPTest *>(cbdata); + AittTcpTest *test = static_cast<AittTcpTest *>(cbdata); INFO("Got Message(Topic:%s, size:%d)", handle->GetTopic().c_str(), szmsg); ++cnt; @@ -77,12 +78,13 @@ class AITTTCPTest : public testing::Test, public AittTests { }); aitt.Connect(); - mainLoop->AddTimeout( + auto timeout = mainLoop->AddTimeout( CHECK_INTERVAL, [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, nullptr); IterateEventLoop(); + mainLoop->RemoveTimeout(timeout); ASSERT_TRUE(ready); } catch (std::exception &e) { @@ -92,20 +94,23 @@ class AITTTCPTest : public testing::Test, public AittTests { void TCP_SubscribeSameTopicTwiceTemplate(AittProtocol protocol) { try { + ready = false; + ready2 = false; + AITT aitt(clientId, LOCAL_IP); aitt.Connect(); aitt.Subscribe( testTopic, [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTCPTest *test = static_cast<AITTTCPTest *>(cbdata); + AittTcpTest *test = static_cast<AittTcpTest *>(cbdata); test->ToggleReady(); }, static_cast<void *>(this), protocol); aitt.Subscribe( testTopic, [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTCPTest *test = static_cast<AITTTCPTest *>(cbdata); + AittTcpTest *test = static_cast<AittTcpTest *>(cbdata); test->ToggleReady2(); }, static_cast<void *>(this), protocol); @@ -116,12 +121,13 @@ class AITTTCPTest : public testing::Test, public AittTests { aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), protocol); - mainLoop->AddTimeout( + auto timeout = mainLoop->AddTimeout( CHECK_INTERVAL, [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { return ReadyAllCheck(static_cast<AittTests *>(this)); }, nullptr); IterateEventLoop(); + mainLoop->RemoveTimeout(timeout); ASSERT_TRUE(ready); ASSERT_TRUE(ready2); @@ -129,29 +135,233 @@ class AITTTCPTest : public testing::Test, public AittTests { FAIL() << "Unexpected exception: " << e.what(); } } + void PublishSubscribeTCPTwiceTemplate(AittProtocol protocol) + { + try { + AITT aitt(clientId, LOCAL_IP); + aitt.Connect(); + + int cnt = 0; + ready = false; + aitt.Subscribe( + testTopic, + [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { + AittTcpTest *test = static_cast<AittTcpTest *>(cbdata); + ++cnt; + std::string receivedMsg(static_cast<const char *>(msg), szmsg); + DBG("Subscribe callback called: %d, szmsg = %d, msg = [%s]", cnt, szmsg, + receivedMsg.c_str()); + if (cnt == 1) { + ASSERT_TRUE(!strcmp(receivedMsg.c_str(), TEST_MSG)); + } else if (cnt == 2) { + ASSERT_TRUE(!strcmp(receivedMsg.c_str(), TEST_MSG2)); + test->ToggleReady(); + } + }, + static_cast<void *>(this), protocol); + + // Wait a few seconds to the AITT client gets server list (discover devices) + while (aitt.CountSubscriber(testTopic, protocol) == 0) { + usleep(SLEEP_10MS); + } + + // NOTE: + // Select target peers and send the data through the specified protocol - TCP + aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), protocol); + + // NOTE: + // Publish message through the specified protocol - TCP + aitt.Publish(testTopic, TEST_MSG2, sizeof(TEST_MSG2), protocol); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) + -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, + nullptr); + + IterateEventLoop(); + + ASSERT_TRUE(ready); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } + } + + void PublishDisconnectTemplate(AittProtocol protocol) + { + ready = false; + const char character_set[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + std::mt19937 random_gen{std::random_device{}()}; + std::uniform_int_distribution<std::string::size_type> gen(0, 61); + + char dump_msg[204800] = {}; + for (size_t i = 0; i < sizeof(dump_msg); i++) { + dump_msg[i] = character_set[gen(random_gen)]; + } + + try { + AITT aitt(clientId, LOCAL_IP); + AITT aitt_retry("retry_test", LOCAL_IP); + aitt.Connect(); + aitt_retry.Connect(); + + int cnt = 0; + aitt.Subscribe( + TEST_STRESS_TOPIC, + [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { + AittTcpTest *test = static_cast<AittTcpTest *>(cbdata); + ++cnt; + if (szmsg == 0 && cnt != 12) { + FAIL() << "Unexpected value" << cnt; + } + + if (msg) { + ASSERT_TRUE(!strncmp(static_cast<const char *>(msg), dump_msg, + sizeof(dump_msg))); + } + + if (cnt == 10) + test->ToggleReady(); + if (cnt == 11) + test->ToggleReady(); + }, + static_cast<void *>(this), protocol); + + { + AITT aitt1("stress_test1", LOCAL_IP); + aitt1.Connect(); + + // Wait a few seconds to the AITT client gets server list (discover devices) + while (aitt1.CountSubscriber(TEST_STRESS_TOPIC, protocol) == 0) { + usleep(SLEEP_10MS); + } + + for (int i = 0; i < 10; i++) { + INFO("size = %zu", sizeof(dump_msg)); + aitt1.Publish(TEST_STRESS_TOPIC, dump_msg, sizeof(dump_msg), protocol, + AITT_QOS_AT_MOST_ONCE); + } + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) + -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, + nullptr); + + IterateEventLoop(); + } + DBG("Client aitt1 is finished"); + + // Here, an unexpected callback(szmsg = 0) is received + // when the publisher is disconnected. + + ASSERT_TRUE(ready); + ready = false; + + aitt_retry.Publish(TEST_STRESS_TOPIC, dump_msg, sizeof(dump_msg), protocol, + AITT_QOS_AT_MOST_ONCE); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) + -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, + nullptr); + + IterateEventLoop(); + + ASSERT_TRUE(ready); + + aitt_retry.Publish(TEST_STRESS_TOPIC, nullptr, 0, protocol, AITT_QOS_AT_LEAST_ONCE); + // Check auto release of aitt. There should be no segmentation faults. + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } + } + + void SubscribeRetainedTCPTemplate(AittProtocol protocol) + { + try { + ready = false; + AITT aitt(clientId, LOCAL_IP); + + aitt.SetConnectionCallback([&](AITT &handle, int status, void *user_data) { + if (status != AITT_CONNECTED) + return; + + // Subscribers who subscribe after publishing will not receive this message + aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), AITT_TYPE_MQTT, + AITT_QOS_AT_MOST_ONCE, true); + + aitt.Subscribe( + testTopic, + [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { + AittTcpTest *test = static_cast<AittTcpTest *>(cbdata); + std::string receivedMsg(static_cast<const char *>(msg), szmsg); + EXPECT_STREQ(receivedMsg.c_str(), TEST_MSG2); + test->ToggleReady(); + }, + static_cast<void *>(this), protocol); + + // Wait a few seconds to the AITT client gets server list (discover devices) + while (aitt.CountSubscriber(testTopic, protocol) == 0) { + usleep(SLEEP_10MS); + } + + aitt.Publish(testTopic, TEST_MSG2, sizeof(TEST_MSG2), protocol); + }); + aitt.Connect(); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) + -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, + nullptr); + + IterateEventLoop(); + ASSERT_TRUE(ready); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } + } }; -TEST_F(AITTTCPTest, TCP_Wildcard_single_Anytime) +TEST_F(AittTcpTest, TCP_Wildcard_single_Anytime) { TCPWildcardsTopicTemplate(AITT_TYPE_TCP, true); + TCPWildcardsTopicTemplate(AITT_TYPE_TCP_SECURE, true); } -TEST_F(AITTTCPTest, SECURE_TCP_Wildcard_single_Anytime) +TEST_F(AittTcpTest, TCP_Wildcard_multi_Anytime) { - TCPWildcardsTopicTemplate(AITT_TYPE_TCP_SECURE, true); + TCPWildcardsTopicTemplate(AITT_TYPE_TCP, false); + TCPWildcardsTopicTemplate(AITT_TYPE_TCP_SECURE, false); } -TEST_F(AITTTCPTest, TCP_Wildcard_multi_Anytime) +TEST_F(AittTcpTest, Subscribe_Same_Topic_twice_Anytime) { - TCPWildcardsTopicTemplate(AITT_TYPE_TCP, false); + TCP_SubscribeSameTopicTwiceTemplate(AITT_TYPE_TCP); + TCP_SubscribeSameTopicTwiceTemplate(AITT_TYPE_TCP_SECURE); } -TEST_F(AITTTCPTest, SECURE_TCP_Wildcard_multi_Anytime) +TEST_F(AittTcpTest, PublishSubscribe_twice_P_Anytime) { - TCPWildcardsTopicTemplate(AITT_TYPE_TCP_SECURE, false); + PublishSubscribeTCPTwiceTemplate(AITT_TYPE_TCP); + PublishSubscribeTCPTwiceTemplate(AITT_TYPE_TCP_SECURE); +} + +TEST_F(AittTcpTest, Subscribe_Retained_P_Anytime) +{ + SubscribeRetainedTCPTemplate(AITT_TYPE_TCP); + SubscribeRetainedTCPTemplate(AITT_TYPE_TCP_SECURE); +} + +TEST_F(AittTcpTest, Publish_Disconnect_P_Anytime) +{ + PublishDisconnectTemplate(AITT_TYPE_TCP); + PublishDisconnectTemplate(AITT_TYPE_TCP_SECURE); } -TEST_F(AITTTCPTest, SECURE_TCP_various_msg_Anytime) +TEST_F(AittTcpTest, SECURE_TCP_various_msg_Anytime) { std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned char> random_engine; std::vector<unsigned char> data(20000); @@ -171,7 +381,7 @@ TEST_F(AITTTCPTest, SECURE_TCP_various_msg_Anytime) testTopic, [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTCPTest *test = static_cast<AITTTCPTest *>(cbdata); + AittTcpTest *test = static_cast<AittTcpTest *>(cbdata); DBG("Subscribe() invoked : size(%d)", szmsg); @@ -211,13 +421,3 @@ TEST_F(AITTTCPTest, SECURE_TCP_various_msg_Anytime) FAIL() << "Unexpected exception: " << e.what(); } } - -TEST_F(AITTTCPTest, TCP_Subscribe_Same_Topic_twice_Anytime) -{ - TCP_SubscribeSameTopicTwiceTemplate(AITT_TYPE_TCP); -} - -TEST_F(AITTTCPTest, Secure_TCP_Subscribe_Same_Topic_twice_Anytime) -{ - TCP_SubscribeSameTopicTwiceTemplate(AITT_TYPE_TCP_SECURE); -} diff --git a/tests/AITT_fixturetest.cc b/tests/AITT_fixturetest.cc new file mode 100644 index 0000000..65a9d28 --- /dev/null +++ b/tests/AITT_fixturetest.cc @@ -0,0 +1,448 @@ +/* + * Copyright 2021-2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "AITT.h" + +#include <gtest/gtest.h> + +#include <random> + +#include "AittTests.h" +#include "aitt_internal.h" + +using AITT = aitt::AITT; + +class AITTTest : public testing::Test, public AittTests { + protected: + void SetUp() override { Init(); } + void TearDown() override { Deinit(); } + + void PubSub(AITT &aitt, const char *test_msg, AittProtocol protocol, AITTTest *aitt_test) + { + aitt.Subscribe( + testTopic, + [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { + AITTTest *test = static_cast<AITTTest *>(cbdata); + std::string receivedMsg(static_cast<const char *>(msg), szmsg); + if (msg) + DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); + else + DBG("Subscribe invoked: zero size msg(%d)", szmsg); + test->StopEventLoop(); + }, + aitt_test, protocol); + + // Wait a few seconds until the AITT client gets a server list (discover devices) + while (aitt.CountSubscriber(testTopic, protocol) == 0) { + usleep(SLEEP_10MS); + } + + DBG("Publish(%s) : %s(%zu)", testTopic.c_str(), test_msg, strlen(test_msg)); + aitt.Publish(testTopic, test_msg, strlen(test_msg), protocol); + } + + void PubSubFull(const char *test_msg, AittProtocol protocol) + { + try { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + aitt.SetConnectionCallback( + [&, test_msg, protocol](AITT &handle, int status, void *user_data) { + if (status == AITT_CONNECTED) + PubSub(aitt, test_msg, protocol, this); + }, + this); + + aitt.Connect(); + + IterateEventLoop(); + aitt.Disconnect(); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } + } + + bool WaitDiscovery(AITT &aitt, std::string topic, int count, int max_ms = 2000) + { + int i = 0; + int max_loop = max_ms / 10; + int result = false; + + for (i = 0; i < max_loop; ++i) { + if (aitt.CountSubscriber(topic) == count) { + result = true; + break; + } + + usleep(SLEEP_10MS); + } + + DBG("WAIT %d ms", i * SLEEP_10MS); + return result; + } + + static void TempSubCallback(AittMsg *msg, const void *data, const int data_len, void *user_data) + { + DBG("TEMP CALLBACK"); + } +}; + +TEST_F(AITTTest, SetConnectionCallback_P_Anytime) +{ + try { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + aitt.SetConnectionCallback( + [&](AITT &handle, int status, void *user_data) { + AITTTest *test = static_cast<AITTTest *>(user_data); + + if (test->ready2) { + EXPECT_EQ(status, AITT_DISCONNECTED); + test->ToggleReady(); + } else { + EXPECT_EQ(status, AITT_CONNECTED); + test->ToggleReady2(); + handle.Disconnect(); + } + }, + this); + aitt.Connect(); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + return ReadyCheck(static_cast<AittTests *>(this)); + }, + nullptr); + + IterateEventLoop(); + ASSERT_TRUE(ready); + ASSERT_TRUE(ready2); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, PubSubInConnectionCB_P_Anytime) +{ + try { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + aitt.SetConnectionCallback( + [&](AITT &handle, int status, void *user_data) { + if (status == AITT_CONNECTED) + PubSub(aitt, TEST_MSG, AITT_TYPE_MQTT, this); + }, + this); + aitt.Connect(); + + IterateEventLoop(); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, UnsetConnectionCallback_P_Anytime) +{ + try { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + aitt.SetConnectionCallback( + [&](AITT &handle, int status, void *user_data) { + AITTTest *test = static_cast<AITTTest *>(user_data); + + if (test->ready) { + FAIL() << "Should not be called"; + } else { + EXPECT_EQ(status, AITT_CONNECTED); + test->ToggleReady(); + handle.SetConnectionCallback(nullptr, nullptr); + handle.Disconnect(); + } + }, + this); + aitt.Connect(); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + return ReadyCheck(static_cast<AittTests *>(this)); + }, + nullptr); + + IterateEventLoop(); + ASSERT_FALSE(ready2); + ASSERT_TRUE(ready); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, PublishSubscribe_P_Anytime) +{ + PubSubFull(TEST_MSG, AITT_TYPE_MQTT); + PubSubFull(TEST_MSG, AITT_TYPE_TCP); + PubSubFull(TEST_MSG, AITT_TYPE_TCP_SECURE); +} + +TEST_F(AITTTest, Publish_0_P_Anytime) +{ + PubSubFull("", AITT_TYPE_MQTT); + PubSubFull("", AITT_TYPE_TCP); + PubSubFull("", AITT_TYPE_TCP_SECURE); +} + +TEST_F(AITTTest, Unsubscribe_in_Subscribe_MQTT_P_Anytime) +{ + try { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + aitt.Connect(); + AittSubscribeID subscribeHandle = aitt.Subscribe( + testTopic, + [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { + AITTTest *test = static_cast<AITTTest *>(cbdata); + std::string receivedMsg(static_cast<const char *>(msg), szmsg); + DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); + + static int cnt = 0; + ++cnt; + if (cnt == 2) + FAIL() << "Should not be called"; + + aitt.Unsubscribe(subscribeHandle); + DBG("Ready flag is toggled"); + test->ToggleReady(); + }, + static_cast<void *>(this)); + + DBG("Publish message to %s (%s)", testTopic.c_str(), TEST_MSG); + aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG)); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + return ReadyCheck(static_cast<AittTests *>(this)); + }, + nullptr); + + IterateEventLoop(); + + ASSERT_TRUE(ready); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, Subscribe_in_Subscribe_MQTT_P_Anytime) +{ + try { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + aitt.Connect(); + aitt.Subscribe( + testTopic, + [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { + std::string receivedMsg(static_cast<const char *>(msg), szmsg); + DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); + + static int cnt = 0; + ++cnt; + if (cnt == 2) + FAIL() << "Should not be called"; + + aitt.Subscribe( + "topic1InCallback", + [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) {}, + cbdata); + + aitt.Subscribe( + "topic2InCallback", + [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) {}, + cbdata); + DBG("Ready flag is toggled"); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, + MainLoopIface::MainLoopData *data) -> int { + AITTTest *test = static_cast<AITTTest *>(this); + test->ToggleReady(); + return AITT_LOOP_EVENT_REMOVE; + }, + nullptr); + }, + static_cast<void *>(this)); + + DBG("Publish message to %s (%s)", testTopic.c_str(), TEST_MSG); + aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG)); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + return ReadyCheck(static_cast<AittTests *>(this)); + }, + nullptr); + + IterateEventLoop(); + + ASSERT_TRUE(ready); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, PublishSubscribe_Multiple_Protocols_P_Anytime) +{ + try { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + aitt.Connect(); + aitt.Subscribe( + testTopic, + [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { + AITTTest *test = static_cast<AITTTest *>(cbdata); + std::string receivedMsg(static_cast<const char *>(msg), szmsg); + DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); + test->ToggleReady(); + }, + static_cast<void *>(this), AITT_TYPE_TCP); + + aitt.Subscribe( + testTopic, + [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { + AITTTest *test = static_cast<AITTTest *>(cbdata); + std::string receivedMsg(static_cast<const char *>(msg), szmsg); + DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); + test->ToggleReady2(); + }, + static_cast<void *>(this), AITT_TYPE_MQTT); + + // Wait a few seconds to the AITT client gets server list (discover devices) + while ( + aitt.CountSubscriber(testTopic, (AittProtocol)(AITT_TYPE_MQTT | AITT_TYPE_TCP)) < 2) { + usleep(SLEEP_10MS); + } + + DBG("Publish message to %s (%s) / %zu", testTopic.c_str(), TEST_MSG, sizeof(TEST_MSG)); + aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), + (AittProtocol)(AITT_TYPE_MQTT | AITT_TYPE_TCP)); + + mainLoop->AddTimeout( + CHECK_INTERVAL, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + return ReadyCheck(static_cast<AittTests *>(this)); + }, + nullptr); + + IterateEventLoop(); + + ASSERT_TRUE(ready); + ASSERT_TRUE(ready2); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, CountSubscriber_P_Anytime) +{ + try { + AITT aitt_client1(clientId + std::string(".1"), LOCAL_IP, AittOption(true, false)); + AITT aitt_client2(clientId + std::string(".2"), LOCAL_IP, AittOption(true, false)); + AITT aitt_server(clientId + std::string(".server"), LOCAL_IP, AittOption(true, false)); + + aitt_client1.Connect(); + aitt_client2.Connect(); + aitt_server.Connect(); + + aitt_client1.Subscribe("topic1", TempSubCallback, nullptr, AITT_TYPE_MQTT); + aitt_client1.Subscribe("topic1", TempSubCallback, nullptr, AITT_TYPE_MQTT); + aitt_client1.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_TCP); + aitt_client1.Subscribe("topic1", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); + aitt_client1.Subscribe("topic1", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); + + aitt_client2.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_MQTT); + aitt_client1.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); + aitt_client2.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_TCP); + aitt_client2.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_TCP); + + ASSERT_TRUE(WaitDiscovery(aitt_server, std::string("topic1"), 4)); + ASSERT_TRUE(WaitDiscovery(aitt_server, std::string("topic2"), 5)); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, CountSubscriber_With_Wildcard_N_Anytime) +{ + try { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + + aitt.Connect(); + aitt.Subscribe("topic1/1", TempSubCallback, nullptr); + aitt.Subscribe("topic1/2", TempSubCallback, nullptr); + + EXPECT_EQ(aitt.CountSubscriber("topic1/+"), AITT_ERROR_NOT_SUPPORTED); + EXPECT_EQ(aitt.CountSubscriber("topic1/#"), AITT_ERROR_NOT_SUPPORTED); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, CountSubscriber_Wildcard_Singlelevel_P_Anytime) +{ + try { + AITT aitt_client1(clientId + std::string(".1"), LOCAL_IP, AittOption(true, false)); + AITT aitt_client2(clientId + std::string(".2"), LOCAL_IP, AittOption(true, false)); + AITT aitt_server(clientId + std::string(".server"), LOCAL_IP, AittOption(true, false)); + + aitt_client1.Connect(); + aitt_client2.Connect(); + aitt_server.Connect(); + + aitt_client1.Subscribe("topic/+/single/level", TempSubCallback, nullptr, AITT_TYPE_MQTT); + aitt_client1.Subscribe("topic/client/+/level", TempSubCallback, nullptr, AITT_TYPE_TCP); + aitt_client2.Subscribe("topic/client/single/+", TempSubCallback, nullptr, + AITT_TYPE_TCP_SECURE); + + aitt_client2.Subscribe("topic2/client/+/+", TempSubCallback, nullptr, AITT_TYPE_MQTT); + aitt_client2.Subscribe("topic2/+/single/+", TempSubCallback, nullptr, AITT_TYPE_TCP); + aitt_client1.Subscribe("topic2/+/+/level", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); + + aitt_client1.Subscribe("topic3/+/+/+", TempSubCallback, nullptr, AITT_TYPE_MQTT); + + ASSERT_TRUE(WaitDiscovery(aitt_server, "topic/client/single/level", 3)); + ASSERT_TRUE(WaitDiscovery(aitt_server, "topic2/client/single/level", 3)); + ASSERT_TRUE(WaitDiscovery(aitt_server, "topic3/client/single/level", 1)); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} + +TEST_F(AITTTest, CountSubscriber_Wildcard_Multilevel_P_Anytime) +{ + try { + AITT aitt_client1(clientId + std::string(".1"), LOCAL_IP, AittOption(true, false)); + AITT aitt_client2(clientId + std::string(".2"), LOCAL_IP, AittOption(true, false)); + AITT aitt_server(clientId + std::string(".server"), LOCAL_IP, AittOption(true, false)); + + aitt_client1.Connect(); + aitt_client2.Connect(); + aitt_server.Connect(); + + aitt_client2.Subscribe("#", TempSubCallback, nullptr, AITT_TYPE_MQTT); + aitt_client1.Subscribe("topic/#", TempSubCallback, nullptr, AITT_TYPE_TCP); + aitt_client1.Subscribe("topic/client/#", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); + aitt_client2.Subscribe("topic/client/multi/#", TempSubCallback, nullptr, + AITT_TYPE_TCP_SECURE); + + ASSERT_TRUE(WaitDiscovery(aitt_server, "topic/client/multi/level", 4)); + } catch (std::exception &e) { + FAIL() << "Unexpected exception: " << e.what(); + } +} diff --git a/tests/AITT_manualtest.cc b/tests/AITT_manualtest.cc index 40f2508..21e97e2 100644 --- a/tests/AITT_manualtest.cc +++ b/tests/AITT_manualtest.cc @@ -28,7 +28,7 @@ class AITTManualTest : public testing::Test, public AittTests { void TearDown() override { Deinit(); } }; -TEST_F(AITTManualTest, WillSet_P) +TEST_F(AITTManualTest, WillSet_P_manual) { try { AITT aitt("", LOCAL_IP, AittOption(true, false)); @@ -67,7 +67,7 @@ TEST_F(AITTManualTest, WillSet_P) } } -TEST(AITT_MANUAL, Connect_with_ID_P) +TEST(AITT_MANUAL, Connect_with_ID_P_manual) { try { AITT aitt("", LOCAL_IP); @@ -76,3 +76,13 @@ TEST(AITT_MANUAL, Connect_with_ID_P) FAIL() << "Unexpected exception: " << e.what(); } } + +TEST(AITT_MANUAL, Connect_with_ID_N_manual) +{ + EXPECT_THROW( + { + AITT aitt("", LOCAL_IP); + aitt.Connect(LOCAL_IP, 1883, "InvalidID", "InvalidPasswd"); + }, + std::exception); +} diff --git a/tests/AITT_test.cc b/tests/AITT_test.cc index 5b3659b..f0681ae 100644 --- a/tests/AITT_test.cc +++ b/tests/AITT_test.cc @@ -24,414 +24,107 @@ using AITT = aitt::AITT; -class AITTTest : public testing::Test, public AittTests { - protected: - void SetUp() override { Init(); } - void TearDown() override { Deinit(); } - - void PubSub(AITT &aitt, const char *test_msg, AittProtocol protocol, AITTTest *aitt_test) - { - aitt.Subscribe( - testTopic, - [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTest *test = static_cast<AITTTest *>(cbdata); - std::string receivedMsg(static_cast<const char *>(msg), szmsg); - if (msg) - DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); - else - DBG("Subscribe invoked: zero size msg(%d)", szmsg); - test->StopEventLoop(); - }, - aitt_test, protocol); - - // Wait a few seconds until the AITT client gets a server list (discover devices) - while (aitt.CountSubscriber(testTopic, protocol) == 0) { - usleep(SLEEP_10MS); - } - - DBG("Publish(%s) : %s(%zu)", testTopic.c_str(), test_msg, strlen(test_msg)); - aitt.Publish(testTopic, test_msg, strlen(test_msg), protocol); - } - - void PubSubFull(const char *test_msg, AittProtocol protocol) - { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.SetConnectionCallback( - [&, test_msg, protocol](AITT &handle, int status, void *user_data) { - if (status == AITT_CONNECTED) - PubSub(aitt, test_msg, protocol, this); - }, - this); - - aitt.Connect(); - - IterateEventLoop(); - aitt.Disconnect(); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } - } - - void PublishDisconnectTemplate(AittProtocol protocol) - { - const char character_set[] = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - std::mt19937 random_gen{std::random_device{}()}; - std::uniform_int_distribution<std::string::size_type> gen(0, 61); - - char dump_msg[204800] = {}; - for (size_t i = 0; i < sizeof(dump_msg); i++) { - dump_msg[i] = character_set[gen(random_gen)]; - } - - try { - AITT aitt(clientId, LOCAL_IP); - AITT aitt_retry("retry_test", LOCAL_IP); - aitt.Connect(); - aitt_retry.Connect(); - - int cnt = 0; - aitt.Subscribe( - TEST_STRESS_TOPIC, - [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTest *test = static_cast<AITTTest *>(cbdata); - ++cnt; - if (szmsg == 0 && cnt != 12) { - FAIL() << "Unexpected value" << cnt; - } - - if (msg) { - ASSERT_TRUE(!strncmp(static_cast<const char *>(msg), dump_msg, - sizeof(dump_msg))); - } - - if (cnt == 10) - test->ToggleReady(); - if (cnt == 11) - test->ToggleReady(); - }, - static_cast<void *>(this), protocol); - - { - AITT aitt1("stress_test1", LOCAL_IP); - aitt1.Connect(); - - // Wait a few seconds to the AITT client gets server list (discover devices) - while (aitt1.CountSubscriber(TEST_STRESS_TOPIC, protocol) == 0) { - usleep(SLEEP_10MS); - } - - for (int i = 0; i < 10; i++) { - INFO("size = %zu", sizeof(dump_msg)); - aitt1.Publish(TEST_STRESS_TOPIC, dump_msg, sizeof(dump_msg), protocol, - AITT_QOS_AT_MOST_ONCE); - } - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) - -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, - nullptr); - - IterateEventLoop(); - } - DBG("Client aitt1 is finished"); - - // Here, an unexpected callback(szmsg = 0) is received - // when the publisher is disconnected. - - ASSERT_TRUE(ready); - ready = false; - - aitt_retry.Publish(TEST_STRESS_TOPIC, dump_msg, sizeof(dump_msg), protocol, - AITT_QOS_AT_MOST_ONCE); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) - -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, - nullptr); - - IterateEventLoop(); - - ASSERT_TRUE(ready); - - aitt_retry.Publish(TEST_STRESS_TOPIC, nullptr, 0, protocol, AITT_QOS_AT_LEAST_ONCE); - // Check auto release of aitt. There should be no segmentation faults. - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } - } - - void PublishSubscribeTCPTwiceTemplate(AittProtocol protocol) - { - try { - AITT aitt(clientId, LOCAL_IP); - aitt.Connect(); - - int cnt = 0; - aitt.Subscribe( - testTopic, - [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTest *test = static_cast<AITTTest *>(cbdata); - // NOTE: - // Subscribe callback will be invoked 2 times - ++cnt; - std::string receivedMsg(static_cast<const char *>(msg), szmsg); - DBG("Subscribe callback called: %d, szmsg = %d, msg = [%s]", cnt, szmsg, - receivedMsg.c_str()); - if (cnt == 1) { - ASSERT_TRUE(!strcmp(receivedMsg.c_str(), TEST_MSG)); - } else if (cnt == 2) { - ASSERT_TRUE(!strcmp(receivedMsg.c_str(), TEST_MSG2)); - test->ToggleReady(); - } - }, - static_cast<void *>(this), protocol); - - // Wait a few seconds to the AITT client gets server list (discover devices) - while (aitt.CountSubscriber(testTopic, protocol) == 0) { - usleep(SLEEP_10MS); - } - - // NOTE: - // Select target peers and send the data through the specified protocol - TCP - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), protocol); - - // NOTE: - // Publish message through the specified protocol - TCP - aitt.Publish(testTopic, TEST_MSG2, sizeof(TEST_MSG2), protocol); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) - -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, - nullptr); - - IterateEventLoop(); - - ASSERT_TRUE(ready); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } - } - - void SubscribeRetainedTCPTemplate(AittProtocol protocol) - { - try { - AITT aitt(clientId, LOCAL_IP); - - aitt.SetConnectionCallback([&](AITT &handle, int status, void *user_data) { - if (status != AITT_CONNECTED) - return; - - // Subscribers who subscribe after publishing will not receive this message - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), AITT_TYPE_MQTT, - AITT_QOS_AT_MOST_ONCE, true); - - aitt.Subscribe( - testTopic, - [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTest *test = static_cast<AITTTest *>(cbdata); - std::string receivedMsg(static_cast<const char *>(msg), szmsg); - EXPECT_STREQ(receivedMsg.c_str(), TEST_MSG2); - test->ToggleReady(); - }, - static_cast<void *>(this), protocol); - - // Wait a few seconds to the AITT client gets server list (discover devices) - while (aitt.CountSubscriber(testTopic, protocol) == 0) { - usleep(SLEEP_10MS); - } - - aitt.Publish(testTopic, TEST_MSG2, sizeof(TEST_MSG2), protocol); - }); - aitt.Connect(); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) - -> int { return ReadyCheck(static_cast<AittTests *>(this)); }, - nullptr); - - IterateEventLoop(); - ASSERT_TRUE(ready); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } - } - - bool WaitDiscovery(AITT &aitt, std::string topic, int count, int max_ms = 2000) - { - int i = 0; - int max_loop = max_ms / 10; - int result = false; - - for (i = 0; i < max_loop; ++i) { - if (aitt.CountSubscriber(topic) == count) { - result = true; - break; - } - - usleep(SLEEP_10MS); - } - - DBG("WAIT %d ms", i * SLEEP_10MS); - return result; - } - - static void TempSubCallback(AittMsg *msg, const void *data, const int data_len, void *user_data) - { - DBG("TEMP CALLBACK"); - } -}; - -TEST_F(AITTTest, Create_P_Anytime) +TEST(AITT_Test, Create_P_Anytime) { try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(AITTTest, SetConnectionCallback_P_Anytime) +TEST(AITT_Test, Create_Custom_Mqtt_N_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.SetConnectionCallback( - [&](AITT &handle, int status, void *user_data) { - AITTTest *test = static_cast<AITTTest *>(user_data); - - if (test->ready2) { - EXPECT_EQ(status, AITT_DISCONNECTED); - test->ToggleReady(); - } else { - EXPECT_EQ(status, AITT_CONNECTED); - test->ToggleReady2(); - handle.Disconnect(); - } - }, - this); - aitt.Connect(); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - return ReadyCheck(static_cast<AittTests *>(this)); - }, - nullptr); - - IterateEventLoop(); - ASSERT_TRUE(ready); - ASSERT_TRUE(ready2); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + EXPECT_THROW({ AITT aitt("clientId", LOCAL_IP, AittOption(true, true)); }, std::exception); } -TEST_F(AITTTest, PubSubInConnectionCB_P_Anytime) +TEST(AITT_Test, Connect_P_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.SetConnectionCallback( - [&](AITT &handle, int status, void *user_data) { - if (status == AITT_CONNECTED) - PubSub(aitt, TEST_MSG, AITT_TYPE_MQTT, this); - }, - this); + EXPECT_NO_THROW({ + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); - - IterateEventLoop(); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + }); } -TEST_F(AITTTest, UnsetConnectionCallback_P_Anytime) +TEST(AITT_Test, Connect_Invalid_User_N_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.SetConnectionCallback( - [&](AITT &handle, int status, void *user_data) { - AITTTest *test = static_cast<AITTTest *>(user_data); - - if (test->ready) { - FAIL() << "Should not be called"; - } else { - EXPECT_EQ(status, AITT_CONNECTED); - test->ToggleReady(); - handle.SetConnectionCallback(nullptr, nullptr); - handle.Disconnect(); - } - }, - this); - aitt.Connect(); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - return ReadyCheck(static_cast<AittTests *>(this)); - }, - nullptr); + char malformed_user[2] = {(char)-1, (char)-2}; + std::string user(malformed_user, 2); - IterateEventLoop(); - ASSERT_FALSE(ready2); - ASSERT_TRUE(ready); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + EXPECT_THROW( + { + AITT aitt("clientId", LOCAL_IP); + aitt.Connect(AITT_LOCALHOST, AITT_PORT, user, "passwd"); + FAIL() << "Should not be called"; + }, + aitt::AittException); } -TEST_F(AITTTest, Connect_P_Anytime) +TEST(AITT_Test, Connect_Invalid_Port_N_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.Connect(); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + EXPECT_THROW( + { + int invalid_port = -1; + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + aitt.Connect(AITT_LOCALHOST, invalid_port); + }, + aitt::AittException); } -TEST_F(AITTTest, Disconnect_P_Anytime) +TEST(AITT_Test, Disconnect_P_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + EXPECT_NO_THROW({ + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); aitt.Disconnect(); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + }); } -TEST_F(AITTTest, Connect_twice_P_Anytime) +TEST(AITT_Test, Disconnect_N_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + EXPECT_THROW( + { + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + aitt.Disconnect(); + }, + std::exception); +} + +TEST(AITT_Test, Connect_twice_P_Anytime) +{ + EXPECT_NO_THROW({ + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); aitt.Disconnect(); aitt.Connect(); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + }); } -TEST_F(AITTTest, Ready_P_Anytime) +TEST(AITT_Test, Connect_twice_N_) { - try { + EXPECT_THROW( + { + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + aitt.Connect(); + aitt.Connect(); + }, + std::exception); +} + +TEST(AITT_Test, Ready_P_Anytime) +{ + EXPECT_NO_THROW({ AITT aitt(AITT_MUST_CALL_READY); - aitt.Ready(clientId, LOCAL_IP, AittOption(true, false)); + aitt.Ready("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); AITT aitt1("Must Call Ready() First"); aitt1.Ready("", LOCAL_IP, AittOption(true, false)); aitt1.Connect(); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + }); } -TEST_F(AITTTest, Ready_N_Anytime) +TEST(AITT_Test, Ready_N_Anytime) { EXPECT_THROW({ AITT aitt("must call ready() first"); }, aitt::AittException); EXPECT_THROW({ AITT aitt("not ready"); }, aitt::AittException); @@ -440,20 +133,20 @@ TEST_F(AITTTest, Ready_N_Anytime) EXPECT_THROW( { AITT aitt(AITT_MUST_CALL_READY); - aitt.Ready(clientId, LOCAL_IP); - aitt.Ready(clientId, LOCAL_IP, AittOption(true, false)); + aitt.Ready("clientId", LOCAL_IP); + aitt.Ready("clientId", LOCAL_IP, AittOption(true, false)); }, aitt::AittException); EXPECT_THROW( { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.Ready(clientId, LOCAL_IP); + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + aitt.Ready("clientId", LOCAL_IP); }, aitt::AittException); } -TEST_F(AITTTest, Not_READY_STATUS_N_Anytime) +TEST(AITT_Test, Not_READY_STATUS_N_Anytime) { EXPECT_DEATH( { @@ -465,410 +158,232 @@ TEST_F(AITTTest, Not_READY_STATUS_N_Anytime) ""); } -TEST_F(AITTTest, Publish_MQTT_P_Anytime) +TEST(AITT_Test, Publish_P_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + EXPECT_NO_THROW({ + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG)); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + aitt.Publish("testTopic", TEST_MSG, sizeof(TEST_MSG)); + aitt.Publish("testTopic", TEST_MSG, sizeof(TEST_MSG), AITT_TYPE_TCP); + aitt.Publish("testTopic", TEST_MSG, sizeof(TEST_MSG), AITT_TYPE_TCP_SECURE); + }); } -TEST_F(AITTTest, Publish_TCP_P_Anytime) +TEST(AITT_Test, Publish_max_size_N_Anytime) { try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), AITT_TYPE_TCP); + EXPECT_THROW(aitt.Publish("testTopic", TEST_MSG, AITT_PAYLOAD_MAX + 1), + aitt::AittException); + EXPECT_THROW(aitt.Publish("testTopic", TEST_MSG, AITT_PAYLOAD_MAX + 1, AITT_TYPE_TCP), + aitt::AittException); + EXPECT_THROW( + aitt.Publish("testTopic", TEST_MSG, AITT_PAYLOAD_MAX + 1, AITT_TYPE_TCP_SECURE), + aitt::AittException); } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(AITTTest, Publish_SECURE_TCP_P_Anytime) +TEST(AITT_Test, Publish_Without_Connection_N_Anytime) { try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.Connect(); - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), AITT_TYPE_TCP_SECURE); + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + EXPECT_THROW(aitt.Publish("testTopic", TEST_MSG, sizeof(TEST_MSG)), aitt::AittException); + EXPECT_THROW(aitt.Publish("testTopic", TEST_MSG, sizeof(TEST_MSG), AITT_TYPE_TCP), + aitt::AittException); + EXPECT_THROW(aitt.Publish("testTopic", TEST_MSG, sizeof(TEST_MSG), AITT_TYPE_TCP_SECURE), + aitt::AittException); } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(AITTTest, Publish_minus_size_N_Anytime) +TEST(AITT_Test, Publish_minus_size_N_Anytime) { try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); - EXPECT_THROW(aitt.Publish(testTopic, TEST_MSG, -1, AITT_TYPE_TCP), aitt::AittException); - EXPECT_THROW(aitt.Publish(testTopic, TEST_MSG, -1, AITT_TYPE_MQTT), aitt::AittException); + EXPECT_THROW(aitt.Publish("testTopic", TEST_MSG, -1, AITT_TYPE_MQTT), aitt::AittException); + EXPECT_THROW(aitt.Publish("testTopic", TEST_MSG, -1, AITT_TYPE_TCP), aitt::AittException); + EXPECT_THROW(aitt.Publish("testTopic", TEST_MSG, -1, AITT_TYPE_TCP_SECURE), + aitt::AittException); } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(AITTTest, Publish_Multiple_Protocols_P_Anytime) +TEST(AITT_Test, Publish_Multiple_Protocols_P_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + EXPECT_NO_THROW({ + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), - (AittProtocol)(AITT_TYPE_MQTT | AITT_TYPE_TCP)); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + aitt.Publish("testTopic", TEST_MSG, sizeof(TEST_MSG), + (AittProtocol)(AITT_TYPE_MQTT | AITT_TYPE_TCP | AITT_TYPE_TCP_SECURE)); + }); } -TEST_F(AITTTest, Unsubscribe_MQTT_P_Anytime) +TEST(AITT_Test, Publish_Invalid_Protocols_N_Anytime) { try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); - subscribeHandle = aitt.Subscribe( - testTopic, - [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void {}, - nullptr, AITT_TYPE_MQTT); - DBG(">>> Handle: %p", reinterpret_cast<void *>(subscribeHandle)); - aitt.Unsubscribe(subscribeHandle); + aitt.Publish("testTopic", TEST_MSG, sizeof(TEST_MSG), (AittProtocol)0x100); + } catch (aitt::AittException &e) { + EXPECT_EQ(e.getErrCode(), aitt::AittException::INVALID_ARG); } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(AITTTest, Unsubscribe_TCP_P_Anytime) +TEST(AITT_Test, Unsubscribe_P_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + EXPECT_NO_THROW({ + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); aitt.Connect(); + + auto subscribeHandle = aitt.Subscribe( + "testTopic", + [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void {}, + nullptr, AITT_TYPE_MQTT); + aitt.Unsubscribe(subscribeHandle); + subscribeHandle = aitt.Subscribe( - testTopic, + "testTopic", [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void {}, nullptr, AITT_TYPE_TCP); - DBG("Subscribe handle: %p", reinterpret_cast<void *>(subscribeHandle)); aitt.Unsubscribe(subscribeHandle); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } -} -TEST_F(AITTTest, Unsubscribe_SECURE_TCP_P_Anytime) -{ - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.Connect(); subscribeHandle = aitt.Subscribe( - testTopic, + "testTopic", [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void {}, nullptr, AITT_TYPE_TCP_SECURE); - DBG("Subscribe handle: %p", reinterpret_cast<void *>(subscribeHandle)); aitt.Unsubscribe(subscribeHandle); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + }); } -TEST_F(AITTTest, PublishSubscribe_MQTT_P_Anytime) +TEST(AITT_Test, Unsubscribe_Invalid_ID_N_Anytime) { - PubSubFull(TEST_MSG, AITT_TYPE_MQTT); -} - -TEST_F(AITTTest, Publish_0_MQTT_P_Anytime) -{ - PubSubFull("", AITT_TYPE_MQTT); -} - -TEST_F(AITTTest, Unsubscribe_in_Subscribe_MQTT_P_Anytime) -{ - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.Connect(); - subscribeHandle = aitt.Subscribe( - testTopic, - [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTest *test = static_cast<AITTTest *>(cbdata); - std::string receivedMsg(static_cast<const char *>(msg), szmsg); - DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); - - static int cnt = 0; - ++cnt; - if (cnt == 2) - FAIL() << "Should not be called"; - - aitt.Unsubscribe(test->subscribeHandle); - DBG("Ready flag is toggled"); - test->ToggleReady(); - }, - static_cast<void *>(this)); - - DBG("Publish message to %s (%s)", testTopic.c_str(), TEST_MSG); - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG)); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - return ReadyCheck(static_cast<AittTests *>(this)); - }, - nullptr); - - IterateEventLoop(); - - ASSERT_TRUE(ready); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + EXPECT_THROW( + { + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + aitt.Unsubscribe((AittSubscribeID)0x100); + }, + aitt::AittException); } -TEST_F(AITTTest, Subscribe_in_Subscribe_MQTT_P_Anytime) +TEST(AITT_Test, Unsubscribe_Twice_N_Anytime) { - try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.Connect(); - subscribeHandle = aitt.Subscribe( - testTopic, - [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - std::string receivedMsg(static_cast<const char *>(msg), szmsg); - DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); - - static int cnt = 0; - ++cnt; - if (cnt == 2) - FAIL() << "Should not be called"; - - aitt.Subscribe( - "topic1InCallback", - [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) {}, - cbdata); - - aitt.Subscribe( - "topic2InCallback", - [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) {}, - cbdata); - DBG("Ready flag is toggled"); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, - MainLoopIface::MainLoopData *data) -> int { - AITTTest *test = static_cast<AITTTest *>(this); - test->ToggleReady(); - return AITT_LOOP_EVENT_REMOVE; - }, - nullptr); - }, - static_cast<void *>(this)); - - DBG("Publish message to %s (%s)", testTopic.c_str(), TEST_MSG); - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG)); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - return ReadyCheck(static_cast<AittTests *>(this)); - }, - nullptr); - - IterateEventLoop(); - - ASSERT_TRUE(ready); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } -} + EXPECT_THROW( + { + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + aitt.Connect(); -TEST_F(AITTTest, PublishSubscribe_TCP_P_Anytime) -{ - PubSubFull(TEST_MSG, AITT_TYPE_TCP); -} + auto subscribeHandle = aitt.Subscribe( + "testTopic", + [](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) {}, nullptr, + AITT_TYPE_MQTT); -TEST_F(AITTTest, PublishSubscribe_SECURE_TCP_P_Anytime) -{ - PubSubFull(TEST_MSG, AITT_TYPE_TCP_SECURE); + aitt.Unsubscribe(subscribeHandle); + aitt.Unsubscribe(subscribeHandle); + }, + aitt::AittException); } -TEST_F(AITTTest, Publish_0_TCP_P_Anytime) +TEST(AITT_Test, WillSet_invalid_topic_N_Anytime) { - PubSubFull("", AITT_TYPE_TCP); + EXPECT_THROW( + { + const char *topic_wildcard = "topic/+"; + AITT aitt_will("", LOCAL_IP, AittOption(true, false)); + aitt_will.SetWillInfo(topic_wildcard, "will msg", 8, AITT_QOS_AT_MOST_ONCE, false); + }, + aitt::AittException); } -TEST_F(AITTTest, Publish_0_SECURE_TCP_P_Anytime) +TEST(AITT_Test, WillSet_size_N_Anytime) { - PubSubFull("", AITT_TYPE_TCP_SECURE); + EXPECT_THROW( + { + AITT aitt_will("", LOCAL_IP, AittOption(true, false)); + aitt_will.SetWillInfo("testTopic", "will msg", -1, AITT_QOS_AT_MOST_ONCE, false); + }, + aitt::AittException); + EXPECT_THROW( + { + AITT aitt_will("", LOCAL_IP, AittOption(true, false)); + aitt_will.SetWillInfo("testTopic", "will msg", AITT_PAYLOAD_MAX + 1, + AITT_QOS_AT_MOST_ONCE, false); + }, + aitt::AittException); } -TEST_F(AITTTest, PublishSubscribe_Multiple_Protocols_P_Anytime) +TEST(AITT_Test, PublishWithReply_N_Anytime) { try { - AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); - aitt.Connect(); - aitt.Subscribe( - testTopic, - [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTest *test = static_cast<AITTTest *>(cbdata); - std::string receivedMsg(static_cast<const char *>(msg), szmsg); - DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); - test->ToggleReady(); - }, - static_cast<void *>(this), AITT_TYPE_TCP); - - aitt.Subscribe( - testTopic, - [&](AittMsg *handle, const void *msg, const int szmsg, void *cbdata) -> void { - AITTTest *test = static_cast<AITTTest *>(cbdata); - std::string receivedMsg(static_cast<const char *>(msg), szmsg); - DBG("Subscribe invoked: %s %d", receivedMsg.c_str(), szmsg); - test->ToggleReady2(); - }, - static_cast<void *>(this), AITT_TYPE_MQTT); - - // Wait a few seconds to the AITT client gets server list (discover devices) - while ( - aitt.CountSubscriber(testTopic, (AittProtocol)(AITT_TYPE_MQTT | AITT_TYPE_TCP)) < 2) { - usleep(SLEEP_10MS); - } - - DBG("Publish message to %s (%s) / %zu", testTopic.c_str(), TEST_MSG, sizeof(TEST_MSG)); - aitt.Publish(testTopic, TEST_MSG, sizeof(TEST_MSG), - (AittProtocol)(AITT_TYPE_MQTT | AITT_TYPE_TCP)); - - mainLoop->AddTimeout( - CHECK_INTERVAL, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - return ReadyCheck(static_cast<AittTests *>(this)); - }, - nullptr); - - IterateEventLoop(); - - ASSERT_TRUE(ready); - ASSERT_TRUE(ready2); + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + EXPECT_THROW( + aitt.PublishWithReply( + "testTopic", TEST_MSG, 0, AITT_TYPE_MQTT, AITT_QOS_AT_MOST_ONCE, false, + [](AittMsg *msg, const void *data, const int data_len, void *user_data) {}, + nullptr, "correlation"), + aitt::AittException); + EXPECT_THROW( + aitt.PublishWithReply( + "testTopic", TEST_MSG, AITT_PAYLOAD_MAX + 1, AITT_TYPE_MQTT, + AITT_QOS_AT_MOST_ONCE, false, + [](AittMsg *msg, const void *data, const int data_len, void *user_data) {}, + nullptr, "correlation"), + aitt::AittException); + ; } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(AITTTest, CountSubscriber_P_Anytime) +TEST(AITT_Test, PublishWithReplySync_N_Anytime) { try { - AITT aitt_client1(clientId + std::string(".1"), LOCAL_IP, AittOption(true, false)); - AITT aitt_client2(clientId + std::string(".2"), LOCAL_IP, AittOption(true, false)); - AITT aitt_server(clientId + std::string(".server"), LOCAL_IP, AittOption(true, false)); - - aitt_client1.Connect(); - aitt_client2.Connect(); - aitt_server.Connect(); - - aitt_client1.Subscribe("topic1", TempSubCallback, nullptr, AITT_TYPE_MQTT); - aitt_client1.Subscribe("topic1", TempSubCallback, nullptr, AITT_TYPE_MQTT); - aitt_client1.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_TCP); - aitt_client1.Subscribe("topic1", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); - aitt_client1.Subscribe("topic1", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); - - aitt_client2.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_MQTT); - aitt_client1.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); - aitt_client2.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_TCP); - aitt_client2.Subscribe("topic2", TempSubCallback, nullptr, AITT_TYPE_TCP); - - ASSERT_TRUE(WaitDiscovery(aitt_server, std::string("topic1"), 4)); - ASSERT_TRUE(WaitDiscovery(aitt_server, std::string("topic2"), 5)); + AITT aitt("clientId", LOCAL_IP, AittOption(true, false)); + EXPECT_THROW( + aitt.PublishWithReplySync( + "testTopic", TEST_MSG, 0, AITT_TYPE_MQTT, AITT_QOS_AT_MOST_ONCE, false, + [](AittMsg *msg, const void *data, const int data_len, void *user_data) {}, + nullptr, "correlation"), + aitt::AittException); + EXPECT_THROW( + aitt.PublishWithReplySync( + "testTopic", TEST_MSG, AITT_PAYLOAD_MAX + 1, AITT_TYPE_MQTT, + AITT_QOS_AT_MOST_ONCE, false, + [](AittMsg *msg, const void *data, const int data_len, void *user_data) {}, + nullptr, "correlation"), + aitt::AittException); + ; } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(AITTTest, CountSubscriber_Wildcard_Singlelevel_P_Anytime) +TEST(AITT_Test, CreateStream_N_Anytime) { try { - AITT aitt_client1(clientId + std::string(".1"), LOCAL_IP, AittOption(true, false)); - AITT aitt_client2(clientId + std::string(".2"), LOCAL_IP, AittOption(true, false)); - AITT aitt_server(clientId + std::string(".server"), LOCAL_IP, AittOption(true, false)); - - aitt_client1.Connect(); - aitt_client2.Connect(); - aitt_server.Connect(); - - aitt_client1.Subscribe("topic/+/single/level", TempSubCallback, nullptr, AITT_TYPE_MQTT); - aitt_client1.Subscribe("topic/client/+/level", TempSubCallback, nullptr, AITT_TYPE_TCP); - aitt_client2.Subscribe("topic/client/single/+", TempSubCallback, nullptr, - AITT_TYPE_TCP_SECURE); - - aitt_client2.Subscribe("topic2/client/+/+", TempSubCallback, nullptr, AITT_TYPE_MQTT); - aitt_client2.Subscribe("topic2/+/single/+", TempSubCallback, nullptr, AITT_TYPE_TCP); - aitt_client1.Subscribe("topic2/+/+/level", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); - - aitt_client1.Subscribe("topic3/+/+/+", TempSubCallback, nullptr, AITT_TYPE_MQTT); - - ASSERT_TRUE(WaitDiscovery(aitt_server, "topic/client/single/level", 3)); - ASSERT_TRUE(WaitDiscovery(aitt_server, "topic2/client/single/level", 3)); - ASSERT_TRUE(WaitDiscovery(aitt_server, "topic3/client/single/level", 1)); + AITT aitt("clientId", LOCAL_IP); + EXPECT_EQ(nullptr, aitt.CreateStream(AITT_STREAM_TYPE_MAX, "topic/Invalid/Stream_Type", + AITT_STREAM_ROLE_PUBLISHER)); + EXPECT_EQ(nullptr, aitt.CreateStream(AITT_STREAM_TYPE_MAX, "topic/Invalid/Stream_Type", + AITT_STREAM_ROLE_SUBSCRIBER)); } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(AITTTest, CountSubscriber_Wildcard_Multilevel_P_Anytime) +TEST(AITT_Test, DestroyStream_N_Anytime) { try { - AITT aitt_client1(clientId + std::string(".1"), LOCAL_IP, AittOption(true, false)); - AITT aitt_client2(clientId + std::string(".2"), LOCAL_IP, AittOption(true, false)); - AITT aitt_server(clientId + std::string(".server"), LOCAL_IP, AittOption(true, false)); - - aitt_client1.Connect(); - aitt_client2.Connect(); - aitt_server.Connect(); - - aitt_client2.Subscribe("#", TempSubCallback, nullptr, AITT_TYPE_MQTT); - aitt_client1.Subscribe("topic/#", TempSubCallback, nullptr, AITT_TYPE_TCP); - aitt_client1.Subscribe("topic/client/#", TempSubCallback, nullptr, AITT_TYPE_TCP_SECURE); - aitt_client2.Subscribe("topic/client/multi/#", TempSubCallback, nullptr, - AITT_TYPE_TCP_SECURE); - - ASSERT_TRUE(WaitDiscovery(aitt_server, "topic/client/multi/level", 4)); + AITT aitt("clientId", LOCAL_IP); + EXPECT_NO_THROW(aitt.DestroyStream(nullptr)); } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } - -TEST_F(AITTTest, PublishSubscribe_TCP_twice_P_Anytime) -{ - PublishSubscribeTCPTwiceTemplate(AITT_TYPE_TCP); -} - -TEST_F(AITTTest, PublishSubscribe_SECURE_TCP_twice_P_Anytime) -{ - PublishSubscribeTCPTwiceTemplate(AITT_TYPE_TCP_SECURE); -} - -TEST_F(AITTTest, Subscribe_Retained_TCP_P_Anytime) -{ - SubscribeRetainedTCPTemplate(AITT_TYPE_TCP); -} - -TEST_F(AITTTest, Subscribe_Retained_SECURE_TCP_P_Anytime) -{ - SubscribeRetainedTCPTemplate(AITT_TYPE_TCP_SECURE); -} - -TEST_F(AITTTest, Publish_Disconnect_TCP_P_Anytime) -{ - PublishDisconnectTemplate(AITT_TYPE_TCP); -} - -TEST_F(AITTTest, Publish_Disconnect_SECURE_TCP_P_Anytime) -{ - PublishDisconnectTemplate(AITT_TYPE_TCP_SECURE); -} - -TEST_F(AITTTest, WillSet_N_Anytime) -{ - EXPECT_THROW( - { - AITT aitt_will("", LOCAL_IP, AittOption(true, false)); - aitt_will.SetWillInfo("+", "will msg", 8, AITT_QOS_AT_MOST_ONCE, false); - aitt_will.Connect(); - aitt_will.Disconnect(); - }, - std::exception); -} diff --git a/tests/AittOption_test.cc b/tests/AittOption_test.cc new file mode 100644 index 0000000..1f5cc02 --- /dev/null +++ b/tests/AittOption_test.cc @@ -0,0 +1,78 @@ +/* + * Copyright 2023 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "AittOption.h" + +#include <gtest/gtest.h> + +TEST(Option, CustomBroker_SetServiceID_N_Anytime) +{ + AittOption option; + + option.SetUseCustomMqttBroker(true); + + option.SetServiceID("test_service_id"); + EXPECT_STREQ(option.GetServiceID(), "test_service_id"); + + option.SetUseCustomMqttBroker(false); + + option.SetServiceID(""); + EXPECT_STRNE(option.GetServiceID(), ""); +} + +TEST(Option, CustomBroker_SetLocationID_N_Anytime) +{ + AittOption option; + + option.SetUseCustomMqttBroker(true); + + option.SetLocationID("test_location_id"); + EXPECT_STREQ(option.GetLocationID(), "test_location_id"); + + option.SetUseCustomMqttBroker(false); + + option.SetLocationID(""); + EXPECT_STRNE(option.GetLocationID(), ""); +} + +TEST(Option, CustomBroker_SetRootCA_N_Anytime) +{ + AittOption option; + + option.SetUseCustomMqttBroker(true); + + option.SetRootCA("test_root_ca"); + EXPECT_STREQ(option.GetRootCA(), "test_root_ca"); + + option.SetUseCustomMqttBroker(false); + + option.SetRootCA(""); + EXPECT_STRNE(option.GetRootCA(), ""); +} + +TEST(Option, CustomBroker_SetCustomRWFile_N_Anytime) +{ + AittOption option; + + option.SetUseCustomMqttBroker(true); + + option.SetCustomRWFile("test_custom_rw_file"); + EXPECT_STREQ(option.GetCustomRWFile(), "test_custom_rw_file"); + + option.SetUseCustomMqttBroker(false); + + option.SetCustomRWFile(""); + EXPECT_STRNE(option.GetCustomRWFile(), ""); +} diff --git a/tests/AittStream_test.cc b/tests/AittStream_test.cc index 58c19b8..b828547 100644 --- a/tests/AittStream_test.cc +++ b/tests/AittStream_test.cc @@ -172,8 +172,26 @@ TEST_F(AITTWEBRTCTest, Set_Source_Type_Media_Packet_P) FAIL() << "Unexpected exception: " << e.what(); } } -#endif +TEST_F(AITTWEBRTCTest, SetConfig_param_N_) +{ + EXPECT_THROW({ publisher->SetConfig("UNKNOWN", ""); }, aitt::AittException); + EXPECT_THROW({ subscriber->SetConfig("UNKNOWN", ""); }, aitt::AittException); +} + +TEST_F(AITTWEBRTCTest, SetConfig_after_start_N_) +{ + EXPECT_THROW( + { + publisher->Start(); + publisher->SetConfig("WIDTH", std::to_string(HD_WIDTH)); + }, + aitt::AittException); +} + +#endif // WITH_WEBRTC + +#ifdef WITH_RTSP class AITTRTSPTest : public testing::Test { protected: void SetUp() override @@ -205,6 +223,16 @@ class AITTRTSPTest : public testing::Test { MainLoopIface *main_loop; }; +TEST_F(AITTRTSPTest, Publisher_SetConfig_N_) +{ + EXPECT_THROW( + { + publisher->SetConfig("URI", + "192.168.1.52:554/cam/realmonitor?channel=1&subtype=0&authbasic=64"); + }, + aitt::AittException); +} + TEST_F(AITTRTSPTest, Publisher_First_P) { try { @@ -235,6 +263,11 @@ TEST_F(AITTRTSPTest, Publisher_First_P) } } +TEST_F(AITTRTSPTest, Subscriber_SetConfig_N_) +{ + EXPECT_THROW({ subscriber->SetConfig("FPS", "NOT_NUMBER"); }, aitt::AittException); +} + TEST_F(AITTRTSPTest, Subscriber_First_P) { try { @@ -258,3 +291,4 @@ TEST_F(AITTRTSPTest, Subscriber_First_P) FAIL() << "Unexpected exception: " << e.what(); } } +#endif // WITH_RTSP diff --git a/tests/AittTests.h b/tests/AittTests.h index b5620dd..8a225ed 100644 --- a/tests/AittTests.h +++ b/tests/AittTests.h @@ -39,13 +39,7 @@ using aitt::MainLoopIface; class AittTests { public: - AittTests() - : subscribeHandle(nullptr), - ready(false), - ready2(false), - mainLoop(aitt::MainLoopHandler::new_loop()) - { - } + AittTests() : ready(false), ready2(false), mainLoop(aitt::MainLoopHandler::new_loop()) {} void Init() { @@ -97,7 +91,6 @@ class AittTests { DBG("Go forward"); } - AittSubscribeID subscribeHandle; bool ready; bool ready2; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dabf97c..ae6c92a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,8 +8,8 @@ link_directories(${GTEST_LIBRARY_DIRS}) ########################################################################### -set(AITT_UT_SRC AITT_test.cc RequestResponse_test.cc MainLoopHandler_test.cc aitt_c_test.cc - AITT_TCP_test.cc) +set(AITT_UT_SRC AITT_test.cc AITT_fixturetest.cc RequestResponse_test.cc MainLoopHandler_test.cc aitt_c_test.cc + AITT_TCP_test.cc AittOption_test.cc) add_executable(${AITT_UT} ${AITT_UT_SRC}) target_link_libraries(${AITT_UT} Threads::Threads ${GTEST_LIBRARIES} ${PROJECT_NAME}) @@ -23,7 +23,26 @@ add_test( LD_LIBRARY_PATH=../modules/tcp/:../modules/webrtc/:../:../common/:$ENV{LD_LIBRARY_PATH} ${CMAKE_CURRENT_BINARY_DIR}/${AITT_UT} --gtest_filter=*_Anytime ${XML_OUTPUT} ) +########################################################################### + +if(USE_GLIB) + set(AITT_UT_LOOP_SRC ${CMAKE_SOURCE_DIR}/common/PosixMainLoop.cc ${CMAKE_SOURCE_DIR}/common/MainLoopHandler.cc) + + set(AITT_UT_LOOP ${AITT_UT}_posixloop) + add_executable(${AITT_UT_LOOP} MainLoopHandler_test.cc ${AITT_UT_LOOP_SRC}) + target_link_libraries(${AITT_UT_LOOP} Threads::Threads ${GTEST_LIBRARIES} rt) + install(TARGETS ${AITT_UT_LOOP} DESTINATION ${AITT_TEST_BINDIR}) + + add_test( + NAME + ${AITT_UT_LOOP} + COMMAND + ${CMAKE_COMMAND} -E env + LD_LIBRARY_PATH=../:../common/:$ENV{LD_LIBRARY_PATH} + ${CMAKE_CURRENT_BINARY_DIR}/${AITT_UT_LOOP} --gtest_filter=*_Anytime ${XML_OUTPUT} + ) +endif(USE_GLIB) ########################################################################### set(AITT_STREAM_UT ${PROJECT_NAME}_stream_ut) diff --git a/tests/MainLoopHandler_test.cc b/tests/MainLoopHandler_test.cc index 9772f4e..6611b37 100644 --- a/tests/MainLoopHandler_test.cc +++ b/tests/MainLoopHandler_test.cc @@ -26,9 +26,30 @@ #include "MainLoopIface.h" #include "aitt_internal.h" +#define SLEEP_10MS 10000 +#define MAINLOOP_MESSAGE "1" using aitt::MainLoopIface; class MainLoopTest : public testing::Test { + public: + static int CheckCount(MainLoopIface *handler, int &count) + { + switch (count) { + case 0: + count++; + return AITT_LOOP_EVENT_CONTINUE; + case 1: + std::thread([&, handler]() { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + handler->Quit(); + }).detach(); + return AITT_LOOP_EVENT_REMOVE; + default: + ADD_FAILURE() << "Should not be called"; + return AITT_LOOP_EVENT_REMOVE; + } + } + protected: void SetUp() override { @@ -55,29 +76,17 @@ class MainLoopTest : public testing::Test { remove(addr.sun_path); } + void ReadAndCheck(int fd) + { + char buf[2] = {0}; + EXPECT_EQ(read(fd, buf, 1), 1); + EXPECT_STREQ(buf, MAINLOOP_MESSAGE); + } + int server_fd; struct sockaddr_un addr; std::thread my_thread; - protected: - int CheckCount(MainLoopIface *handler, int &count) - { - switch (count) { - case 0: - count++; - return AITT_LOOP_EVENT_CONTINUE; - case 1: - std::thread([&, handler]() { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - handler->Quit(); - }).detach(); - return AITT_LOOP_EVENT_REMOVE; - default: - ADD_FAILURE() << "Should not be called"; - return AITT_LOOP_EVENT_REMOVE; - } - } - private: void eventWriter() { @@ -88,48 +97,196 @@ class MainLoopTest : public testing::Test { ret = connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)); ASSERT_NE(ret, -1); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - ret = write(fd, "1", 1); + ret = write(fd, MAINLOOP_MESSAGE, 1); ASSERT_NE(ret, -1); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); close(fd); } }; -TEST_F(MainLoopTest, Normal_Anytime) +TEST(MainLoop_Test, Quit_N_Anytime) { MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); + EXPECT_EQ(handler->Quit(), false); + delete handler; +} + +TEST(MainLoop_Test, Destructor_WO_quit_N_Anytime) +{ + EXPECT_NO_THROW({ + MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); + handler->AddIdle( + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + return AITT_LOOP_EVENT_CONTINUE; + }, + nullptr); + delete handler; + }); +} + +TEST(MainLoop_Test, AddIdle_Anytime) +{ + bool ret = false; + MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); + MainLoopIface::MainLoopData test_data; + + handler->AddIdle( + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + EXPECT_EQ(data, &test_data); + handler->Quit(); + ret = true; + return AITT_LOOP_EVENT_REMOVE; + }, + &test_data); + + handler->Run(); + delete handler; + + EXPECT_TRUE(ret); +} + +TEST(MainLoop_Test, IDLE_CB_Return_P_Anytime) +{ + std::unique_ptr<MainLoopIface> handler(aitt::MainLoopHandler::new_loop()); + + handler->AddIdle( + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + static int count = 0; + EXPECT_EQ(result, MainLoopIface::Event::OKAY); + return MainLoopTest::CheckCount(handler.get(), count); + }, + nullptr); + + handler->Run(); +} + +TEST(MainLoop_Test, AddTimeout_P_Anytime) +{ + std::vector<int> interval_list = {1, 10}; + + for (auto interval : interval_list) { + bool ret = false; + struct timespec ts_start, ts_end; + MainLoopIface::MainLoopData test_data; + MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); + + clock_gettime(CLOCK_MONOTONIC, &ts_start); + + handler->AddTimeout( + interval, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + EXPECT_EQ(data, &test_data); + clock_gettime(CLOCK_MONOTONIC, &ts_end); + double diff = 1000.0 * ts_end.tv_sec + 1e-6 * ts_end.tv_nsec + - (1000.0 * ts_start.tv_sec + 1e-6 * ts_start.tv_nsec); + EXPECT_GE(diff, interval); + handler->Quit(); + DBG("diff: %f", diff); + ret = true; + return AITT_LOOP_EVENT_REMOVE; + }, + &test_data); + + handler->Run(); + delete handler; + + EXPECT_TRUE(ret); + } +} + +TEST(MainLoop_Test, AddTimeout_N_Anytime) +{ + MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); + + std::vector<int> interval_list = {-1, 0}; + for (auto interval : interval_list) { + auto id = handler->AddTimeout( + interval, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + ADD_FAILURE() << "Should not be called"; + return AITT_LOOP_EVENT_REMOVE; + }, + nullptr); + EXPECT_EQ(id, 0); + } + delete handler; +} + +TEST(MainLoop_Test, Timeout_CB_Return_P_Anytime) +{ + int interval = 10; + std::unique_ptr<MainLoopIface> handler(aitt::MainLoopHandler::new_loop()); + + handler->AddTimeout( + interval, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + static int count = 0; + EXPECT_EQ(result, MainLoopIface::Event::OKAY); + return MainLoopTest::CheckCount(handler.get(), count); + }, + nullptr); + + handler->Run(); +} + +TEST(MainLoop_Test, Quit_Without_RemoveTimeout_Anytime) +{ + bool ret = false; + int interval = 1; + std::unique_ptr<MainLoopIface> handler(aitt::MainLoopHandler::new_loop()); + MainLoopIface::MainLoopData test_data; + + handler->AddTimeout( + interval, + [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + handler->Quit(); + EXPECT_FALSE(ret); + ret = !ret; + return AITT_LOOP_EVENT_CONTINUE; + }, + &test_data); + + handler->Run(); + usleep(SLEEP_10MS); + + EXPECT_TRUE(ret); +} + +TEST_F(MainLoopTest, AddWatch_Normal_P_Anytime) +{ bool ret = false; + MainLoopIface::MainLoopData test_data; + MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); handler->AddWatch( server_fd, [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + EXPECT_EQ(data, &test_data); int client_fd = accept(server_fd, 0, 0); EXPECT_NE(client_fd, -1); handler->AddWatch( client_fd, [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { + EXPECT_EQ(data, &test_data); EXPECT_EQ(result, MainLoopIface::Event::OKAY); - char buf[2] = {0}; - EXPECT_EQ(read(fd, buf, 1), 1); - EXPECT_STREQ(buf, "1"); + ReadAndCheck(fd); handler->Quit(); ret = true; return AITT_LOOP_EVENT_REMOVE; }, - nullptr); + &test_data); return AITT_LOOP_EVENT_REMOVE; }, - nullptr); + &test_data); handler->Run(); delete handler; EXPECT_TRUE(ret); } -TEST_F(MainLoopTest, HANGUP_Anytime) +TEST_F(MainLoopTest, HANGUP_N_Anytime) { MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); bool ret = false; @@ -144,9 +301,7 @@ TEST_F(MainLoopTest, HANGUP_Anytime) [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { if (result == MainLoopIface::Event::OKAY) { - char buf[2] = {0}; - EXPECT_EQ(read(fd, buf, 1), 1); - EXPECT_STREQ(buf, "1"); + ReadAndCheck(fd); return AITT_LOOP_EVENT_CONTINUE; } @@ -166,7 +321,7 @@ TEST_F(MainLoopTest, HANGUP_Anytime) EXPECT_TRUE(ret); } -TEST_F(MainLoopTest, removeWatch_Anytime) +TEST_F(MainLoopTest, removeWatch_P_Anytime) { MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); MainLoopIface::MainLoopData test_data; @@ -184,100 +339,16 @@ TEST_F(MainLoopTest, removeWatch_Anytime) EXPECT_TRUE(&test_data == check_data); } -TEST_F(MainLoopTest, UserData_Anytime) -{ - MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); - bool ret = false; - - MainLoopIface::MainLoopData test_data; - - handler->AddWatch( - server_fd, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - EXPECT_EQ(data, &test_data); - handler->Quit(); - ret = true; - return AITT_LOOP_EVENT_REMOVE; - }, - &test_data); - - handler->Run(); - delete handler; - - EXPECT_TRUE(ret); -} - -TEST_F(MainLoopTest, AddIdle_Anytime) +TEST(MainLoop_Test, removeWatch_N_Anytime) { - bool ret = false; + int unknown_fd = 777; MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); MainLoopIface::MainLoopData test_data; - handler->AddIdle( - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - EXPECT_EQ(data, &test_data); - handler->Quit(); - ret = true; - return AITT_LOOP_EVENT_REMOVE; - }, - &test_data); - - handler->Run(); + MainLoopIface::MainLoopData *check_data = handler->RemoveWatch(unknown_fd); delete handler; - EXPECT_TRUE(ret); -} - -TEST_F(MainLoopTest, AddTimeout_Anytime) -{ - bool ret = false; - int interval = 100; - MainLoopIface *handler = aitt::MainLoopHandler::new_loop(); - struct timespec ts_start, ts_end; - MainLoopIface::MainLoopData test_data; - - clock_gettime(CLOCK_MONOTONIC, &ts_start); - - handler->AddTimeout( - interval, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - EXPECT_EQ(data, &test_data); - clock_gettime(CLOCK_MONOTONIC, &ts_end); - double diff = 1000.0 * ts_end.tv_sec + 1e-6 * ts_end.tv_nsec - - (1000.0 * ts_start.tv_sec + 1e-6 * ts_start.tv_nsec); - EXPECT_GE(diff, interval); - handler->Quit(); - ret = true; - return AITT_LOOP_EVENT_REMOVE; - }, - &test_data); - - handler->Run(); - delete handler; - - EXPECT_TRUE(ret); -} - -TEST_F(MainLoopTest, Quit_Without_RemoveTimeout_Anytime) -{ - bool ret = false; - int interval = 1; - std::unique_ptr<MainLoopIface> handler(aitt::MainLoopHandler::new_loop()); - MainLoopIface::MainLoopData test_data; - - handler->AddTimeout( - interval, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - handler->Quit(); - EXPECT_FALSE(ret); - ret = true; - return AITT_LOOP_EVENT_CONTINUE; - }, - &test_data); - - handler->Run(); - - EXPECT_TRUE(ret); + EXPECT_EQ(check_data, nullptr); } TEST_F(MainLoopTest, Watch_Event_CB_Return_P_Anytime) @@ -303,34 +374,3 @@ TEST_F(MainLoopTest, Watch_Event_CB_Return_P_Anytime) nullptr); handler->Run(); } - -TEST_F(MainLoopTest, IDLE_CB_Return_P_Anytime) -{ - std::unique_ptr<MainLoopIface> handler(aitt::MainLoopHandler::new_loop()); - - handler->AddIdle( - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - static int count = 0; - EXPECT_EQ(result, MainLoopIface::Event::OKAY); - return CheckCount(handler.get(), count); - }, - nullptr); - - handler->Run(); -} - -TEST_F(MainLoopTest, Timeout_CB_Return_P_Anytime) -{ - std::unique_ptr<MainLoopIface> handler(aitt::MainLoopHandler::new_loop()); - - handler->AddTimeout( - 200, - [&](MainLoopIface::Event result, int fd, MainLoopIface::MainLoopData *data) -> int { - static int count = 0; - EXPECT_EQ(result, MainLoopIface::Event::OKAY); - return CheckCount(handler.get(), count); - }, - nullptr); - - handler->Run(); -} diff --git a/tests/ModuleLoader_test.cc b/tests/ModuleLoader_test.cc index ba80191..3e52c2e 100644 --- a/tests/ModuleLoader_test.cc +++ b/tests/ModuleLoader_test.cc @@ -19,13 +19,14 @@ #include "AittTests.h" #include "AittTransport.h" #include "ModuleManager.h" +#include "NullTransport.h" #include "aitt_internal.h" using ModuleManager = aitt::ModuleManager; -class ModuleLoaderTest : public testing::Test { +class ModuleManagerTest : public testing::Test { public: - ModuleLoaderTest(void) : discovery("test_id"), modules(LOCAL_IP, discovery) {} + ModuleManagerTest(void) : discovery("test_id"), modules(LOCAL_IP, discovery) {} protected: void SetUp() override {} @@ -35,14 +36,15 @@ class ModuleLoaderTest : public testing::Test { aitt::ModuleManager modules; }; -TEST_F(ModuleLoaderTest, Get_P_Anytime) +TEST_F(ModuleManagerTest, Get_P_Anytime) { aitt::AittTransport &tcp = modules.Get(AITT_TYPE_TCP); EXPECT_TRUE(tcp.GetProtocol() == AITT_TYPE_TCP); aitt::AittTransport &tcp_secure = modules.Get(AITT_TYPE_TCP_SECURE); EXPECT_TRUE(tcp_secure.GetProtocol() == AITT_TYPE_TCP_SECURE); } -TEST_F(ModuleLoaderTest, Get_N_Anytime) + +TEST_F(ModuleManagerTest, Get_N_Anytime) { EXPECT_THROW( { @@ -52,7 +54,7 @@ TEST_F(ModuleLoaderTest, Get_N_Anytime) aitt::AittException); } -TEST_F(ModuleLoaderTest, NewCustomMQ_P) +TEST_F(ModuleManagerTest, NewCustomMQ_P) { EXPECT_NO_THROW({ std::unique_ptr<aitt::MQ> mq = modules.NewCustomMQ("test", AittOption(false, true)); @@ -60,7 +62,7 @@ TEST_F(ModuleLoaderTest, NewCustomMQ_P) }); } -TEST_F(ModuleLoaderTest, NewCustomMQ_N_Anytime) +TEST_F(ModuleManagerTest, NewCustomMQ_N_Anytime) { EXPECT_THROW( { @@ -69,3 +71,38 @@ TEST_F(ModuleLoaderTest, NewCustomMQ_N_Anytime) }, aitt::AittException); } + +TEST_F(ModuleManagerTest, CreateStream_N_Anytime) +{ + EXPECT_EQ(nullptr, modules.CreateStream(AITT_STREAM_TYPE_MAX, "topic/Invalid/Stream_Type", + AITT_STREAM_ROLE_PUBLISHER)); + EXPECT_EQ(nullptr, modules.CreateStream(AITT_STREAM_TYPE_MAX, "topic/Invalid/Stream_Type", + AITT_STREAM_ROLE_SUBSCRIBER)); +} + +TEST_F(ModuleManagerTest, DestroyStream_N_Anytime) +{ + EXPECT_NO_THROW(modules.DestroyStream(nullptr)); +} + +TEST_F(ModuleManagerTest, NullTranport_N_Anytime) +{ + NullTransport null_transport(discovery, LOCAL_IP); + + EXPECT_NO_THROW({ + null_transport.Publish("AnyTopic", "AnyData", 0); + null_transport.PublishWithReply("AnyTopic", "AnyData", 0, AITT_QOS_AT_MOST_ONCE, false, + "AnyReplyTopic", "AnyCorrelation"); + null_transport.SendReply(nullptr, "AnyData", 0, AITT_QOS_AT_MOST_ONCE, false); + + EXPECT_EQ(nullptr, + null_transport.Subscribe( + "AnyTopic", + [](AittMsg *handle, const void *data, const int datalen, void *cbdata) {}, + nullptr)); + EXPECT_EQ(nullptr, null_transport.Unsubscribe(nullptr)); + char any_pointer; + EXPECT_EQ(nullptr, null_transport.Unsubscribe(&any_pointer)); + EXPECT_EQ(0, null_transport.CountSubscriber("AnyTopic")); + }); +} diff --git a/tests/MosquittoMQ_mocktest.cc b/tests/MosquittoMQ_mocktest.cc index 7d407cc..9794eec 100644 --- a/tests/MosquittoMQ_mocktest.cc +++ b/tests/MosquittoMQ_mocktest.cc @@ -17,10 +17,12 @@ #include <gmock/gmock.h> #include <gtest/gtest.h> +#include <mqtt_protocol.h> #include <condition_variable> #include <mutex> +#include "AittException.h" #include "AittTypes.h" #include "MosquittoMock.h" @@ -42,21 +44,35 @@ class MQMockTest : public ::testing::Test { MosquittoMock mqttMock; }; -TEST_F(MQMockTest, Create_lib_init_N_Anytime) +TEST_F(MQMockTest, Construtor_P_Anytime) { - EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_NOT_SUPPORTED)); - EXPECT_CALL(mqttMock, mosquitto_destroy(nullptr)).WillOnce(Return()); + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, + mosquitto_int_option(TEST_HANDLE, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5)) + .Times(1); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); try { aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); - FAIL() << "lib_init must be failed"; } catch (std::exception &e) { - ASSERT_STREQ(e.what(), "MQTT failure : MosquittoMQ Constructor Error"); + FAIL() << "Unexpected exception occurred"; } } -TEST_F(MQMockTest, Create_new_N_Anytime) +TEST_F(MQMockTest, Construtor_lib_init_N_Anytime) +{ + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_NOT_SUPPORTED)); + EXPECT_CALL(mqttMock, mosquitto_destroy(nullptr)).WillOnce(Return()); + EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + + EXPECT_THROW({ aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); }, aitt::AittException); +} + +TEST_F(MQMockTest, Construtor_new_N_Anytime) { EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) @@ -64,194 +80,368 @@ TEST_F(MQMockTest, Create_new_N_Anytime) EXPECT_CALL(mqttMock, mosquitto_destroy(nullptr)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); - try { - aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); - FAIL() << "lib_init must be failed"; - } catch (std::exception &e) { - ASSERT_STREQ(e.what(), "MQTT failure : MosquittoMQ Constructor Error"); - } + EXPECT_THROW({ aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); }, aitt::AittException); } -TEST_F(MQMockTest, Publish_P_Anytime) +TEST_F(MQMockTest, Construtor_option_N_Anytime) { EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) .WillOnce(Return(TEST_HANDLE)); - EXPECT_CALL(mqttMock, - mosquitto_int_option(TEST_HANDLE, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5)) - .WillOnce(Return(MOSQ_ERR_SUCCESS)); - EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); - EXPECT_CALL(mqttMock, mosquitto_loop_start(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_SUCCESS)); - EXPECT_CALL(mqttMock, mosquitto_connect(TEST_HANDLE, testing::StrEq(TEST_HOST), TEST_PORT, 60)) - .WillOnce(Return(MOSQ_ERR_SUCCESS)); - EXPECT_CALL(mqttMock, mosquitto_publish(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), - sizeof(TEST_PAYLOAD), TEST_PAYLOAD, AITT_QOS_AT_MOST_ONCE, false)) - .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_int_option(TEST_HANDLE, testing::_, testing::_)) + .WillOnce(Return(MOSQ_ERR_INVAL)); EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); - try { - aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); - mq.Connect(TEST_HOST, TEST_PORT, "", ""); - mq.Publish(TEST_TOPIC, TEST_PAYLOAD, sizeof(TEST_PAYLOAD)); - } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); - } + EXPECT_THROW({ aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); }, aitt::AittException); } -TEST_F(MQMockTest, Subscribe_P_Anytime) +TEST_F(MQMockTest, Connect_P_Anytime) { EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) .WillOnce(Return(TEST_HANDLE)); EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); - EXPECT_CALL(mqttMock, mosquitto_loop_start(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_connect(TEST_HANDLE, testing::StrEq(TEST_HOST), TEST_PORT, 60)) .WillOnce(Return(MOSQ_ERR_SUCCESS)); - EXPECT_CALL(mqttMock, mosquitto_subscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), - AITT_QOS_AT_MOST_ONCE)) - .WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); - try { aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); mq.Connect(TEST_HOST, TEST_PORT, "", ""); - mq.Subscribe( - TEST_TOPIC, - [](AittMsg *info, const void *msg, const int szmsg, const void *cbdata) -> void {}, - nullptr, AITT_QOS_AT_MOST_ONCE); } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); + FAIL() << "Unepxected exception: " << e.what(); } } -TEST_F(MQMockTest, Unsubscribe_P_Anytime) +TEST_F(MQMockTest, Connect_N_Anytime) +{ + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_connect(TEST_HANDLE, testing::StrEq(TEST_HOST), TEST_PORT, 60)) + .WillOnce(Return(MOSQ_ERR_PROTOCOL)); + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.Connect(TEST_HOST, TEST_PORT, "", ""); + }, + aitt::AittException); +} + +TEST_F(MQMockTest, Connect_loop_N_Anytime) { EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) .WillOnce(Return(TEST_HANDLE)); EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); - EXPECT_CALL(mqttMock, mosquitto_loop_start(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_connect(TEST_HANDLE, testing::StrEq(TEST_HOST), TEST_PORT, 60)) .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_loop_start(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_ERRNO)); + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.Connect(TEST_HOST, TEST_PORT, "", ""); + }, + aitt::AittException); +} + +TEST_F(MQMockTest, Connect_User_P_Anytime) +{ + std::string username = "test"; + std::string password = "test"; + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); EXPECT_CALL(mqttMock, - mosquitto_subscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), 0)) - .WillOnce(Return(MOSQ_ERR_SUCCESS)); - EXPECT_CALL(mqttMock, - mosquitto_unsubscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC))) + mosquitto_username_pw_set(TEST_HANDLE, username.c_str(), password.c_str())) + .Times(1); + EXPECT_CALL(mqttMock, mosquitto_connect(TEST_HANDLE, testing::StrEq(TEST_HOST), TEST_PORT, 60)) .WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); - try { aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); - mq.Connect(TEST_HOST, TEST_PORT, "", ""); - void *handle = mq.Subscribe( - TEST_TOPIC, - [](AittMsg *info, const void *msg, const int szmsg, const void *cbdata) -> void {}, - nullptr, AITT_QOS_AT_MOST_ONCE); - mq.Unsubscribe(handle); + mq.Connect(TEST_HOST, TEST_PORT, username, password); } catch (std::exception &e) { - FAIL() << "Unexpected exception: " << e.what(); + FAIL() << "Unepxected exception: " << e.what(); } } -TEST_F(MQMockTest, Create_P_Anytime) +TEST_F(MQMockTest, Connect_User_N_Anytime) { + std::string username = "Invalid_User"; + std::string password = "Invalid_Password"; EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); EXPECT_CALL(mqttMock, - mosquitto_int_option(TEST_HANDLE, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5)) - .Times(1); + mosquitto_username_pw_set(TEST_HANDLE, username.c_str(), password.c_str())) + .WillOnce(Return(MOSQ_ERR_INVAL)); + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.Connect(TEST_HOST, TEST_PORT, username, password); + }, + aitt::AittException); +} + +TEST_F(MQMockTest, Set_will_N_Anytime) +{ + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_will_set(TEST_HANDLE, testing::StrEq("lastWill"), + sizeof(TEST_PAYLOAD), TEST_PAYLOAD, AITT_QOS_AT_MOST_ONCE, true)) + .WillOnce(Return(MOSQ_ERR_NOMEM)); EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.SetWillInfo("lastWill", TEST_PAYLOAD, sizeof(TEST_PAYLOAD), AITT_QOS_AT_MOST_ONCE, + true); + }, + aitt::AittException); +} +TEST_F(MQMockTest, Disconnect_P_Anytime) +{ + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_disconnect(testing::_)).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_will_clear(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); try { aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.Disconnect(); } catch (std::exception &e) { - FAIL() << "Unexpected exception occurred"; + FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(MQMockTest, Connect_will_set_N_Anytime) +TEST_F(MQMockTest, Disconnect_N_Anytime) { EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) .WillOnce(Return(TEST_HANDLE)); EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); - EXPECT_CALL(mqttMock, mosquitto_will_set(TEST_HANDLE, testing::StrEq("lastWill"), - sizeof(TEST_PAYLOAD), TEST_PAYLOAD, AITT_QOS_AT_MOST_ONCE, true)) - .WillOnce(Return(MOSQ_ERR_NOMEM)); + EXPECT_CALL(mqttMock, mosquitto_disconnect(testing::_)).WillOnce(Return(MOSQ_ERR_NO_CONN)); + EXPECT_CALL(mqttMock, mosquitto_will_clear(TEST_HANDLE)).Times(0); EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); try { aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); - mq.SetWillInfo("lastWill", TEST_PAYLOAD, sizeof(TEST_PAYLOAD), AITT_QOS_AT_MOST_ONCE, true); - mq.Connect(TEST_HOST, TEST_PORT, "", ""); - FAIL() << "Connect() must be failed"; + mq.Disconnect(); } catch (std::exception &e) { - ASSERT_STREQ(e.what(), "MQTT failure"); + FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(MQMockTest, Connect_P_Anytime) +TEST_F(MQMockTest, Publish_P_Anytime) { EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, + mosquitto_int_option(TEST_HANDLE, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5)) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_loop_start(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_connect(TEST_HANDLE, testing::StrEq(TEST_HOST), TEST_PORT, 60)) .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_publish(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), + sizeof(TEST_PAYLOAD), TEST_PAYLOAD, AITT_QOS_AT_MOST_ONCE, false)) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + try { aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); mq.Connect(TEST_HOST, TEST_PORT, "", ""); + mq.Publish(TEST_TOPIC, TEST_PAYLOAD, sizeof(TEST_PAYLOAD)); } catch (std::exception &e) { - FAIL() << "Unepxected exception: " << e.what(); + FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(MQMockTest, Connect_User_P_Anytime) +TEST_F(MQMockTest, Publish_N_Anytime) { - std::string username = "test"; - std::string password = "test"; EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) .WillOnce(Return(TEST_HANDLE)); - EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); EXPECT_CALL(mqttMock, - mosquitto_username_pw_set(TEST_HANDLE, username.c_str(), password.c_str())) - .Times(1); + mosquitto_int_option(TEST_HANDLE, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5)) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_publish(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), + sizeof(TEST_PAYLOAD), TEST_PAYLOAD, AITT_QOS_AT_MOST_ONCE, false)) + .WillOnce(Return(MOSQ_ERR_NOT_SUPPORTED)); + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.Publish(TEST_TOPIC, TEST_PAYLOAD, sizeof(TEST_PAYLOAD)); + }, + aitt::AittException); +} + +TEST_F(MQMockTest, Subscribe_P_Anytime) +{ + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_loop_start(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_connect(TEST_HANDLE, testing::StrEq(TEST_HOST), TEST_PORT, 60)) .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_subscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), + AITT_QOS_AT_MOST_ONCE)) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + try { aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); - mq.Connect(TEST_HOST, TEST_PORT, username, password); + mq.Connect(TEST_HOST, TEST_PORT, "", ""); + mq.Subscribe( + TEST_TOPIC, + [](AittMsg *info, const void *msg, const int szmsg, const void *cbdata) -> void {}, + nullptr, AITT_QOS_AT_MOST_ONCE); } catch (std::exception &e) { - FAIL() << "Unepxected exception: " << e.what(); + FAIL() << "Unexpected exception: " << e.what(); } } -TEST_F(MQMockTest, Disconnect_P_Anytime) +TEST_F(MQMockTest, Subscribe_N_Anytime) +{ + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_subscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), + AITT_QOS_AT_MOST_ONCE)) + .WillOnce(Return(MOSQ_ERR_INVAL)); + + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.Subscribe( + TEST_TOPIC, + [](AittMsg *info, const void *msg, const int szmsg, + const void *cbdata) -> void {}, + nullptr, AITT_QOS_AT_MOST_ONCE); + }, + aitt::AittException); +} + +TEST_F(MQMockTest, Unsubscribe_P_Anytime) { EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) .WillOnce(Return(TEST_HANDLE)); EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); - EXPECT_CALL(mqttMock, mosquitto_disconnect(testing::_)).WillOnce(Return(MOSQ_ERR_SUCCESS)); - EXPECT_CALL(mqttMock, mosquitto_will_clear(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_loop_start(TEST_HANDLE)).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_connect(TEST_HANDLE, testing::StrEq(TEST_HOST), TEST_PORT, 60)) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, + mosquitto_subscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), 0)) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, + mosquitto_unsubscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC))) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); EXPECT_CALL(mqttMock, mosquitto_destroy(TEST_HANDLE)).Times(1); EXPECT_CALL(mqttMock, mosquitto_lib_cleanup()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + try { aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); - mq.Disconnect(); + mq.Connect(TEST_HOST, TEST_PORT, "", ""); + void *handle = mq.Subscribe( + TEST_TOPIC, + [](AittMsg *info, const void *msg, const int szmsg, const void *cbdata) -> void {}, + nullptr, AITT_QOS_AT_MOST_ONCE); + mq.Unsubscribe(handle); } catch (std::exception &e) { FAIL() << "Unexpected exception: " << e.what(); } } + +TEST_F(MQMockTest, Unsubscribe_N_Anytime) +{ + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, + mosquitto_subscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), 0)) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, + mosquitto_unsubscribe(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC))) + .WillOnce(Return(MOSQ_ERR_NOT_SUPPORTED)); + + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + void *handle = mq.Subscribe( + TEST_TOPIC, + [](AittMsg *info, const void *msg, const int szmsg, + const void *cbdata) -> void {}, + nullptr, AITT_QOS_AT_MOST_ONCE); + mq.Unsubscribe(handle); + }, + aitt::AittException); +} + +TEST_F(MQMockTest, PublishWithReply_memory_N_Anytime) +{ + std::string replyTopic = "replyTopic"; + + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_property_add_string(testing::_, MQTT_PROP_RESPONSE_TOPIC, + testing::StrEq(replyTopic))) + .WillOnce(Return(MOSQ_ERR_NOMEM)); + + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.PublishWithReply(TEST_TOPIC, TEST_PAYLOAD, sizeof(TEST_PAYLOAD), + AITT_QOS_AT_MOST_ONCE, false, replyTopic, ""); + }, + aitt::AittException); +} + +TEST_F(MQMockTest, PublishWithReply_N_Anytime) +{ + std::string replyTopic = "replyTopic"; + std::string correlation = "CorrelationData"; + + EXPECT_CALL(mqttMock, mosquitto_lib_init()).WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_new(testing::StrEq(TEST_CLIENT_ID), true, testing::_)) + .WillOnce(Return(TEST_HANDLE)); + EXPECT_CALL(mqttMock, mosquitto_message_v5_callback_set(TEST_HANDLE, testing::_)).Times(1); + EXPECT_CALL(mqttMock, mosquitto_property_add_string(testing::_, MQTT_PROP_RESPONSE_TOPIC, + testing::StrEq(replyTopic))) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, mosquitto_property_add_binary(testing::_, MQTT_PROP_CORRELATION_DATA, + testing::_, correlation.size())) + .WillOnce(Return(MOSQ_ERR_SUCCESS)); + EXPECT_CALL(mqttMock, + mosquitto_publish_v5(TEST_HANDLE, testing::_, testing::StrEq(TEST_TOPIC), + AITT_MESSAGE_MAX, TEST_PAYLOAD, AITT_QOS_AT_MOST_ONCE, false, testing::_)) + .WillOnce(Return(MOSQ_ERR_OVERSIZE_PACKET)); + + EXPECT_THROW( + { + aitt::MosquittoMQ mq(TEST_CLIENT_ID, true); + mq.PublishWithReply(TEST_TOPIC, TEST_PAYLOAD, AITT_MESSAGE_MAX, AITT_QOS_AT_MOST_ONCE, + false, replyTopic, correlation); + }, + aitt::AittException); +} diff --git a/tests/MosquittoMQ_test.cc b/tests/MosquittoMQ_test.cc index 7999feb..b110a20 100644 --- a/tests/MosquittoMQ_test.cc +++ b/tests/MosquittoMQ_test.cc @@ -70,3 +70,27 @@ TEST_F(MQTest, Subscribe_in_Subscribe_MQTT_P_Anytime) FAIL() << "Unexpected exception: " << e.what(); } } + +TEST_F(MQTest, Unsubscribe_N_Anytime) +{ + EXPECT_THROW( + { + MosquittoMQ mq("MQ_TEST_ID"); + EXPECT_EQ(nullptr, mq.Unsubscribe(nullptr)); + + int invalid_pointer; + mq.Unsubscribe(&invalid_pointer); + }, + aitt::AittException); +} + +TEST_F(MQTest, CompareTopic_N_Anytime) +{ + MosquittoMQ mq("MQ_TEST_ID"); + EXPECT_TRUE(mq.CompareTopic("topic1/+", "topic1/test")); + EXPECT_TRUE(mq.CompareTopic("topic1/#", "topic1/test1/test2")); + EXPECT_TRUE(mq.CompareTopic("topic1/#", "topic1")); + + EXPECT_FALSE(mq.CompareTopic("topic1/+", "topic1/test1/test2")); + EXPECT_FALSE(mq.CompareTopic("topic1/+", "topic1")); +} diff --git a/tests/MosquittoMock.cc b/tests/MosquittoMock.cc index da310a4..b4ee7d6 100644 --- a/tests/MosquittoMock.cc +++ b/tests/MosquittoMock.cc @@ -31,9 +31,14 @@ CMOCK_MOCK_FUNCTION1(MosquittoMock, mosquitto_will_clear, int(struct mosquitto * CMOCK_MOCK_FUNCTION4(MosquittoMock, mosquitto_connect, int(struct mosquitto *mosq, const char *host, int port, int keepalive)); CMOCK_MOCK_FUNCTION1(MosquittoMock, mosquitto_disconnect, int(struct mosquitto *mosq)); + CMOCK_MOCK_FUNCTION7(MosquittoMock, mosquitto_publish, int(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain)); +CMOCK_MOCK_FUNCTION8(MosquittoMock, mosquitto_publish_v5, + int(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, + int qos, bool retain, const mosquitto_property *properties)); + CMOCK_MOCK_FUNCTION4(MosquittoMock, mosquitto_subscribe, int(struct mosquitto *mosq, int *mid, const char *sub, int qos)); CMOCK_MOCK_FUNCTION3(MosquittoMock, mosquitto_unsubscribe, @@ -50,3 +55,10 @@ CMOCK_MOCK_FUNCTION2(MosquittoMock, mosquitto_connect_v5_callback_set, CMOCK_MOCK_FUNCTION2(MosquittoMock, mosquitto_disconnect_v5_callback_set, void(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *))); + +CMOCK_MOCK_FUNCTION3(MosquittoMock, mosquitto_property_add_string, + int(mosquitto_property **proplist, int identifier, const char *value)); +CMOCK_MOCK_FUNCTION4(MosquittoMock, mosquitto_property_add_binary, + int(mosquitto_property **proplist, int identifier, const void *value, uint16_t len)); +CMOCK_MOCK_FUNCTION1(MosquittoMock, mosquitto_property_free_all, + void(mosquitto_property **property)); diff --git a/tests/MosquittoMock.h b/tests/MosquittoMock.h index f0185c9..cf54339 100644 --- a/tests/MosquittoMock.h +++ b/tests/MosquittoMock.h @@ -34,9 +34,14 @@ class MosquittoMock : public CMockMocker<MosquittoMock> { MOCK_METHOD4(mosquitto_connect, int(struct mosquitto *mosq, const char *host, int port, int keepalive)); MOCK_METHOD1(mosquitto_disconnect, int(struct mosquitto *mosq)); + MOCK_METHOD7(mosquitto_publish, int(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain)); + MOCK_METHOD8(mosquitto_publish_v5, + int(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, + const void *payload, int qos, bool retain, const mosquitto_property *properties)); + MOCK_METHOD4(mosquitto_subscribe, int(struct mosquitto *mosq, int *mid, const char *sub, int qos)); MOCK_METHOD3(mosquitto_unsubscribe, int(struct mosquitto *mosq, int *mid, const char *sub)); @@ -52,4 +57,9 @@ class MosquittoMock : public CMockMocker<MosquittoMock> { MOCK_METHOD2(mosquitto_disconnect_v5_callback_set, void(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *))); + MOCK_METHOD3(mosquitto_property_add_string, + int(mosquitto_property **proplist, int identifier, const char *value)); + MOCK_METHOD4(mosquitto_property_add_binary, + int(mosquitto_property **proplist, int identifier, const void *value, uint16_t len)); + MOCK_METHOD1(mosquitto_property_free_all, void(mosquitto_property **property)); }; diff --git a/tests/RequestResponse_test.cc b/tests/RequestResponse_test.cc index 3be5d9b..f220eaf 100644 --- a/tests/RequestResponse_test.cc +++ b/tests/RequestResponse_test.cc @@ -249,6 +249,24 @@ TEST_F(AITTRRTest, RequestResponse_P_Anytime) } } +TEST_F(AITTRRTest, RequestResponse_Multi_protocol_N_Anytime) +{ + EXPECT_THROW( + { + AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); + aitt.Connect(); + + aitt.PublishWithReply( + rr_topic, message.c_str(), message.size(), + (AittProtocol)(AITT_TYPE_MQTT | AITT_TYPE_TCP), AITT_QOS_AT_MOST_ONCE, false, + [](AittMsg *msg, const void *data, const int datalen, void *cbdata) { + FAIL() << "Should not be called"; + }, + nullptr, correlation); + }, + aitt::AittException); +} + TEST_F(AITTRRTest, RequestResponse_asymmetry_Anytime) { std::string reply1 = "1st data"; @@ -387,7 +405,7 @@ TEST_F(AITTRRTest, RequestResponse_sync_in_sync_P_Anytime) } } -TEST_F(AITTRRTest, RequestResponse_timeout_P_Anytime) +TEST_F(AITTRRTest, RequestResponse_timeout_N_Anytime) { try { AITT aitt(clientId, LOCAL_IP, AittOption(true, false)); @@ -407,7 +425,7 @@ TEST_F(AITTRRTest, RequestResponse_timeout_P_Anytime) } } -TEST_F(AITTRRTest, RequestResponse_timeout_restart_P_Anytime) +TEST_F(AITTRRTest, RequestResponse_timeout_restart_N_Anytime) { bool sub_ok, reply_ok; sub_ok = reply_ok = false; diff --git a/tests/aitt_c_manualtest.cc b/tests/aitt_c_manualtest.cc index 7b699d7..d5a5d3d 100644 --- a/tests/aitt_c_manualtest.cc +++ b/tests/aitt_c_manualtest.cc @@ -22,7 +22,7 @@ #define TEST_C_WILL_TOPIC "test/topic_will" -TEST(AITT_C_MANUAL, will_set_P) +TEST(AITT_C_MANUAL, will_set_P_manual) { int ret; aitt_h handle = aitt_new("test14", nullptr); @@ -85,7 +85,7 @@ TEST(AITT_C_MANUAL, will_set_P) } // Set user/passwd in mosquitto.conf before testing -TEST(AITT_C_MANUAL, connect_id_passwd_P) +TEST(AITT_C_MANUAL, connect_id_passwd_P_manual) { aitt_h handle = aitt_new("test15", nullptr); ASSERT_NE(handle, nullptr); @@ -98,3 +98,37 @@ TEST(AITT_C_MANUAL, connect_id_passwd_P) aitt_destroy(handle); } + +TEST(AITT_C_MANUAL, connect_id_passwd_N_manual) +{ + aitt_h handle = aitt_new("test15", nullptr); + ASSERT_NE(handle, nullptr); + + int ret = aitt_connect_full(handle, LOCAL_IP, 1883, "InvalidID", "InvalidPasswd"); + ASSERT_EQ(ret, AITT_ERROR_SYSTEM); + + ret = aitt_disconnect(handle); + EXPECT_EQ(ret, AITT_ERROR_NONE); + + aitt_destroy(handle); +} + +TEST(AITT_C_INTERFACE, connect_custom_N_manual) +{ + int ret; + + aitt_option_h option = aitt_option_new(); + ASSERT_NE(option, nullptr); + + ret = aitt_option_set(option, AITT_OPT_CUSTOM_BROKER, "true"); + EXPECT_EQ(ret, AITT_ERROR_NONE); + + aitt_h handle = aitt_new("test", option); + aitt_option_destroy(option); + ASSERT_NE(handle, nullptr); + + ret = aitt_connect(handle, nullptr, 1883); + EXPECT_EQ(ret, AITT_ERROR_INVALID_PARAMETER); + + aitt_destroy(handle); +} diff --git a/tests/aitt_c_test.cc b/tests/aitt_c_test.cc index 42501ce..815de29 100644 --- a/tests/aitt_c_test.cc +++ b/tests/aitt_c_test.cc @@ -127,6 +127,19 @@ TEST(AITT_C_INTERFACE, option_N_Anytime) aitt_option_destroy(option); } +TEST(AITT_C_INTERFACE, option_No_set_N_Anytime) +{ + aitt_option_h option = aitt_option_new(); + ASSERT_NE(option, nullptr); + + EXPECT_EQ(nullptr, aitt_option_get(option, AITT_OPT_MY_IP)); + EXPECT_STREQ("false", aitt_option_get(option, AITT_OPT_CLEAN_SESSION)); + EXPECT_STREQ("false", aitt_option_get(option, AITT_OPT_CUSTOM_BROKER)); + EXPECT_EQ(nullptr, aitt_option_get(option, AITT_OPT_UNKNOWN)); + + aitt_option_destroy(option); +} + TEST(AITT_C_INTERFACE, connect_disconnect_P_Anytime) { int ret; @@ -169,6 +182,9 @@ TEST(AITT_C_INTERFACE, connect_N_Anytime) ret = aitt_connect(handle, invalid_ip, 1883); EXPECT_EQ(ret, AITT_ERROR_INVALID_PARAMETER); + ret = aitt_connect(handle, nullptr, 1883); + EXPECT_EQ(ret, AITT_ERROR_INVALID_PARAMETER); + int invalid_port = -1; ret = aitt_connect(handle, LOCAL_IP, invalid_port); EXPECT_EQ(ret, AITT_ERROR_SYSTEM); @@ -253,6 +269,46 @@ TEST(AITT_C_INTERFACE, pub_N_Anytime) ret = aitt_publish(handle, TEST_C_TOPIC, TEST_C_MSG, strlen(TEST_C_MSG)); EXPECT_EQ(ret, AITT_ERROR_NOT_READY); + aitt_destroy(handle); +} + +TEST(AITT_C_INTERFACE, pub_wildcard_topic_N_Anytime) +{ + int ret; + + aitt_option_h option = aitt_option_new(); + ASSERT_NE(option, nullptr); + + ret = aitt_option_set(option, AITT_OPT_MY_IP, LOCAL_IP); + EXPECT_EQ(ret, AITT_ERROR_NONE); + + aitt_h handle = aitt_new("test_c", option); + aitt_option_destroy(option); + ASSERT_NE(handle, nullptr); + + ret = aitt_connect(handle, LOCAL_IP, 1883); + EXPECT_EQ(ret, AITT_ERROR_NONE); + + ret = aitt_publish(handle, "test/#", TEST_C_MSG, strlen(TEST_C_MSG)); + EXPECT_EQ(ret, AITT_ERROR_SYSTEM); + + aitt_destroy(handle); +} + +TEST(AITT_C_INTERFACE, pub_invalid_param_N_Anytime) +{ + int ret; + + aitt_option_h option = aitt_option_new(); + ASSERT_NE(option, nullptr); + + ret = aitt_option_set(option, AITT_OPT_MY_IP, LOCAL_IP); + EXPECT_EQ(ret, AITT_ERROR_NONE); + + aitt_h handle = aitt_new("test9", option); + aitt_option_destroy(option); + ASSERT_NE(handle, nullptr); + ret = aitt_publish(nullptr, TEST_C_TOPIC, TEST_C_MSG, strlen(TEST_C_MSG)); EXPECT_EQ(ret, AITT_ERROR_INVALID_PARAMETER); @@ -351,14 +407,25 @@ TEST(AITT_C_INTERFACE, pub_with_reply_N_Anytime) aitt_destroy(handle); } -TEST(AITT_C_INTERFACE, will_set_N_Anytime) +TEST(AITT_C_INTERFACE, will_set_with_null_N_Anytime) { int ret; + aitt_h invalid_handle = nullptr; - ret = aitt_will_set(nullptr, "test/will_topic", "test", 4, AITT_QOS_AT_MOST_ONCE, false); + ret = aitt_will_set(invalid_handle, "test/will_topic", "test", 4, AITT_QOS_AT_MOST_ONCE, false); EXPECT_EQ(ret, AITT_ERROR_INVALID_PARAMETER); } +TEST_F(AITTCTest, will_set_N_Anytime) +{ + int ret; + aitt_h handle = NewAitt(); + ASSERT_NE(handle, nullptr); + + ret = aitt_will_set(handle, "test/will_topic/+", "test", 4, AITT_QOS_AT_MOST_ONCE, false); + EXPECT_EQ(ret, AITT_ERROR_SYSTEM); +} + TEST_F(AITTCTest, pub_with_reply_send_reply_P_Anytime) { int ret; @@ -488,3 +555,36 @@ TEST_F(AITTCTest, connect_cb_P_Anytime) aitt_destroy(handle); } + +TEST(AITT_C_INTERFACE, connect_cb_N_Anytime) +{ + int ret = aitt_set_connect_callback( + nullptr, [](aitt_h aitt_handle, int status, void *user_data) {}, nullptr); + EXPECT_EQ(ret, AITT_ERROR_INVALID_PARAMETER); +} + +TEST(AITT_C_INTERFACE, unsubscribe_N_anytime) +{ + int ret = aitt_unsubscribe(nullptr, nullptr); + EXPECT_EQ(ret, AITT_ERROR_INVALID_PARAMETER); +} + +TEST_F(AITTCTest, unsubscribe_N_Anytime) +{ + int ret; + aitt_h handle = NewAitt(); + ASSERT_NE(handle, nullptr); + + ret = aitt_unsubscribe(handle, nullptr); + EXPECT_EQ(ret, AITT_ERROR_NOT_READY); + + ret = aitt_connect(handle, LOCAL_IP, 1883); + ASSERT_EQ(ret, AITT_ERROR_NONE); + + ret = aitt_unsubscribe(handle, nullptr); + EXPECT_EQ(ret, AITT_ERROR_INVALID_PARAMETER); + + int invalid_pointer; + ret = aitt_unsubscribe(handle, &invalid_pointer); + EXPECT_EQ(ret, AITT_ERROR_SYSTEM); +} |