From 7809efc25faf65a911b0c6fc2d7963b8eb56fb54 Mon Sep 17 00:00:00 2001 From: ruchir Date: Fri, 21 Jun 2024 15:07:48 -0400 Subject: [PATCH] Notificationsource Implementation --- .../up-cpp/communication/NotificationSource.h | 6 +- src/communication/NotificationSource.cpp | 34 ++++ .../communication/NotificationSourceTest.cpp | 157 +++++++++++++++++- 3 files changed, 188 insertions(+), 9 deletions(-) diff --git a/include/up-cpp/communication/NotificationSource.h b/include/up-cpp/communication/NotificationSource.h index 9cffdb245..1c21dad04 100644 --- a/include/up-cpp/communication/NotificationSource.h +++ b/include/up-cpp/communication/NotificationSource.h @@ -48,7 +48,7 @@ struct NotificationSource { /// @param ttl How long messages will be valid from the time notify() is /// called. NotificationSource(std::shared_ptr transport, - const v1::UUri& source, const v1::UUri& sink, + v1::UUri&& source, v1::UUri&& sink, std::optional payload_format = {}, std::optional priority = {}, std::optional ttl = {}); @@ -57,13 +57,13 @@ struct NotificationSource { /// /// @param A Payload builder containing the payload to be sent with the /// notification. - v1::UStatus notify(datamodel::builder::Payload&&); + v1::UStatus notify(datamodel::builder::Payload&&) const; /// @brief Send a notification to the selected sink. /// /// This can only be called if no payload format was provided at /// construction time. - v1::UStatus notify(); + v1::UStatus notify() const; private: std::shared_ptr transport_; diff --git a/src/communication/NotificationSource.cpp b/src/communication/NotificationSource.cpp index 3902c0231..42201421c 100644 --- a/src/communication/NotificationSource.cpp +++ b/src/communication/NotificationSource.cpp @@ -10,3 +10,37 @@ // SPDX-License-Identifier: Apache-2.0 #include "up-cpp/communication/NotificationSource.h" + +namespace uprotocol::communication { +using namespace uprotocol::datamodel::builder; + +NotificationSource::NotificationSource( + std::shared_ptr transport, v1::UUri&& source, + v1::UUri&& sink, std::optional payload_format, + std::optional priority, + std::optional ttl) + : transport_(std::move(transport)), + notify_builder_( + UMessageBuilder::notification(std::move(source), std::move(sink)) + .withPriority(priority.value_or(v1::UPriority::UPRIORITY_CS1))) { + if (payload_format.has_value()) { + notify_builder_.withPayloadFormat(payload_format.value()); + } + + if (ttl.has_value()) { + notify_builder_.withTtl(ttl.value()); + } +} + +v1::UStatus NotificationSource::notify( + datamodel::builder::Payload&& payload) const { + auto message = notify_builder_.build(std::move(payload)); + return transport_->send(std::move(message)); +} + +v1::UStatus NotificationSource::notify() const { + auto message = notify_builder_.build(); + return transport_->send(std::move(message)); +} + +} // namespace uprotocol::communication \ No newline at end of file diff --git a/test/coverage/communication/NotificationSourceTest.cpp b/test/coverage/communication/NotificationSourceTest.cpp index 4acded291..e30c546b6 100644 --- a/test/coverage/communication/NotificationSourceTest.cpp +++ b/test/coverage/communication/NotificationSourceTest.cpp @@ -11,30 +11,175 @@ #include #include +#include +#include +#include #include "UTransportMock.h" +#include "up-cpp/datamodel/builder/UMessage.h" +#include "up-cpp/datamodel/validator/UMessage.h" +#include "up-cpp/transport/UTransport.h" + +using namespace uprotocol::communication; +using namespace uprotocol::datamodel::builder; +using namespace uprotocol::v1; +using ::testing::_; +using ::testing::Return; namespace { -class TestFixture : public testing::Test { +class TestNotificationSource : public testing::Test { protected: // Run once per TEST_F. // Used to set up clean environments per test. - void SetUp() override {} + void SetUp() override { + source_.set_authority_name("10.0.0.1"); + source_.set_ue_id(0x00011101); + source_.set_ue_version_major(0xF1); + source_.set_resource_id(0x0); + + sink_.set_authority_name("10.0.0.1"); + sink_.set_ue_id(0x00011101); + sink_.set_ue_version_major(0xF8); + sink_.set_resource_id(0x8101); + transportMock_ = + std::make_shared(source_); + + format_ = UPayloadFormat::UPAYLOAD_FORMAT_TEXT; + priority_ = UPriority::UPRIORITY_CS1; + ttl_ = std::chrono::milliseconds(1000); + } void TearDown() override {} // Run once per execution of the test application. // Used for setup of all tests. Has access to this instance. - TestFixture() = default; - ~TestFixture() = default; + TestNotificationSource() = default; + ~TestNotificationSource() = default; // Run once per execution of the test application. // Used only for global setup outside of tests. static void SetUpTestSuite() {} static void TearDownTestSuite() {} + + std::shared_ptr transportMock_; + UUri source_; + UUri sink_; + UPayloadFormat format_; + std::optional priority_; + std::optional ttl_; }; -// TODO replace -TEST_F(TestFixture, SomeTestName) {} +TEST_F(TestNotificationSource, NotifyWithPayloadSuccess) { + std::string testPayloadStr = "test_payload"; + NotificationSource notificationSource(transportMock_, std::move(source_), + std::move(sink_), format_, priority_, + ttl_); + Payload testPayload(testPayloadStr, format_); + + uprotocol::v1::UStatus retval; + retval.set_code(uprotocol::v1::UCode::OK); + transportMock_->send_status_ = retval; + + auto status = notificationSource.notify(std::move(testPayload)); + + EXPECT_EQ(status.code(), retval.code()); + + auto [valid, reason] = + uprotocol::datamodel::validator::message::isValidNotification( + transportMock_->message_); + EXPECT_EQ(valid, true); +} + +TEST_F(TestNotificationSource, NotifyWithPayloadSuccessWithoutTTL) { + std::string testPayloadStr = "test_payload"; + NotificationSource notificationSource(transportMock_, std::move(source_), + std::move(sink_), format_, priority_); + Payload testPayload(testPayloadStr, format_); + + uprotocol::v1::UStatus retval; + retval.set_code(uprotocol::v1::UCode::OK); + transportMock_->send_status_ = retval; + + auto status = notificationSource.notify(std::move(testPayload)); + + EXPECT_EQ(status.code(), retval.code()); + + auto [valid, reason] = + uprotocol::datamodel::validator::message::isValidNotification( + transportMock_->message_); + EXPECT_EQ(valid, true); + + EXPECT_EQ(transportMock_->message_.attributes().ttl(), 0); +} + +TEST_F(TestNotificationSource, NotifyWithPayloadSuccessWithoutPriority) { + std::string testPayloadStr = "test_payload"; + priority_.reset(); + NotificationSource notificationSource(transportMock_, std::move(source_), + std::move(sink_), format_, priority_); + Payload testPayload(testPayloadStr, format_); + + uprotocol::v1::UStatus retval; + retval.set_code(uprotocol::v1::UCode::OK); + transportMock_->send_status_ = retval; + + auto status = notificationSource.notify(std::move(testPayload)); + + EXPECT_EQ(status.code(), retval.code()); + + auto [valid, reason] = + uprotocol::datamodel::validator::message::isValidNotification( + transportMock_->message_); + EXPECT_EQ(valid, true); + + EXPECT_EQ(transportMock_->message_.attributes().priority(), + UPriority::UPRIORITY_CS1); +} + +TEST_F(TestNotificationSource, NotifyWithPayloadFailure) { + std::string testPayloadStr = "test_payload"; + NotificationSource notificationSource(transportMock_, std::move(source_), + std::move(sink_), format_, priority_, + ttl_); + Payload testPayload(testPayloadStr, format_); + + uprotocol::v1::UStatus retval; + retval.set_code(uprotocol::v1::UCode::DATA_LOSS); + transportMock_->send_status_ = retval; + + auto status = notificationSource.notify(std::move(testPayload)); + + EXPECT_EQ(status.code(), retval.code()); +} + +TEST_F(TestNotificationSource, NotifyWithoutPayloadSuccess) { + NotificationSource notificationSource(transportMock_, std::move(source_), + std::move(sink_)); + + uprotocol::v1::UStatus retval; + retval.set_code(uprotocol::v1::UCode::OK); + transportMock_->send_status_ = retval; + + auto status = notificationSource.notify(); + + EXPECT_EQ(status.code(), retval.code()); + + EXPECT_EQ(transportMock_->message_.attributes().ttl(), 0); + EXPECT_EQ(transportMock_->message_.attributes().priority(), + UPriority::UPRIORITY_CS1); +} + +TEST_F(TestNotificationSource, NotifyWithoutPayloadFailure) { + NotificationSource notificationSource(transportMock_, std::move(source_), + std::move(sink_)); + + uprotocol::v1::UStatus retval; + retval.set_code(uprotocol::v1::UCode::DATA_LOSS); + transportMock_->send_status_ = retval; + + auto status = notificationSource.notify(); + + EXPECT_EQ(status.code(), retval.code()); +} } // namespace