From 076052c8d0c9c5ad451601280c76661b6b7af09d Mon Sep 17 00:00:00 2001 From: Tim Niklas Uhl Date: Mon, 24 Jul 2023 13:01:14 +0200 Subject: [PATCH] Testing. --- include/kamping/result.hpp | 3 +- tests/CMakeLists.txt | 1 + tests/nonblocking_result_test.cpp | 189 ++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 tests/nonblocking_result_test.cpp diff --git a/include/kamping/result.hpp b/include/kamping/result.hpp index 934f293ef..69330e76b 100644 --- a/include/kamping/result.hpp +++ b/include/kamping/result.hpp @@ -271,7 +271,8 @@ class NonBlockingResult { /// result. auto extract() { if constexpr (owns_request) { - return std::make_tuple(_request.extract(), extract_result()); + auto result = extract_result(); // we try to extract the result first, so that we get a nice error message + return std::make_tuple(_request.extract(), std::move(result)); } else { return extract_result(); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5bbf4fc5d..502ed8563 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,6 +22,7 @@ option(KAMPING_TEST_ENABLE_SANITIZERS "Enable undefined behavior sanitizer and a # Registering tests without MPI: kamping_register_test(test_checking_casts FILES checking_casts_test.cpp) kamping_register_test(test_result FILES result_test.cpp) +kamping_register_test(test_nonblocking_result FILES nonblocking_result_test.cpp) kamping_register_test(test_mpi_operations FILES mpi_operations_test.cpp) kamping_register_test(test_named_parameter_check FILES named_parameter_check_test.cpp) kamping_register_test(test_named_parameter_selection FILES named_parameter_selection_test.cpp) diff --git a/tests/nonblocking_result_test.cpp b/tests/nonblocking_result_test.cpp new file mode 100644 index 000000000..a1e1c47f5 --- /dev/null +++ b/tests/nonblocking_result_test.cpp @@ -0,0 +1,189 @@ +// This file is part of KaMPIng. +// +// Copyright 2023 The KaMPIng Authors +// +// KaMPIng is free software : you can redistribute it and/or modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +// version. KaMPIng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License along with KaMPIng. If not, see +// . + +#include +#include + +#include "helpers_for_testing.hpp" +#include "kamping/named_parameters.hpp" +#include "kamping/result.hpp" + +using namespace kamping; + +static bool test_succeed = false; + +KAMPING_MAKE_HAS_MEMBER(wait) +KAMPING_MAKE_HAS_MEMBER(test) + +int MPI_Wait(MPI_Request*, MPI_Status*) { + return MPI_SUCCESS; +} + +int MPI_Test(MPI_Request*, int* flag, MPI_Status*) { + *flag = test_succeed; + return MPI_SUCCESS; +} + +class NonBlockingResultTest : public ::testing::Test { + void SetUp() override { + test_succeed = false; + } + void TearDown() override { + test_succeed = false; + } +}; + +TEST_F(NonBlockingResultTest, owning_request_and_result_types_match) { + auto recv_buf_obj = recv_buf(alloc_new>); + using expected_result_type = MPIResult< + internal::ResultCategoryNotUsed, + decltype(recv_buf_obj), + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed>; + auto request_obj = request(); + auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj)); + + EXPECT_TRUE(has_member_test_v); + using test_return_type = decltype(result.test()); + EXPECT_TRUE((internal::is_specialization::value)); + EXPECT_TRUE((std::is_same_v)); + + EXPECT_TRUE(has_member_wait_v); + using wait_return_type = decltype(result.wait()); + EXPECT_TRUE((std::is_same_v)); +} + +TEST_F(NonBlockingResultTest, owning_request_and_result_wait_works) { + auto recv_buf_obj = recv_buf(alloc_new>); + recv_buf_obj.underlying().push_back(42); + recv_buf_obj.underlying().push_back(43); + recv_buf_obj.underlying().push_back(44); + auto request_obj = request(); + auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj)); + auto data = result.wait().extract_recv_buffer(); + auto expected_data = std::vector{42, 43, 44}; + EXPECT_EQ(data, expected_data); + EXPECT_KASSERT_FAILS(result.extract(), "The result of this request has already been extracted."); +} + +TEST_F(NonBlockingResultTest, owning_request_and_result_test_works) { + auto recv_buf_obj = recv_buf(alloc_new>); + recv_buf_obj.underlying().push_back(42); + recv_buf_obj.underlying().push_back(43); + recv_buf_obj.underlying().push_back(44); + auto request_obj = request(); + auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj)); + test_succeed = false; + EXPECT_FALSE(result.test().has_value()); + test_succeed = true; + auto data = result.test(); + EXPECT_TRUE(data.has_value()); + auto expected_data = std::vector{42, 43, 44}; + EXPECT_EQ(data.value().extract_recv_buffer(), expected_data); +} + +TEST_F(NonBlockingResultTest, owning_request_and_result_extract_works) { + auto recv_buf_obj = recv_buf(alloc_new>); + using expected_result_type = MPIResult< + internal::ResultCategoryNotUsed, + decltype(recv_buf_obj), + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed>; + recv_buf_obj.underlying().push_back(42); + recv_buf_obj.underlying().push_back(43); + recv_buf_obj.underlying().push_back(44); + auto request_obj = request(); + auto nonblocking_result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj)); + auto [req, result] = nonblocking_result.extract(); + EXPECT_TRUE((std::is_same_v)); + EXPECT_TRUE((std::is_same_v)); + + auto expected_data = std::vector{42, 43, 44}; + EXPECT_EQ(result.extract_recv_buffer(), expected_data); + EXPECT_KASSERT_FAILS(nonblocking_result.extract(), "The result of this request has already been extracted."); +} + +TEST_F(NonBlockingResultTest, owning_request_and_empty_result_types_match) { + auto request_obj = request(); + auto result = kamping::make_nonblocking_result(std::move(request_obj)); + EXPECT_TRUE(has_member_test_v); + using test_return_type = decltype(result.test()); + EXPECT_TRUE((std::is_same_v)); + EXPECT_TRUE(has_member_wait_v); + using wait_return_type = decltype(result.wait()); + EXPECT_TRUE((std::is_same_v)); +} + +TEST_F(NonBlockingResultTest, owning_request_and_empty_result_test_works) { + auto request_obj = request(); + auto result = kamping::make_nonblocking_result(std::move(request_obj)); + test_succeed = false; + EXPECT_FALSE(result.test()); + test_succeed = true; + EXPECT_TRUE(result.test()); +} + +TEST_F(NonBlockingResultTest, owning_request_and_empty_result_extract_works) { + using expected_result_type = MPIResult< + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed>; + auto request_obj = request(); + auto nonblocking_result = kamping::make_nonblocking_result(std::move(request_obj)); + auto [req, result] = nonblocking_result.extract(); + EXPECT_TRUE((std::is_same_v)); + EXPECT_TRUE((std::is_same_v)); + + EXPECT_KASSERT_FAILS(nonblocking_result.extract(), "The result of this request has already been extracted."); +} + +TEST_F(NonBlockingResultTest, non_owning_request_and_result_types_match) { + auto recv_buf_obj = recv_buf(alloc_new>); + Request req; + auto request_obj = request(req); + auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj)); + EXPECT_FALSE(has_member_test_v) + << "The result does not own the request, so test() should not be available."; + EXPECT_FALSE(has_member_wait_v) + << "The result does not own the request, so wait() should not be available."; +} + +TEST_F(NonBlockingResultTest, non_owning_request_and_result_extract_works) { + auto recv_buf_obj = recv_buf(alloc_new>); + using expected_result_type = MPIResult< + internal::ResultCategoryNotUsed, + decltype(recv_buf_obj), + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed, + internal::ResultCategoryNotUsed>; + recv_buf_obj.underlying().push_back(42); + recv_buf_obj.underlying().push_back(43); + recv_buf_obj.underlying().push_back(44); + Request req; + auto request_obj = request(req); + auto nonblocking_result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj)); + auto result = nonblocking_result.extract(); + EXPECT_TRUE((std::is_same_v)); + + auto expected_data = std::vector{42, 43, 44}; + EXPECT_EQ(result.extract_recv_buffer(), expected_data); + EXPECT_KASSERT_FAILS(nonblocking_result.extract(), "The result of this request has already been extracted."); +}