diff options
Diffstat (limited to 'chromium/net/dns/host_resolver_impl_unittest.cc')
-rw-r--r-- | chromium/net/dns/host_resolver_impl_unittest.cc | 476 |
1 files changed, 471 insertions, 5 deletions
diff --git a/chromium/net/dns/host_resolver_impl_unittest.cc b/chromium/net/dns/host_resolver_impl_unittest.cc index fdb1a0ab32f..fb433d78565 100644 --- a/chromium/net/dns/host_resolver_impl_unittest.cc +++ b/chromium/net/dns/host_resolver_impl_unittest.cc @@ -34,8 +34,11 @@ #include "net/base/mock_network_change_notifier.h" #include "net/base/net_errors.h" #include "net/dns/dns_client.h" +#include "net/dns/dns_config.h" #include "net/dns/dns_test_util.h" #include "net/dns/mock_host_resolver.h" +#include "net/dns/mock_mdns_client.h" +#include "net/dns/mock_mdns_socket_factory.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_source_type.h" #include "net/log/net_log_with_source.h" @@ -47,7 +50,11 @@ using net::test::IsError; using net::test::IsOk; +using ::testing::_; +using ::testing::Between; +using ::testing::ByMove; using ::testing::NotNull; +using ::testing::Return; namespace net { @@ -3012,6 +3019,274 @@ TEST_F(HostResolverImplTest, IsSpeculative_ResolveHost) { EXPECT_EQ(1u, proc_->GetCaptureList().size()); // No increase. } +#if BUILDFLAG(ENABLE_MDNS) +const uint8_t kMdnsResponseA[] = { + // Header + 0x00, 0x00, // ID is zeroed out + 0x81, 0x80, // Standard query response, RA, no error + 0x00, 0x00, // No questions (for simplicity) + 0x00, 0x01, // 1 RR (answers) + 0x00, 0x00, // 0 authority RRs + 0x00, 0x00, // 0 additional RRs + + // "myhello.local." + 0x07, 'm', 'y', 'h', 'e', 'l', 'l', 'o', 0x05, 'l', 'o', 'c', 'a', 'l', + 0x00, + + 0x00, 0x01, // TYPE is A. + 0x00, 0x01, // CLASS is IN. + 0x00, 0x00, 0x00, 0x10, // TTL is 16 (seconds) + 0x00, 0x04, // RDLENGTH is 4 bytes. + 0x01, 0x02, 0x03, 0x04, // 1.2.3.4 +}; + +const uint8_t kMdnsResponseAAAA[] = { + // Header + 0x00, 0x00, // ID is zeroed out + 0x81, 0x80, // Standard query response, RA, no error + 0x00, 0x00, // No questions (for simplicity) + 0x00, 0x01, // 1 RR (answers) + 0x00, 0x00, // 0 authority RRs + 0x00, 0x00, // 0 additional RRs + + // "myhello.local." + 0x07, 'm', 'y', 'h', 'e', 'l', 'l', 'o', 0x05, 'l', 'o', 'c', 'a', 'l', + 0x00, + + 0x00, 0x1C, // TYPE is AAAA. + 0x00, 0x01, // CLASS is IN. + 0x00, 0x00, 0x00, 0x10, // TTL is 16 (seconds) + 0x00, 0x10, // RDLENGTH is 16 bytes. + + // 000a:0000:0000:0000:0001:0002:0003:0004 + 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x03, 0x00, 0x04, +}; + +// An MDNS response indicating that the responder owns the hostname, but the +// specific requested type (AAAA) does not exist because the responder only has +// A addresses. +const uint8_t kMdnsResponseNsec[] = { + // Header + 0x00, 0x00, // ID is zeroed out + 0x81, 0x80, // Standard query response, RA, no error + 0x00, 0x00, // No questions (for simplicity) + 0x00, 0x01, // 1 RR (answers) + 0x00, 0x00, // 0 authority RRs + 0x00, 0x00, // 0 additional RRs + + // "myhello.local." + 0x07, 'm', 'y', 'h', 'e', 'l', 'l', 'o', 0x05, 'l', 'o', 'c', 'a', 'l', + 0x00, + + 0x00, 0x2f, // TYPE is NSEC. + 0x00, 0x01, // CLASS is IN. + 0x00, 0x00, 0x00, 0x10, // TTL is 16 (seconds) + 0x00, 0x06, // RDLENGTH is 6 bytes. + 0xc0, 0x0c, // Next Domain Name (always pointer back to name in MDNS) + 0x00, // Bitmap block number (always 0 in MDNS) + 0x02, // Bitmap length is 2 + 0x00, 0x08 // A type only +}; + +TEST_F(HostResolverImplTest, Mdns) { + auto socket_factory = std::make_unique<MockMDnsSocketFactory>(); + MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get(); + resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory)); + // 2 socket creations for every transaction. + EXPECT_CALL(*socket_factory_ptr, OnSendTo(_)).Times(4); + + HostResolver::ResolveHostParameters parameters; + parameters.source = HostResolverSource::MULTICAST_DNS; + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("myhello.local", 80), NetLogWithSource(), parameters)); + + socket_factory_ptr->SimulateReceive(kMdnsResponseA, sizeof(kMdnsResponseA)); + socket_factory_ptr->SimulateReceive(kMdnsResponseAAAA, + sizeof(kMdnsResponseAAAA)); + + EXPECT_THAT(response.result_error(), IsOk()); + EXPECT_THAT( + response.request()->GetAddressResults().value().endpoints(), + testing::UnorderedElementsAre( + CreateExpected("1.2.3.4", 80), + CreateExpected("000a:0000:0000:0000:0001:0002:0003:0004", 80))); +} + +TEST_F(HostResolverImplTest, Mdns_AaaaOnly) { + auto socket_factory = std::make_unique<MockMDnsSocketFactory>(); + MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get(); + resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory)); + // 2 socket creations for every transaction. + EXPECT_CALL(*socket_factory_ptr, OnSendTo(_)).Times(2); + + HostResolver::ResolveHostParameters parameters; + parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + parameters.source = HostResolverSource::MULTICAST_DNS; + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("myhello.local", 80), NetLogWithSource(), parameters)); + + socket_factory_ptr->SimulateReceive(kMdnsResponseAAAA, + sizeof(kMdnsResponseAAAA)); + + EXPECT_THAT(response.result_error(), IsOk()); + EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected( + "000a:0000:0000:0000:0001:0002:0003:0004", 80))); +} + +// Test multicast DNS handling of NSEC responses (used for explicit negative +// response). +TEST_F(HostResolverImplTest, Mdns_Nsec) { + auto socket_factory = std::make_unique<MockMDnsSocketFactory>(); + MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get(); + resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory)); + // 2 socket creations for every transaction. + EXPECT_CALL(*socket_factory_ptr, OnSendTo(_)).Times(2); + + HostResolver::ResolveHostParameters parameters; + parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + parameters.source = HostResolverSource::MULTICAST_DNS; + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("myhello.local", 80), NetLogWithSource(), parameters)); + + socket_factory_ptr->SimulateReceive(kMdnsResponseNsec, + sizeof(kMdnsResponseNsec)); + + EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); + EXPECT_FALSE(response.request()->GetAddressResults()); +} + +TEST_F(HostResolverImplTest, Mdns_NoResponse) { + auto socket_factory = std::make_unique<MockMDnsSocketFactory>(); + MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get(); + resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory)); + // 2 socket creations for every transaction. + EXPECT_CALL(*socket_factory_ptr, OnSendTo(_)).Times(4); + + // Add a little bit of extra fudge to the delay to allow reasonable + // flexibility for time > vs >= etc. We don't need to fail the test if we + // timeout at t=6001 instead of t=6000. + base::TimeDelta kSleepFudgeFactor = base::TimeDelta::FromMilliseconds(1); + + // Override the current thread task runner, so we can simulate the passage of + // time to trigger the timeout. + auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + base::ScopedClosureRunner task_runner_override_scoped_cleanup = + base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + + HostResolver::ResolveHostParameters parameters; + parameters.source = HostResolverSource::MULTICAST_DNS; + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("myhello.local", 80), NetLogWithSource(), parameters)); + + ASSERT_TRUE(test_task_runner->HasPendingTask()); + test_task_runner->FastForwardBy(MDnsTransaction::kTransactionTimeout + + kSleepFudgeFactor); + + EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); + EXPECT_FALSE(response.request()->GetAddressResults()); + + test_task_runner->FastForwardUntilNoTasksRemain(); +} + +// Test for a request for both A and AAAA results where results only exist for +// one type. +TEST_F(HostResolverImplTest, Mdns_PartialResults) { + auto socket_factory = std::make_unique<MockMDnsSocketFactory>(); + MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get(); + resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory)); + // 2 socket creations for every transaction. + EXPECT_CALL(*socket_factory_ptr, OnSendTo(_)).Times(4); + + // Add a little bit of extra fudge to the delay to allow reasonable + // flexibility for time > vs >= etc. We don't need to fail the test if we + // timeout at t=6001 instead of t=6000. + base::TimeDelta kSleepFudgeFactor = base::TimeDelta::FromMilliseconds(1); + + // Override the current thread task runner, so we can simulate the passage of + // time to trigger the timeout. + auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + base::ScopedClosureRunner task_runner_override_scoped_cleanup = + base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + + HostResolver::ResolveHostParameters parameters; + parameters.source = HostResolverSource::MULTICAST_DNS; + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("myhello.local", 80), NetLogWithSource(), parameters)); + + ASSERT_TRUE(test_task_runner->HasPendingTask()); + + socket_factory_ptr->SimulateReceive(kMdnsResponseA, sizeof(kMdnsResponseA)); + test_task_runner->FastForwardBy(MDnsTransaction::kTransactionTimeout + + kSleepFudgeFactor); + + EXPECT_THAT(response.result_error(), IsOk()); + EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("1.2.3.4", 80))); + + test_task_runner->FastForwardUntilNoTasksRemain(); +} + +TEST_F(HostResolverImplTest, Mdns_Cancel) { + auto socket_factory = std::make_unique<MockMDnsSocketFactory>(); + MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get(); + resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory)); + // 2 socket creations for every transaction. + EXPECT_CALL(*socket_factory_ptr, OnSendTo(_)).Times(4); + + HostResolver::ResolveHostParameters parameters; + parameters.source = HostResolverSource::MULTICAST_DNS; + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("myhello.local", 80), NetLogWithSource(), parameters)); + + response.CancelRequest(); + + socket_factory_ptr->SimulateReceive(kMdnsResponseA, sizeof(kMdnsResponseA)); + socket_factory_ptr->SimulateReceive(kMdnsResponseAAAA, + sizeof(kMdnsResponseAAAA)); + + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(response.complete()); +} + +// Test for a two-transaction query where the first fails to start. The second +// should be cancelled. +TEST_F(HostResolverImplTest, Mdns_PartialFailure) { + // Setup a mock MDnsClient where the first transaction will always return + // |false| immediately on Start(). Second transaction may or may not be + // created, but if it is, Start() not expected to be called because the + // overall request should immediately fail. + auto transaction1 = std::make_unique<MockMDnsTransaction>(); + EXPECT_CALL(*transaction1, Start()).WillOnce(Return(false)); + auto transaction2 = std::make_unique<MockMDnsTransaction>(); + EXPECT_CALL(*transaction2, Start()).Times(0); + + auto client = std::make_unique<MockMDnsClient>(); + EXPECT_CALL(*client, CreateTransaction(_, _, _, _)) + .Times(Between(1, 2)) // Second transaction optionally created. + .WillOnce(Return(ByMove(std::move(transaction1)))) + .WillOnce(Return(ByMove(std::move(transaction2)))); + EXPECT_CALL(*client, IsListening()).WillRepeatedly(Return(true)); + resolver_->SetMdnsClientForTesting(std::move(client)); + + HostResolver::ResolveHostParameters parameters; + parameters.source = HostResolverSource::MULTICAST_DNS; + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("myhello.local", 80), NetLogWithSource(), parameters)); + + EXPECT_THAT(response.result_error(), IsError(ERR_FAILED)); + EXPECT_FALSE(response.request()->GetAddressResults()); +} +#endif // BUILDFLAG(ENABLE_MDNS) + DnsConfig CreateValidDnsConfig() { IPAddress dns_ip(192, 168, 1, 0); DnsConfig config; @@ -5267,7 +5542,10 @@ TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerAfterConfig) { resolver_->SetDnsClientEnabled(true); std::string server("https://dnsserver.example.net/dns-query{?dns}"); - resolver_->AddDnsOverHttpsServer(server, true); + DnsConfigOverrides overrides; + overrides.dns_over_https_servers.emplace( + {DnsConfig::DnsOverHttpsServerConfig(server, true)}); + resolver_->SetDnsConfigOverrides(overrides); base::DictionaryValue* config; auto value = resolver_->GetDnsConfigAsValue(); @@ -5297,7 +5575,10 @@ TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerBeforeConfig) { CreateSerialResolver(); // To guarantee order of resolutions. resolver_->SetDnsClientEnabled(true); std::string server("https://dnsserver.example.net/dns-query{?dns}"); - resolver_->AddDnsOverHttpsServer(server, true); + DnsConfigOverrides overrides; + overrides.dns_over_https_servers.emplace( + {DnsConfig::DnsOverHttpsServerConfig(server, true)}); + resolver_->SetDnsConfigOverrides(overrides); notifier.mock_network_change_notifier()->SetConnectionType( NetworkChangeNotifier::CONNECTION_WIFI); @@ -5330,7 +5611,10 @@ TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerBeforeClient) { test::ScopedMockNetworkChangeNotifier notifier; CreateSerialResolver(); // To guarantee order of resolutions. std::string server("https://dnsserver.example.net/dns-query{?dns}"); - resolver_->AddDnsOverHttpsServer(server, true); + DnsConfigOverrides overrides; + overrides.dns_over_https_servers.emplace( + {DnsConfig::DnsOverHttpsServerConfig(server, true)}); + resolver_->SetDnsConfigOverrides(overrides); notifier.mock_network_change_notifier()->SetConnectionType( NetworkChangeNotifier::CONNECTION_WIFI); @@ -5365,7 +5649,10 @@ TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerAndThenRemove) { test::ScopedMockNetworkChangeNotifier notifier; CreateSerialResolver(); // To guarantee order of resolutions. std::string server("https://dns.example.com/"); - resolver_->AddDnsOverHttpsServer(server, true); + DnsConfigOverrides overrides; + overrides.dns_over_https_servers.emplace( + {DnsConfig::DnsOverHttpsServerConfig(server, true)}); + resolver_->SetDnsConfigOverrides(overrides); notifier.mock_network_change_notifier()->SetConnectionType( NetworkChangeNotifier::CONNECTION_WIFI); @@ -5394,7 +5681,7 @@ TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerAndThenRemove) { EXPECT_TRUE(server_method->GetString("server_template", &server_template)); EXPECT_EQ(server_template, server); - resolver_->ClearDnsOverHttpsServers(); + resolver_->SetDnsConfigOverrides(DnsConfigOverrides()); value = resolver_->GetDnsConfigAsValue(); EXPECT_TRUE(value); if (!value) @@ -5407,4 +5694,183 @@ TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerAndThenRemove) { EXPECT_EQ(doh_servers->GetSize(), 0u); } +TEST_F(HostResolverImplDnsTest, SetDnsConfigOverrides) { + DnsConfig original_config = CreateValidDnsConfig(); + ChangeDnsConfig(original_config); + + // Confirm pre-override state. + ASSERT_TRUE(original_config.Equals(*dns_client_->GetConfig())); + + DnsConfigOverrides overrides; + const std::vector<IPEndPoint> nameservers = { + CreateExpected("192.168.0.1", 92)}; + overrides.nameservers = nameservers; + const std::vector<std::string> search = {"str"}; + overrides.search = search; + const DnsHosts hosts = { + {DnsHostsKey("host", ADDRESS_FAMILY_IPV4), IPAddress(192, 168, 1, 1)}}; + overrides.hosts = hosts; + overrides.append_to_multi_label_name = false; + overrides.randomize_ports = true; + const int ndots = 5; + overrides.ndots = ndots; + const base::TimeDelta timeout = base::TimeDelta::FromSeconds(10); + overrides.timeout = timeout; + const int attempts = 20; + overrides.attempts = attempts; + overrides.rotate = true; + overrides.use_local_ipv6 = true; + const std::vector<DnsConfig::DnsOverHttpsServerConfig> + dns_over_https_servers = { + DnsConfig::DnsOverHttpsServerConfig("dns.example.com", true)}; + overrides.dns_over_https_servers = dns_over_https_servers; + + resolver_->SetDnsConfigOverrides(overrides); + + const DnsConfig* overridden_config = dns_client_->GetConfig(); + EXPECT_EQ(nameservers, overridden_config->nameservers); + EXPECT_EQ(search, overridden_config->search); + EXPECT_EQ(hosts, overridden_config->hosts); + EXPECT_FALSE(overridden_config->append_to_multi_label_name); + EXPECT_TRUE(overridden_config->randomize_ports); + EXPECT_EQ(ndots, overridden_config->ndots); + EXPECT_EQ(timeout, overridden_config->timeout); + EXPECT_EQ(attempts, overridden_config->attempts); + EXPECT_TRUE(overridden_config->rotate); + EXPECT_TRUE(overridden_config->use_local_ipv6); + EXPECT_EQ(dns_over_https_servers, overridden_config->dns_over_https_servers); +} + +TEST_F(HostResolverImplDnsTest, SetDnsConfigOverrides_PartialOverride) { + DnsConfig original_config = CreateValidDnsConfig(); + ChangeDnsConfig(original_config); + + // Confirm pre-override state. + ASSERT_TRUE(original_config.Equals(*dns_client_->GetConfig())); + + DnsConfigOverrides overrides; + const std::vector<IPEndPoint> nameservers = { + CreateExpected("192.168.0.2", 192)}; + overrides.nameservers = nameservers; + overrides.rotate = true; + + resolver_->SetDnsConfigOverrides(overrides); + + const DnsConfig* overridden_config = dns_client_->GetConfig(); + EXPECT_EQ(nameservers, overridden_config->nameservers); + EXPECT_EQ(original_config.search, overridden_config->search); + EXPECT_EQ(original_config.hosts, overridden_config->hosts); + EXPECT_TRUE(overridden_config->append_to_multi_label_name); + EXPECT_FALSE(overridden_config->randomize_ports); + EXPECT_EQ(original_config.ndots, overridden_config->ndots); + EXPECT_EQ(original_config.timeout, overridden_config->timeout); + EXPECT_EQ(original_config.attempts, overridden_config->attempts); + EXPECT_TRUE(overridden_config->rotate); + EXPECT_FALSE(overridden_config->use_local_ipv6); + EXPECT_EQ(original_config.dns_over_https_servers, + overridden_config->dns_over_https_servers); +} + +// Test that overridden configs are reapplied over a changed underlying system +// config. +TEST_F(HostResolverImplDnsTest, SetDnsConfigOverrides_NewConfig) { + DnsConfig original_config = CreateValidDnsConfig(); + ChangeDnsConfig(original_config); + + // Confirm pre-override state. + ASSERT_TRUE(original_config.Equals(*dns_client_->GetConfig())); + + DnsConfigOverrides overrides; + const std::vector<IPEndPoint> nameservers = { + CreateExpected("192.168.0.2", 192)}; + overrides.nameservers = nameservers; + + resolver_->SetDnsConfigOverrides(overrides); + ASSERT_EQ(nameservers, dns_client_->GetConfig()->nameservers); + + DnsConfig new_config = original_config; + new_config.attempts = 103; + ASSERT_NE(nameservers, new_config.nameservers); + ChangeDnsConfig(new_config); + + const DnsConfig* overridden_config = dns_client_->GetConfig(); + EXPECT_EQ(nameservers, overridden_config->nameservers); + EXPECT_EQ(new_config.attempts, overridden_config->attempts); +} + +TEST_F(HostResolverImplDnsTest, SetDnsConfigOverrides_ClearOverrides) { + DnsConfig original_config = CreateValidDnsConfig(); + ChangeDnsConfig(original_config); + + DnsConfigOverrides overrides; + overrides.attempts = 245; + resolver_->SetDnsConfigOverrides(overrides); + + ASSERT_FALSE(original_config.Equals(*dns_client_->GetConfig())); + + resolver_->SetDnsConfigOverrides(DnsConfigOverrides()); + EXPECT_TRUE(original_config.Equals(*dns_client_->GetConfig())); +} + +// Test that in-progress queries are cancelled on applying new DNS config +// overrides, same as receiving a new DnsConfig from the system. +TEST_F(HostResolverImplDnsTest, CancelQueriesOnSettingOverrides) { + ChangeDnsConfig(CreateValidDnsConfig()); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); + ASSERT_FALSE(response.complete()); + + DnsConfigOverrides overrides; + overrides.attempts = 123; + resolver_->SetDnsConfigOverrides(overrides); + + EXPECT_THAT(response.result_error(), IsError(ERR_NETWORK_CHANGED)); +} + +// Queries should not be cancelled if equal overrides are set. +TEST_F(HostResolverImplDnsTest, CancelQueriesOnSettingOverrides_SameOverrides) { + ChangeDnsConfig(CreateValidDnsConfig()); + DnsConfigOverrides overrides; + overrides.attempts = 123; + resolver_->SetDnsConfigOverrides(overrides); + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); + ASSERT_FALSE(response.complete()); + + resolver_->SetDnsConfigOverrides(overrides); + + EXPECT_THAT(response.result_error(), IsOk()); +} + +// Test that in-progress queries are cancelled on clearing DNS config overrides, +// same as receiving a new DnsConfig from the system. +TEST_F(HostResolverImplDnsTest, CancelQueriesOnClearingOverrides) { + ChangeDnsConfig(CreateValidDnsConfig()); + DnsConfigOverrides overrides; + overrides.attempts = 123; + resolver_->SetDnsConfigOverrides(overrides); + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); + ASSERT_FALSE(response.complete()); + + resolver_->SetDnsConfigOverrides(DnsConfigOverrides()); + + EXPECT_THAT(response.result_error(), IsError(ERR_NETWORK_CHANGED)); +} + +// Queries should not be cancelled on clearing overrides if there were not any +// overrides. +TEST_F(HostResolverImplDnsTest, CancelQueriesOnClearingOverrides_NoOverrides) { + ChangeDnsConfig(CreateValidDnsConfig()); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); + ASSERT_FALSE(response.complete()); + + resolver_->SetDnsConfigOverrides(DnsConfigOverrides()); + + EXPECT_THAT(response.result_error(), IsOk()); +} + } // namespace net |