Loading Android.bp +4 −5 Original line number Original line Diff line number Diff line Loading @@ -147,9 +147,6 @@ cc_defaults { suffix: "64", suffix: "64", }, }, }, }, data: [ ":resolv_test_keys", ], } } cc_library { cc_library { Loading Loading @@ -266,7 +263,8 @@ cc_library_static { genrule { genrule { name: "statslog_resolv.h", name: "statslog_resolv.h", tools: ["stats-log-api-gen"], tools: ["stats-log-api-gen"], cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv --namespace android,net,stats", cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv" + " --namespace android,net,stats --minApiLevel 29", out: [ out: [ "statslog_resolv.h", "statslog_resolv.h", ], ], Loading @@ -275,7 +273,8 @@ genrule { genrule { genrule { name: "statslog_resolv.cpp", name: "statslog_resolv.cpp", tools: ["stats-log-api-gen"], tools: ["stats-log-api-gen"], cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv --namespace android,net,stats --importHeader statslog_resolv.h --supportQ", cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv" + " --namespace android,net,stats --importHeader statslog_resolv.h --minApiLevel 29", out: [ out: [ "statslog_resolv.cpp", "statslog_resolv.cpp", ], ], Loading DnsStats.cpp +25 −22 Original line number Original line Diff line number Diff line Loading @@ -59,10 +59,10 @@ std::string rcodeToName(int rcode) { // clang-format on // clang-format on } } bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { bool ensureNoInvalidIp(const std::vector<IPSockAddr>& addrs) { for (const auto& server : servers) { for (const auto& addr : addrs) { if (server.ip() == INVALID_IPADDRESS || server.port() == 0) { if (addr.ip() == INVALID_IPADDRESS || addr.port() == 0) { LOG(WARNING) << "Invalid server: " << server; LOG(WARNING) << "Invalid addr: " << addr; return false; return false; } } } } Loading @@ -73,8 +73,8 @@ bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { // The comparison ignores the last update time. // The comparison ignores the last update time. bool StatsData::operator==(const StatsData& o) const { bool StatsData::operator==(const StatsData& o) const { return std::tie(serverSockAddr, total, rcodeCounts, latencyUs) == return std::tie(sockAddr, total, rcodeCounts, latencyUs) == std::tie(o.serverSockAddr, o.total, o.rcodeCounts, o.latencyUs); std::tie(o.sockAddr, o.total, o.rcodeCounts, o.latencyUs); } } int StatsData::averageLatencyMs() const { int StatsData::averageLatencyMs() const { Loading @@ -82,7 +82,7 @@ int StatsData::averageLatencyMs() const { } } std::string StatsData::toString() const { std::string StatsData::toString() const { if (total == 0) return StringPrintf("%s <no data>", serverSockAddr.ip().toString().c_str()); if (total == 0) return StringPrintf("%s <no data>", sockAddr.ip().toString().c_str()); const auto now = std::chrono::steady_clock::now(); const auto now = std::chrono::steady_clock::now(); const int lastUpdateSec = duration_cast<seconds>(now - lastUpdate).count(); const int lastUpdateSec = duration_cast<seconds>(now - lastUpdate).count(); Loading @@ -92,7 +92,7 @@ std::string StatsData::toString() const { buf += StringPrintf("%s:%d ", rcodeToName(rcode).c_str(), counts); buf += StringPrintf("%s:%d ", rcodeToName(rcode).c_str(), counts); } } } } return StringPrintf("%s (%d, %dms, [%s], %ds)", serverSockAddr.ip().toString().c_str(), total, return StringPrintf("%s (%d, %dms, [%s], %ds)", sockAddr.ip().toString().c_str(), total, averageLatencyMs(), buf.c_str(), lastUpdateSec); averageLatencyMs(), buf.c_str(), lastUpdateSec); } } Loading Loading @@ -171,20 +171,20 @@ void StatsRecords::incrementSkippedCount() { mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); } } bool DnsStats::setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol) { bool DnsStats::setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol) { if (!ensureNoInvalidIp(servers)) return false; if (!ensureNoInvalidIp(addrs)) return false; ServerStatsMap& statsMap = mStats[protocol]; StatsMap& statsMap = mStats[protocol]; for (const auto& server : servers) { for (const auto& addr : addrs) { statsMap.try_emplace(server, StatsRecords(server, kLogSize)); statsMap.try_emplace(addr, StatsRecords(addr, kLogSize)); } } // Clean up the map to eliminate the nodes not belonging to the given list of servers. // Clean up the map to eliminate the nodes not belonging to the given list of servers. const auto cleanup = [&](ServerStatsMap* statsMap) { const auto cleanup = [&](StatsMap* statsMap) { ServerStatsMap tmp; StatsMap tmp; for (const auto& server : servers) { for (const auto& addr : addrs) { if (statsMap->find(server) != statsMap->end()) { if (statsMap->find(addr) != statsMap->end()) { tmp.insert(statsMap->extract(server)); tmp.insert(statsMap->extract(addr)); } } } } statsMap->swap(tmp); statsMap->swap(tmp); Loading @@ -199,8 +199,8 @@ bool DnsStats::addStats(const IPSockAddr& ipSockAddr, const DnsQueryEvent& recor if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; bool added = false; bool added = false; for (auto& [serverSockAddr, statsRecords] : mStats[record.protocol()]) { for (auto& [sockAddr, statsRecords] : mStats[record.protocol()]) { if (serverSockAddr == ipSockAddr) { if (sockAddr == ipSockAddr) { const StatsRecords::Record rec = { const StatsRecords::Record rec = { .rcode = record.rcode(), .rcode = record.rcode(), .linux_errno = record.linux_errno(), .linux_errno = record.linux_errno(), Loading Loading @@ -265,10 +265,10 @@ std::vector<StatsData> DnsStats::getStats(Protocol protocol) const { } } void DnsStats::dump(DumpWriter& dw) { void DnsStats::dump(DumpWriter& dw) { const auto dumpStatsMap = [&](ServerStatsMap& statsMap) { const auto dumpStatsMap = [&](StatsMap& statsMap) { ScopedIndent indentLog(dw); ScopedIndent indentLog(dw); if (statsMap.size() == 0) { if (statsMap.size() == 0) { dw.println("<no server>"); dw.println("<no data>"); return; return; } } for (const auto& [_, statsRecords] : statsMap) { for (const auto& [_, statsRecords] : statsMap) { Loading @@ -290,6 +290,9 @@ void DnsStats::dump(DumpWriter& dw) { dw.println("over TCP"); dw.println("over TCP"); dumpStatsMap(mStats[PROTO_TCP]); dumpStatsMap(mStats[PROTO_TCP]); dw.println("over MDNS"); dumpStatsMap(mStats[PROTO_MDNS]); } } } // namespace android::net } // namespace android::net DnsStats.h +8 −8 Original line number Original line Diff line number Diff line Loading @@ -33,12 +33,12 @@ namespace android::net { // The overall information of a StatsRecords. // The overall information of a StatsRecords. struct StatsData { struct StatsData { StatsData(const netdutils::IPSockAddr& ipSockAddr) : serverSockAddr(ipSockAddr) { StatsData(const netdutils::IPSockAddr& ipSockAddr) : sockAddr(ipSockAddr) { lastUpdate = std::chrono::steady_clock::now(); lastUpdate = std::chrono::steady_clock::now(); }; }; // Server socket address. // Socket address. netdutils::IPSockAddr serverSockAddr; netdutils::IPSockAddr sockAddr; // The most recent number of records being accumulated. // The most recent number of records being accumulated. int total = 0; int total = 0; Loading Loading @@ -106,15 +106,15 @@ class StatsRecords { static constexpr int kMaxQuality = 10000; static constexpr int kMaxQuality = 10000; }; }; // DnsStats class manages the statistics of DNS servers per netId. // DnsStats class manages the statistics of DNS servers or MDNS multicast addresses per netId. // The class itself is not thread-safe. // The class itself is not thread-safe. class DnsStats { class DnsStats { public: public: using ServerStatsMap = std::map<netdutils::IPSockAddr, StatsRecords>; using StatsMap = std::map<netdutils::IPSockAddr, StatsRecords>; // Add |servers| to the map, and remove no-longer-used servers. // Add |addrs| to the map, and remove no-longer-used addresses. // Return true if they are successfully added; otherwise, return false. // Return true if they are successfully added; otherwise, return false. bool setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol); bool setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol); // Return true if |record| is successfully added into |server|'s stats; otherwise, return false. // Return true if |record| is successfully added into |server|'s stats; otherwise, return false. bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); Loading @@ -133,7 +133,7 @@ class DnsStats { static constexpr size_t kLogSize = 128; static constexpr size_t kLogSize = 128; private: private: std::map<Protocol, ServerStatsMap> mStats; std::map<Protocol, StatsMap> mStats; }; }; } // namespace android::net } // namespace android::net DnsStatsTest.cpp +75 −41 Original line number Original line Diff line number Diff line Loading @@ -116,7 +116,8 @@ class DnsStatsTest : public ::testing::Test { // Get the output string from dump() and check the content. // Get the output string from dump() and check the content. void verifyDumpOutput(const std::vector<StatsData>& tcpData, void verifyDumpOutput(const std::vector<StatsData>& tcpData, const std::vector<StatsData>& udpData, const std::vector<StatsData>& udpData, const std::vector<StatsData>& dotData) { const std::vector<StatsData>& dotData, const std::vector<StatsData>& mdnsData) { // A pattern to capture three matches: // A pattern to capture three matches: // server address (empty allowed), the statistics, and the score. // server address (empty allowed), the statistics, and the score. const std::regex pattern(R"(\s{4,}([0-9a-fA-F:\.]*)[ ]?([<(].*[>)])[ ]?(\S*))"); const std::regex pattern(R"(\s{4,}([0-9a-fA-F:\.]*)[ ]?([<(].*[>)])[ ]?(\S*))"); Loading @@ -128,11 +129,11 @@ class DnsStatsTest : public ::testing::Test { ASSERT_NE(dumpString->find(protocol), std::string::npos); ASSERT_NE(dumpString->find(protocol), std::string::npos); std::smatch sm; std::smatch sm; // Expect to show something even if none of servers is set. // Expect to show something even if none of servers or mdns multicast addresses is set. if (statsData.empty()) { if (statsData.empty()) { ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); EXPECT_TRUE(sm[1].str().empty()); EXPECT_TRUE(sm[1].str().empty()); EXPECT_EQ(sm[2], "<no server>"); EXPECT_EQ(sm[2], "<no data>"); EXPECT_TRUE(sm[3].str().empty()); EXPECT_TRUE(sm[3].str().empty()); *dumpString = sm.suffix(); *dumpString = sm.suffix(); return; return; Loading @@ -140,7 +141,7 @@ class DnsStatsTest : public ::testing::Test { for (const auto& stats : statsData) { for (const auto& stats : statsData) { ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); EXPECT_EQ(sm[1], stats.serverSockAddr.ip().toString()); EXPECT_EQ(sm[1], stats.sockAddr.ip().toString()); EXPECT_FALSE(sm[2].str().empty()); EXPECT_FALSE(sm[2].str().empty()); EXPECT_FALSE(sm[3].str().empty()); EXPECT_FALSE(sm[3].str().empty()); *dumpString = sm.suffix(); *dumpString = sm.suffix(); Loading @@ -150,6 +151,7 @@ class DnsStatsTest : public ::testing::Test { check(udpData, "UDP", &dumpString); check(udpData, "UDP", &dumpString); check(dotData, "TLS", &dumpString); check(dotData, "TLS", &dumpString); check(tcpData, "TCP", &dumpString); check(tcpData, "TCP", &dumpString); check(mdnsData, "MDNS", &dumpString); // Ensure the whole string has been checked. // Ensure the whole string has been checked. EXPECT_EQ(dumpString, "\n"); EXPECT_EQ(dumpString, "\n"); Loading @@ -169,9 +171,9 @@ class DnsStatsTest : public ::testing::Test { DnsStats mDnsStats; DnsStats mDnsStats; }; }; TEST_F(DnsStatsTest, SetServers) { TEST_F(DnsStatsTest, SetAddrs) { // Check before any operation to mDnsStats. // Check before any operation to mDnsStats. verifyDumpOutput({}, {}, {}); verifyDumpOutput({}, {}, {}, {}); static const struct { static const struct { std::vector<std::string> servers; std::vector<std::string> servers; Loading Loading @@ -213,9 +215,9 @@ TEST_F(DnsStatsTest, SetServers) { ipSockAddrs.push_back(IPSockAddr::toIPSockAddr(server, 53)); ipSockAddrs.push_back(IPSockAddr::toIPSockAddr(server, 53)); } } EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_TCP) == isSuccess); EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_TCP) == isSuccess); EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_UDP) == isSuccess); EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_UDP) == isSuccess); EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_DOT) == isSuccess); EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_DOT) == isSuccess); std::vector<StatsData> expectedStats; std::vector<StatsData> expectedStats; expectedStats.reserve(expectation.size()); expectedStats.reserve(expectation.size()); Loading @@ -228,7 +230,7 @@ TEST_F(DnsStatsTest, SetServers) { EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); } } verifyDumpOutput({}, {}, {}); verifyDumpOutput({}, {}, {}, {}); } } TEST_F(DnsStatsTest, SetServersDifferentPorts) { TEST_F(DnsStatsTest, SetServersDifferentPorts) { Loading @@ -240,18 +242,18 @@ TEST_F(DnsStatsTest, SetServersDifferentPorts) { }; }; // Servers setup fails due to port unset. // Servers setup fails due to port unset. EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_TCP)); EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_TCP)); EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_UDP)); EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_DOT)); EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_DOT)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); verifyDumpOutput({}, {}, {}); verifyDumpOutput({}, {}, {}, {}); EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_TCP)); EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_TCP)); EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_UDP)); EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_DOT)); const std::vector<StatsData> expectedStats = { const std::vector<StatsData> expectedStats = { makeStatsData(servers[2], 0, 0ms, {}), makeStatsData(servers[3], 0, 0ms, {}), makeStatsData(servers[2], 0, 0ms, {}), makeStatsData(servers[3], 0, 0ms, {}), Loading @@ -262,7 +264,7 @@ TEST_F(DnsStatsTest, SetServersDifferentPorts) { EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); verifyDumpOutput(expectedStats, expectedStats, expectedStats); verifyDumpOutput(expectedStats, expectedStats, expectedStats, {}); } } TEST_F(DnsStatsTest, AddStatsAndClear) { TEST_F(DnsStatsTest, AddStatsAndClear) { Loading @@ -270,10 +272,16 @@ TEST_F(DnsStatsTest, AddStatsAndClear) { IPSockAddr::toIPSockAddr("127.0.0.1", 53), IPSockAddr::toIPSockAddr("127.0.0.1", 53), IPSockAddr::toIPSockAddr("127.0.0.2", 53), IPSockAddr::toIPSockAddr("127.0.0.2", 53), }; }; const std::vector<IPSockAddr> mdnsaddrs = { IPSockAddr::toIPSockAddr("ff02::fb", 5353), IPSockAddr::toIPSockAddr("224.0.0.251", 5353), }; const DnsQueryEvent record = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); const DnsQueryEvent record = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); const DnsQueryEvent mdnsrecord = makeDnsQueryEvent(PROTO_MDNS, NS_R_NO_ERROR, 10ms); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(mdnsaddrs, PROTO_MDNS)); // Fail to add stats because of incorrect arguments. // Fail to add stats because of incorrect arguments. EXPECT_FALSE(mDnsStats.addStats(IPSockAddr::toIPSockAddr("127.0.0.4", 53), record)); EXPECT_FALSE(mDnsStats.addStats(IPSockAddr::toIPSockAddr("127.0.0.4", 53), record)); Loading @@ -282,6 +290,8 @@ TEST_F(DnsStatsTest, AddStatsAndClear) { EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); EXPECT_TRUE(mDnsStats.addStats(servers[1], record)); EXPECT_TRUE(mDnsStats.addStats(servers[1], record)); EXPECT_TRUE(mDnsStats.addStats(mdnsaddrs[0], mdnsrecord)); EXPECT_TRUE(mDnsStats.addStats(mdnsaddrs[1], mdnsrecord)); const std::vector<StatsData> expectedStatsForTcp = { const std::vector<StatsData> expectedStatsForTcp = { makeStatsData(servers[0], 0, 0ms, {}), makeStatsData(servers[0], 0, 0ms, {}), Loading @@ -292,19 +302,27 @@ TEST_F(DnsStatsTest, AddStatsAndClear) { makeStatsData(servers[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}), makeStatsData(servers[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}), }; }; const std::vector<StatsData> expectedStatsForMdns = { makeStatsData(mdnsaddrs[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}), makeStatsData(mdnsaddrs[0], 1, 10ms, {{NS_R_NO_ERROR, 1}}), }; EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStatsForTcp, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStatsForTcp, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStatsForUdp, 10ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStatsForUdp, 10ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); verifyDumpOutput(expectedStatsForTcp, expectedStatsForUdp, {}); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, expectedStatsForMdns, 10ms)); verifyDumpOutput(expectedStatsForTcp, expectedStatsForUdp, {}, expectedStatsForMdns); // Clear stats. // Clear stats. EXPECT_TRUE(mDnsStats.setServers({}, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setServers({}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setServers({}, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_MDNS)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); verifyDumpOutput({}, {}, {}); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, {}, NO_AVERAGE_LATENCY)); verifyDumpOutput({}, {}, {}, {}); } } TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { Loading @@ -315,7 +333,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { const DnsQueryEvent recordNoError = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); const DnsQueryEvent recordNoError = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); const DnsQueryEvent recordTimeout = makeDnsQueryEvent(PROTO_UDP, NS_R_TIMEOUT, 250ms); const DnsQueryEvent recordTimeout = makeDnsQueryEvent(PROTO_UDP, NS_R_TIMEOUT, 250ms); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP)); // Add a record to 127.0.0.1. // Add a record to 127.0.0.1. EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); Loading @@ -332,7 +350,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { }; }; EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); verifyDumpOutput({}, expectedStats, {}); verifyDumpOutput({}, expectedStats, {}, {}); // Update the server list, the stats of 127.0.0.2 will remain. // Update the server list, the stats of 127.0.0.2 will remain. servers = { servers = { Loading @@ -340,7 +358,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { IPSockAddr::toIPSockAddr("127.0.0.3", 53), IPSockAddr::toIPSockAddr("127.0.0.3", 53), IPSockAddr::toIPSockAddr("127.0.0.4", 53), IPSockAddr::toIPSockAddr("127.0.0.4", 53), }; }; EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP)); expectedStats = { expectedStats = { makeStatsData(servers[0], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}), makeStatsData(servers[0], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}), makeStatsData(servers[1], 0, 0ms, {}), makeStatsData(servers[1], 0, 0ms, {}), Loading @@ -348,7 +366,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { }; }; EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 130ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 130ms)); verifyDumpOutput({}, expectedStats, {}); verifyDumpOutput({}, expectedStats, {}, {}); // Let's add a record to 127.0.0.2 again. // Let's add a record to 127.0.0.2 again. EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); Loading @@ -359,7 +377,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { }; }; EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); verifyDumpOutput({}, expectedStats, {}); verifyDumpOutput({}, expectedStats, {}, {}); } } TEST_F(DnsStatsTest, AddStatsRecords_100000) { TEST_F(DnsStatsTest, AddStatsRecords_100000) { Loading @@ -375,6 +393,11 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) { IPSockAddr::toIPSockAddr("127.0.0.4", 53), IPSockAddr::toIPSockAddr("127.0.0.4", 53), }; }; const std::vector<IPSockAddr> mdnsaddrs = { IPSockAddr::toIPSockAddr("ff02::fb", 5353), IPSockAddr::toIPSockAddr("224.0.0.251", 5353), }; // To test unknown rcode in rcodeToName(), store the elements as type int. // To test unknown rcode in rcodeToName(), store the elements as type int. const std::array<int, rcodeNum> rcodes = { const std::array<int, rcodeNum> rcodes = { NS_R_NO_ERROR, // NOERROR NS_R_NO_ERROR, // NOERROR Loading @@ -383,9 +406,10 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) { NS_R_INTERNAL_ERROR, // INTERNAL_ERROR NS_R_INTERNAL_ERROR, // INTERNAL_ERROR }; }; EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs(mdnsaddrs, PROTO_MDNS)); for (size_t i = 0; i < operations; i++) { for (size_t i = 0; i < operations; i++) { const NsRcode rcode = static_cast<NsRcode>(rcodes[i % rcodeNum]); const NsRcode rcode = static_cast<NsRcode>(rcodes[i % rcodeNum]); Loading @@ -398,6 +422,11 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) { ASSERT_TRUE(mDnsStats.addStats(server, eventUdp)); ASSERT_TRUE(mDnsStats.addStats(server, eventUdp)); ASSERT_TRUE(mDnsStats.addStats(server, eventDot)); ASSERT_TRUE(mDnsStats.addStats(server, eventDot)); } } const auto eventMdns = makeDnsQueryEvent(PROTO_MDNS, rcode, milliseconds(i)); for (const auto& mdnsaddr : mdnsaddrs) { SCOPED_TRACE(mdnsaddr.toString() + "-" + std::to_string(i)); ASSERT_TRUE(mDnsStats.addStats(mdnsaddr, eventMdns)); } } } std::map<int, int> expectedRcodeCounts; std::map<int, int> expectedRcodeCounts; Loading @@ -414,10 +443,15 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) { makeStatsData(servers[3], logSize, logSize * 99935500us, expectedRcodeCounts), makeStatsData(servers[3], logSize, logSize * 99935500us, expectedRcodeCounts), }; }; const std::vector<StatsData> expectedMdnsStats = { makeStatsData(mdnsaddrs[1], logSize, logSize * 99935500us, expectedRcodeCounts), makeStatsData(mdnsaddrs[0], logSize, logSize * 99935500us, expectedRcodeCounts), }; EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, 99935500us)); verifyDumpOutput(expectedStats, expectedStats, expectedStats); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, expectedMdnsStats, 99935500us)); verifyDumpOutput(expectedStats, expectedStats, expectedStats, expectedMdnsStats); } } TEST_F(DnsStatsTest, GetServers_SortingByLatency) { TEST_F(DnsStatsTest, GetServers_SortingByLatency) { Loading @@ -430,8 +464,8 @@ TEST_F(DnsStatsTest, GetServers_SortingByLatency) { EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), IsEmpty()); EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), IsEmpty()); // Before there's any stats, the list of the sorted servers is the same as the setup's one. // Before there's any stats, the list of the sorted servers is the same as the setup's one. EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_DOT)); EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), testing::ElementsAreArray({server1, server2, server3, server4})); testing::ElementsAreArray({server1, server2, server3, server4})); Loading Loading @@ -473,7 +507,7 @@ TEST_F(DnsStatsTest, GetServers_SortingByLatency) { testing::ElementsAreArray({server2, server3, server1, server4})); testing::ElementsAreArray({server2, server3, server1, server4})); // The list of the DNS servers changed. // The list of the DNS servers changed. EXPECT_TRUE(mDnsStats.setServers({server2, server4}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs({server2, server4}, PROTO_UDP)); EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), testing::ElementsAreArray({server2, server4})); testing::ElementsAreArray({server2, server4})); Loading @@ -490,7 +524,7 @@ TEST_F(DnsStatsTest, GetServers_DeprioritizingBadServers) { const IPSockAddr server3 = IPSockAddr::toIPSockAddr("127.0.0.3", 53); const IPSockAddr server3 = IPSockAddr::toIPSockAddr("127.0.0.3", 53); const IPSockAddr server4 = IPSockAddr::toIPSockAddr("127.0.0.4", 53); const IPSockAddr server4 = IPSockAddr::toIPSockAddr("127.0.0.4", 53); EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_UDP)); int server1Counts = 0; int server1Counts = 0; int server2Counts = 0; int server2Counts = 0; Loading Loading @@ -521,15 +555,15 @@ TEST_F(DnsStatsTest, GetServers_DeprioritizingBadServers) { const std::vector<StatsData> allStatsData = mDnsStats.getStats(PROTO_UDP); const std::vector<StatsData> allStatsData = mDnsStats.getStats(PROTO_UDP); for (const auto& data : allStatsData) { for (const auto& data : allStatsData) { EXPECT_EQ(data.rcodeCounts.size(), 1U); EXPECT_EQ(data.rcodeCounts.size(), 1U); if (data.serverSockAddr == server1 || data.serverSockAddr == server2) { if (data.sockAddr == server1 || data.sockAddr == server2) { const auto it = data.rcodeCounts.find(NS_R_NO_ERROR); const auto it = data.rcodeCounts.find(NS_R_NO_ERROR); ASSERT_NE(it, data.rcodeCounts.end()); ASSERT_NE(it, data.rcodeCounts.end()); EXPECT_GT(server2Counts, 2 * server1Counts); // At least twice larger. EXPECT_GT(server2Counts, 2 * server1Counts); // At least twice larger. } else if (data.serverSockAddr == server3) { } else if (data.sockAddr == server3) { const auto it = data.rcodeCounts.find(NS_R_TIMEOUT); const auto it = data.rcodeCounts.find(NS_R_TIMEOUT); ASSERT_NE(it, data.rcodeCounts.end()); ASSERT_NE(it, data.rcodeCounts.end()); EXPECT_LT(it->second, 10); EXPECT_LT(it->second, 10); } else if (data.serverSockAddr == server4) { } else if (data.sockAddr == server4) { const auto it = data.rcodeCounts.find(NS_R_INTERNAL_ERROR); const auto it = data.rcodeCounts.find(NS_R_INTERNAL_ERROR); ASSERT_NE(it, data.rcodeCounts.end()); ASSERT_NE(it, data.rcodeCounts.end()); EXPECT_LT(it->second, 10); EXPECT_LT(it->second, 10); Loading Experiments.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,7 @@ class Experiments { "dot_validation_latency_factor", "dot_validation_latency_factor", "dot_validation_latency_offset_ms", "dot_validation_latency_offset_ms", "doh", "doh", "mdns_resolution", }; }; // This value is used in updateInternal as the default value if any flags can't be found. // This value is used in updateInternal as the default value if any flags can't be found. static constexpr int kFlagIntDefault = INT_MIN; static constexpr int kFlagIntDefault = INT_MIN; Loading Loading
Android.bp +4 −5 Original line number Original line Diff line number Diff line Loading @@ -147,9 +147,6 @@ cc_defaults { suffix: "64", suffix: "64", }, }, }, }, data: [ ":resolv_test_keys", ], } } cc_library { cc_library { Loading Loading @@ -266,7 +263,8 @@ cc_library_static { genrule { genrule { name: "statslog_resolv.h", name: "statslog_resolv.h", tools: ["stats-log-api-gen"], tools: ["stats-log-api-gen"], cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv --namespace android,net,stats", cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv" + " --namespace android,net,stats --minApiLevel 29", out: [ out: [ "statslog_resolv.h", "statslog_resolv.h", ], ], Loading @@ -275,7 +273,8 @@ genrule { genrule { genrule { name: "statslog_resolv.cpp", name: "statslog_resolv.cpp", tools: ["stats-log-api-gen"], tools: ["stats-log-api-gen"], cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv --namespace android,net,stats --importHeader statslog_resolv.h --supportQ", cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv" + " --namespace android,net,stats --importHeader statslog_resolv.h --minApiLevel 29", out: [ out: [ "statslog_resolv.cpp", "statslog_resolv.cpp", ], ], Loading
DnsStats.cpp +25 −22 Original line number Original line Diff line number Diff line Loading @@ -59,10 +59,10 @@ std::string rcodeToName(int rcode) { // clang-format on // clang-format on } } bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { bool ensureNoInvalidIp(const std::vector<IPSockAddr>& addrs) { for (const auto& server : servers) { for (const auto& addr : addrs) { if (server.ip() == INVALID_IPADDRESS || server.port() == 0) { if (addr.ip() == INVALID_IPADDRESS || addr.port() == 0) { LOG(WARNING) << "Invalid server: " << server; LOG(WARNING) << "Invalid addr: " << addr; return false; return false; } } } } Loading @@ -73,8 +73,8 @@ bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { // The comparison ignores the last update time. // The comparison ignores the last update time. bool StatsData::operator==(const StatsData& o) const { bool StatsData::operator==(const StatsData& o) const { return std::tie(serverSockAddr, total, rcodeCounts, latencyUs) == return std::tie(sockAddr, total, rcodeCounts, latencyUs) == std::tie(o.serverSockAddr, o.total, o.rcodeCounts, o.latencyUs); std::tie(o.sockAddr, o.total, o.rcodeCounts, o.latencyUs); } } int StatsData::averageLatencyMs() const { int StatsData::averageLatencyMs() const { Loading @@ -82,7 +82,7 @@ int StatsData::averageLatencyMs() const { } } std::string StatsData::toString() const { std::string StatsData::toString() const { if (total == 0) return StringPrintf("%s <no data>", serverSockAddr.ip().toString().c_str()); if (total == 0) return StringPrintf("%s <no data>", sockAddr.ip().toString().c_str()); const auto now = std::chrono::steady_clock::now(); const auto now = std::chrono::steady_clock::now(); const int lastUpdateSec = duration_cast<seconds>(now - lastUpdate).count(); const int lastUpdateSec = duration_cast<seconds>(now - lastUpdate).count(); Loading @@ -92,7 +92,7 @@ std::string StatsData::toString() const { buf += StringPrintf("%s:%d ", rcodeToName(rcode).c_str(), counts); buf += StringPrintf("%s:%d ", rcodeToName(rcode).c_str(), counts); } } } } return StringPrintf("%s (%d, %dms, [%s], %ds)", serverSockAddr.ip().toString().c_str(), total, return StringPrintf("%s (%d, %dms, [%s], %ds)", sockAddr.ip().toString().c_str(), total, averageLatencyMs(), buf.c_str(), lastUpdateSec); averageLatencyMs(), buf.c_str(), lastUpdateSec); } } Loading Loading @@ -171,20 +171,20 @@ void StatsRecords::incrementSkippedCount() { mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); } } bool DnsStats::setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol) { bool DnsStats::setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol) { if (!ensureNoInvalidIp(servers)) return false; if (!ensureNoInvalidIp(addrs)) return false; ServerStatsMap& statsMap = mStats[protocol]; StatsMap& statsMap = mStats[protocol]; for (const auto& server : servers) { for (const auto& addr : addrs) { statsMap.try_emplace(server, StatsRecords(server, kLogSize)); statsMap.try_emplace(addr, StatsRecords(addr, kLogSize)); } } // Clean up the map to eliminate the nodes not belonging to the given list of servers. // Clean up the map to eliminate the nodes not belonging to the given list of servers. const auto cleanup = [&](ServerStatsMap* statsMap) { const auto cleanup = [&](StatsMap* statsMap) { ServerStatsMap tmp; StatsMap tmp; for (const auto& server : servers) { for (const auto& addr : addrs) { if (statsMap->find(server) != statsMap->end()) { if (statsMap->find(addr) != statsMap->end()) { tmp.insert(statsMap->extract(server)); tmp.insert(statsMap->extract(addr)); } } } } statsMap->swap(tmp); statsMap->swap(tmp); Loading @@ -199,8 +199,8 @@ bool DnsStats::addStats(const IPSockAddr& ipSockAddr, const DnsQueryEvent& recor if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; bool added = false; bool added = false; for (auto& [serverSockAddr, statsRecords] : mStats[record.protocol()]) { for (auto& [sockAddr, statsRecords] : mStats[record.protocol()]) { if (serverSockAddr == ipSockAddr) { if (sockAddr == ipSockAddr) { const StatsRecords::Record rec = { const StatsRecords::Record rec = { .rcode = record.rcode(), .rcode = record.rcode(), .linux_errno = record.linux_errno(), .linux_errno = record.linux_errno(), Loading Loading @@ -265,10 +265,10 @@ std::vector<StatsData> DnsStats::getStats(Protocol protocol) const { } } void DnsStats::dump(DumpWriter& dw) { void DnsStats::dump(DumpWriter& dw) { const auto dumpStatsMap = [&](ServerStatsMap& statsMap) { const auto dumpStatsMap = [&](StatsMap& statsMap) { ScopedIndent indentLog(dw); ScopedIndent indentLog(dw); if (statsMap.size() == 0) { if (statsMap.size() == 0) { dw.println("<no server>"); dw.println("<no data>"); return; return; } } for (const auto& [_, statsRecords] : statsMap) { for (const auto& [_, statsRecords] : statsMap) { Loading @@ -290,6 +290,9 @@ void DnsStats::dump(DumpWriter& dw) { dw.println("over TCP"); dw.println("over TCP"); dumpStatsMap(mStats[PROTO_TCP]); dumpStatsMap(mStats[PROTO_TCP]); dw.println("over MDNS"); dumpStatsMap(mStats[PROTO_MDNS]); } } } // namespace android::net } // namespace android::net
DnsStats.h +8 −8 Original line number Original line Diff line number Diff line Loading @@ -33,12 +33,12 @@ namespace android::net { // The overall information of a StatsRecords. // The overall information of a StatsRecords. struct StatsData { struct StatsData { StatsData(const netdutils::IPSockAddr& ipSockAddr) : serverSockAddr(ipSockAddr) { StatsData(const netdutils::IPSockAddr& ipSockAddr) : sockAddr(ipSockAddr) { lastUpdate = std::chrono::steady_clock::now(); lastUpdate = std::chrono::steady_clock::now(); }; }; // Server socket address. // Socket address. netdutils::IPSockAddr serverSockAddr; netdutils::IPSockAddr sockAddr; // The most recent number of records being accumulated. // The most recent number of records being accumulated. int total = 0; int total = 0; Loading Loading @@ -106,15 +106,15 @@ class StatsRecords { static constexpr int kMaxQuality = 10000; static constexpr int kMaxQuality = 10000; }; }; // DnsStats class manages the statistics of DNS servers per netId. // DnsStats class manages the statistics of DNS servers or MDNS multicast addresses per netId. // The class itself is not thread-safe. // The class itself is not thread-safe. class DnsStats { class DnsStats { public: public: using ServerStatsMap = std::map<netdutils::IPSockAddr, StatsRecords>; using StatsMap = std::map<netdutils::IPSockAddr, StatsRecords>; // Add |servers| to the map, and remove no-longer-used servers. // Add |addrs| to the map, and remove no-longer-used addresses. // Return true if they are successfully added; otherwise, return false. // Return true if they are successfully added; otherwise, return false. bool setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol); bool setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol); // Return true if |record| is successfully added into |server|'s stats; otherwise, return false. // Return true if |record| is successfully added into |server|'s stats; otherwise, return false. bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); Loading @@ -133,7 +133,7 @@ class DnsStats { static constexpr size_t kLogSize = 128; static constexpr size_t kLogSize = 128; private: private: std::map<Protocol, ServerStatsMap> mStats; std::map<Protocol, StatsMap> mStats; }; }; } // namespace android::net } // namespace android::net
DnsStatsTest.cpp +75 −41 Original line number Original line Diff line number Diff line Loading @@ -116,7 +116,8 @@ class DnsStatsTest : public ::testing::Test { // Get the output string from dump() and check the content. // Get the output string from dump() and check the content. void verifyDumpOutput(const std::vector<StatsData>& tcpData, void verifyDumpOutput(const std::vector<StatsData>& tcpData, const std::vector<StatsData>& udpData, const std::vector<StatsData>& udpData, const std::vector<StatsData>& dotData) { const std::vector<StatsData>& dotData, const std::vector<StatsData>& mdnsData) { // A pattern to capture three matches: // A pattern to capture three matches: // server address (empty allowed), the statistics, and the score. // server address (empty allowed), the statistics, and the score. const std::regex pattern(R"(\s{4,}([0-9a-fA-F:\.]*)[ ]?([<(].*[>)])[ ]?(\S*))"); const std::regex pattern(R"(\s{4,}([0-9a-fA-F:\.]*)[ ]?([<(].*[>)])[ ]?(\S*))"); Loading @@ -128,11 +129,11 @@ class DnsStatsTest : public ::testing::Test { ASSERT_NE(dumpString->find(protocol), std::string::npos); ASSERT_NE(dumpString->find(protocol), std::string::npos); std::smatch sm; std::smatch sm; // Expect to show something even if none of servers is set. // Expect to show something even if none of servers or mdns multicast addresses is set. if (statsData.empty()) { if (statsData.empty()) { ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); EXPECT_TRUE(sm[1].str().empty()); EXPECT_TRUE(sm[1].str().empty()); EXPECT_EQ(sm[2], "<no server>"); EXPECT_EQ(sm[2], "<no data>"); EXPECT_TRUE(sm[3].str().empty()); EXPECT_TRUE(sm[3].str().empty()); *dumpString = sm.suffix(); *dumpString = sm.suffix(); return; return; Loading @@ -140,7 +141,7 @@ class DnsStatsTest : public ::testing::Test { for (const auto& stats : statsData) { for (const auto& stats : statsData) { ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); EXPECT_EQ(sm[1], stats.serverSockAddr.ip().toString()); EXPECT_EQ(sm[1], stats.sockAddr.ip().toString()); EXPECT_FALSE(sm[2].str().empty()); EXPECT_FALSE(sm[2].str().empty()); EXPECT_FALSE(sm[3].str().empty()); EXPECT_FALSE(sm[3].str().empty()); *dumpString = sm.suffix(); *dumpString = sm.suffix(); Loading @@ -150,6 +151,7 @@ class DnsStatsTest : public ::testing::Test { check(udpData, "UDP", &dumpString); check(udpData, "UDP", &dumpString); check(dotData, "TLS", &dumpString); check(dotData, "TLS", &dumpString); check(tcpData, "TCP", &dumpString); check(tcpData, "TCP", &dumpString); check(mdnsData, "MDNS", &dumpString); // Ensure the whole string has been checked. // Ensure the whole string has been checked. EXPECT_EQ(dumpString, "\n"); EXPECT_EQ(dumpString, "\n"); Loading @@ -169,9 +171,9 @@ class DnsStatsTest : public ::testing::Test { DnsStats mDnsStats; DnsStats mDnsStats; }; }; TEST_F(DnsStatsTest, SetServers) { TEST_F(DnsStatsTest, SetAddrs) { // Check before any operation to mDnsStats. // Check before any operation to mDnsStats. verifyDumpOutput({}, {}, {}); verifyDumpOutput({}, {}, {}, {}); static const struct { static const struct { std::vector<std::string> servers; std::vector<std::string> servers; Loading Loading @@ -213,9 +215,9 @@ TEST_F(DnsStatsTest, SetServers) { ipSockAddrs.push_back(IPSockAddr::toIPSockAddr(server, 53)); ipSockAddrs.push_back(IPSockAddr::toIPSockAddr(server, 53)); } } EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_TCP) == isSuccess); EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_TCP) == isSuccess); EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_UDP) == isSuccess); EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_UDP) == isSuccess); EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_DOT) == isSuccess); EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_DOT) == isSuccess); std::vector<StatsData> expectedStats; std::vector<StatsData> expectedStats; expectedStats.reserve(expectation.size()); expectedStats.reserve(expectation.size()); Loading @@ -228,7 +230,7 @@ TEST_F(DnsStatsTest, SetServers) { EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); } } verifyDumpOutput({}, {}, {}); verifyDumpOutput({}, {}, {}, {}); } } TEST_F(DnsStatsTest, SetServersDifferentPorts) { TEST_F(DnsStatsTest, SetServersDifferentPorts) { Loading @@ -240,18 +242,18 @@ TEST_F(DnsStatsTest, SetServersDifferentPorts) { }; }; // Servers setup fails due to port unset. // Servers setup fails due to port unset. EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_TCP)); EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_TCP)); EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_UDP)); EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_DOT)); EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_DOT)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); verifyDumpOutput({}, {}, {}); verifyDumpOutput({}, {}, {}, {}); EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_TCP)); EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_TCP)); EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_UDP)); EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_DOT)); const std::vector<StatsData> expectedStats = { const std::vector<StatsData> expectedStats = { makeStatsData(servers[2], 0, 0ms, {}), makeStatsData(servers[3], 0, 0ms, {}), makeStatsData(servers[2], 0, 0ms, {}), makeStatsData(servers[3], 0, 0ms, {}), Loading @@ -262,7 +264,7 @@ TEST_F(DnsStatsTest, SetServersDifferentPorts) { EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); verifyDumpOutput(expectedStats, expectedStats, expectedStats); verifyDumpOutput(expectedStats, expectedStats, expectedStats, {}); } } TEST_F(DnsStatsTest, AddStatsAndClear) { TEST_F(DnsStatsTest, AddStatsAndClear) { Loading @@ -270,10 +272,16 @@ TEST_F(DnsStatsTest, AddStatsAndClear) { IPSockAddr::toIPSockAddr("127.0.0.1", 53), IPSockAddr::toIPSockAddr("127.0.0.1", 53), IPSockAddr::toIPSockAddr("127.0.0.2", 53), IPSockAddr::toIPSockAddr("127.0.0.2", 53), }; }; const std::vector<IPSockAddr> mdnsaddrs = { IPSockAddr::toIPSockAddr("ff02::fb", 5353), IPSockAddr::toIPSockAddr("224.0.0.251", 5353), }; const DnsQueryEvent record = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); const DnsQueryEvent record = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); const DnsQueryEvent mdnsrecord = makeDnsQueryEvent(PROTO_MDNS, NS_R_NO_ERROR, 10ms); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(mdnsaddrs, PROTO_MDNS)); // Fail to add stats because of incorrect arguments. // Fail to add stats because of incorrect arguments. EXPECT_FALSE(mDnsStats.addStats(IPSockAddr::toIPSockAddr("127.0.0.4", 53), record)); EXPECT_FALSE(mDnsStats.addStats(IPSockAddr::toIPSockAddr("127.0.0.4", 53), record)); Loading @@ -282,6 +290,8 @@ TEST_F(DnsStatsTest, AddStatsAndClear) { EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); EXPECT_TRUE(mDnsStats.addStats(servers[1], record)); EXPECT_TRUE(mDnsStats.addStats(servers[1], record)); EXPECT_TRUE(mDnsStats.addStats(mdnsaddrs[0], mdnsrecord)); EXPECT_TRUE(mDnsStats.addStats(mdnsaddrs[1], mdnsrecord)); const std::vector<StatsData> expectedStatsForTcp = { const std::vector<StatsData> expectedStatsForTcp = { makeStatsData(servers[0], 0, 0ms, {}), makeStatsData(servers[0], 0, 0ms, {}), Loading @@ -292,19 +302,27 @@ TEST_F(DnsStatsTest, AddStatsAndClear) { makeStatsData(servers[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}), makeStatsData(servers[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}), }; }; const std::vector<StatsData> expectedStatsForMdns = { makeStatsData(mdnsaddrs[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}), makeStatsData(mdnsaddrs[0], 1, 10ms, {{NS_R_NO_ERROR, 1}}), }; EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStatsForTcp, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStatsForTcp, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStatsForUdp, 10ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStatsForUdp, 10ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); verifyDumpOutput(expectedStatsForTcp, expectedStatsForUdp, {}); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, expectedStatsForMdns, 10ms)); verifyDumpOutput(expectedStatsForTcp, expectedStatsForUdp, {}, expectedStatsForMdns); // Clear stats. // Clear stats. EXPECT_TRUE(mDnsStats.setServers({}, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setServers({}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setServers({}, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_MDNS)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); verifyDumpOutput({}, {}, {}); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, {}, NO_AVERAGE_LATENCY)); verifyDumpOutput({}, {}, {}, {}); } } TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { Loading @@ -315,7 +333,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { const DnsQueryEvent recordNoError = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); const DnsQueryEvent recordNoError = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); const DnsQueryEvent recordTimeout = makeDnsQueryEvent(PROTO_UDP, NS_R_TIMEOUT, 250ms); const DnsQueryEvent recordTimeout = makeDnsQueryEvent(PROTO_UDP, NS_R_TIMEOUT, 250ms); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP)); // Add a record to 127.0.0.1. // Add a record to 127.0.0.1. EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); Loading @@ -332,7 +350,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { }; }; EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); verifyDumpOutput({}, expectedStats, {}); verifyDumpOutput({}, expectedStats, {}, {}); // Update the server list, the stats of 127.0.0.2 will remain. // Update the server list, the stats of 127.0.0.2 will remain. servers = { servers = { Loading @@ -340,7 +358,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { IPSockAddr::toIPSockAddr("127.0.0.3", 53), IPSockAddr::toIPSockAddr("127.0.0.3", 53), IPSockAddr::toIPSockAddr("127.0.0.4", 53), IPSockAddr::toIPSockAddr("127.0.0.4", 53), }; }; EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP)); expectedStats = { expectedStats = { makeStatsData(servers[0], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}), makeStatsData(servers[0], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}), makeStatsData(servers[1], 0, 0ms, {}), makeStatsData(servers[1], 0, 0ms, {}), Loading @@ -348,7 +366,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { }; }; EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 130ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 130ms)); verifyDumpOutput({}, expectedStats, {}); verifyDumpOutput({}, expectedStats, {}, {}); // Let's add a record to 127.0.0.2 again. // Let's add a record to 127.0.0.2 again. EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); Loading @@ -359,7 +377,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { }; }; EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); verifyDumpOutput({}, expectedStats, {}); verifyDumpOutput({}, expectedStats, {}, {}); } } TEST_F(DnsStatsTest, AddStatsRecords_100000) { TEST_F(DnsStatsTest, AddStatsRecords_100000) { Loading @@ -375,6 +393,11 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) { IPSockAddr::toIPSockAddr("127.0.0.4", 53), IPSockAddr::toIPSockAddr("127.0.0.4", 53), }; }; const std::vector<IPSockAddr> mdnsaddrs = { IPSockAddr::toIPSockAddr("ff02::fb", 5353), IPSockAddr::toIPSockAddr("224.0.0.251", 5353), }; // To test unknown rcode in rcodeToName(), store the elements as type int. // To test unknown rcode in rcodeToName(), store the elements as type int. const std::array<int, rcodeNum> rcodes = { const std::array<int, rcodeNum> rcodes = { NS_R_NO_ERROR, // NOERROR NS_R_NO_ERROR, // NOERROR Loading @@ -383,9 +406,10 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) { NS_R_INTERNAL_ERROR, // INTERNAL_ERROR NS_R_INTERNAL_ERROR, // INTERNAL_ERROR }; }; EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_TCP)); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs(mdnsaddrs, PROTO_MDNS)); for (size_t i = 0; i < operations; i++) { for (size_t i = 0; i < operations; i++) { const NsRcode rcode = static_cast<NsRcode>(rcodes[i % rcodeNum]); const NsRcode rcode = static_cast<NsRcode>(rcodes[i % rcodeNum]); Loading @@ -398,6 +422,11 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) { ASSERT_TRUE(mDnsStats.addStats(server, eventUdp)); ASSERT_TRUE(mDnsStats.addStats(server, eventUdp)); ASSERT_TRUE(mDnsStats.addStats(server, eventDot)); ASSERT_TRUE(mDnsStats.addStats(server, eventDot)); } } const auto eventMdns = makeDnsQueryEvent(PROTO_MDNS, rcode, milliseconds(i)); for (const auto& mdnsaddr : mdnsaddrs) { SCOPED_TRACE(mdnsaddr.toString() + "-" + std::to_string(i)); ASSERT_TRUE(mDnsStats.addStats(mdnsaddr, eventMdns)); } } } std::map<int, int> expectedRcodeCounts; std::map<int, int> expectedRcodeCounts; Loading @@ -414,10 +443,15 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) { makeStatsData(servers[3], logSize, logSize * 99935500us, expectedRcodeCounts), makeStatsData(servers[3], logSize, logSize * 99935500us, expectedRcodeCounts), }; }; const std::vector<StatsData> expectedMdnsStats = { makeStatsData(mdnsaddrs[1], logSize, logSize * 99935500us, expectedRcodeCounts), makeStatsData(mdnsaddrs[0], logSize, logSize * 99935500us, expectedRcodeCounts), }; EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, 99935500us)); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, 99935500us)); verifyDumpOutput(expectedStats, expectedStats, expectedStats); EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, expectedMdnsStats, 99935500us)); verifyDumpOutput(expectedStats, expectedStats, expectedStats, expectedMdnsStats); } } TEST_F(DnsStatsTest, GetServers_SortingByLatency) { TEST_F(DnsStatsTest, GetServers_SortingByLatency) { Loading @@ -430,8 +464,8 @@ TEST_F(DnsStatsTest, GetServers_SortingByLatency) { EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), IsEmpty()); EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), IsEmpty()); // Before there's any stats, the list of the sorted servers is the same as the setup's one. // Before there's any stats, the list of the sorted servers is the same as the setup's one. EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_DOT)); EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_DOT)); EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), testing::ElementsAreArray({server1, server2, server3, server4})); testing::ElementsAreArray({server1, server2, server3, server4})); Loading Loading @@ -473,7 +507,7 @@ TEST_F(DnsStatsTest, GetServers_SortingByLatency) { testing::ElementsAreArray({server2, server3, server1, server4})); testing::ElementsAreArray({server2, server3, server1, server4})); // The list of the DNS servers changed. // The list of the DNS servers changed. EXPECT_TRUE(mDnsStats.setServers({server2, server4}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs({server2, server4}, PROTO_UDP)); EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), testing::ElementsAreArray({server2, server4})); testing::ElementsAreArray({server2, server4})); Loading @@ -490,7 +524,7 @@ TEST_F(DnsStatsTest, GetServers_DeprioritizingBadServers) { const IPSockAddr server3 = IPSockAddr::toIPSockAddr("127.0.0.3", 53); const IPSockAddr server3 = IPSockAddr::toIPSockAddr("127.0.0.3", 53); const IPSockAddr server4 = IPSockAddr::toIPSockAddr("127.0.0.4", 53); const IPSockAddr server4 = IPSockAddr::toIPSockAddr("127.0.0.4", 53); EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_UDP)); EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_UDP)); int server1Counts = 0; int server1Counts = 0; int server2Counts = 0; int server2Counts = 0; Loading Loading @@ -521,15 +555,15 @@ TEST_F(DnsStatsTest, GetServers_DeprioritizingBadServers) { const std::vector<StatsData> allStatsData = mDnsStats.getStats(PROTO_UDP); const std::vector<StatsData> allStatsData = mDnsStats.getStats(PROTO_UDP); for (const auto& data : allStatsData) { for (const auto& data : allStatsData) { EXPECT_EQ(data.rcodeCounts.size(), 1U); EXPECT_EQ(data.rcodeCounts.size(), 1U); if (data.serverSockAddr == server1 || data.serverSockAddr == server2) { if (data.sockAddr == server1 || data.sockAddr == server2) { const auto it = data.rcodeCounts.find(NS_R_NO_ERROR); const auto it = data.rcodeCounts.find(NS_R_NO_ERROR); ASSERT_NE(it, data.rcodeCounts.end()); ASSERT_NE(it, data.rcodeCounts.end()); EXPECT_GT(server2Counts, 2 * server1Counts); // At least twice larger. EXPECT_GT(server2Counts, 2 * server1Counts); // At least twice larger. } else if (data.serverSockAddr == server3) { } else if (data.sockAddr == server3) { const auto it = data.rcodeCounts.find(NS_R_TIMEOUT); const auto it = data.rcodeCounts.find(NS_R_TIMEOUT); ASSERT_NE(it, data.rcodeCounts.end()); ASSERT_NE(it, data.rcodeCounts.end()); EXPECT_LT(it->second, 10); EXPECT_LT(it->second, 10); } else if (data.serverSockAddr == server4) { } else if (data.sockAddr == server4) { const auto it = data.rcodeCounts.find(NS_R_INTERNAL_ERROR); const auto it = data.rcodeCounts.find(NS_R_INTERNAL_ERROR); ASSERT_NE(it, data.rcodeCounts.end()); ASSERT_NE(it, data.rcodeCounts.end()); EXPECT_LT(it->second, 10); EXPECT_LT(it->second, 10); Loading
Experiments.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,7 @@ class Experiments { "dot_validation_latency_factor", "dot_validation_latency_factor", "dot_validation_latency_offset_ms", "dot_validation_latency_offset_ms", "doh", "doh", "mdns_resolution", }; }; // This value is used in updateInternal as the default value if any flags can't be found. // This value is used in updateInternal as the default value if any flags can't be found. static constexpr int kFlagIntDefault = INT_MIN; static constexpr int kFlagIntDefault = INT_MIN; Loading