From 7701a535b9154d6a7c97041edef5ae4b37bc8291 Mon Sep 17 00:00:00 2001 From: Arseniy Obolenskiy Date: Wed, 3 Jun 2026 19:35:32 +0200 Subject: [PATCH 1/3] Restore example backend test filtering --- scripts/run_tests.py | 11 ++++++- .../processes/t1/tests/functional/main.cpp | 21 ++++++++++-- .../processes/t2/tests/functional/main.cpp | 21 ++++++++++-- .../processes/t3/tests/functional/main.cpp | 21 ++++++++++-- .../example/threads/tests/functional/main.cpp | 33 +++++++++++++++++-- 5 files changed, 98 insertions(+), 9 deletions(-) diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 482b3011..7c713f8b 100755 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -198,12 +198,21 @@ def __build_mpi_cmd(self, ppc_num_proc, additional_mpi_args): @staticmethod def __get_gtest_settings(repeats_count, type_task): + type_task_patterns = { + "_all_": ["_all_", "AllEnabled"], + "_mpi_": ["_mpi_", "MpiEnabled"], + "_omp_": ["_omp_", "OmpEnabled"], + "_seq_": ["_seq_", "SeqEnabled"], + "_stl_": ["_stl_", "StlEnabled"], + "_tbb_": ["_tbb_", "TbbEnabled"], + } + filter_patterns = type_task_patterns.get(type_task, [type_task]) command = [ f"--gtest_repeat={repeats_count}", "--gtest_recreate_environments_when_repeating", "--gtest_color=0", "--gtest_shuffle", - f"--gtest_filter=*{type_task}*", + "--gtest_filter=" + ":".join(f"*{pattern}*" for pattern in filter_patterns), ] return command diff --git a/tasks/example/processes/t1/tests/functional/main.cpp b/tasks/example/processes/t1/tests/functional/main.cpp index 1c32faa9..cc1ffa75 100644 --- a/tasks/example/processes/t1/tests/functional/main.cpp +++ b/tasks/example/processes/t1/tests/functional/main.cpp @@ -38,6 +38,19 @@ class NesterovARunFuncTestsProcesses : public ppc::util::BaseRunFuncTests(ppc::util::GTestParamIndex::kNameTest)>(test_param); + if (test_name.contains(task_tag)) { + RunTestCase(test_param); + } + }; + (run_if_tagged(test_params), ...); + }, test_tasks_list); + } + void SetInputData() { int width = -1; int height = -1; @@ -83,8 +96,12 @@ const auto kTestTasksList = std::tuple_cat( } // namespace -TEST_F(NesterovARunFuncTestsProcesses, MatmulFromPic) { - std::apply([this](const auto &...test_params) { (RunTestCase(test_params), ...); }, kTestTasksList); +TEST_F(NesterovARunFuncTestsProcesses, MatmulFromPicMpiEnabled) { + RunTestCasesWithTag(kTestTasksList, "_mpi_"); +} + +TEST_F(NesterovARunFuncTestsProcesses, MatmulFromPicSeqEnabled) { + RunTestCasesWithTag(kTestTasksList, "_seq_"); } } // namespace example_processes_t1 diff --git a/tasks/example/processes/t2/tests/functional/main.cpp b/tasks/example/processes/t2/tests/functional/main.cpp index 0ea55456..2470be49 100644 --- a/tasks/example/processes/t2/tests/functional/main.cpp +++ b/tasks/example/processes/t2/tests/functional/main.cpp @@ -38,6 +38,19 @@ class NesterovARunFuncTestsProcesses2 : public ppc::util::BaseRunFuncTests(ppc::util::GTestParamIndex::kNameTest)>(test_param); + if (test_name.contains(task_tag)) { + RunTestCase(test_param); + } + }; + (run_if_tagged(test_params), ...); + }, test_tasks_list); + } + void SetInputData() { int width = -1; int height = -1; @@ -83,8 +96,12 @@ const auto kTestTasksList = std::tuple_cat( } // namespace -TEST_F(NesterovARunFuncTestsProcesses2, MatmulFromPic) { - std::apply([this](const auto &...test_params) { (RunTestCase(test_params), ...); }, kTestTasksList); +TEST_F(NesterovARunFuncTestsProcesses2, MatmulFromPicMpiEnabled) { + RunTestCasesWithTag(kTestTasksList, "_mpi_"); +} + +TEST_F(NesterovARunFuncTestsProcesses2, MatmulFromPicSeqEnabled) { + RunTestCasesWithTag(kTestTasksList, "_seq_"); } } // namespace example_processes_t2 diff --git a/tasks/example/processes/t3/tests/functional/main.cpp b/tasks/example/processes/t3/tests/functional/main.cpp index 02672a54..28d6ba73 100644 --- a/tasks/example/processes/t3/tests/functional/main.cpp +++ b/tasks/example/processes/t3/tests/functional/main.cpp @@ -38,6 +38,19 @@ class NesterovARunFuncTestsProcesses3 : public ppc::util::BaseRunFuncTests(ppc::util::GTestParamIndex::kNameTest)>(test_param); + if (test_name.contains(task_tag)) { + RunTestCase(test_param); + } + }; + (run_if_tagged(test_params), ...); + }, test_tasks_list); + } + void SetInputData() { int width = -1; int height = -1; @@ -83,8 +96,12 @@ const auto kTestTasksList = std::tuple_cat( } // namespace -TEST_F(NesterovARunFuncTestsProcesses3, MatmulFromPic) { - std::apply([this](const auto &...test_params) { (RunTestCase(test_params), ...); }, kTestTasksList); +TEST_F(NesterovARunFuncTestsProcesses3, MatmulFromPicMpiEnabled) { + RunTestCasesWithTag(kTestTasksList, "_mpi_"); +} + +TEST_F(NesterovARunFuncTestsProcesses3, MatmulFromPicSeqEnabled) { + RunTestCasesWithTag(kTestTasksList, "_seq_"); } } // namespace example_processes_t3 diff --git a/tasks/example/threads/tests/functional/main.cpp b/tasks/example/threads/tests/functional/main.cpp index 1ae1ff42..83cc3afb 100644 --- a/tasks/example/threads/tests/functional/main.cpp +++ b/tasks/example/threads/tests/functional/main.cpp @@ -41,6 +41,19 @@ class NesterovARunFuncTestsThreads : public ppc::util::BaseRunFuncTests(ppc::util::GTestParamIndex::kNameTest)>(test_param); + if (test_name.contains(task_tag)) { + RunTestCase(test_param); + } + }; + (run_if_tagged(test_params), ...); + }, test_tasks_list); + } + void SetInputData() { int width = -1; int height = -1; @@ -89,8 +102,24 @@ const auto kTestTasksList = } // namespace -TEST_F(NesterovARunFuncTestsThreads, MatmulFromPic) { - std::apply([this](const auto &...test_params) { (RunTestCase(test_params), ...); }, kTestTasksList); +TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicAllEnabled) { + RunTestCasesWithTag(kTestTasksList, "_all_"); +} + +TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicOmpEnabled) { + RunTestCasesWithTag(kTestTasksList, "_omp_"); +} + +TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicSeqEnabled) { + RunTestCasesWithTag(kTestTasksList, "_seq_"); +} + +TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicStlEnabled) { + RunTestCasesWithTag(kTestTasksList, "_stl_"); +} + +TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicTbbEnabled) { + RunTestCasesWithTag(kTestTasksList, "_tbb_"); } } // namespace example_threads From dd8e538920ee25a17a1f61dd206743b8372e627a Mon Sep 17 00:00:00 2001 From: Arseniy Obolenskiy Date: Wed, 3 Jun 2026 20:05:50 +0200 Subject: [PATCH 2/3] Address comments --- modules/util/include/func_test_util.hpp | 50 +++++++++++++++++++ modules/util/tests/util.cpp | 48 ++++++++++++++++++ .../processes/t1/tests/functional/main.cpp | 19 ++----- .../processes/t2/tests/functional/main.cpp | 19 ++----- .../processes/t3/tests/functional/main.cpp | 19 ++----- .../example/threads/tests/functional/main.cpp | 25 +++------- 6 files changed, 113 insertions(+), 67 deletions(-) diff --git a/modules/util/include/func_test_util.hpp b/modules/util/include/func_test_util.hpp index 6af48e4c..cc4965f4 100644 --- a/modules/util/include/func_test_util.hpp +++ b/modules/util/include/func_test_util.hpp @@ -29,6 +29,9 @@ concept HasPrintTestParam = requires(TestType value) { { T::PrintTestParam(value) } -> std::same_as; }; +template +void RunTestCasesWithTag(const TestTasksList &test_tasks_list, std::string_view task_tag, RunTestCase run_test_case); + template /// @brief Base class for running functional tests on parallel tasks. /// @tparam InType Type of input data. @@ -56,6 +59,16 @@ class BaseRunFuncTests : public ::testing::TestWithParam &test_param) { + ExecuteTest(test_param); + } + + template + void RunTestCasesWithTag(const TestTasksList &test_tasks_list, std::string_view task_tag) { + ppc::util::RunTestCasesWithTag(test_tasks_list, task_tag, + [this](const auto &test_param) { RunTestCase(test_param); }); + } + void ExecuteTest(FuncTestParam test_param) { const std::string &test_name = std::get(GTestParamIndex::kNameTest)>(test_param); @@ -120,6 +133,43 @@ class BaseRunFuncTests : public ::testing::TestWithParam task_; }; +namespace detail { + +[[nodiscard]] inline std::string MakeFuncTestTaskTagPattern(std::string_view task_tag) { + std::string tag_pattern{task_tag}; + if (!tag_pattern.starts_with('_')) { + tag_pattern.insert(0, 1, '_'); + } + if (!tag_pattern.ends_with('_')) { + tag_pattern.push_back('_'); + } + return tag_pattern; +} + +} // namespace detail + +template +void RunTestCasesWithTag(const TestTasksList &test_tasks_list, std::string_view task_tag, RunTestCase run_test_case) { + if (task_tag.empty()) { + ADD_FAILURE() << "Functional test task tag must not be empty"; + return; + } + + const std::string task_tag_pattern = detail::MakeFuncTestTaskTagPattern(task_tag); + bool has_matching_task = false; + std::apply([&](const auto &...test_params) { + auto run_if_tagged = [&](const auto &test_param) { + const std::string &test_name = std::get(GTestParamIndex::kNameTest)>(test_param); + if (test_name.contains(task_tag_pattern)) { + has_matching_task = true; + std::invoke(run_test_case, test_param); + } + }; + (run_if_tagged(test_params), ...); + }, test_tasks_list); + EXPECT_TRUE(has_matching_task) << "No functional test cases matched tag: " << std::string(task_tag); +} + template auto ExpandToValuesImpl(const Tuple &t, std::index_sequence /*unused*/) { return ::testing::Values(std::get(t)...); diff --git a/modules/util/tests/util.cpp b/modules/util/tests/util.cpp index 6da563a9..d7403851 100644 --- a/modules/util/tests/util.cpp +++ b/modules/util/tests/util.cpp @@ -1,12 +1,17 @@ #include "util/include/util.hpp" +#include #include +#include #include #include #include +#include +#include #include "omp.h" +#include "util/include/func_test_util.hpp" namespace my::nested { struct Type {}; @@ -124,3 +129,46 @@ TEST(GetNumProc, ReadsFromEnvironment) { env::detail::set_scoped_environment_variable scoped("PPC_NUM_PROC", "4"); EXPECT_EQ(ppc::util::GetNumProc(), 4); } + +namespace { + +using FuncTestUtilParam = ppc::util::FuncTestParam; + +FuncTestUtilParam MakeFuncTestUtilParam(const std::string &test_name, int value) { + return FuncTestUtilParam{[](int) -> ppc::task::TaskPtr { return {}; }, test_name, value}; +} + +} // namespace + +TEST(FuncTestUtil, RunTestCasesWithTagAcceptsBareTags) { + const auto test_tasks = std::make_tuple(MakeFuncTestUtilParam("example_threads_seq_enabled", 1), + MakeFuncTestUtilParam("example_threads_tbb_enabled", 2), + MakeFuncTestUtilParam("example_threads_tbb_disabled", 3)); + + std::vector visited_params; + ppc::util::RunTestCasesWithTag(test_tasks, "tbb", [&](const auto &test_param) { + visited_params.push_back(std::get(ppc::util::GTestParamIndex::kTestParams)>(test_param)); + }); + + ASSERT_EQ(visited_params.size(), std::size_t{2}); + EXPECT_EQ(visited_params[0], 2); + EXPECT_EQ(visited_params[1], 3); +} + +TEST(FuncTestUtil, RunTestCasesWithTagFailsWhenTagIsMissing) { + const auto test_tasks = std::make_tuple(MakeFuncTestUtilParam("example_threads_seq_enabled", 1)); + + bool callback_was_called = false; + ::testing::TestPartResultArray failures; + { + ::testing::ScopedFakeTestPartResultReporter reporter( + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, &failures); + ppc::util::RunTestCasesWithTag(test_tasks, "omp", [&](const auto & /*test_param*/) { callback_was_called = true; }); + } + + ASSERT_EQ(failures.size(), 1); + EXPECT_EQ(failures.GetTestPartResult(0).type(), ::testing::TestPartResult::kNonFatalFailure); + EXPECT_NE(std::string(failures.GetTestPartResult(0).message()).find("No functional test cases matched tag: omp"), + std::string::npos); + EXPECT_FALSE(callback_was_called); +} diff --git a/tasks/example/processes/t1/tests/functional/main.cpp b/tasks/example/processes/t1/tests/functional/main.cpp index cc1ffa75..50b8c77d 100644 --- a/tasks/example/processes/t1/tests/functional/main.cpp +++ b/tasks/example/processes/t1/tests/functional/main.cpp @@ -27,7 +27,7 @@ class NesterovARunFuncTestsProcesses : public ppc::util::BaseRunFuncTests &test_param) { + void RunTestCase(const ppc::util::FuncTestParam &test_param) override { const std::string &test_name = std::get(ppc::util::GTestParamIndex::kNameTest)>(test_param); if (IsTestDisabled(test_name) || ShouldSkipNonMpiTask(test_name)) { @@ -38,19 +38,6 @@ class NesterovARunFuncTestsProcesses : public ppc::util::BaseRunFuncTests(ppc::util::GTestParamIndex::kNameTest)>(test_param); - if (test_name.contains(task_tag)) { - RunTestCase(test_param); - } - }; - (run_if_tagged(test_params), ...); - }, test_tasks_list); - } - void SetInputData() { int width = -1; int height = -1; @@ -97,11 +84,11 @@ const auto kTestTasksList = std::tuple_cat( } // namespace TEST_F(NesterovARunFuncTestsProcesses, MatmulFromPicMpiEnabled) { - RunTestCasesWithTag(kTestTasksList, "_mpi_"); + RunTestCasesWithTag(kTestTasksList, "mpi"); } TEST_F(NesterovARunFuncTestsProcesses, MatmulFromPicSeqEnabled) { - RunTestCasesWithTag(kTestTasksList, "_seq_"); + RunTestCasesWithTag(kTestTasksList, "seq"); } } // namespace example_processes_t1 diff --git a/tasks/example/processes/t2/tests/functional/main.cpp b/tasks/example/processes/t2/tests/functional/main.cpp index 2470be49..6e60e0f5 100644 --- a/tasks/example/processes/t2/tests/functional/main.cpp +++ b/tasks/example/processes/t2/tests/functional/main.cpp @@ -27,7 +27,7 @@ class NesterovARunFuncTestsProcesses2 : public ppc::util::BaseRunFuncTests &test_param) { + void RunTestCase(const ppc::util::FuncTestParam &test_param) override { const std::string &test_name = std::get(ppc::util::GTestParamIndex::kNameTest)>(test_param); if (IsTestDisabled(test_name) || ShouldSkipNonMpiTask(test_name)) { @@ -38,19 +38,6 @@ class NesterovARunFuncTestsProcesses2 : public ppc::util::BaseRunFuncTests(ppc::util::GTestParamIndex::kNameTest)>(test_param); - if (test_name.contains(task_tag)) { - RunTestCase(test_param); - } - }; - (run_if_tagged(test_params), ...); - }, test_tasks_list); - } - void SetInputData() { int width = -1; int height = -1; @@ -97,11 +84,11 @@ const auto kTestTasksList = std::tuple_cat( } // namespace TEST_F(NesterovARunFuncTestsProcesses2, MatmulFromPicMpiEnabled) { - RunTestCasesWithTag(kTestTasksList, "_mpi_"); + RunTestCasesWithTag(kTestTasksList, "mpi"); } TEST_F(NesterovARunFuncTestsProcesses2, MatmulFromPicSeqEnabled) { - RunTestCasesWithTag(kTestTasksList, "_seq_"); + RunTestCasesWithTag(kTestTasksList, "seq"); } } // namespace example_processes_t2 diff --git a/tasks/example/processes/t3/tests/functional/main.cpp b/tasks/example/processes/t3/tests/functional/main.cpp index 28d6ba73..57bd3ebc 100644 --- a/tasks/example/processes/t3/tests/functional/main.cpp +++ b/tasks/example/processes/t3/tests/functional/main.cpp @@ -27,7 +27,7 @@ class NesterovARunFuncTestsProcesses3 : public ppc::util::BaseRunFuncTests &test_param) { + void RunTestCase(const ppc::util::FuncTestParam &test_param) override { const std::string &test_name = std::get(ppc::util::GTestParamIndex::kNameTest)>(test_param); if (IsTestDisabled(test_name) || ShouldSkipNonMpiTask(test_name)) { @@ -38,19 +38,6 @@ class NesterovARunFuncTestsProcesses3 : public ppc::util::BaseRunFuncTests(ppc::util::GTestParamIndex::kNameTest)>(test_param); - if (test_name.contains(task_tag)) { - RunTestCase(test_param); - } - }; - (run_if_tagged(test_params), ...); - }, test_tasks_list); - } - void SetInputData() { int width = -1; int height = -1; @@ -97,11 +84,11 @@ const auto kTestTasksList = std::tuple_cat( } // namespace TEST_F(NesterovARunFuncTestsProcesses3, MatmulFromPicMpiEnabled) { - RunTestCasesWithTag(kTestTasksList, "_mpi_"); + RunTestCasesWithTag(kTestTasksList, "mpi"); } TEST_F(NesterovARunFuncTestsProcesses3, MatmulFromPicSeqEnabled) { - RunTestCasesWithTag(kTestTasksList, "_seq_"); + RunTestCasesWithTag(kTestTasksList, "seq"); } } // namespace example_processes_t3 diff --git a/tasks/example/threads/tests/functional/main.cpp b/tasks/example/threads/tests/functional/main.cpp index 83cc3afb..ff70a999 100644 --- a/tasks/example/threads/tests/functional/main.cpp +++ b/tasks/example/threads/tests/functional/main.cpp @@ -30,7 +30,7 @@ class NesterovARunFuncTestsThreads : public ppc::util::BaseRunFuncTests &test_param) { + void RunTestCase(const ppc::util::FuncTestParam &test_param) override { const std::string &test_name = std::get(ppc::util::GTestParamIndex::kNameTest)>(test_param); if (IsTestDisabled(test_name) || ShouldSkipNonMpiTask(test_name)) { @@ -41,19 +41,6 @@ class NesterovARunFuncTestsThreads : public ppc::util::BaseRunFuncTests(ppc::util::GTestParamIndex::kNameTest)>(test_param); - if (test_name.contains(task_tag)) { - RunTestCase(test_param); - } - }; - (run_if_tagged(test_params), ...); - }, test_tasks_list); - } - void SetInputData() { int width = -1; int height = -1; @@ -103,23 +90,23 @@ const auto kTestTasksList = } // namespace TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicAllEnabled) { - RunTestCasesWithTag(kTestTasksList, "_all_"); + RunTestCasesWithTag(kTestTasksList, "all"); } TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicOmpEnabled) { - RunTestCasesWithTag(kTestTasksList, "_omp_"); + RunTestCasesWithTag(kTestTasksList, "omp"); } TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicSeqEnabled) { - RunTestCasesWithTag(kTestTasksList, "_seq_"); + RunTestCasesWithTag(kTestTasksList, "seq"); } TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicStlEnabled) { - RunTestCasesWithTag(kTestTasksList, "_stl_"); + RunTestCasesWithTag(kTestTasksList, "stl"); } TEST_F(NesterovARunFuncTestsThreads, MatmulFromPicTbbEnabled) { - RunTestCasesWithTag(kTestTasksList, "_tbb_"); + RunTestCasesWithTag(kTestTasksList, "tbb"); } } // namespace example_threads From 5e3e13b6929bfe97e206f143e125eeae22365e7e Mon Sep 17 00:00:00 2001 From: Arseniy Obolenskiy Date: Wed, 3 Jun 2026 21:37:31 +0200 Subject: [PATCH 3/3] tidy --- modules/util/tests/util.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/util/tests/util.cpp b/modules/util/tests/util.cpp index d7403851..088ec37f 100644 --- a/modules/util/tests/util.cpp +++ b/modules/util/tests/util.cpp @@ -7,10 +7,12 @@ #include #include #include +#include #include #include #include "omp.h" +#include "task/include/task.hpp" #include "util/include/func_test_util.hpp" namespace my::nested { @@ -138,6 +140,13 @@ FuncTestUtilParam MakeFuncTestUtilParam(const std::string &test_name, int value) return FuncTestUtilParam{[](int) -> ppc::task::TaskPtr { return {}; }, test_name, value}; } +void ExpectSingleNonFatalFailureContains(const ::testing::TestPartResultArray &failures, std::string_view message) { + ASSERT_EQ(failures.size(), 1); + const ::testing::TestPartResult &failure = failures.GetTestPartResult(0); + EXPECT_EQ(failure.type(), ::testing::TestPartResult::kNonFatalFailure); + EXPECT_NE(std::string_view(failure.message()).find(message), std::string_view::npos); +} + } // namespace TEST(FuncTestUtil, RunTestCasesWithTagAcceptsBareTags) { @@ -150,9 +159,8 @@ TEST(FuncTestUtil, RunTestCasesWithTagAcceptsBareTags) { visited_params.push_back(std::get(ppc::util::GTestParamIndex::kTestParams)>(test_param)); }); - ASSERT_EQ(visited_params.size(), std::size_t{2}); - EXPECT_EQ(visited_params[0], 2); - EXPECT_EQ(visited_params[1], 3); + const std::vector expected_params{2, 3}; + EXPECT_EQ(visited_params, expected_params); } TEST(FuncTestUtil, RunTestCasesWithTagFailsWhenTagIsMissing) { @@ -166,9 +174,6 @@ TEST(FuncTestUtil, RunTestCasesWithTagFailsWhenTagIsMissing) { ppc::util::RunTestCasesWithTag(test_tasks, "omp", [&](const auto & /*test_param*/) { callback_was_called = true; }); } - ASSERT_EQ(failures.size(), 1); - EXPECT_EQ(failures.GetTestPartResult(0).type(), ::testing::TestPartResult::kNonFatalFailure); - EXPECT_NE(std::string(failures.GetTestPartResult(0).message()).find("No functional test cases matched tag: omp"), - std::string::npos); + ExpectSingleNonFatalFailureContains(failures, "No functional test cases matched tag: omp"); EXPECT_FALSE(callback_was_called); }