Skip to content

Commit d72a930

Browse files
committed
[TEST] Let a cancelled request end either of the two ways it can
RepeatedCallerThreadCancelsAreClean summed Cancelled and Response over twenty attempts against a closed port and asked for at least one each. There is a third way such an attempt ends: the connection fails before the cancel arrives, and the cancel is then correctly a no-op. Where the caller and the IO thread share a core that is the usual outcome, and the case fails. Measured with the run pinned to one core, fifteen runs each: 15 of 15 fail on main at 3fb1d31, on open-telemetry#4395 at 66ab56c, and on this branch either side of the change it carries, all with the same 3 to 7 cancels out of 20. Unpinned all four pass. The failure the valgrind job hit is that, not anything about the handle accounting. The connection failure is counted apart from terminal_count_, which two other cases pin to an exact value, and it is taken before the existing chain rather than inside it, because ACancelBeforeTheResponseReportsCancelled cancels from ConnectFailed and needs that branch to keep firing. The case now asks each attempt to end somewhere the handler is told about rather than to end the same way twenty times, which is what it was after. Pinned to one core it goes from 15 of 15 failing to 0 of 15. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
1 parent ba35858 commit d72a930

1 file changed

Lines changed: 17 additions & 7 deletions

File tree

‎ext/test/http/curl_http_test.cc‎

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ class TerminalCountingHandler : public CustomEventHandler
143143

144144
void OnEvent(http_client::SessionState state, nostd::string_view reason) noexcept override
145145
{
146+
// Counted on its own, and before the chain below rather than inside it: a case can cancel
147+
// from one of these, and two others pin terminal_count_ to an exact value.
148+
if (state == http_client::SessionState::ConnectFailed ||
149+
state == http_client::SessionState::SendFailed)
150+
{
151+
failed_count_.fetch_add(1, std::memory_order_release);
152+
}
153+
146154
if (state == http_client::SessionState::Cancelled)
147155
{
148156
terminal_count_.fetch_add(1, std::memory_order_release);
@@ -168,6 +176,7 @@ class TerminalCountingHandler : public CustomEventHandler
168176
http_client::SessionState cancel_at_ = http_client::SessionState::Response;
169177
std::thread::id cancelled_from_{};
170178
std::atomic<int> terminal_count_{0};
179+
std::atomic<int> failed_count_{0};
171180
std::atomic<int> cancelled_from_callback_{0};
172181
};
173182

@@ -822,8 +831,6 @@ TEST_F(BasicCurlHttpTests, ACancelFromTheCallerThreadReportsCancelled)
822831
// thread sanitizer this reports against the unfixed client on every run.
823832
TEST_F(BasicCurlHttpTests, RepeatedCallerThreadCancelsAreClean)
824833
{
825-
int terminal_total = 0;
826-
827834
for (int i = 0; i < 20; ++i)
828835
{
829836
auto session_manager = std::make_shared<http_client::curl::HttpCurlClientFactory>()->Create();
@@ -840,12 +847,15 @@ TEST_F(BasicCurlHttpTests, RepeatedCallerThreadCancelsAreClean)
840847
session_manager->FinishAllSessions();
841848

842849
EXPECT_FALSE(handler->got_response_.load(std::memory_order_acquire));
843-
terminal_total += handler->terminal_count_.load(std::memory_order_acquire);
844-
}
845850

846-
// A lower bound, not a count: #4360 tracks the same cancel arriving twice, and how many
847-
// arrive is not what this case decides.
848-
EXPECT_GE(terminal_total, 20);
851+
// Whichever side wins, the attempt ends somewhere the handler is told about: the cancel
852+
// lands first, or the connection to a closed port fails first and the cancel is then
853+
// correctly a no-op. How many cancels arrive is not what this case decides, #4360 tracks
854+
// that, and neither is which of the two wins.
855+
EXPECT_GT(handler->terminal_count_.load(std::memory_order_acquire) +
856+
handler->failed_count_.load(std::memory_order_acquire),
857+
0);
858+
}
849859
}
850860

851861
TEST_F(BasicCurlHttpTests, SendGetRequestSync)

0 commit comments

Comments
 (0)