1 /* 2 * Copyright 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 #ifdef NDEBUG 18 #undef NDEBUG 19 #endif 20 21 #include <netdb.h> 22 23 #include <iostream> 24 #include <regex> 25 #include <string> 26 #include <thread> 27 #include <vector> 28 29 #include <aidl/android/net/IDnsResolver.h> 30 #include <android-base/file.h> 31 #include <android-base/format.h> 32 #include <android-base/stringprintf.h> 33 #include <android-base/strings.h> 34 #include <android-base/unique_fd.h> 35 #include <android/binder_manager.h> 36 #include <android/binder_process.h> 37 #include <gmock/gmock-matchers.h> 38 #include <gtest/gtest.h> 39 #include <netdutils/Stopwatch.h> 40 41 #include "dns_metrics_listener/base_metrics_listener.h" 42 #include "dns_metrics_listener/test_metrics.h" 43 #include "unsolicited_listener/unsolicited_event_listener.h" 44 45 #include "ResolverStats.h" 46 #include "dns_responder.h" 47 #include "dns_responder_client_ndk.h" 48 49 using aidl::android::net::IDnsResolver; 50 using aidl::android::net::ResolverHostsParcel; 51 using aidl::android::net::ResolverOptionsParcel; 52 using aidl::android::net::ResolverParamsParcel; 53 using aidl::android::net::metrics::INetdEventListener; 54 using android::base::ReadFdToString; 55 using android::base::StringPrintf; 56 using android::base::unique_fd; 57 using android::net::ResolverStats; 58 using android::net::metrics::TestOnDnsEvent; 59 using android::net::resolv::aidl::UnsolicitedEventListener; 60 using android::netdutils::Stopwatch; 61 62 // TODO: make this dynamic and stop depending on implementation details. 63 // Sync from TEST_NETID in dns_responder_client.cpp as resolv_integration_test.cpp does. 64 constexpr int TEST_NETID = 30; 65 66 namespace { 67 68 std::vector<std::string> dumpService(ndk::SpAIBinder binder) { 69 unique_fd localFd, remoteFd; 70 bool success = Pipe(&localFd, &remoteFd); 71 EXPECT_TRUE(success) << "Failed to open pipe for dumping: " << strerror(errno); 72 if (!success) return {}; 73 74 // dump() blocks until another thread has consumed all its output. 75 std::thread dumpThread = std::thread([binder, remoteFd{std::move(remoteFd)}]() { 76 EXPECT_EQ(STATUS_OK, AIBinder_dump(binder.get(), remoteFd, nullptr, 0)); 77 }); 78 79 std::string dumpContent; 80 81 EXPECT_TRUE(ReadFdToString(localFd.get(), &dumpContent)) 82 << "Error during dump: " << strerror(errno); 83 dumpThread.join(); 84 85 std::stringstream dumpStream(std::move(dumpContent)); 86 std::vector<std::string> lines; 87 std::string line; 88 while (std::getline(dumpStream, line)) { 89 lines.push_back(std::move(line)); 90 } 91 92 return lines; 93 } 94 95 } // namespace 96 97 class DnsResolverBinderTest : public ::testing::Test { 98 public: 99 DnsResolverBinderTest() { 100 ndk::SpAIBinder resolvBinder = ndk::SpAIBinder(AServiceManager_getService("dnsresolver")); 101 102 mDnsResolver = IDnsResolver::fromBinder(resolvBinder); 103 // This could happen when the test isn't running as root, or if netd isn't running. 104 assert(nullptr != mDnsResolver.get()); 105 // Create cache for test 106 mDnsResolver->createNetworkCache(TEST_NETID); 107 } 108 109 ~DnsResolverBinderTest() { 110 expectLog(); 111 // Destroy cache for test 112 mDnsResolver->destroyNetworkCache(TEST_NETID); 113 } 114 115 protected: 116 void expectLog() { 117 ndk::SpAIBinder netdBinder = ndk::SpAIBinder(AServiceManager_getService("netd")); 118 // This could happen when the test isn't running as root, or if netd isn't running. 119 assert(nullptr != netdBinder.get()); 120 // Send the service dump request to netd. 121 std::vector<std::string> lines = dumpService(netdBinder); 122 123 // Basic regexp to match dump output lines. Matches the beginning and end of the line, and 124 // puts the output of the command itself into the first match group. 125 // Example: " 11-05 00:23:39.481 myCommand(args) <2.02ms>". 126 // Accept any number of the leading space. 127 const std::basic_regex lineRegex( 128 "^\\s*[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[.][0-9]{3} " 129 "(.*)" 130 " <[0-9]+[.][0-9]{2}ms>$"); 131 132 // For each element of testdata, check that the expected output appears in the dump output. 133 // If not, fail the test and use hintRegex to print similar lines to assist in debugging. 134 for (const auto& td : mExpectedLogData) { 135 const bool found = 136 std::any_of(lines.begin(), lines.end(), [&](const std::string& line) { 137 std::smatch match; 138 if (!std::regex_match(line, match, lineRegex)) return false; 139 if (match.size() != 2) return false; 140 141 // The binder_to_string format is changed from S that will add "(null)" to 142 // the log on method's argument if binder object is null. But Q and R don't 143 // have this format in log. So to make register null listener tests are 144 // compatible from all version, just remove the "(null)" argument from 145 // output logs if existed. 146 const std::string output = android::base::StringReplace( 147 match[1].str(), "(null)", "", /*all=*/true); 148 return output == td.output; 149 }); 150 EXPECT_TRUE(found) << "Didn't find line '" << td.output << "' in dumpsys output."; 151 if (found) continue; 152 std::cerr << "Similar lines" << std::endl; 153 for (const auto& line : lines) { 154 if (std::regex_search(line, std::basic_regex(td.hintRegex))) { 155 std::cerr << line << std::endl; 156 } 157 } 158 } 159 160 // The log output is different between R and S, either one is fine for the 161 // test to avoid test compatible issue. 162 // TODO: Remove after S. 163 for (const auto& td : mExpectedLogDataWithPacel) { 164 const bool found = 165 std::any_of(lines.begin(), lines.end(), [&](const std::string& line) { 166 std::smatch match; 167 if (!std::regex_match(line, match, lineRegex)) return false; 168 return (match.size() == 2) && ((match[1].str() == td.withPacel.output) || 169 (match[1].str() == td.withoutPacel.output)); 170 }); 171 EXPECT_TRUE(found) << fmt::format("Didn't find line '{}' or '{}' in dumpsys output.", 172 td.withPacel.output, td.withoutPacel.output); 173 if (found) continue; 174 std::cerr << "Similar lines" << std::endl; 175 for (const auto& line : lines) { 176 if (std::regex_search(line, std::basic_regex(td.withPacel.hintRegex))) { 177 std::cerr << line << std::endl; 178 } 179 if (std::regex_search(line, std::basic_regex(td.withoutPacel.hintRegex))) { 180 std::cerr << line << std::endl; 181 } 182 } 183 } 184 } 185 186 struct LogData { 187 // Expected contents of the dump command. 188 const std::string output; 189 // A regex that might be helpful in matching relevant lines in the output. 190 // Used to make it easier to add test cases for this code. 191 const std::string hintRegex; 192 }; 193 194 // TODO: Remove this struct and below toString methods after S. 195 struct PossibleLogData { 196 LogData withPacel; 197 LogData withoutPacel; 198 }; 199 200 std::string toString(const std::vector<ResolverHostsParcel>& parms) { 201 std::string o; 202 const size_t size = parms.size(); 203 for (size_t i = 0; i < size; ++i) { 204 o.append(fmt::format("ResolverHostsParcel{{ipAddr: {}, hostName: {}}}", parms[i].ipAddr, 205 parms[i].hostName)); 206 if (i + 1 < size) o.append(", "); 207 } 208 return o; 209 } 210 211 std::string toString(const std::optional<ResolverOptionsParcel>& parms) { 212 if (!parms.has_value()) return "(null)"; 213 return fmt::format("ResolverOptionsParcel{{hosts: [{}], tcMode: {}, enforceDnsUid: {}}}", 214 toString(parms->hosts), parms->tcMode, parms->enforceDnsUid); 215 } 216 217 std::string toString(const ResolverParamsParcel& parms) { 218 return fmt::format( 219 "ResolverParamsParcel{{netId: {}, sampleValiditySeconds: {}, successThreshold: {}, " 220 "minSamples: {}, " 221 "maxSamples: {}, baseTimeoutMsec: {}, retryCount: {}, " 222 "servers: [{}], domains: [{}], " 223 "tlsName: {}, tlsServers: [{}], " 224 "tlsFingerprints: [{}], " 225 "caCertificate: {}, tlsConnectTimeoutMs: {}, " 226 "resolverOptions: {}, transportTypes: [{}]}}", 227 parms.netId, parms.sampleValiditySeconds, parms.successThreshold, parms.minSamples, 228 parms.maxSamples, parms.baseTimeoutMsec, parms.retryCount, 229 fmt::join(parms.servers, ", "), fmt::join(parms.domains, ", "), parms.tlsName, 230 fmt::join(parms.tlsServers, ", "), fmt::join(parms.tlsFingerprints, ", "), 231 android::base::StringReplace(parms.caCertificate, "\n", "\\n", true), 232 parms.tlsConnectTimeoutMs, toString(parms.resolverOptions), 233 fmt::join(parms.transportTypes, ", ")); 234 } 235 236 PossibleLogData toSetResolverConfigurationLogData(const ResolverParamsParcel& parms, 237 int returnCode = 0) { 238 std::string outputWithParcel = "setResolverConfiguration(" + toString(parms) + ")"; 239 std::string hintRegexWithParcel = fmt::format("setResolverConfiguration.*{}", parms.netId); 240 241 std::string outputWithoutParcel = "setResolverConfiguration()"; 242 std::string hintRegexWithoutParcel = "setResolverConfiguration"; 243 if (returnCode != 0) { 244 outputWithParcel.append(fmt::format(" -> ServiceSpecificException({}, \"{}\")", 245 returnCode, strerror(returnCode))); 246 hintRegexWithParcel.append(fmt::format(".*{}", returnCode)); 247 outputWithoutParcel.append(fmt::format(" -> ServiceSpecificException({}, \"{}\")", 248 returnCode, strerror(returnCode))); 249 hintRegexWithoutParcel.append(fmt::format(".*{}", returnCode)); 250 } 251 return {{std::move(outputWithParcel), std::move(hintRegexWithParcel)}, 252 {std::move(outputWithoutParcel), std::move(hintRegexWithoutParcel)}}; 253 } 254 255 std::shared_ptr<aidl::android::net::IDnsResolver> mDnsResolver; 256 std::vector<LogData> mExpectedLogData; 257 std::vector<PossibleLogData> mExpectedLogDataWithPacel; 258 }; 259 260 class TimedOperation : public Stopwatch { 261 public: 262 explicit TimedOperation(const std::string& name) : mName(name) {} 263 virtual ~TimedOperation() { 264 std::cerr << " " << mName << ": " << timeTakenUs() << "us" << std::endl; 265 } 266 267 private: 268 std::string mName; 269 }; 270 271 TEST_F(DnsResolverBinderTest, IsAlive) { 272 TimedOperation t("isAlive RPC"); 273 bool isAlive = false; 274 mDnsResolver->isAlive(&isAlive); 275 ASSERT_TRUE(isAlive); 276 } 277 278 TEST_F(DnsResolverBinderTest, RegisterEventListener_NullListener) { 279 ::ndk::ScopedAStatus status = mDnsResolver->registerEventListener(nullptr); 280 ASSERT_FALSE(status.isOk()); 281 ASSERT_EQ(EINVAL, status.getServiceSpecificError()); 282 mExpectedLogData.push_back( 283 {"registerEventListener() -> ServiceSpecificException(22, \"Invalid argument\")", 284 "registerEventListener.*22"}); 285 } 286 287 TEST_F(DnsResolverBinderTest, RegisterEventListener_DuplicateSubscription) { 288 class FakeListener : public android::net::metrics::BaseMetricsListener {}; 289 290 // Expect to subscribe successfully. 291 std::shared_ptr<FakeListener> fakeListener = ndk::SharedRefBase::make<FakeListener>(); 292 ::ndk::ScopedAStatus status = mDnsResolver->registerEventListener(fakeListener); 293 ASSERT_TRUE(status.isOk()) << status.getMessage(); 294 mExpectedLogData.push_back({"registerEventListener()", "registerEventListener.*"}); 295 296 // Expect to subscribe failed with registered listener instance. 297 status = mDnsResolver->registerEventListener(fakeListener); 298 ASSERT_FALSE(status.isOk()); 299 ASSERT_EQ(EEXIST, status.getServiceSpecificError()); 300 mExpectedLogData.push_back( 301 {"registerEventListener() -> ServiceSpecificException(17, \"File exists\")", 302 "registerEventListener.*17"}); 303 } 304 305 TEST_F(DnsResolverBinderTest, RegisterUnsolicitedEventListener_NullListener) { 306 ::ndk::ScopedAStatus status = mDnsResolver->registerUnsolicitedEventListener(nullptr); 307 ASSERT_FALSE(status.isOk()); 308 ASSERT_EQ(EINVAL, status.getServiceSpecificError()); 309 mExpectedLogData.push_back( 310 {"registerUnsolicitedEventListener() -> ServiceSpecificException(22, \"Invalid " 311 "argument\")", 312 "registerUnsolicitedEventListener.*22"}); 313 } 314 315 TEST_F(DnsResolverBinderTest, RegisterUnsolicitedEventListener_DuplicateSubscription) { 316 // Expect to subscribe successfully. 317 std::shared_ptr<UnsolicitedEventListener> listener = 318 ndk::SharedRefBase::make<UnsolicitedEventListener>(TEST_NETID); 319 ::ndk::ScopedAStatus status = mDnsResolver->registerUnsolicitedEventListener(listener); 320 ASSERT_TRUE(status.isOk()) << status.getMessage(); 321 mExpectedLogData.push_back( 322 {"registerUnsolicitedEventListener()", "registerUnsolicitedEventListener.*"}); 323 324 // Expect to subscribe failed with registered listener instance. 325 status = mDnsResolver->registerUnsolicitedEventListener(listener); 326 ASSERT_FALSE(status.isOk()); 327 ASSERT_EQ(EEXIST, status.getServiceSpecificError()); 328 mExpectedLogData.push_back( 329 {"registerUnsolicitedEventListener() -> ServiceSpecificException(17, \"File exists\")", 330 "registerUnsolicitedEventListener.*17"}); 331 } 332 333 // TODO: Move this test to resolv_integration_test.cpp 334 TEST_F(DnsResolverBinderTest, RegisterEventListener_onDnsEvent) { 335 // The test configs are used to trigger expected events. The expected results are defined in 336 // expectedResults. 337 static const struct TestConfig { 338 std::string hostname; 339 int returnCode; 340 } testConfigs[] = { 341 {"hi", 0 /*success*/}, 342 {"nonexistent", EAI_NODATA}, 343 }; 344 345 // The expected results define expected event content for test verification. 346 static const std::vector<TestOnDnsEvent::TestResult> expectedResults = { 347 {TEST_NETID, INetdEventListener::EVENT_GETADDRINFO, 0 /*success*/, 1, "hi", "1.2.3.4"}, 348 {TEST_NETID, INetdEventListener::EVENT_GETADDRINFO, EAI_NODATA, 0, "nonexistent", ""}, 349 }; 350 351 // Start the Binder thread pool. 352 // TODO: Consider doing this once if there has another event listener unit test. 353 ABinderProcess_startThreadPool(); 354 355 // Setup network. 356 // TODO: Setup device configuration and DNS responser server as resolver test does. 357 // Currently, leave DNS related configuration in this test because only it needs DNS 358 // client-server testing environment. 359 DnsResponderClient dnsClient; 360 dnsClient.SetUp(); 361 362 // Setup DNS responder server. 363 constexpr char listen_addr[] = "127.0.0.3"; 364 constexpr char listen_srv[] = "53"; 365 test::DNSResponder dns(listen_addr, listen_srv, ns_rcode::ns_r_servfail); 366 dns.addMapping("hi.example.com.", ns_type::ns_t_a, "1.2.3.4"); 367 ASSERT_TRUE(dns.startServer()); 368 369 // Setup DNS configuration. 370 const std::vector<std::string> test_servers = {listen_addr}; 371 std::vector<std::string> test_domains = {"example.com"}; 372 std::vector<int> test_params = {300 /*sample_validity*/, 25 /*success_threshold*/, 373 8 /*min_samples*/, 8 /*max_samples*/}; 374 375 ASSERT_TRUE(dnsClient.SetResolversForNetwork(test_servers, test_domains, test_params)); 376 dns.clearQueries(); 377 378 // Register event listener. 379 std::shared_ptr<TestOnDnsEvent> testOnDnsEvent = 380 ndk::SharedRefBase::make<TestOnDnsEvent>(expectedResults); 381 ::ndk::ScopedAStatus status = mDnsResolver->registerEventListener(testOnDnsEvent); 382 ASSERT_TRUE(status.isOk()) << status.getMessage(); 383 mExpectedLogData.push_back({"registerEventListener()", "registerEventListener.*"}); 384 385 // DNS queries. 386 // Once all expected events of expectedResults are received by the listener, the unit test will 387 // be notified. Otherwise, notified with a timeout expired failure. 388 auto& cv = testOnDnsEvent->getCv(); 389 auto& cvMutex = testOnDnsEvent->getCvMutex(); 390 { 391 std::unique_lock lock(cvMutex); 392 393 for (const auto& config : testConfigs) { 394 SCOPED_TRACE(config.hostname); 395 396 addrinfo* result = nullptr; 397 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM}; 398 int status = getaddrinfo(config.hostname.c_str(), nullptr, &hints, &result); 399 EXPECT_EQ(config.returnCode, status); 400 401 if (result) freeaddrinfo(result); 402 } 403 404 // Wait for receiving expected events. 405 EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lock, std::chrono::seconds(2))); 406 } 407 408 // Verify that all testcases are passed. 409 EXPECT_TRUE(testOnDnsEvent->isVerified()); 410 411 dnsClient.TearDown(); 412 } 413 414 // TODO: Need to test more than one server cases. 415 TEST_F(DnsResolverBinderTest, SetResolverConfiguration_Tls) { 416 const std::vector<std::string> LOCALLY_ASSIGNED_DNS{"8.8.8.8", "2001:4860:4860::8888"}; 417 static const std::vector<std::string> valid_v4_addr = {"192.0.2.1"}; 418 static const std::vector<std::string> valid_v6_addr = {"2001:db8::2"}; 419 static const std::vector<std::string> invalid_v4_addr = {"192.0.*.5"}; 420 static const std::vector<std::string> invalid_v6_addr = {"2001:dg8::6"}; 421 constexpr char valid_tls_name[] = "example.com"; 422 std::vector<int> test_params = {300, 25, 8, 8}; 423 // We enumerate valid and invalid v4/v6 address, and several different TLS names 424 // to be the input data and verify the binder status. 425 static const struct TestData { 426 const std::vector<std::string> servers; 427 const std::string tlsName; 428 const int expectedReturnCode; 429 } kTlsTestData[] = { 430 {valid_v4_addr, valid_tls_name, 0}, 431 {valid_v4_addr, "host.com", 0}, 432 {valid_v4_addr, "@@@@", 0}, 433 {valid_v4_addr, "", 0}, 434 {valid_v6_addr, valid_tls_name, 0}, 435 {valid_v6_addr, "host.com", 0}, 436 {valid_v6_addr, "@@@@", 0}, 437 {valid_v6_addr, "", 0}, 438 {invalid_v4_addr, valid_tls_name, EINVAL}, 439 {invalid_v4_addr, "host.com", EINVAL}, 440 {invalid_v4_addr, "@@@@", EINVAL}, 441 {invalid_v4_addr, "", EINVAL}, 442 {invalid_v6_addr, valid_tls_name, EINVAL}, 443 {invalid_v6_addr, "host.com", EINVAL}, 444 {invalid_v6_addr, "@@@@", EINVAL}, 445 {invalid_v6_addr, "", EINVAL}, 446 {{}, "", 0}, 447 {{""}, "", EINVAL}, 448 }; 449 450 for (size_t i = 0; i < std::size(kTlsTestData); i++) { 451 const auto& td = kTlsTestData[i]; 452 453 const auto resolverParams = DnsResponderClient::makeResolverParamsParcel( 454 TEST_NETID, test_params, LOCALLY_ASSIGNED_DNS, {}, td.tlsName, td.servers); 455 ::ndk::ScopedAStatus status = mDnsResolver->setResolverConfiguration(resolverParams); 456 457 if (td.expectedReturnCode == 0) { 458 SCOPED_TRACE(StringPrintf("test case %zu should have passed", i)); 459 SCOPED_TRACE(status.getMessage()); 460 EXPECT_EQ(0, status.getServiceSpecificError()); 461 mExpectedLogDataWithPacel.push_back(toSetResolverConfigurationLogData(resolverParams)); 462 } else { 463 SCOPED_TRACE(StringPrintf("test case %zu should have failed", i)); 464 EXPECT_EQ(EX_SERVICE_SPECIFIC, status.getExceptionCode()); 465 EXPECT_EQ(td.expectedReturnCode, status.getServiceSpecificError()); 466 mExpectedLogDataWithPacel.push_back( 467 toSetResolverConfigurationLogData(resolverParams, td.expectedReturnCode)); 468 } 469 } 470 } 471 472 TEST_F(DnsResolverBinderTest, SetResolverConfiguration_TransportTypes) { 473 using ::testing::HasSubstr; 474 auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel(); 475 resolverParams.transportTypes = {IDnsResolver::TRANSPORT_WIFI, IDnsResolver::TRANSPORT_VPN}; 476 ::ndk::ScopedAStatus status = mDnsResolver->setResolverConfiguration(resolverParams); 477 EXPECT_TRUE(status.isOk()) << status.getMessage(); 478 mExpectedLogDataWithPacel.push_back(toSetResolverConfigurationLogData(resolverParams)); 479 // TODO: Find a way to fix a potential deadlock here if it's larger than pipe buffer 480 // size(65535). 481 android::base::unique_fd writeFd, readFd; 482 EXPECT_TRUE(Pipe(&readFd, &writeFd)); 483 EXPECT_EQ(mDnsResolver->dump(writeFd.get(), nullptr, 0), 0); 484 writeFd.reset(); 485 std::string str; 486 ASSERT_TRUE(ReadFdToString(readFd, &str)) << strerror(errno); 487 EXPECT_THAT(str, HasSubstr("WIFI_VPN")); 488 } 489 490 TEST_F(DnsResolverBinderTest, SetResolverConfiguration_TransportTypes_Default) { 491 using ::testing::HasSubstr; 492 auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel(); 493 ::ndk::ScopedAStatus status = mDnsResolver->setResolverConfiguration(resolverParams); 494 EXPECT_TRUE(status.isOk()) << status.getMessage(); 495 mExpectedLogDataWithPacel.push_back(toSetResolverConfigurationLogData(resolverParams)); 496 android::base::unique_fd writeFd, readFd; 497 EXPECT_TRUE(Pipe(&readFd, &writeFd)); 498 EXPECT_EQ(mDnsResolver->dump(writeFd.get(), nullptr, 0), 0); 499 writeFd.reset(); 500 std::string str; 501 ASSERT_TRUE(ReadFdToString(readFd, &str)) << strerror(errno); 502 EXPECT_THAT(str, HasSubstr("UNKNOWN")); 503 } 504 505 TEST_F(DnsResolverBinderTest, GetResolverInfo) { 506 std::vector<std::string> servers = {"127.0.0.1", "127.0.0.2"}; 507 std::vector<std::string> domains = {"example.com"}; 508 std::vector<int> testParams = { 509 300, // sample validity in seconds 510 25, // success threshod in percent 511 8, 8, // {MIN,MAX}_SAMPLES 512 100, // BASE_TIMEOUT_MSEC 513 3, // retry count 514 }; 515 const auto resolverParams = DnsResponderClient::makeResolverParamsParcel( 516 TEST_NETID, testParams, servers, domains, "", {}); 517 ::ndk::ScopedAStatus status = mDnsResolver->setResolverConfiguration(resolverParams); 518 EXPECT_TRUE(status.isOk()) << status.getMessage(); 519 mExpectedLogDataWithPacel.push_back(toSetResolverConfigurationLogData(resolverParams)); 520 521 std::vector<std::string> res_servers; 522 std::vector<std::string> res_domains; 523 std::vector<std::string> res_tls_servers; 524 std::vector<int32_t> params32; 525 std::vector<int32_t> stats32; 526 std::vector<int32_t> wait_for_pending_req_timeout_count32{0}; 527 status = mDnsResolver->getResolverInfo(TEST_NETID, &res_servers, &res_domains, &res_tls_servers, 528 ¶ms32, &stats32, 529 &wait_for_pending_req_timeout_count32); 530 531 EXPECT_TRUE(status.isOk()) << status.getMessage(); 532 EXPECT_EQ(servers.size(), res_servers.size()); 533 EXPECT_EQ(domains.size(), res_domains.size()); 534 EXPECT_EQ(0U, res_tls_servers.size()); 535 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), testParams.size()); 536 EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY], 537 params32[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY]); 538 EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD], 539 params32[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD]); 540 EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], 541 params32[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES]); 542 EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], 543 params32[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES]); 544 EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC], 545 params32[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC]); 546 EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], 547 params32[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT]); 548 549 std::vector<ResolverStats> stats; 550 ResolverStats::decodeAll(stats32, &stats); 551 552 EXPECT_EQ(servers.size(), stats.size()); 553 554 EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers)); 555 EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains)); 556 } 557 558 TEST_F(DnsResolverBinderTest, CreateDestroyNetworkCache) { 559 // Must not be the same as TEST_NETID 560 const int ANOTHER_TEST_NETID = TEST_NETID + 1; 561 562 // Create a new network cache. 563 EXPECT_TRUE(mDnsResolver->createNetworkCache(ANOTHER_TEST_NETID).isOk()); 564 mExpectedLogData.push_back({"createNetworkCache(31)", "createNetworkCache.*31"}); 565 566 // create it again, expect a EEXIST. 567 EXPECT_EQ(EEXIST, 568 mDnsResolver->createNetworkCache(ANOTHER_TEST_NETID).getServiceSpecificError()); 569 mExpectedLogData.push_back( 570 {"createNetworkCache(31) -> ServiceSpecificException(17, \"File exists\")", 571 "createNetworkCache.*31.*17"}); 572 573 // destroy it. 574 EXPECT_TRUE(mDnsResolver->destroyNetworkCache(ANOTHER_TEST_NETID).isOk()); 575 mExpectedLogData.push_back({"destroyNetworkCache(31)", "destroyNetworkCache.*31"}); 576 577 // re-create it 578 EXPECT_TRUE(mDnsResolver->createNetworkCache(ANOTHER_TEST_NETID).isOk()); 579 mExpectedLogData.push_back({"createNetworkCache(31)", "createNetworkCache.*31"}); 580 581 // destroy it. 582 EXPECT_TRUE(mDnsResolver->destroyNetworkCache(ANOTHER_TEST_NETID).isOk()); 583 mExpectedLogData.push_back({"destroyNetworkCache(31)", "destroyNetworkCache.*31"}); 584 585 // re-destroy it 586 EXPECT_TRUE(mDnsResolver->destroyNetworkCache(ANOTHER_TEST_NETID).isOk()); 587 mExpectedLogData.push_back({"destroyNetworkCache(31)", "destroyNetworkCache.*31"}); 588 } 589 590 TEST_F(DnsResolverBinderTest, FlushNetworkCache) { 591 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsResolver.get(), 4); 592 // cache has beed created in DnsResolverBinderTest constructor 593 EXPECT_TRUE(mDnsResolver->flushNetworkCache(TEST_NETID).isOk()); 594 mExpectedLogData.push_back({"flushNetworkCache(30)", "destroyNetworkCache.*30"}); 595 EXPECT_EQ(ENONET, mDnsResolver->flushNetworkCache(-1).getServiceSpecificError()); 596 mExpectedLogData.push_back( 597 {"flushNetworkCache(-1) -> ServiceSpecificException(64, \"Machine is not on the " 598 "network\")", 599 "flushNetworkCache.*-1.*64"}); 600 } 601 602 TEST_F(DnsResolverBinderTest, setLogSeverity) { 603 // Expect fail 604 EXPECT_EQ(EINVAL, mDnsResolver->setLogSeverity(-1).getServiceSpecificError()); 605 mExpectedLogData.push_back( 606 {"setLogSeverity(-1) -> ServiceSpecificException(22, \"Invalid argument\")", 607 "flushNetworkCache.*-1.*22"}); 608 609 // Test set different log level 610 EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_VERBOSE).isOk()); 611 mExpectedLogData.push_back({"setLogSeverity(0)", "setLogSeverity.*0"}); 612 613 EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_DEBUG).isOk()); 614 mExpectedLogData.push_back({"setLogSeverity(1)", "setLogSeverity.*1"}); 615 616 EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_INFO).isOk()); 617 mExpectedLogData.push_back({"setLogSeverity(2)", "setLogSeverity.*2"}); 618 619 EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_WARNING).isOk()); 620 mExpectedLogData.push_back({"setLogSeverity(3)", "setLogSeverity.*3"}); 621 622 EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_ERROR).isOk()); 623 mExpectedLogData.push_back({"setLogSeverity(4)", "setLogSeverity.*4"}); 624 625 // Set back to default 626 EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_WARNING).isOk()); 627 mExpectedLogData.push_back({"setLogSeverity(3)", "setLogSeverity.*3"}); 628 } 629 630 TEST_F(DnsResolverBinderTest, SetResolverOptions) { 631 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsResolver.get(), 9); 632 ResolverOptionsParcel options; 633 options.tcMode = 1; 634 options.enforceDnsUid = true; 635 EXPECT_TRUE(mDnsResolver->setResolverOptions(TEST_NETID, options).isOk()); 636 mExpectedLogData.push_back( 637 {"setResolverOptions(30, " + toString(options) + ")", "setResolverOptions.*30"}); 638 EXPECT_EQ(ENONET, mDnsResolver->setResolverOptions(-1, options).getServiceSpecificError()); 639 mExpectedLogData.push_back({"setResolverOptions(-1, " + toString(options) + 640 ") -> ServiceSpecificException(64, \"Machine is not on the " 641 "network\")", 642 "setResolverOptions.*-1.*64"}); 643 } 644