| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/host_resolver_impl.h" | 5 #include "net/base/host_resolver_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 14 #include "base/synchronization/condition_variable.h" | 14 #include "base/synchronization/condition_variable.h" |
| 15 #include "base/synchronization/lock.h" | 15 #include "base/synchronization/lock.h" |
| 16 #include "base/time.h" | 16 #include "base/time.h" |
| 17 #include "net/base/address_list.h" | 17 #include "net/base/address_list.h" |
| 18 #include "net/base/completion_callback.h" | 18 #include "net/base/completion_callback.h" |
| 19 #include "net/base/host_cache.h" | 19 #include "net/base/host_cache.h" |
| 20 #include "net/base/mock_host_resolver.h" | 20 #include "net/base/mock_host_resolver.h" |
| 21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 22 #include "net/base/net_log_unittest.h" | 22 #include "net/base/net_log_unittest.h" |
| 23 #include "net/base/net_util.h" | 23 #include "net/base/net_util.h" |
| 24 #include "net/base/sys_addrinfo.h" | 24 #include "net/base/sys_addrinfo.h" |
| 25 #include "net/base/test_completion_callback.h" | 25 #include "net/base/test_completion_callback.h" |
| 26 #include "net/base/test_host_resolver_observer.h" | |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 28 | 27 |
| 29 // TODO(eroman): | 28 // TODO(eroman): |
| 30 // - Test mixing async with sync (in particular how does sync update the | 29 // - Test mixing async with sync (in particular how does sync update the |
| 31 // cache while an async is already pending). | 30 // cache while an async is already pending). |
| 32 | 31 |
| 33 namespace net { | 32 namespace net { |
| 34 | 33 |
| 35 using base::TimeDelta; | 34 using base::TimeDelta; |
| 36 using base::TimeTicks; | 35 using base::TimeTicks; |
| (...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 // checks that the right things happened. | 974 // checks that the right things happened. |
| 976 BypassCacheVerifier verifier; | 975 BypassCacheVerifier verifier; |
| 977 | 976 |
| 978 // Start a request. | 977 // Start a request. |
| 979 ResolveRequest req1(host_resolver.get(), "a", 80, &verifier); | 978 ResolveRequest req1(host_resolver.get(), "a", 80, &verifier); |
| 980 | 979 |
| 981 // |verifier| will send quit message once all the requests have finished. | 980 // |verifier| will send quit message once all the requests have finished. |
| 982 MessageLoop::current()->Run(); | 981 MessageLoop::current()->Run(); |
| 983 } | 982 } |
| 984 | 983 |
| 985 // Test that registering, unregistering, and notifying of observers works. | |
| 986 // Does not test the cancellation notification since all resolves are | |
| 987 // synchronous. | |
| 988 TEST_F(HostResolverImplTest, Observers) { | |
| 989 scoped_ptr<HostResolver> host_resolver( | |
| 990 CreateHostResolverImpl(NULL)); | |
| 991 | |
| 992 TestHostResolverObserver observer; | |
| 993 | |
| 994 host_resolver->AddObserver(&observer); | |
| 995 | |
| 996 AddressList addrlist; | |
| 997 | |
| 998 // Resolve "host1". | |
| 999 HostResolver::RequestInfo info1(HostPortPair("host1", 70)); | |
| 1000 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | |
| 1001 TestOldCompletionCallback callback; | |
| 1002 int rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, | |
| 1003 log.bound()); | |
| 1004 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1005 rv = callback.WaitForResult(); | |
| 1006 EXPECT_EQ(OK, rv); | |
| 1007 | |
| 1008 CapturingNetLog::EntryList entries; | |
| 1009 log.GetEntries(&entries); | |
| 1010 | |
| 1011 EXPECT_EQ(2u, entries.size()); | |
| 1012 EXPECT_TRUE(LogContainsBeginEvent( | |
| 1013 entries, 0, NetLog::TYPE_HOST_RESOLVER_IMPL)); | |
| 1014 EXPECT_TRUE(LogContainsEndEvent( | |
| 1015 entries, 1, NetLog::TYPE_HOST_RESOLVER_IMPL)); | |
| 1016 | |
| 1017 EXPECT_EQ(1U, observer.start_log.size()); | |
| 1018 EXPECT_EQ(1U, observer.finish_log.size()); | |
| 1019 EXPECT_EQ(0U, observer.cancel_log.size()); | |
| 1020 EXPECT_TRUE(observer.start_log[0] == | |
| 1021 TestHostResolverObserver::StartOrCancelEntry(0, info1)); | |
| 1022 EXPECT_TRUE(observer.finish_log[0] == | |
| 1023 TestHostResolverObserver::FinishEntry(0, true, info1)); | |
| 1024 | |
| 1025 // Resolve "host1" again -- this time it will be served from cache, but it | |
| 1026 // should still notify of completion. | |
| 1027 rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, BoundNetLog()); | |
| 1028 ASSERT_EQ(OK, rv); // Should complete synchronously. | |
| 1029 | |
| 1030 EXPECT_EQ(2U, observer.start_log.size()); | |
| 1031 EXPECT_EQ(2U, observer.finish_log.size()); | |
| 1032 EXPECT_EQ(0U, observer.cancel_log.size()); | |
| 1033 EXPECT_TRUE(observer.start_log[1] == | |
| 1034 TestHostResolverObserver::StartOrCancelEntry(1, info1)); | |
| 1035 EXPECT_TRUE(observer.finish_log[1] == | |
| 1036 TestHostResolverObserver::FinishEntry(1, true, info1)); | |
| 1037 | |
| 1038 // Resolve "host2", setting referrer to "http://foobar.com" | |
| 1039 HostResolver::RequestInfo info2(HostPortPair("host2", 70)); | |
| 1040 info2.set_referrer(GURL("http://foobar.com")); | |
| 1041 rv = host_resolver->Resolve(info2, &addrlist, &callback, NULL, BoundNetLog()); | |
| 1042 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1043 rv = callback.WaitForResult(); | |
| 1044 EXPECT_EQ(OK, rv); | |
| 1045 | |
| 1046 EXPECT_EQ(3U, observer.start_log.size()); | |
| 1047 EXPECT_EQ(3U, observer.finish_log.size()); | |
| 1048 EXPECT_EQ(0U, observer.cancel_log.size()); | |
| 1049 EXPECT_TRUE(observer.start_log[2] == | |
| 1050 TestHostResolverObserver::StartOrCancelEntry(2, info2)); | |
| 1051 EXPECT_TRUE(observer.finish_log[2] == | |
| 1052 TestHostResolverObserver::FinishEntry(2, true, info2)); | |
| 1053 | |
| 1054 // Unregister the observer. | |
| 1055 host_resolver->RemoveObserver(&observer); | |
| 1056 | |
| 1057 // Resolve "host3" | |
| 1058 HostResolver::RequestInfo info3(HostPortPair("host3", 70)); | |
| 1059 host_resolver->Resolve(info3, &addrlist, &callback, NULL, BoundNetLog()); | |
| 1060 | |
| 1061 // No effect this time, since observer was removed. | |
| 1062 EXPECT_EQ(3U, observer.start_log.size()); | |
| 1063 EXPECT_EQ(3U, observer.finish_log.size()); | |
| 1064 EXPECT_EQ(0U, observer.cancel_log.size()); | |
| 1065 } | |
| 1066 | |
| 1067 // Tests that observers are sent OnCancelResolution() whenever a request is | |
| 1068 // cancelled. There are two ways to cancel a request: | |
| 1069 // (1) Delete the HostResolver while job is outstanding. | |
| 1070 // (2) Call HostResolver::CancelRequest() while a request is outstanding. | |
| 1071 TEST_F(HostResolverImplTest, CancellationObserver) { | |
| 1072 TestHostResolverObserver observer; | |
| 1073 { | |
| 1074 // Create a host resolver and attach an observer. | |
| 1075 scoped_ptr<HostResolver> host_resolver( | |
| 1076 CreateHostResolverImpl(NULL)); | |
| 1077 host_resolver->AddObserver(&observer); | |
| 1078 | |
| 1079 TestOldCompletionCallback callback; | |
| 1080 | |
| 1081 EXPECT_EQ(0U, observer.start_log.size()); | |
| 1082 EXPECT_EQ(0U, observer.finish_log.size()); | |
| 1083 EXPECT_EQ(0U, observer.cancel_log.size()); | |
| 1084 | |
| 1085 // Start an async resolve for (host1:70). | |
| 1086 HostResolver::RequestInfo info1(HostPortPair("host1", 70)); | |
| 1087 HostResolver::RequestHandle req = NULL; | |
| 1088 AddressList addrlist; | |
| 1089 int rv = host_resolver->Resolve(info1, &addrlist, &callback, &req, | |
| 1090 BoundNetLog()); | |
| 1091 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1092 EXPECT_TRUE(NULL != req); | |
| 1093 | |
| 1094 EXPECT_EQ(1U, observer.start_log.size()); | |
| 1095 EXPECT_EQ(0U, observer.finish_log.size()); | |
| 1096 EXPECT_EQ(0U, observer.cancel_log.size()); | |
| 1097 | |
| 1098 EXPECT_TRUE(observer.start_log[0] == | |
| 1099 TestHostResolverObserver::StartOrCancelEntry(0, info1)); | |
| 1100 | |
| 1101 // Cancel the request. | |
| 1102 host_resolver->CancelRequest(req); | |
| 1103 | |
| 1104 EXPECT_EQ(1U, observer.start_log.size()); | |
| 1105 EXPECT_EQ(0U, observer.finish_log.size()); | |
| 1106 EXPECT_EQ(1U, observer.cancel_log.size()); | |
| 1107 | |
| 1108 EXPECT_TRUE(observer.cancel_log[0] == | |
| 1109 TestHostResolverObserver::StartOrCancelEntry(0, info1)); | |
| 1110 | |
| 1111 // Start an async request for (host2:60) | |
| 1112 HostResolver::RequestInfo info2(HostPortPair("host2", 60)); | |
| 1113 rv = host_resolver->Resolve(info2, &addrlist, &callback, NULL, | |
| 1114 BoundNetLog()); | |
| 1115 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1116 EXPECT_TRUE(NULL != req); | |
| 1117 | |
| 1118 EXPECT_EQ(2U, observer.start_log.size()); | |
| 1119 EXPECT_EQ(0U, observer.finish_log.size()); | |
| 1120 EXPECT_EQ(1U, observer.cancel_log.size()); | |
| 1121 | |
| 1122 EXPECT_TRUE(observer.start_log[1] == | |
| 1123 TestHostResolverObserver::StartOrCancelEntry(1, info2)); | |
| 1124 | |
| 1125 // Upon exiting this scope, HostResolver is destroyed, so all requests are | |
| 1126 // implicitly cancelled. | |
| 1127 } | |
| 1128 | |
| 1129 // Check that destroying the HostResolver sent a notification for | |
| 1130 // cancellation of host2:60 request. | |
| 1131 | |
| 1132 EXPECT_EQ(2U, observer.start_log.size()); | |
| 1133 EXPECT_EQ(0U, observer.finish_log.size()); | |
| 1134 EXPECT_EQ(2U, observer.cancel_log.size()); | |
| 1135 | |
| 1136 HostResolver::RequestInfo info(HostPortPair("host2", 60)); | |
| 1137 EXPECT_TRUE(observer.cancel_log[1] == | |
| 1138 TestHostResolverObserver::StartOrCancelEntry(1, info)); | |
| 1139 } | |
| 1140 | |
| 1141 // Test that IP address changes flush the cache. | 984 // Test that IP address changes flush the cache. |
| 1142 TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange) { | 985 TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange) { |
| 1143 scoped_ptr<HostResolver> host_resolver( | 986 scoped_ptr<HostResolver> host_resolver( |
| 1144 new HostResolverImpl(NULL, HostCache::CreateDefaultCache(), kMaxJobs, | 987 new HostResolverImpl(NULL, HostCache::CreateDefaultCache(), kMaxJobs, |
| 1145 kMaxRetryAttempts, NULL)); | 988 kMaxRetryAttempts, NULL)); |
| 1146 | 989 |
| 1147 AddressList addrlist; | 990 AddressList addrlist; |
| 1148 | 991 |
| 1149 // Resolve "host1". | 992 // Resolve "host1". |
| 1150 HostResolver::RequestInfo info1(HostPortPair("host1", 70)); | 993 HostResolver::RequestInfo info1(HostPortPair("host1", 70)); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 scoped_refptr<CapturingHostResolverProc> resolver_proc( | 1137 scoped_refptr<CapturingHostResolverProc> resolver_proc( |
| 1295 new CapturingHostResolverProc(NULL)); | 1138 new CapturingHostResolverProc(NULL)); |
| 1296 | 1139 |
| 1297 // This HostResolverImpl will only allow 1 outstanding resolve at a time. | 1140 // This HostResolverImpl will only allow 1 outstanding resolve at a time. |
| 1298 size_t kMaxJobs = 1u; | 1141 size_t kMaxJobs = 1u; |
| 1299 const size_t kRetryAttempts = 0u; | 1142 const size_t kRetryAttempts = 0u; |
| 1300 scoped_ptr<HostResolver> host_resolver( | 1143 scoped_ptr<HostResolver> host_resolver( |
| 1301 new HostResolverImpl(resolver_proc, HostCache::CreateDefaultCache(), | 1144 new HostResolverImpl(resolver_proc, HostCache::CreateDefaultCache(), |
| 1302 kMaxJobs, kRetryAttempts, NULL)); | 1145 kMaxJobs, kRetryAttempts, NULL)); |
| 1303 | 1146 |
| 1304 TestHostResolverObserver observer; | |
| 1305 host_resolver->AddObserver(&observer); | |
| 1306 | |
| 1307 // Note that at this point the CapturingHostResolverProc is blocked, so any | 1147 // Note that at this point the CapturingHostResolverProc is blocked, so any |
| 1308 // requests we make will not complete. | 1148 // requests we make will not complete. |
| 1309 | 1149 |
| 1310 HostResolver::RequestInfo req[] = { | 1150 HostResolver::RequestInfo req[] = { |
| 1311 CreateResolverRequest("req0", LOW), | 1151 CreateResolverRequest("req0", LOW), |
| 1312 CreateResolverRequest("req1", MEDIUM), | 1152 CreateResolverRequest("req1", MEDIUM), |
| 1313 CreateResolverRequest("req2", MEDIUM), | 1153 CreateResolverRequest("req2", MEDIUM), |
| 1314 CreateResolverRequest("req3", LOW), | 1154 CreateResolverRequest("req3", LOW), |
| 1315 CreateResolverRequest("req4", HIGHEST), | 1155 CreateResolverRequest("req4", HIGHEST), |
| 1316 CreateResolverRequest("req5", LOW), | 1156 CreateResolverRequest("req5", LOW), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1329 } | 1169 } |
| 1330 | 1170 |
| 1331 // Unblock the resolver thread so the requests can run. | 1171 // Unblock the resolver thread so the requests can run. |
| 1332 resolver_proc->Signal(); | 1172 resolver_proc->Signal(); |
| 1333 | 1173 |
| 1334 // Wait for all the requests to complete succesfully. | 1174 // Wait for all the requests to complete succesfully. |
| 1335 for (size_t i = 0; i < arraysize(req); ++i) { | 1175 for (size_t i = 0; i < arraysize(req); ++i) { |
| 1336 EXPECT_EQ(OK, callback[i].WaitForResult()) << "i=" << i; | 1176 EXPECT_EQ(OK, callback[i].WaitForResult()) << "i=" << i; |
| 1337 } | 1177 } |
| 1338 | 1178 |
| 1339 host_resolver->RemoveObserver(&observer); | |
| 1340 | |
| 1341 // Since we have restricted to a single concurrent thread in the jobpool, | 1179 // Since we have restricted to a single concurrent thread in the jobpool, |
| 1342 // the requests should complete in order of priority (with the exception | 1180 // the requests should complete in order of priority (with the exception |
| 1343 // of the first request, which gets started right away, since there is | 1181 // of the first request, which gets started right away, since there is |
| 1344 // nothing outstanding). | 1182 // nothing outstanding). |
| 1345 CapturingHostResolverProc::CaptureList capture_list = | 1183 CapturingHostResolverProc::CaptureList capture_list = |
| 1346 resolver_proc->GetCaptureList(); | 1184 resolver_proc->GetCaptureList(); |
| 1347 ASSERT_EQ(7u, capture_list.size()); | 1185 ASSERT_EQ(7u, capture_list.size()); |
| 1348 | 1186 |
| 1349 EXPECT_EQ("req0", capture_list[0].hostname); | 1187 EXPECT_EQ("req0", capture_list[0].hostname); |
| 1350 EXPECT_EQ("req4", capture_list[1].hostname); | 1188 EXPECT_EQ("req4", capture_list[1].hostname); |
| 1351 EXPECT_EQ("req5", capture_list[2].hostname); | 1189 EXPECT_EQ("req5", capture_list[2].hostname); |
| 1352 EXPECT_EQ("req1", capture_list[3].hostname); | 1190 EXPECT_EQ("req1", capture_list[3].hostname); |
| 1353 EXPECT_EQ("req2", capture_list[4].hostname); | 1191 EXPECT_EQ("req2", capture_list[4].hostname); |
| 1354 EXPECT_EQ("req3", capture_list[5].hostname); | 1192 EXPECT_EQ("req3", capture_list[5].hostname); |
| 1355 EXPECT_EQ("req6", capture_list[6].hostname); | 1193 EXPECT_EQ("req6", capture_list[6].hostname); |
| 1356 | |
| 1357 // Also check using the observer's trace. | |
| 1358 EXPECT_EQ(8U, observer.start_log.size()); | |
| 1359 EXPECT_EQ(8U, observer.finish_log.size()); | |
| 1360 EXPECT_EQ(0U, observer.cancel_log.size()); | |
| 1361 | |
| 1362 EXPECT_EQ("req0", observer.finish_log[0].info.hostname()); | |
| 1363 EXPECT_EQ("req4", observer.finish_log[1].info.hostname()); | |
| 1364 | |
| 1365 // There were two requests for "req5". The highest priority | |
| 1366 // one should have been dispatched earlier. | |
| 1367 EXPECT_EQ("req5", observer.finish_log[2].info.hostname()); | |
| 1368 EXPECT_EQ("req5", observer.finish_log[3].info.hostname()); | |
| 1369 EXPECT_EQ(HIGHEST, observer.finish_log[2].info.priority()); | |
| 1370 EXPECT_EQ(LOW, observer.finish_log[3].info.priority()); | |
| 1371 | |
| 1372 EXPECT_EQ("req1", observer.finish_log[4].info.hostname()); | |
| 1373 EXPECT_EQ("req2", observer.finish_log[5].info.hostname()); | |
| 1374 EXPECT_EQ("req3", observer.finish_log[6].info.hostname()); | |
| 1375 EXPECT_EQ("req6", observer.finish_log[7].info.hostname()); | |
| 1376 } | 1194 } |
| 1377 | 1195 |
| 1378 // Try cancelling a request which has not been attached to a job yet. | 1196 // Try cancelling a request which has not been attached to a job yet. |
| 1379 TEST_F(HostResolverImplTest, CancelPendingRequest) { | 1197 TEST_F(HostResolverImplTest, CancelPendingRequest) { |
| 1380 scoped_refptr<CapturingHostResolverProc> resolver_proc( | 1198 scoped_refptr<CapturingHostResolverProc> resolver_proc( |
| 1381 new CapturingHostResolverProc(NULL)); | 1199 new CapturingHostResolverProc(NULL)); |
| 1382 | 1200 |
| 1383 // This HostResolverImpl will only allow 1 outstanding resolve at a time. | 1201 // This HostResolverImpl will only allow 1 outstanding resolve at a time. |
| 1384 const size_t kMaxJobs = 1u; | 1202 const size_t kMaxJobs = 1u; |
| 1385 const size_t kRetryAttempts = 0u; | 1203 const size_t kRetryAttempts = 0u; |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1732 resolver_proc->WaitForAllAttemptsToFinish(TimeDelta::FromMilliseconds(60000)); | 1550 resolver_proc->WaitForAllAttemptsToFinish(TimeDelta::FromMilliseconds(60000)); |
| 1733 MessageLoop::current()->RunAllPending(); | 1551 MessageLoop::current()->RunAllPending(); |
| 1734 | 1552 |
| 1735 EXPECT_EQ(resolver_proc->total_attempts_resolved(), kTotalAttempts); | 1553 EXPECT_EQ(resolver_proc->total_attempts_resolved(), kTotalAttempts); |
| 1736 EXPECT_EQ(resolver_proc->resolved_attempt_number(), kAttemptNumberToResolve); | 1554 EXPECT_EQ(resolver_proc->resolved_attempt_number(), kAttemptNumberToResolve); |
| 1737 } | 1555 } |
| 1738 | 1556 |
| 1739 // TODO(cbentzel): Test a mix of requests with different HostResolverFlags. | 1557 // TODO(cbentzel): Test a mix of requests with different HostResolverFlags. |
| 1740 | 1558 |
| 1741 } // namespace net | 1559 } // namespace net |
| OLD | NEW |