From 642897f8dd9ec9c30bf8b91bfd64940334473fc5dc81a41f82074bc1ea11d8db Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Fri, 3 Jan 2025 23:37:04 +0100 Subject: [PATCH] unit test fix from upstream --- ...524a3d085fcd9a5e25d5f6cbdb953082c2b9.patch | 318 ++++++++++++++++++ c-ares.changes | 6 + c-ares.spec | 3 +- skip-test.patch | 22 -- 4 files changed, 325 insertions(+), 24 deletions(-) create mode 100644 a531524a3d085fcd9a5e25d5f6cbdb953082c2b9.patch delete mode 100644 skip-test.patch diff --git a/a531524a3d085fcd9a5e25d5f6cbdb953082c2b9.patch b/a531524a3d085fcd9a5e25d5f6cbdb953082c2b9.patch new file mode 100644 index 0000000..570870e --- /dev/null +++ b/a531524a3d085fcd9a5e25d5f6cbdb953082c2b9.patch @@ -0,0 +1,318 @@ +commit a531524a3d085fcd9a5e25d5f6cbdb953082c2b9 +Author: Brad House +Date: Fri Jan 3 12:55:54 2025 -0500 + + tests: Convert some live tests to Mock tests (#954) + + In Issue #953 `GetTCPSock` and `VerifySocketFunctionCallback` tests + might rely on the fact that `connect()` doesn't return an immediate + failure. If `connect()` returned `EWOULDBLOCK`/`EAGAIN` the test would + succeed, but on systems that check on the call for available routes or + listening servers on localhost the `connect()` function would return an + immediate failure. + + These functions were not actually tagged with a `Live` prefix so they + would run even callers exclude Live tests. These are testing functions + that shouldn't be limited to live scenarios so we need to move them to + the Mock frameworks and test appropriately. + + Fixes #953 + Signed-off-by: Brad House (@bradh352) + +diff --git a/test/ares-test-live.cc b/test/ares-test-live.cc +index e23dadfe..557c485e 100644 +--- a/test/ares-test-live.cc ++++ b/test/ares-test-live.cc +@@ -669,115 +669,7 @@ VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoAllocFail) { + EXPECT_EQ(ARES_ENOMEM, result.status_); + } + +-VIRT_NONVIRT_TEST_F(DefaultChannelTest, GetSock) { +- ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD}; +- int bitmask = ares_getsock(channel_, socks, 3); +- EXPECT_EQ(0, bitmask); +- bitmask = ares_getsock(channel_, nullptr, 0); +- EXPECT_EQ(0, bitmask); +- +- // Ask again with a pending query. +- HostResult result; +- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); +- bitmask = ares_getsock(channel_, socks, 3); +- EXPECT_NE(0, bitmask); +- +- size_t sock_cnt = 0; +- for (size_t i=0; i<3; i++) { +- if (ARES_GETSOCK_READABLE(bitmask, i) || ARES_GETSOCK_WRITABLE(bitmask, i)) { +- EXPECT_NE(ARES_SOCKET_BAD, socks[i]); +- if (socks[i] != ARES_SOCKET_BAD) +- sock_cnt++; +- } +- } +- EXPECT_NE((size_t)0, sock_cnt); +- +- bitmask = ares_getsock(channel_, nullptr, 0); +- EXPECT_EQ(0, bitmask); +- +- Process(); +-} +- +-TEST_F(LibraryTest, GetTCPSock) { +- ares_channel_t *channel; +- struct ares_options opts; +- memset(&opts, 0, sizeof(opts)); +- opts.tcp_port = 53; +- opts.flags = ARES_FLAG_USEVC; +- int optmask = ARES_OPT_TCP_PORT | ARES_OPT_FLAGS; +- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask)); +- EXPECT_NE(nullptr, channel); +- +- ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD}; +- int bitmask = ares_getsock(channel, socks, 3); +- EXPECT_EQ(0, bitmask); +- bitmask = ares_getsock(channel, nullptr, 0); +- EXPECT_EQ(0, bitmask); +- +- // Ask again with a pending query. +- HostResult result; +- ares_gethostbyname(channel, "www.google.com.", AF_INET, HostCallback, &result); +- bitmask = ares_getsock(channel, socks, 3); +- EXPECT_NE(0, bitmask); +- +- size_t sock_cnt = 0; +- for (size_t i=0; i<3; i++) { +- if (ARES_GETSOCK_READABLE(bitmask, i) || ARES_GETSOCK_WRITABLE(bitmask, i)) { +- EXPECT_NE(ARES_SOCKET_BAD, socks[i]); +- if (socks[i] != ARES_SOCKET_BAD) +- sock_cnt++; +- } +- } +- EXPECT_NE((size_t)0, sock_cnt); +- +- bitmask = ares_getsock(channel, nullptr, 0); +- EXPECT_EQ(0, bitmask); +- +- ProcessWork(channel, NoExtraFDs, nullptr); + +- ares_destroy(channel); +-} +- +-TEST_F(DefaultChannelTest, VerifySocketFunctionCallback) { +- VirtualizeIO vio(channel_); +- +- auto my_functions = VirtualizeIO::default_functions; +- size_t count = 0; +- +- my_functions.asocket = [](int af, int type, int protocol, void * p) -> ares_socket_t { +- EXPECT_NE(nullptr, p); +- (*reinterpret_cast(p))++; +- return ::socket(af, type, protocol); +- }; +- +- ares_set_socket_functions(channel_, &my_functions, &count); +- +- { +- count = 0; +- HostResult result; +- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); +- Process(); +- +- EXPECT_TRUE(result.done_); +- EXPECT_NE((size_t)0, count); +- } +- +- { +- count = 0; +- ares_channel_t *copy; +- EXPECT_EQ(ARES_SUCCESS, ares_dup(©, channel_)); +- +- HostResult result; +- ares_gethostbyname(copy, "www.google.com.", AF_INET, HostCallback, &result); +- +- ProcessWork(copy, NoExtraFDs, nullptr); +- +- EXPECT_TRUE(result.done_); +- ares_destroy(copy); +- EXPECT_NE((size_t)0, count); +- } +- +-} + + TEST_F(DefaultChannelTest, LiveSetServers) { + struct ares_addr_node server1; +diff --git a/test/ares-test-mock.cc b/test/ares-test-mock.cc +index 8c74c05f..ebae7140 100644 +--- a/test/ares-test-mock.cc ++++ b/test/ares-test-mock.cc +@@ -1662,6 +1662,135 @@ TEST_P(MockChannelTest, GetHostByAddrDestroy) { + EXPECT_EQ(0, result.timeouts_); + } + ++TEST_P(MockUDPChannelTest, GetSock) { ++ DNSPacket reply; ++ reply.set_response().set_aa() ++ .add_question(new DNSQuestion("www.google.com", T_A)) ++ .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04})); ++ ON_CALL(server_, OnRequest("www.google.com", T_A)) ++ .WillByDefault(SetReply(&server_, &reply)); ++ ++ ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD}; ++ int bitmask; ++ ++ bitmask = ares_getsock(channel_, socks, 3); ++ EXPECT_EQ(0, bitmask); ++ bitmask = ares_getsock(channel_, nullptr, 0); ++ EXPECT_EQ(0, bitmask); ++ ++ // Ask again with a pending query. ++ HostResult result; ++ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); ++ bitmask = ares_getsock(channel_, socks, 3); ++ EXPECT_NE(0, bitmask); ++ ++ size_t sock_cnt = 0; ++ for (size_t i=0; i<3; i++) { ++ if (ARES_GETSOCK_READABLE(bitmask, i) || ARES_GETSOCK_WRITABLE(bitmask, i)) { ++ EXPECT_NE(ARES_SOCKET_BAD, socks[i]); ++ if (socks[i] != ARES_SOCKET_BAD) ++ sock_cnt++; ++ } ++ } ++ EXPECT_NE((size_t)0, sock_cnt); ++ ++ Process(); ++ ++ bitmask = ares_getsock(channel_, nullptr, 0); ++ EXPECT_EQ(0, bitmask); ++} ++ ++TEST_P(MockTCPChannelTest, GetSock) { ++ DNSPacket reply; ++ reply.set_response().set_aa() ++ .add_question(new DNSQuestion("www.google.com", T_A)) ++ .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04})); ++ ON_CALL(server_, OnRequest("www.google.com", T_A)) ++ .WillByDefault(SetReply(&server_, &reply)); ++ ++ ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD}; ++ int bitmask; ++ ++ bitmask = ares_getsock(channel_, socks, 3); ++ EXPECT_EQ(0, bitmask); ++ bitmask = ares_getsock(channel_, nullptr, 0); ++ EXPECT_EQ(0, bitmask); ++ ++ // Ask again with a pending query. ++ HostResult result; ++ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); ++ bitmask = ares_getsock(channel_, socks, 3); ++ EXPECT_NE(0, bitmask); ++ ++ size_t sock_cnt = 0; ++ for (size_t i=0; i<3; i++) { ++ if (ARES_GETSOCK_READABLE(bitmask, i) || ARES_GETSOCK_WRITABLE(bitmask, i)) { ++ EXPECT_NE(ARES_SOCKET_BAD, socks[i]); ++ if (socks[i] != ARES_SOCKET_BAD) ++ sock_cnt++; ++ } ++ } ++ EXPECT_NE((size_t)0, sock_cnt); ++ ++ Process(); ++ ++ bitmask = ares_getsock(channel_, nullptr, 0); ++ EXPECT_EQ(0, bitmask); ++} ++ ++ ++TEST_P(MockChannelTest, VerifySocketFunctionCallback) { ++ ares_socket_functions sock_funcs; ++ memset(&sock_funcs, 0, sizeof(sock_funcs)); ++ ++ DNSPacket reply; ++ reply.set_response().set_aa() ++ .add_question(new DNSQuestion("www.google.com", T_A)) ++ .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04})); ++ ON_CALL(server_, OnRequest("www.google.com", T_A)) ++ .WillByDefault(SetReply(&server_, &reply)); ++ ++ size_t count = 0; ++ ++ sock_funcs.asocket = [](int af, int type, int protocol, void * p) -> ares_socket_t { ++ EXPECT_NE(nullptr, p); ++ (*reinterpret_cast(p))++; ++ return ::socket(af, type, protocol); ++ }; ++ ++ ares_set_socket_functions(channel_, &sock_funcs, &count); ++ ++ { ++ count = 0; ++ HostResult result; ++ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); ++ Process(); ++ ++ EXPECT_TRUE(result.done_); ++ EXPECT_EQ(ARES_SUCCESS, result.status_); ++ EXPECT_EQ(0, result.timeouts_); ++ EXPECT_NE((size_t)0, count); ++ } ++ ++ { ++ count = 0; ++ ares_channel_t *copy; ++ EXPECT_EQ(ARES_SUCCESS, ares_dup(©, channel_)); ++ ++ HostResult result; ++ ares_gethostbyname(copy, "www.google.com.", AF_INET, HostCallback, &result); ++ ++ ProcessAltChannel(copy); ++ ++ EXPECT_TRUE(result.done_); ++ ares_destroy(copy); ++ EXPECT_NE((size_t)0, count); ++ EXPECT_EQ(ARES_SUCCESS, result.status_); ++ EXPECT_EQ(0, result.timeouts_); ++ } ++ ++} ++ + static const unsigned char * + fetch_server_cookie(const ares_dns_record_t *dnsrec, size_t *len) + { +diff --git a/test/ares-test.cc b/test/ares-test.cc +index 99ab0a00..f383ecbe 100644 +--- a/test/ares-test.cc ++++ b/test/ares-test.cc +@@ -888,14 +888,18 @@ void MockChannelOptsTest::ProcessFD(ares_socket_t fd) { + } + } + +-void MockChannelOptsTest::Process(unsigned int cancel_ms) { ++void MockChannelOptsTest::ProcessAltChannel(ares_channel_t *chan, unsigned int cancel_ms) { + using namespace std::placeholders; +- ProcessWork(channel_, ++ ProcessWork(chan, + std::bind(&MockChannelOptsTest::fds, this), + std::bind(&MockChannelOptsTest::ProcessFD, this, _1), + cancel_ms); + } + ++void MockChannelOptsTest::Process(unsigned int cancel_ms) { ++ ProcessAltChannel(channel_, cancel_ms); ++} ++ + void MockEventThreadOptsTest::Process(unsigned int cancel_ms) { + std::set fds; + +diff --git a/test/ares-test.h b/test/ares-test.h +index 61275921..77baa902 100644 +--- a/test/ares-test.h ++++ b/test/ares-test.h +@@ -328,6 +328,7 @@ public: + + // Process all pending work on ares-owned and mock-server-owned file + // descriptors. ++ void ProcessAltChannel(ares_channel_t *chan, unsigned int cancel_ms = 0); + void Process(unsigned int cancel_ms = 0); + + protected: diff --git a/c-ares.changes b/c-ares.changes index b426780..bb60e4f 100644 --- a/c-ares.changes +++ b/c-ares.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Jan 3 22:36:24 UTC 2025 - Adam Majer + +- skip-test.patch replaced with upstream unit test fix + a531524a3d085fcd9a5e25d5f6cbdb953082c2b9.patch + ------------------------------------------------------------------- Mon Dec 30 11:13:26 UTC 2024 - Adam Majer diff --git a/c-ares.spec b/c-ares.spec index e375cf1..26be8ce 100644 --- a/c-ares.spec +++ b/c-ares.spec @@ -36,8 +36,7 @@ Source1: https://github.com/c-ares/c-ares/releases/download/v%{version}/c Source3: c-ares.keyring Source4: baselibs.conf Source5: series -# forwarded: https://github.com/c-ares/c-ares/issues/953 -Patch1: skip-test.patch +Patch1: a531524a3d085fcd9a5e25d5f6cbdb953082c2b9.patch BuildRequires: c++_compiler BuildRequires: cmake # Needed for getservbyport_r function to work properly. diff --git a/skip-test.patch b/skip-test.patch deleted file mode 100644 index fe73759..0000000 --- a/skip-test.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: c-ares-1.34.4/test/ares-test-live.cc -=================================================================== ---- c-ares-1.34.4.orig/test/ares-test-live.cc -+++ c-ares-1.34.4/test/ares-test-live.cc -@@ -718,7 +718,7 @@ TEST_F(LibraryTest, GetTCPSock) { - HostResult result; - ares_gethostbyname(channel, "www.google.com.", AF_INET, HostCallback, &result); - bitmask = ares_getsock(channel, socks, 3); -- EXPECT_NE(0, bitmask); -+ // EXPECT_NE(0, bitmask); - - size_t sock_cnt = 0; - for (size_t i=0; i<3; i++) { -@@ -728,7 +728,7 @@ TEST_F(LibraryTest, GetTCPSock) { - sock_cnt++; - } - } -- EXPECT_NE((size_t)0, sock_cnt); -+ // EXPECT_NE((size_t)0, sock_cnt); - - bitmask = ares_getsock(channel, nullptr, 0); - EXPECT_EQ(0, bitmask);