Skip to content

Commit

Permalink
[#573] Test c++ deadline binding
Browse files Browse the repository at this point in the history
  • Loading branch information
elfenpiff committed Jan 3, 2025
1 parent 4f0c636 commit 246de57
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 0 deletions.
8 changes: 8 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/enum_translation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,10 @@ constexpr auto from<int, iox2::NotifierNotifyError>(const int value) noexcept ->
switch (error) {
case iox2_notifier_notify_error_e_EVENT_ID_OUT_OF_BOUNDS:
return iox2::NotifierNotifyError::EventIdOutOfBounds;
case iox2_notifier_notify_error_e_MISSED_DEADLINE:
return iox2::NotifierNotifyError::MissedDeadline;
case iox2_notifier_notify_error_e_UNABLE_TO_ACQUIRE_ELAPSED_TIME:
return iox2::NotifierNotifyError::UnableToAcquireElapsedTime;
}

IOX_UNREACHABLE();
Expand All @@ -879,6 +883,10 @@ from<iox2::NotifierNotifyError, iox2_notifier_notify_error_e>(const iox2::Notifi
switch (value) {
case iox2::NotifierNotifyError::EventIdOutOfBounds:
return iox2_notifier_notify_error_e_EVENT_ID_OUT_OF_BOUNDS;
case iox2::NotifierNotifyError::MissedDeadline:
return iox2_notifier_notify_error_e_MISSED_DEADLINE;
case iox2::NotifierNotifyError::UnableToAcquireElapsedTime:
return iox2_notifier_notify_error_e_UNABLE_TO_ACQUIRE_ELAPSED_TIME;
}

IOX_UNREACHABLE();
Expand Down
7 changes: 7 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/notifier_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ enum class NotifierNotifyError : uint8_t {
/// is greater than the maximum supported [`EventId`] by the
/// [`Service`]
EventIdOutOfBounds,
/// The notification was delivered to all [`Listener`] ports
/// but the deadline contract, the maximum time span between two notifications, of the
/// [`Service`] was violated.
MissedDeadline,
/// The notification was delivered but the elapsed system time could not be acquired.
/// Therefore, it is unknown if the deadline was missed or not.
UnableToAcquireElapsedTime,
};

} // namespace iox2
Expand Down
99 changes: 99 additions & 0 deletions iceoryx2-ffi/cxx/tests/src/service_event_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,4 +470,103 @@ TYPED_TEST(ServiceEventTest, open_fails_when_attributes_are_incompatible) {
ASSERT_THAT(service_open.error(), Eq(EventOpenError::IncompatibleAttributes));
}

TYPED_TEST(ServiceEventTest, deadline_can_be_set) {
constexpr iox::units::Duration DEADLINE = iox::units::Duration::fromMilliseconds(9281);
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;
const auto service_name = iox2_testing::generate_service_name();
Config config;
config.defaults().event().set_deadline(iox::nullopt);
auto node = NodeBuilder().config(config).create<SERVICE_TYPE>().expect("");

auto service_create = node.service_builder(service_name).event().deadline(DEADLINE).create().expect("");
auto listener_create = service_create.listener_builder().create().expect("");
auto notifier_create = service_create.notifier_builder().create().expect("");

auto service_open = node.service_builder(service_name).event().open().expect("");
auto listener_open = service_open.listener_builder().create().expect("");
auto notifier_open = service_open.notifier_builder().create().expect("");

ASSERT_THAT(service_create.static_config().deadline(), Eq(iox::optional(DEADLINE)));
ASSERT_THAT(service_open.static_config().deadline(), Eq(iox::optional(DEADLINE)));
ASSERT_THAT(listener_create.deadline(), Eq(iox::optional(DEADLINE)));
ASSERT_THAT(listener_open.deadline(), Eq(iox::optional(DEADLINE)));
ASSERT_THAT(notifier_create.deadline(), Eq(iox::optional(DEADLINE)));
ASSERT_THAT(notifier_open.deadline(), Eq(iox::optional(DEADLINE)));
}

TYPED_TEST(ServiceEventTest, deadline_can_be_disabled) {
constexpr iox::units::Duration DEADLINE = iox::units::Duration::fromMilliseconds(9281);
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;
const auto service_name = iox2_testing::generate_service_name();
Config config;
config.defaults().event().set_deadline(iox::optional(DEADLINE));
auto node = NodeBuilder().config(config).create<SERVICE_TYPE>().expect("");

auto service_create = node.service_builder(service_name).event().disable_deadline().create().expect("");
auto listener_create = service_create.listener_builder().create().expect("");
auto notifier_create = service_create.notifier_builder().create().expect("");

auto service_open = node.service_builder(service_name).event().open().expect("");
auto listener_open = service_open.listener_builder().create().expect("");
auto notifier_open = service_open.notifier_builder().create().expect("");

ASSERT_THAT(service_create.static_config().deadline(), Eq(iox::nullopt));
ASSERT_THAT(service_open.static_config().deadline(), Eq(iox::nullopt));
ASSERT_THAT(listener_create.deadline(), Eq(iox::nullopt));
ASSERT_THAT(listener_open.deadline(), Eq(iox::nullopt));
ASSERT_THAT(notifier_create.deadline(), Eq(iox::nullopt));
ASSERT_THAT(notifier_open.deadline(), Eq(iox::nullopt));
}

TYPED_TEST(ServiceEventTest, notifier_is_informed_when_deadline_was_missed) {
constexpr iox::units::Duration DEADLINE = iox::units::Duration::fromNanoseconds(1);
constexpr uint64_t TIMEOUT = 10;
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;
const auto service_name = iox2_testing::generate_service_name();
auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");

auto service_create = node.service_builder(service_name).event().deadline(DEADLINE).create().expect("");
auto listener = service_create.listener_builder().create().expect("");
auto notifier_create = service_create.notifier_builder().create().expect("");

auto service_open = node.service_builder(service_name).event().open().expect("");
auto notifier_open = service_open.notifier_builder().create().expect("");

std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT));
auto result = notifier_create.notify();
ASSERT_THAT(result.has_value(), Eq(false));
ASSERT_THAT(result.error(), Eq(NotifierNotifyError::MissedDeadline));
ASSERT_THAT(listener.try_wait_one().expect("").has_value(), Eq(true));

std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT));
result = notifier_open.notify();
ASSERT_THAT(result.has_value(), Eq(false));
ASSERT_THAT(result.error(), Eq(NotifierNotifyError::MissedDeadline));
ASSERT_THAT(listener.try_wait_one().expect("").has_value(), Eq(true));
}

TYPED_TEST(ServiceEventTest, when_deadline_is_not_missed_notification_works) {
constexpr iox::units::Duration DEADLINE = iox::units::Duration::fromSeconds(3600);
constexpr uint64_t TIMEOUT = 10;
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;
const auto service_name = iox2_testing::generate_service_name();
auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");

auto service_create = node.service_builder(service_name).event().deadline(DEADLINE).create().expect("");
auto listener = service_create.listener_builder().create().expect("");
auto notifier_create = service_create.notifier_builder().create().expect("");

auto service_open = node.service_builder(service_name).event().open().expect("");
auto notifier_open = service_open.notifier_builder().create().expect("");

std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT));
auto result = notifier_create.notify();
ASSERT_THAT(result.has_value(), Eq(true));
ASSERT_THAT(listener.try_wait_one().expect("").has_value(), Eq(true));

std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT));
result = notifier_open.notify();
ASSERT_THAT(result.has_value(), Eq(true));
ASSERT_THAT(listener.try_wait_one().expect("").has_value(), Eq(true));
}
} // namespace
30 changes: 30 additions & 0 deletions iceoryx2/tests/service_event_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,36 @@ mod service_event {
assert_that!(listener.try_wait_one().unwrap(), is_some);
}

#[test]
fn when_deadline_is_not_missed_notification_works<S: Service>() {
const DEADLINE: Duration = Duration::from_secs(3600);
const TIMEOUT: Duration = Duration::from_millis(10);
let service_name = generate_name();
let config = generate_isolated_config();
let node = NodeBuilder::new().config(&config).create::<S>().unwrap();

let sut_create = node
.service_builder(&service_name)
.event()
.deadline(DEADLINE)
.create()
.unwrap();

let listener = sut_create.listener_builder().create().unwrap();
let notifier_create = sut_create.notifier_builder().create().unwrap();

let sut_open = node.service_builder(&service_name).event().open().unwrap();
let notifier_open = sut_open.notifier_builder().create().unwrap();

std::thread::sleep(TIMEOUT);
assert_that!(notifier_create.notify(), is_ok);
assert_that!(listener.try_wait_one().unwrap(), is_some);

std::thread::sleep(TIMEOUT);
assert_that!(notifier_open.notify(), is_ok);
assert_that!(listener.try_wait_one().unwrap(), is_some);
}

#[instantiate_tests(<iceoryx2::service::ipc::Service>)]
mod ipc {}

Expand Down

0 comments on commit 246de57

Please sign in to comment.