From 4a7b40eb4caceeb844efa2967417a7ca6cc0a868 Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Sun, 28 Apr 2024 02:07:41 +0000 Subject: [PATCH 1/6] iouring: debug arm CI Signed-off-by: He Jie Xu --- test/common/io/BUILD | 13 +++---------- test/common/io/io_uring_impl_test.cc | 4 ++++ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/test/common/io/BUILD b/test/common/io/BUILD index c38687c1d6e6..2a51bf73c945 100644 --- a/test/common/io/BUILD +++ b/test/common/io/BUILD @@ -10,25 +10,18 @@ envoy_package() envoy_cc_test( name = "io_uring_impl_test", - srcs = select({ - "//bazel:linux_x86_64": ["io_uring_impl_test.cc"], - "//conditions:default": [], - }), + srcs = ["io_uring_impl_test.cc"], tags = [ "nocompdb", "skip_on_windows", ], deps = [ + "//source/common/io:io_uring_impl_lib", "//source/common/network:address_lib", "//test/mocks/io:io_mocks", "//test/test_common:environment_lib", "//test/test_common:utility_lib", - ] + select({ - "//bazel:linux": [ - "//source/common/io:io_uring_impl_lib", - ], - "//conditions:default": [], - }), + ], ) envoy_cc_test( diff --git a/test/common/io/io_uring_impl_test.cc b/test/common/io/io_uring_impl_test.cc index b357b60df93b..189dbe760bb7 100644 --- a/test/common/io/io_uring_impl_test.cc +++ b/test/common/io/io_uring_impl_test.cc @@ -337,6 +337,7 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { EXPECT_TRUE(user_data != nullptr); EXPECT_EQ(res, 2); completions_nr++; + ENVOY_LOG_MISC(info, "get uring request completion {}", completions_nr); // Note: generally events are not guaranteed to complete in the same order // we submit them, but for this case of reading from a single file it's ok // to expect the same order. @@ -361,6 +362,9 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); + while (completions_nr < 2) { + dispatcher->run(Event::Dispatcher::RunType::NonBlock); + } // Even though we haven't been notified about ops completion the buffers // are filled already. EXPECT_EQ(static_cast(iov1.iov_base)[0], 'a'); From 5d86e8975df1f76ac1cbd769bbc6a58773f07f99 Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Sun, 28 Apr 2024 04:04:26 +0000 Subject: [PATCH 2/6] fix format Signed-off-by: He Jie Xu --- test/common/io/io_uring_impl_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/common/io/io_uring_impl_test.cc b/test/common/io/io_uring_impl_test.cc index 189dbe760bb7..bf9440eecfbd 100644 --- a/test/common/io/io_uring_impl_test.cc +++ b/test/common/io/io_uring_impl_test.cc @@ -364,7 +364,7 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { while (completions_nr < 2) { dispatcher->run(Event::Dispatcher::RunType::NonBlock); - } + } // Even though we haven't been notified about ops completion the buffers // are filled already. EXPECT_EQ(static_cast(iov1.iov_base)[0], 'a'); From 676b34f451a14e5aa1ba252a2dbb951f3f7dc2df Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Sun, 28 Apr 2024 13:23:21 +0000 Subject: [PATCH 3/6] update Signed-off-by: He Jie Xu --- test/common/io/io_uring_impl_test.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/common/io/io_uring_impl_test.cc b/test/common/io/io_uring_impl_test.cc index bf9440eecfbd..491a715d8160 100644 --- a/test/common/io/io_uring_impl_test.cc +++ b/test/common/io/io_uring_impl_test.cc @@ -105,8 +105,9 @@ TEST_P(IoUringImplParamTest, InvalidParams) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - EXPECT_EQ(completions_nr, 2); + while (completions_nr < 2) { + dispatcher->run(Event::Dispatcher::RunType::NonBlock); + } } TEST_F(IoUringImplTest, InjectCompletion) { @@ -384,6 +385,10 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); + while (completions_nr < 3) { + dispatcher->run(Event::Dispatcher::RunType::NonBlock); + } + EXPECT_EQ(static_cast(iov3.iov_base)[0], 'e'); EXPECT_EQ(static_cast(iov3.iov_base)[1], 'f'); From 7bf78842f0043a466398368439d57915735edb6b Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Mon, 29 Apr 2024 13:37:38 +0000 Subject: [PATCH 4/6] fix all the tests Signed-off-by: He Jie Xu --- test/common/io/io_uring_impl_test.cc | 51 +++++++++++++--------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/test/common/io/io_uring_impl_test.cc b/test/common/io/io_uring_impl_test.cc index 491a715d8160..367663bb2a7d 100644 --- a/test/common/io/io_uring_impl_test.cc +++ b/test/common/io/io_uring_impl_test.cc @@ -1,3 +1,5 @@ +#include + #include "source/common/io/io_uring_impl.h" #include "source/common/network/address_impl.h" @@ -21,6 +23,8 @@ class TestRequest : public Request { MockIoUringSocket mock_io_uring_socket_; }; +using WaitConditionFunc = std::function; + class IoUringImplTest : public ::testing::Test { public: IoUringImplTest() : api_(Api::createApiForTest()), should_skip_(!isIoUringSupported()) { @@ -45,6 +49,17 @@ class IoUringImplTest : public ::testing::Test { } } + void waitForCondition(Event::Dispatcher& dispatcher, WaitConditionFunc condition_func, std::chrono::milliseconds wait_timeout = TestUtility::DefaultTimeout) { + Event::TestTimeSystem::RealTimeBound bound(wait_timeout); + while (!condition_func()) { + if (!bound.withinBound()) { + RELEASE_ASSERT(0, "Timed out waiting for the condition."); + break; + } + dispatcher.run(Event::Dispatcher::RunType::NonBlock); + } + } + Api::ApiPtr api_; IoUringPtr io_uring_{}; const bool should_skip_{}; @@ -105,9 +120,7 @@ TEST_P(IoUringImplParamTest, InvalidParams) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); - while (completions_nr < 2) { - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - } + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); } TEST_F(IoUringImplTest, InjectCompletion) { @@ -137,8 +150,7 @@ TEST_F(IoUringImplTest, InjectCompletion) { file_event->activate(Event::FileReadyType::Read); - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - EXPECT_EQ(completions_nr, 1); + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 1; }); } TEST_F(IoUringImplTest, NestInjectCompletion) { @@ -178,8 +190,7 @@ TEST_F(IoUringImplTest, NestInjectCompletion) { file_event->activate(Event::FileReadyType::Read); - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - EXPECT_EQ(completions_nr, 2); + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); } TEST_F(IoUringImplTest, RemoveInjectCompletion) { @@ -214,8 +225,7 @@ TEST_F(IoUringImplTest, RemoveInjectCompletion) { EXPECT_EQ(-1, data2); file_event->activate(Event::FileReadyType::Read); - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - EXPECT_EQ(completions_nr, 1); + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 1; }); } TEST_F(IoUringImplTest, NestRemoveInjectCompletion) { @@ -254,8 +264,7 @@ TEST_F(IoUringImplTest, NestRemoveInjectCompletion) { file_event->activate(Event::FileReadyType::Read); - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - EXPECT_EQ(completions_nr, 2); + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); } TEST_F(IoUringImplTest, RegisterEventfd) { @@ -299,10 +308,8 @@ TEST_F(IoUringImplTest, PrepareReadvAllDataFitsOneChunk) { EXPECT_STREQ(static_cast(iov.iov_base), ""); io_uring_->submit(); - dispatcher->run(Event::Dispatcher::RunType::Block); - // Check that the completion callback has been actually called. - EXPECT_EQ(completions_nr, 1); + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 1; }); // The file's content is in the read buffer now. EXPECT_STREQ(static_cast(iov.iov_base), "test text"); } @@ -363,9 +370,7 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); - while (completions_nr < 2) { - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - } + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); // Even though we haven't been notified about ops completion the buffers // are filled already. EXPECT_EQ(static_cast(iov1.iov_base)[0], 'a'); @@ -373,11 +378,9 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { EXPECT_EQ(static_cast(iov2.iov_base)[0], 'c'); EXPECT_EQ(static_cast(iov2.iov_base)[1], 'd'); - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - // Only 2 completions are expected because the completion queue can contain // no more than 2 entries. - EXPECT_EQ(completions_nr, 2); + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); // Check a new event gets handled in the next dispatcher run. res = io_uring_->prepareReadv(fd, &iov3, 1, 4, &request3); @@ -385,16 +388,10 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); - while (completions_nr < 3) { - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - } + waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 3; }); EXPECT_EQ(static_cast(iov3.iov_base)[0], 'e'); EXPECT_EQ(static_cast(iov3.iov_base)[1], 'f'); - - dispatcher->run(Event::Dispatcher::RunType::NonBlock); - // Check the completion callback was called actually. - EXPECT_EQ(completions_nr, 3); } } // namespace From 193f070974dd19d8f0af18003ab7a11f5ed53fd4 Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Mon, 29 Apr 2024 13:39:24 +0000 Subject: [PATCH 5/6] fix format Signed-off-by: He Jie Xu --- test/common/io/io_uring_impl_test.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/test/common/io/io_uring_impl_test.cc b/test/common/io/io_uring_impl_test.cc index 367663bb2a7d..f8e340aade2d 100644 --- a/test/common/io/io_uring_impl_test.cc +++ b/test/common/io/io_uring_impl_test.cc @@ -49,7 +49,8 @@ class IoUringImplTest : public ::testing::Test { } } - void waitForCondition(Event::Dispatcher& dispatcher, WaitConditionFunc condition_func, std::chrono::milliseconds wait_timeout = TestUtility::DefaultTimeout) { + void waitForCondition(Event::Dispatcher& dispatcher, WaitConditionFunc condition_func, + std::chrono::milliseconds wait_timeout = TestUtility::DefaultTimeout) { Event::TestTimeSystem::RealTimeBound bound(wait_timeout); while (!condition_func()) { if (!bound.withinBound()) { @@ -120,7 +121,7 @@ TEST_P(IoUringImplParamTest, InvalidParams) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 2; }); } TEST_F(IoUringImplTest, InjectCompletion) { @@ -150,7 +151,7 @@ TEST_F(IoUringImplTest, InjectCompletion) { file_event->activate(Event::FileReadyType::Read); - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 1; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 1; }); } TEST_F(IoUringImplTest, NestInjectCompletion) { @@ -190,7 +191,7 @@ TEST_F(IoUringImplTest, NestInjectCompletion) { file_event->activate(Event::FileReadyType::Read); - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 2; }); } TEST_F(IoUringImplTest, RemoveInjectCompletion) { @@ -225,7 +226,7 @@ TEST_F(IoUringImplTest, RemoveInjectCompletion) { EXPECT_EQ(-1, data2); file_event->activate(Event::FileReadyType::Read); - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 1; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 1; }); } TEST_F(IoUringImplTest, NestRemoveInjectCompletion) { @@ -264,7 +265,7 @@ TEST_F(IoUringImplTest, NestRemoveInjectCompletion) { file_event->activate(Event::FileReadyType::Read); - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 2; }); } TEST_F(IoUringImplTest, RegisterEventfd) { @@ -309,7 +310,7 @@ TEST_F(IoUringImplTest, PrepareReadvAllDataFitsOneChunk) { io_uring_->submit(); // Check that the completion callback has been actually called. - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 1; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 1; }); // The file's content is in the read buffer now. EXPECT_STREQ(static_cast(iov.iov_base), "test text"); } @@ -370,7 +371,7 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 2; }); // Even though we haven't been notified about ops completion the buffers // are filled already. EXPECT_EQ(static_cast(iov1.iov_base)[0], 'a'); @@ -380,7 +381,7 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { // Only 2 completions are expected because the completion queue can contain // no more than 2 entries. - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 2; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 2; }); // Check a new event gets handled in the next dispatcher run. res = io_uring_->prepareReadv(fd, &iov3, 1, 4, &request3); @@ -388,7 +389,7 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { res = io_uring_->submit(); EXPECT_EQ(res, IoUringResult::Ok); - waitForCondition(*dispatcher, [&completions_nr](){ return completions_nr == 3; }); + waitForCondition(*dispatcher, [&completions_nr]() { return completions_nr == 3; }); EXPECT_EQ(static_cast(iov3.iov_base)[0], 'e'); EXPECT_EQ(static_cast(iov3.iov_base)[1], 'f'); From 6176325513fe8e9f833efa1f1c34eeb7b8c17633 Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Mon, 29 Apr 2024 13:44:00 +0000 Subject: [PATCH 6/6] remove debug log Signed-off-by: He Jie Xu --- test/common/io/io_uring_impl_test.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/test/common/io/io_uring_impl_test.cc b/test/common/io/io_uring_impl_test.cc index f8e340aade2d..3347a3e0ca75 100644 --- a/test/common/io/io_uring_impl_test.cc +++ b/test/common/io/io_uring_impl_test.cc @@ -346,7 +346,6 @@ TEST_F(IoUringImplTest, PrepareReadvQueueOverflow) { EXPECT_TRUE(user_data != nullptr); EXPECT_EQ(res, 2); completions_nr++; - ENVOY_LOG_MISC(info, "get uring request completion {}", completions_nr); // Note: generally events are not guaranteed to complete in the same order // we submit them, but for this case of reading from a single file it's ok // to expect the same order.