1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <array> 18 19 #include <android-base/test_utils.h> 20 #include <gmock/gmock.h> 21 #include <gtest/gtest.h> 22 23 #include "DnsStats.h" 24 25 namespace android::net { 26 27 using namespace std::chrono_literals; 28 using android::netdutils::IPSockAddr; 29 using std::chrono::microseconds; 30 using std::chrono::milliseconds; 31 using ::testing::IsEmpty; 32 using ::testing::UnorderedElementsAreArray; 33 34 namespace { 35 36 constexpr auto NO_AVERAGE_LATENCY = std::nullopt; 37 38 // A helper which can propagate the failure to outside of the stmt to know which line 39 // of stmt fails. The expectation fails only for the first failed stmt. 40 #define EXPECT_NO_FAILURE(stmt) \ 41 do { \ 42 bool alreadyFailed = HasFailure(); \ 43 stmt; \ 44 if (!alreadyFailed && HasFailure()) EXPECT_FALSE(HasFailure()); \ 45 } while (0) 46 47 DnsQueryEvent makeDnsQueryEvent(const Protocol protocol, const NsRcode rcode, 48 const milliseconds& latency) { 49 DnsQueryEvent event; 50 event.set_protocol(protocol); 51 event.set_rcode(rcode); 52 event.set_latency_micros(latency.count() * 1000); 53 return event; 54 } 55 56 StatsData makeStatsData(const IPSockAddr& server, const int total, const microseconds& latencyUs, 57 const std::map<int, int>& rcodeCounts) { 58 StatsData ret(server); 59 ret.total = total; 60 ret.latencyUs = latencyUs; 61 ret.rcodeCounts = rcodeCounts; 62 return ret; 63 } 64 65 } // namespace 66 67 // TODO: add StatsDataTest to ensure its methods return correct outputs. 68 69 class StatsRecordsTest : public ::testing::Test {}; 70 71 TEST_F(StatsRecordsTest, PushRecord) { 72 const IPSockAddr server = IPSockAddr::toIPSockAddr("127.0.0.2", 53); 73 constexpr size_t size = 3; 74 const StatsRecords::Record recordNoError = { 75 .rcode = NS_R_NO_ERROR, 76 .linux_errno = 0, 77 .latencyUs{10ms}, 78 }; 79 const StatsRecords::Record recordTimeout = { 80 .rcode = NS_R_TIMEOUT, 81 .linux_errno = 0, 82 .latencyUs{250ms}, 83 }; 84 85 StatsRecords sr(server, size); 86 EXPECT_EQ(sr.getStatsData(), makeStatsData(server, 0, 0ms, {})); 87 88 sr.push(recordNoError); 89 EXPECT_EQ(sr.getStatsData(), makeStatsData(server, 1, 10ms, {{NS_R_NO_ERROR, 1}})); 90 91 sr.push(recordNoError); 92 EXPECT_EQ(sr.getStatsData(), makeStatsData(server, 2, 20ms, {{NS_R_NO_ERROR, 2}})); 93 94 sr.push(recordTimeout); 95 EXPECT_EQ(sr.getStatsData(), 96 makeStatsData(server, 3, 270ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 1}})); 97 98 sr.push(recordTimeout); 99 EXPECT_EQ(sr.getStatsData(), 100 makeStatsData(server, 3, 510ms, {{NS_R_NO_ERROR, 1}, {NS_R_TIMEOUT, 2}})); 101 102 sr.push(recordTimeout); 103 EXPECT_EQ(sr.getStatsData(), 104 makeStatsData(server, 3, 750ms, {{NS_R_NO_ERROR, 0}, {NS_R_TIMEOUT, 3}})); 105 } 106 107 class DnsStatsTest : public ::testing::Test { 108 protected: 109 std::string captureDumpOutput() { 110 netdutils::DumpWriter dw(STDOUT_FILENO); 111 CapturedStdout captured; 112 mDnsStats.dump(dw); 113 return captured.str(); 114 } 115 116 // Get the output string from dump() and check the content. 117 void verifyDumpOutput(const std::vector<StatsData>& tcpData, 118 const std::vector<StatsData>& udpData, 119 const std::vector<StatsData>& dotData) { 120 // A pattern to capture three matches: 121 // server address (empty allowed), the statistics, and the score. 122 const std::regex pattern(R"(\s{4,}([0-9a-fA-F:\.]*)[ ]?([<(].*[>)])[ ]?(\S*))"); 123 std::string dumpString = captureDumpOutput(); 124 125 const auto check = [&](const std::vector<StatsData>& statsData, const std::string& protocol, 126 std::string* dumpString) { 127 SCOPED_TRACE(protocol); 128 ASSERT_NE(dumpString->find(protocol), std::string::npos); 129 std::smatch sm; 130 131 // Expect to show something even if none of servers is set. 132 if (statsData.empty()) { 133 ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); 134 EXPECT_TRUE(sm[1].str().empty()); 135 EXPECT_EQ(sm[2], "<no server>"); 136 EXPECT_TRUE(sm[3].str().empty()); 137 *dumpString = sm.suffix(); 138 return; 139 } 140 141 for (const auto& stats : statsData) { 142 ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern)); 143 EXPECT_EQ(sm[1], stats.serverSockAddr.ip().toString()); 144 EXPECT_FALSE(sm[2].str().empty()); 145 EXPECT_FALSE(sm[3].str().empty()); 146 *dumpString = sm.suffix(); 147 } 148 }; 149 150 check(udpData, "UDP", &dumpString); 151 check(dotData, "TLS", &dumpString); 152 check(tcpData, "TCP", &dumpString); 153 154 // Ensure the whole string has been checked. 155 EXPECT_EQ(dumpString, "\n"); 156 } 157 158 void verifyDnsStatsContent(Protocol protocol, const std::vector<StatsData>& expectedStats, 159 const std::optional<microseconds>& expectedAvgLatency) { 160 if (expectedStats.empty()) { 161 EXPECT_THAT(mDnsStats.getStats(protocol), IsEmpty()); 162 } else { 163 EXPECT_THAT(mDnsStats.getStats(protocol), UnorderedElementsAreArray(expectedStats)); 164 } 165 166 EXPECT_EQ(mDnsStats.getAverageLatencyUs(protocol), expectedAvgLatency); 167 } 168 169 DnsStats mDnsStats; 170 }; 171 172 TEST_F(DnsStatsTest, SetServers) { 173 // Check before any operation to mDnsStats. 174 verifyDumpOutput({}, {}, {}); 175 176 static const struct { 177 std::vector<std::string> servers; 178 std::vector<std::string> expectation; 179 bool isSuccess; 180 } tests[] = { 181 // Normal case. 182 { 183 {"127.0.0.1", "127.0.0.2", "fe80::1%22", "2001:db8::2", "::1"}, 184 {"127.0.0.1", "127.0.0.2", "fe80::1%22", "2001:db8::2", "::1"}, 185 true, 186 }, 187 // Duplicate servers. 188 { 189 {"127.0.0.1", "2001:db8::2", "127.0.0.1", "2001:db8::2"}, 190 {"127.0.0.1", "2001:db8::2"}, 191 true, 192 }, 193 // Invalid server addresses. The state remains in previous state. 194 { 195 {"not_an_ip", "127.0.0.3", "127.a.b.2"}, 196 {"127.0.0.1", "2001:db8::2"}, 197 false, 198 }, 199 // Clean up the old servers 127.0.0.1 and 127.0.0.2. 200 { 201 {"127.0.0.4", "2001:db8::5"}, 202 {"127.0.0.4", "2001:db8::5"}, 203 true, 204 }, 205 // Empty list. 206 {{}, {}, true}, 207 }; 208 209 for (const auto& [servers, expectation, isSuccess] : tests) { 210 std::vector<IPSockAddr> ipSockAddrs; 211 ipSockAddrs.reserve(servers.size()); 212 for (const auto& server : servers) { 213 ipSockAddrs.push_back(IPSockAddr::toIPSockAddr(server, 53)); 214 } 215 216 EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_TCP) == isSuccess); 217 EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_UDP) == isSuccess); 218 EXPECT_TRUE(mDnsStats.setServers(ipSockAddrs, PROTO_DOT) == isSuccess); 219 220 std::vector<StatsData> expectedStats; 221 expectedStats.reserve(expectation.size()); 222 for (const auto& exp : expectation) { 223 expectedStats.push_back(makeStatsData(IPSockAddr::toIPSockAddr(exp, 53), 0, 0ms, {})); 224 } 225 226 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY)); 227 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY)); 228 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); 229 } 230 231 verifyDumpOutput({}, {}, {}); 232 } 233 234 TEST_F(DnsStatsTest, SetServersDifferentPorts) { 235 const std::vector<IPSockAddr> servers = { 236 IPSockAddr::toIPSockAddr("127.0.0.1", 0), IPSockAddr::toIPSockAddr("fe80::1", 0), 237 IPSockAddr::toIPSockAddr("127.0.0.1", 53), IPSockAddr::toIPSockAddr("127.0.0.1", 5353), 238 IPSockAddr::toIPSockAddr("127.0.0.1", 853), IPSockAddr::toIPSockAddr("fe80::1", 53), 239 IPSockAddr::toIPSockAddr("fe80::1", 5353), IPSockAddr::toIPSockAddr("fe80::1", 853), 240 }; 241 242 // Servers setup fails due to port unset. 243 EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_TCP)); 244 EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_UDP)); 245 EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_DOT)); 246 247 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); 248 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); 249 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); 250 verifyDumpOutput({}, {}, {}); 251 252 EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_TCP)); 253 EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_UDP)); 254 EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_DOT)); 255 256 const std::vector<StatsData> expectedStats = { 257 makeStatsData(servers[2], 0, 0ms, {}), makeStatsData(servers[3], 0, 0ms, {}), 258 makeStatsData(servers[4], 0, 0ms, {}), makeStatsData(servers[5], 0, 0ms, {}), 259 makeStatsData(servers[6], 0, 0ms, {}), makeStatsData(servers[7], 0, 0ms, {}), 260 }; 261 262 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY)); 263 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY)); 264 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY)); 265 verifyDumpOutput(expectedStats, expectedStats, expectedStats); 266 } 267 268 TEST_F(DnsStatsTest, AddStatsAndClear) { 269 const std::vector<IPSockAddr> servers = { 270 IPSockAddr::toIPSockAddr("127.0.0.1", 53), 271 IPSockAddr::toIPSockAddr("127.0.0.2", 53), 272 }; 273 const DnsQueryEvent record = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); 274 275 EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_TCP)); 276 EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); 277 278 // Fail to add stats because of incorrect arguments. 279 EXPECT_FALSE(mDnsStats.addStats(IPSockAddr::toIPSockAddr("127.0.0.4", 53), record)); 280 EXPECT_FALSE(mDnsStats.addStats(IPSockAddr::toIPSockAddr("127.a.b.4", 53), record)); 281 282 EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); 283 EXPECT_TRUE(mDnsStats.addStats(servers[0], record)); 284 EXPECT_TRUE(mDnsStats.addStats(servers[1], record)); 285 286 const std::vector<StatsData> expectedStatsForTcp = { 287 makeStatsData(servers[0], 0, 0ms, {}), 288 makeStatsData(servers[1], 0, 0ms, {}), 289 }; 290 const std::vector<StatsData> expectedStatsForUdp = { 291 makeStatsData(servers[0], 2, 20ms, {{NS_R_NO_ERROR, 2}}), 292 makeStatsData(servers[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}), 293 }; 294 295 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStatsForTcp, NO_AVERAGE_LATENCY)); 296 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStatsForUdp, 10ms)); 297 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); 298 verifyDumpOutput(expectedStatsForTcp, expectedStatsForUdp, {}); 299 300 // Clear stats. 301 EXPECT_TRUE(mDnsStats.setServers({}, PROTO_TCP)); 302 EXPECT_TRUE(mDnsStats.setServers({}, PROTO_UDP)); 303 EXPECT_TRUE(mDnsStats.setServers({}, PROTO_DOT)); 304 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY)); 305 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY)); 306 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY)); 307 verifyDumpOutput({}, {}, {}); 308 } 309 310 TEST_F(DnsStatsTest, StatsRemainsInExistentServer) { 311 std::vector<IPSockAddr> servers = { 312 IPSockAddr::toIPSockAddr("127.0.0.1", 53), 313 IPSockAddr::toIPSockAddr("127.0.0.2", 53), 314 }; 315 const DnsQueryEvent recordNoError = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms); 316 const DnsQueryEvent recordTimeout = makeDnsQueryEvent(PROTO_UDP, NS_R_TIMEOUT, 250ms); 317 318 EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); 319 320 // Add a record to 127.0.0.1. 321 EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); 322 323 // Add four records to 127.0.0.2. 324 EXPECT_TRUE(mDnsStats.addStats(servers[1], recordNoError)); 325 EXPECT_TRUE(mDnsStats.addStats(servers[1], recordNoError)); 326 EXPECT_TRUE(mDnsStats.addStats(servers[1], recordTimeout)); 327 EXPECT_TRUE(mDnsStats.addStats(servers[1], recordTimeout)); 328 329 std::vector<StatsData> expectedStats = { 330 makeStatsData(servers[0], 1, 10ms, {{NS_R_NO_ERROR, 1}}), 331 makeStatsData(servers[1], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}), 332 }; 333 EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); 334 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); 335 verifyDumpOutput({}, expectedStats, {}); 336 337 // Update the server list, the stats of 127.0.0.2 will remain. 338 servers = { 339 IPSockAddr::toIPSockAddr("127.0.0.2", 53), 340 IPSockAddr::toIPSockAddr("127.0.0.3", 53), 341 IPSockAddr::toIPSockAddr("127.0.0.4", 53), 342 }; 343 EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); 344 expectedStats = { 345 makeStatsData(servers[0], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}), 346 makeStatsData(servers[1], 0, 0ms, {}), 347 makeStatsData(servers[2], 0, 0ms, {}), 348 }; 349 EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); 350 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 130ms)); 351 verifyDumpOutput({}, expectedStats, {}); 352 353 // Let's add a record to 127.0.0.2 again. 354 EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError)); 355 expectedStats = { 356 makeStatsData(servers[0], 5, 530ms, {{NS_R_NO_ERROR, 3}, {NS_R_TIMEOUT, 2}}), 357 makeStatsData(servers[1], 0, 0ms, {}), 358 makeStatsData(servers[2], 0, 0ms, {}), 359 }; 360 EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats)); 361 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms)); 362 verifyDumpOutput({}, expectedStats, {}); 363 } 364 365 TEST_F(DnsStatsTest, AddStatsRecords_100000) { 366 constexpr size_t operations = 100000; 367 constexpr size_t logSize = DnsStats::kLogSize; 368 constexpr size_t rcodeNum = 4; // A value by which kLogSize is divisible. 369 ASSERT_EQ(logSize % rcodeNum, 0U); 370 371 const std::vector<IPSockAddr> servers = { 372 IPSockAddr::toIPSockAddr("127.0.0.1", 53), 373 IPSockAddr::toIPSockAddr("127.0.0.2", 53), 374 IPSockAddr::toIPSockAddr("127.0.0.3", 53), 375 IPSockAddr::toIPSockAddr("127.0.0.4", 53), 376 }; 377 378 // To test unknown rcode in rcodeToName(), store the elements as type int. 379 const std::array<int, rcodeNum> rcodes = { 380 NS_R_NO_ERROR, // NOERROR 381 NS_R_NXDOMAIN, // NXDOMAIN 382 99, // UNKNOWN(99) 383 NS_R_INTERNAL_ERROR, // INTERNAL_ERROR 384 }; 385 386 EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_TCP)); 387 EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_UDP)); 388 EXPECT_TRUE(mDnsStats.setServers(servers, PROTO_DOT)); 389 390 for (size_t i = 0; i < operations; i++) { 391 const NsRcode rcode = static_cast<NsRcode>(rcodes[i % rcodeNum]); 392 const auto eventTcp = makeDnsQueryEvent(PROTO_TCP, rcode, milliseconds(i)); 393 const auto eventUdp = makeDnsQueryEvent(PROTO_UDP, rcode, milliseconds(i)); 394 const auto eventDot = makeDnsQueryEvent(PROTO_DOT, rcode, milliseconds(i)); 395 for (const auto& server : servers) { 396 SCOPED_TRACE(server.toString() + "-" + std::to_string(i)); 397 ASSERT_TRUE(mDnsStats.addStats(server, eventTcp)); 398 ASSERT_TRUE(mDnsStats.addStats(server, eventUdp)); 399 ASSERT_TRUE(mDnsStats.addStats(server, eventDot)); 400 } 401 } 402 403 std::map<int, int> expectedRcodeCounts; 404 for (const auto& rcode : rcodes) { 405 expectedRcodeCounts.try_emplace(rcode, 32); 406 } 407 408 // The average latency 99935.5 ms is derived from (99872ms + 99873ms + ... + 99999ms) / logSize, 409 // where logSize is 128. 410 const std::vector<StatsData> expectedStats = { 411 makeStatsData(servers[0], logSize, logSize * 99935500us, expectedRcodeCounts), 412 makeStatsData(servers[1], logSize, logSize * 99935500us, expectedRcodeCounts), 413 makeStatsData(servers[2], logSize, logSize * 99935500us, expectedRcodeCounts), 414 makeStatsData(servers[3], logSize, logSize * 99935500us, expectedRcodeCounts), 415 }; 416 417 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, 99935500us)); 418 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 99935500us)); 419 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, 99935500us)); 420 verifyDumpOutput(expectedStats, expectedStats, expectedStats); 421 } 422 423 TEST_F(DnsStatsTest, GetServers_SortingByLatency) { 424 const IPSockAddr server1 = IPSockAddr::toIPSockAddr("127.0.0.1", 53); 425 const IPSockAddr server2 = IPSockAddr::toIPSockAddr("127.0.0.2", 53); 426 const IPSockAddr server3 = IPSockAddr::toIPSockAddr("2001:db8:cafe:d00d::1", 53); 427 const IPSockAddr server4 = IPSockAddr::toIPSockAddr("2001:db8:cafe:d00d::2", 53); 428 429 // Return empty list before setup. 430 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), IsEmpty()); 431 432 // Before there's any stats, the list of the sorted servers is the same as the setup's one. 433 EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_UDP)); 434 EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_DOT)); 435 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 436 testing::ElementsAreArray({server1, server2, server3, server4})); 437 438 // Add a record to server1. The qualities of the other servers increase. 439 EXPECT_TRUE(mDnsStats.addStats(server1, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms))); 440 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 441 testing::ElementsAreArray({server2, server3, server4, server1})); 442 443 // Add a record, with less repose time than server1, to server3. 444 EXPECT_TRUE(mDnsStats.addStats(server3, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 5ms))); 445 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 446 testing::ElementsAreArray({server2, server4, server3, server1})); 447 448 // Even though server2 has zero response time, select server4 as the first server because it 449 // doesn't have stats yet. 450 EXPECT_TRUE(mDnsStats.addStats(server2, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 0ms))); 451 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 452 testing::ElementsAreArray({server4, server2, server3, server1})); 453 454 // Updating DoT record to server4 changes nothing. 455 EXPECT_TRUE(mDnsStats.addStats(server4, makeDnsQueryEvent(PROTO_DOT, NS_R_NO_ERROR, 10ms))); 456 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 457 testing::ElementsAreArray({server4, server2, server3, server1})); 458 459 // Add a record, with a very large value of respose time, to server4. 460 EXPECT_TRUE(mDnsStats.addStats(server4, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 500000ms))); 461 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 462 testing::ElementsAreArray({server2, server3, server1, server4})); 463 464 // Add some internal_error records with permission error to server2. 465 // The internal_error won't cause the priority of server2 drop. (but some of the other 466 // quality factors will still be counted, such as skipped_count and latency) 467 auto recordFromNetworkRestricted = makeDnsQueryEvent(PROTO_UDP, NS_R_INTERNAL_ERROR, 1ms); 468 recordFromNetworkRestricted.set_linux_errno(static_cast<LinuxErrno>(EPERM)); 469 for (int i = 0; i < 3; i++) { 470 EXPECT_TRUE(mDnsStats.addStats(server2, recordFromNetworkRestricted)); 471 } 472 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 473 testing::ElementsAreArray({server2, server3, server1, server4})); 474 475 // The list of the DNS servers changed. 476 EXPECT_TRUE(mDnsStats.setServers({server2, server4}, PROTO_UDP)); 477 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 478 testing::ElementsAreArray({server2, server4})); 479 480 // It fails to add records to an non-existing server, and nothing is changed in getting 481 // the sorted servers. 482 EXPECT_FALSE(mDnsStats.addStats(server1, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms))); 483 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), 484 testing::ElementsAreArray({server2, server4})); 485 } 486 487 TEST_F(DnsStatsTest, GetServers_DeprioritizingBadServers) { 488 const IPSockAddr server1 = IPSockAddr::toIPSockAddr("127.0.0.1", 53); 489 const IPSockAddr server2 = IPSockAddr::toIPSockAddr("127.0.0.2", 53); 490 const IPSockAddr server3 = IPSockAddr::toIPSockAddr("127.0.0.3", 53); 491 const IPSockAddr server4 = IPSockAddr::toIPSockAddr("127.0.0.4", 53); 492 493 EXPECT_TRUE(mDnsStats.setServers({server1, server2, server3, server4}, PROTO_UDP)); 494 495 int server1Counts = 0; 496 int server2Counts = 0; 497 for (int i = 0; i < 5000; i++) { 498 const auto servers = mDnsStats.getSortedServers(PROTO_UDP); 499 EXPECT_EQ(servers.size(), 4U); 500 if (servers[0] == server1) { 501 // server1 is relatively slowly responsive. 502 EXPECT_TRUE(mDnsStats.addStats(servers[0], 503 makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 200ms))); 504 server1Counts++; 505 } else if (servers[0] == server2) { 506 // server2 is relatively quickly responsive. 507 EXPECT_TRUE(mDnsStats.addStats(servers[0], 508 makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 100ms))); 509 server2Counts++; 510 } else if (servers[0] == server3) { 511 // server3 always times out. 512 EXPECT_TRUE(mDnsStats.addStats(servers[0], 513 makeDnsQueryEvent(PROTO_UDP, NS_R_TIMEOUT, 1000ms))); 514 } else if (servers[0] == server4) { 515 // server4 is unusable. 516 EXPECT_TRUE(mDnsStats.addStats(servers[0], 517 makeDnsQueryEvent(PROTO_UDP, NS_R_INTERNAL_ERROR, 1ms))); 518 } 519 } 520 521 const std::vector<StatsData> allStatsData = mDnsStats.getStats(PROTO_UDP); 522 for (const auto& data : allStatsData) { 523 EXPECT_EQ(data.rcodeCounts.size(), 1U); 524 if (data.serverSockAddr == server1 || data.serverSockAddr == server2) { 525 const auto it = data.rcodeCounts.find(NS_R_NO_ERROR); 526 ASSERT_NE(it, data.rcodeCounts.end()); 527 EXPECT_GT(server2Counts, 2 * server1Counts); // At least twice larger. 528 } else if (data.serverSockAddr == server3) { 529 const auto it = data.rcodeCounts.find(NS_R_TIMEOUT); 530 ASSERT_NE(it, data.rcodeCounts.end()); 531 EXPECT_LT(it->second, 10); 532 } else if (data.serverSockAddr == server4) { 533 const auto it = data.rcodeCounts.find(NS_R_INTERNAL_ERROR); 534 ASSERT_NE(it, data.rcodeCounts.end()); 535 EXPECT_LT(it->second, 10); 536 } 537 } 538 } 539 540 } // namespace android::net 541