Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: chrome/browser/net/dns_master_unittest.cc

Issue 21133: Revert "Clean up dns prefetch code, and also port it." (Closed)
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/net/dns_master.cc ('k') | chrome/browser/net/dns_slave.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 // Multi-threaded tests of DnsMaster and DnsPrefetch slave functionality.
6
5 #include <time.h> 7 #include <time.h>
8 #include <ws2tcpip.h>
9 #include <Wspiapi.h> // Needed for win2k compatibility
6 10
7 #include <algorithm> 11 #include <algorithm>
12 #include <map>
8 #include <sstream> 13 #include <sstream>
9 #include <string> 14 #include <string>
10 15
11 #include "base/message_loop.h"
12 #include "base/platform_thread.h" 16 #include "base/platform_thread.h"
13 #include "base/scoped_ptr.h" 17 #include "base/spin_wait.h"
14 #include "base/timer.h"
15 #include "chrome/browser/net/dns_global.h" 18 #include "chrome/browser/net/dns_global.h"
16 #include "chrome/browser/net/dns_host_info.h" 19 #include "chrome/browser/net/dns_host_info.h"
17 #include "chrome/common/net/dns.h" 20 #include "chrome/browser/net/dns_slave.h"
18 #include "net/base/address_list.h"
19 #include "net/base/host_resolver.h"
20 #include "net/base/host_resolver_unittest.h"
21 #include "net/base/winsock_init.h" 21 #include "net/base/winsock_init.h"
22 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
23 23
24
24 using base::Time; 25 using base::Time;
25 using base::TimeDelta; 26 using base::TimeDelta;
26 27
27 namespace chrome_browser_net { 28 namespace {
28 29
29 class WaitForResolutionHelper; 30 class DnsMasterTest : public testing::Test {
30
31 typedef base::RepeatingTimer<WaitForResolutionHelper> HelperTimer;
32
33 class WaitForResolutionHelper {
34 public:
35 WaitForResolutionHelper(DnsMaster* master, const NameList& hosts,
36 HelperTimer* timer)
37 : master_(master),
38 hosts_(hosts),
39 timer_(timer) {
40 }
41
42 void Run() {
43 for (NameList::const_iterator i = hosts_.begin(); i != hosts_.end(); ++i)
44 if (master_->GetResolutionDuration(*i) == DnsHostInfo::kNullDuration)
45 return; // We don't have resolution for that host.
46
47 // When all hostnames have been resolved, exit the loop.
48 timer_->Stop();
49 MessageLoop::current()->Quit();
50 delete timer_;
51 delete this;
52 }
53
54 private:
55 DnsMaster* master_;
56 const NameList hosts_;
57 HelperTimer* timer_;
58 }; 31 };
59 32
60 class DnsMasterTest : public testing::Test { 33 typedef chrome_browser_net::DnsMaster DnsMaster;
61 public: 34 typedef chrome_browser_net::DnsPrefetcherInit DnsPrefetcherInit;
62 DnsMasterTest() 35 typedef chrome_browser_net::DnsHostInfo DnsHostInfo;
63 : loop_(new MessageLoop()), 36 typedef chrome_browser_net::NameList NameList;
64 mapper_(new net::RuleBasedHostMapper()),
65 scoped_mapper_(mapper_.get()) {
66 }
67 37
68 protected:
69 virtual void SetUp() {
70 #if defined(OS_WIN)
71 net::EnsureWinsockInit();
72 #endif
73 mapper_->AddRuleWithLatency("www.google.com", "127.0.0.1", 50);
74 mapper_->AddRuleWithLatency("gmail.google.com.com", "127.0.0.1", 70);
75 mapper_->AddRuleWithLatency("mail.google.com", "127.0.0.1", 44);
76 mapper_->AddRuleWithLatency("gmail.com", "127.0.0.1", 63);
77 }
78 38
79 void WaitForResolution(DnsMaster* master, const NameList& hosts) { 39 //------------------------------------------------------------------------------
80 HelperTimer* timer = new HelperTimer(); 40 // Provide network function stubs to run tests offline (and avoid the variance
81 timer->Start(TimeDelta::FromMilliseconds(100), 41 // of real DNS lookups.
82 new WaitForResolutionHelper(master, hosts, timer), 42 //------------------------------------------------------------------------------
83 &WaitForResolutionHelper::Run);
84 MessageLoop::current()->Run();
85 }
86 43
87 void DestroyMessageLoop() { 44 static void __stdcall fake_free_addr_info(struct addrinfo* ai) {
88 loop_.reset(); 45 // Kill off the dummy results.
89 } 46 EXPECT_TRUE(NULL != ai);
47 delete ai;
48 }
90 49
91 private: 50 static int __stdcall fake_get_addr_info(const char* nodename,
92 scoped_ptr<MessageLoop> loop_; 51 const char* servname,
93 scoped_refptr<net::RuleBasedHostMapper> mapper_; 52 const struct addrinfo* hints,
94 net::ScopedHostMapper scoped_mapper_; 53 struct addrinfo** result) {
95 }; 54 static Lock lock;
55 int duration;
56 bool was_found;
57 std::string hostname(nodename);
58 // Dummy up *some* return results to pass along.
59 *result = new addrinfo;
60 EXPECT_TRUE(NULL != *result);
61 {
62 AutoLock autolock(lock);
63
64 static bool initialized = false;
65 typedef std::map<std::string, int> Latency;
66 static Latency latency;
67 static std::map<std::string, bool> found;
68 if (!initialized) {
69 initialized = true;
70 // List all known hostnames
71 latency["www.google.com"] = 50;
72 latency["gmail.google.com.com"] = 70;
73 latency["mail.google.com"] = 44;
74 latency["gmail.com"] = 63;
75
76 for (Latency::iterator it = latency.begin(); latency.end() != it; it++) {
77 found[it->first] = true;
78 }
79 } // End static initialization
80
81 was_found = found[hostname];
82
83 if (latency.end() != latency.find(hostname)) {
84 duration = latency[hostname];
85 } else {
86 duration = 500;
87 }
88 // Change latency to simulate cache warming (next latency will be short).
89 latency[hostname] = 1;
90 } // Release lock.
91
92 PlatformThread::Sleep(duration);
93
94 return was_found ? 0 : WSAHOST_NOT_FOUND;
95 }
96
97 static void SetupNetworkInfrastructure() {
98 bool kUseFakeNetwork = true;
99 if (kUseFakeNetwork)
100 chrome_browser_net::SetAddrinfoCallbacks(fake_get_addr_info,
101 fake_free_addr_info);
102 }
96 103
97 //------------------------------------------------------------------------------ 104 //------------------------------------------------------------------------------
98 // Provide a function to create unique (nonexistant) domains at *every* call. 105 // Provide a function to create unique (nonexistant) domains at *every* call.
99 //------------------------------------------------------------------------------ 106 //------------------------------------------------------------------------------
100 static std::string GetNonexistantDomain() { 107 static std::string GetNonexistantDomain() {
101 static std::string postfix = ".google.com"; 108 static std::string postfix = ".google.com";
102 static std::string prefix = "www."; 109 static std::string prefix = "www.";
103 static std::string mid = "datecount"; 110 static std::string mid = "datecount";
104 111
105 static int counter = 0; // Make sure its unique. 112 static int counter = 0; // Make sure its unique.
106 time_t number = time(NULL); 113 time_t number = time(NULL);
107 std::ostringstream result; 114 std::ostringstream result;
108 result << prefix << number << mid << ++counter << postfix; 115 result << prefix << number << mid << ++counter << postfix;
109 return result.str(); 116 return result.str();
110 } 117 }
111 118
112 //------------------------------------------------------------------------------ 119 //------------------------------------------------------------------------------
113 // Use a blocking function to contrast results we get via async services. 120 // Use a blocking function to contrast results we get via async services.
114 //------------------------------------------------------------------------------ 121 //------------------------------------------------------------------------------
115 TimeDelta BlockingDnsLookup(const std::string& hostname) { 122 TimeDelta BlockingDnsLookup(const std::string& hostname) {
123 char* port = "80"; // I may need to get the real port
124 struct addrinfo* result = NULL;
116 Time start = Time::Now(); 125 Time start = Time::Now();
117 126
118 net::HostResolver resolver; 127 // Use the same underlying methods as dns_prefetch_slave does
119 net::AddressList addresses; 128 chrome_browser_net::get_getaddrinfo()(hostname.c_str(), port,
120 resolver.Resolve(hostname, 80, &addresses, NULL); 129 NULL, &result);
121 130
122 return Time::Now() - start; 131 TimeDelta duration = Time::Now() - start;
132
133 if (result) {
134 chrome_browser_net::get_freeaddrinfo()(result);
135 result = NULL;
136 }
137
138 return duration;
123 } 139 }
124 140
125 //------------------------------------------------------------------------------ 141 //------------------------------------------------------------------------------
126 142
127 // First test to be sure the OS is caching lookups, which is the whole premise 143 // First test to be sure the OS is caching lookups, which is the whole premise
128 // of DNS prefetching. 144 // of DNS prefetching.
129 TEST_F(DnsMasterTest, OsCachesLookupsTest) { 145 TEST(DnsMasterTest, OsCachesLookupsTest) {
130 const Time start = Time::Now(); 146 SetupNetworkInfrastructure();
131 int all_lookups = 0; 147 net::EnsureWinsockInit();
132 int lookups_with_improvement = 0; 148
133 // This test can be really flaky on Linux. It should run in much shorter time, 149 for (int i = 0; i < 5; i++) {
134 // but sometimes it won't and we don't like bogus failures.
135 while (Time::Now() - start < TimeDelta::FromMinutes(1)) {
136 std::string badname; 150 std::string badname;
137 badname = GetNonexistantDomain(); 151 badname = GetNonexistantDomain();
138
139 TimeDelta duration = BlockingDnsLookup(badname); 152 TimeDelta duration = BlockingDnsLookup(badname);
140 153 TimeDelta cached_duration = BlockingDnsLookup(badname);
141 // Produce more than one result and remove the largest one 154 EXPECT_TRUE(duration > cached_duration);
142 // to reduce flakiness.
143 std::vector<TimeDelta> cached_results;
144 for (int j = 0; j < 3; j++)
145 cached_results.push_back(BlockingDnsLookup(badname));
146 std::sort(cached_results.begin(), cached_results.end());
147 cached_results.pop_back();
148
149 TimeDelta cached_sum = TimeDelta::FromSeconds(0);
150 for (std::vector<TimeDelta>::const_iterator j = cached_results.begin();
151 j != cached_results.end(); ++j)
152 cached_sum += *j;
153 TimeDelta cached_duration = cached_sum / cached_results.size();
154
155 all_lookups++;
156 if (cached_duration < duration)
157 lookups_with_improvement++;
158 if (all_lookups >= 10)
159 if (lookups_with_improvement * 100 > all_lookups * 75)
160 // Okay, we see the improvement for more than 75% of all lookups.
161 return;
162 } 155 }
163 FAIL() << "No substantial improvement in lookup time.";
164 } 156 }
165 157
166 TEST_F(DnsMasterTest, StartupShutdownTest) { 158 TEST(DnsMasterTest, StartupShutdownTest) {
167 DnsMaster testing_master; 159 DnsMaster testing_master(TimeDelta::FromMilliseconds(5000));
168 // We do shutdown on destruction. 160
161 // With no threads, we should have no problem doing a shutdown.
162 EXPECT_TRUE(testing_master.ShutdownSlaves());
169 } 163 }
170 164
171 TEST_F(DnsMasterTest, BenefitLookupTest) { 165 TEST(DnsMasterTest, BenefitLookupTest) {
172 DnsMaster testing_master; 166 SetupNetworkInfrastructure();
167 net::EnsureWinsockInit();
168 DnsPrefetcherInit dns_init(NULL); // Creates global service .
169 DnsMaster testing_master(TimeDelta::FromMilliseconds(5000));
173 170
174 std::string goog("www.google.com"), 171 std::string goog("www.google.com"),
175 goog2("gmail.google.com.com"), 172 goog2("gmail.google.com.com"),
176 goog3("mail.google.com"), 173 goog3("mail.google.com"),
177 goog4("gmail.com"); 174 goog4("gmail.com");
178 DnsHostInfo goog_info, goog2_info, goog3_info, goog4_info; 175 DnsHostInfo goog_info, goog2_info, goog3_info, goog4_info;
179 176
180 // Simulate getting similar names from a network observer 177 // Simulate getting similar names from a network observer
181 goog_info.SetHostname(goog); 178 goog_info.SetHostname(goog);
182 goog2_info.SetHostname(goog2); 179 goog2_info.SetHostname(goog2);
183 goog3_info.SetHostname(goog3); 180 goog3_info.SetHostname(goog3);
184 goog4_info.SetHostname(goog4); 181 goog4_info.SetHostname(goog4);
185 182
186 goog_info.SetStartedState(); 183 goog_info.SetStartedState();
187 goog2_info.SetStartedState(); 184 goog2_info.SetStartedState();
188 goog3_info.SetStartedState(); 185 goog3_info.SetStartedState();
189 goog4_info.SetStartedState(); 186 goog4_info.SetStartedState();
190 187
191 goog_info.SetFinishedState(true); 188 goog_info.SetFinishedState(true);
192 goog2_info.SetFinishedState(true); 189 goog2_info.SetFinishedState(true);
193 goog3_info.SetFinishedState(true); 190 goog3_info.SetFinishedState(true);
194 goog4_info.SetFinishedState(true); 191 goog4_info.SetFinishedState(true);
195 192
196 NameList names; 193 NameList names;
197 names.insert(names.end(), goog); 194 names.insert(names.end(), goog);
198 names.insert(names.end(), goog2); 195 names.insert(names.end(), goog2);
199 names.insert(names.end(), goog3); 196 names.insert(names.end(), goog3);
200 names.insert(names.end(), goog4); 197 names.insert(names.end(), goog4);
201 198
199 // First only cause a minimal set of threads to start up.
200 // Currently we actually start 4 threads when we get called with an array
202 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED); 201 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
203 202
204 WaitForResolution(&testing_master, names); 203 // Wait for some resoultion for each google.
204 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
205 testing_master.GetResolutionDuration(goog).InMilliseconds());
206 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
207 testing_master.GetResolutionDuration(goog2).InMilliseconds());
208 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
209 testing_master.GetResolutionDuration(goog3).InMilliseconds());
210 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
211 testing_master.GetResolutionDuration(goog4).InMilliseconds());
212
213 EXPECT_EQ(std::min(names.size(),
214 4u /* chrome_browser_net::DnsMaster::kSlaveCountMin */ ),
215 testing_master.running_slave_count());
205 216
206 EXPECT_TRUE(testing_master.WasFound(goog)); 217 EXPECT_TRUE(testing_master.WasFound(goog));
207 EXPECT_TRUE(testing_master.WasFound(goog2)); 218 EXPECT_TRUE(testing_master.WasFound(goog2));
208 EXPECT_TRUE(testing_master.WasFound(goog3)); 219 EXPECT_TRUE(testing_master.WasFound(goog3));
209 EXPECT_TRUE(testing_master.WasFound(goog4)); 220 EXPECT_TRUE(testing_master.WasFound(goog4));
210 221
211 // With the mock DNS, each of these should have taken some time, and hence 222 // With the mock DNS, each of these should have taken some time, and hence
212 // shown a benefit (i.e., prefetch cost more than network access time). 223 // shown a benefit (i.e., prefetch cost more than network access time).
213 224
214 // Simulate actual navigation, and acrue the benefit for "helping" the DNS 225 // Simulate actual navigation, and acrue the benefit for "helping" the DNS
215 // part of the navigation. 226 // part of the navigation.
216 EXPECT_TRUE(testing_master.AccruePrefetchBenefits(GURL(), &goog_info)); 227 EXPECT_TRUE(testing_master.AccruePrefetchBenefits(GURL(), &goog_info));
217 EXPECT_TRUE(testing_master.AccruePrefetchBenefits(GURL(), &goog2_info)); 228 EXPECT_TRUE(testing_master.AccruePrefetchBenefits(GURL(), &goog2_info));
218 EXPECT_TRUE(testing_master.AccruePrefetchBenefits(GURL(), &goog3_info)); 229 EXPECT_TRUE(testing_master.AccruePrefetchBenefits(GURL(), &goog3_info));
219 EXPECT_TRUE(testing_master.AccruePrefetchBenefits(GURL(), &goog4_info)); 230 EXPECT_TRUE(testing_master.AccruePrefetchBenefits(GURL(), &goog4_info));
220 231
221 // Benefits can ONLY be reported once (for the first navigation). 232 // Benefits can ONLY be reported once (for the first navigation).
222 EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog_info)); 233 EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog_info));
223 EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog2_info)); 234 EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog2_info));
224 EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog3_info)); 235 EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog3_info));
225 EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog4_info)); 236 EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog4_info));
237
238 // Ensure a clean shutdown.
239 EXPECT_TRUE(testing_master.ShutdownSlaves());
226 } 240 }
227 241
228 TEST_F(DnsMasterTest, DestroyMessageLoop) { 242 TEST(DnsMasterTest, DISABLED_SingleSlaveLookupTest) {
229 scoped_refptr<net::WaitingHostMapper> mapper = new net::WaitingHostMapper(); 243 SetupNetworkInfrastructure();
230 net::ScopedHostMapper scoped_mapper(mapper.get()); 244 net::EnsureWinsockInit();
245 DnsPrefetcherInit dns_init(NULL); // Creates global service.
246 DnsMaster testing_master(TimeDelta::FromMilliseconds(5000));
231 247
232 { 248 std::string goog("www.google.com"),
233 DnsMaster testing_master; 249 goog2("gmail.google.com.com"),
250 goog3("mail.google.com"),
251 goog4("gmail.com");
252 std::string bad1(GetNonexistantDomain()),
253 bad2(GetNonexistantDomain());
234 254
235 std::string localhost("127.0.0.1"); 255 // Warm up local OS cache.
236 NameList names; 256 BlockingDnsLookup(goog);
237 names.insert(names.end(), localhost);
238
239 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
240
241 MessageLoop::current()->PostDelayedTask(FROM_HERE,
242 new MessageLoop::QuitTask(), 500);
243 MessageLoop::current()->Run();
244
245 DestroyMessageLoop();
246 ASSERT_TRUE(MessageLoop::current() == NULL);
247 }
248
249 // Trigger the internal callback (for HostResolver). It should not crash.
250 mapper->Signal();
251 }
252
253 TEST_F(DnsMasterTest, ShutdownWhenResolutionIsPendingTest) {
254 scoped_refptr<net::WaitingHostMapper> mapper = new net::WaitingHostMapper();
255 net::ScopedHostMapper scoped_mapper(mapper.get());
256
257 {
258 DnsMaster testing_master;
259
260 std::string localhost("127.0.0.1");
261 NameList names;
262 names.insert(names.end(), localhost);
263
264 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
265
266 MessageLoop::current()->PostDelayedTask(FROM_HERE,
267 new MessageLoop::QuitTask(), 500);
268 MessageLoop::current()->Run();
269
270 EXPECT_FALSE(testing_master.WasFound(localhost));
271 }
272
273 // Clean up after ourselves.
274 mapper->Signal();
275 MessageLoop::current()->RunAllPending();
276 }
277
278 TEST_F(DnsMasterTest, SingleLookupTest) {
279 DnsMaster testing_master;
280
281 std::string goog("www.google.com");
282 257
283 NameList names; 258 NameList names;
284 names.insert(names.end(), goog); 259 names.insert(names.end(), goog);
260 names.insert(names.end(), bad1);
261 names.insert(names.end(), bad2);
285 262
286 // Try to flood the master with many concurrent requests. 263 // First only cause a single thread to start up
287 for (int i = 0; i < 10; i++) 264 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
288 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
289 265
290 WaitForResolution(&testing_master, names); 266 // Wait for some resoultion for google.
267 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
268 testing_master.GetResolutionDuration(goog).InMilliseconds());
291 269
292 EXPECT_TRUE(testing_master.WasFound(goog)); 270 EXPECT_TRUE(testing_master.WasFound(goog));
271 EXPECT_FALSE(testing_master.WasFound(bad1));
272 EXPECT_FALSE(testing_master.WasFound(bad2));
273 // Verify the reason it is not found is that it is still being proceessed.
274 // Negative time mean no resolution yet.
275 EXPECT_GT(0, testing_master.GetResolutionDuration(bad2).InMilliseconds());
293 276
294 MessageLoop::current()->RunAllPending(); 277 // Spin long enough that we *do* find the resolution of bad2.
278 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
279 testing_master.GetResolutionDuration(bad2).InMilliseconds());
295 280
296 EXPECT_GT(testing_master.peak_pending_lookups(), names.size() / 2); 281 // Verify both fictitious names are resolved by now.
297 EXPECT_LE(testing_master.peak_pending_lookups(), names.size()); 282 // Typical random name takes about 20-30 ms
298 EXPECT_LE(testing_master.peak_pending_lookups(), 283 EXPECT_LT(0, testing_master.GetResolutionDuration(bad1).InMilliseconds());
299 DnsMaster::kMaxConcurrentLookups); 284 EXPECT_LT(0, testing_master.GetResolutionDuration(bad2).InMilliseconds());
285 EXPECT_FALSE(testing_master.WasFound(bad1));
286 EXPECT_FALSE(testing_master.WasFound(bad2));
287
288 EXPECT_EQ(1U, testing_master.running_slave_count());
289
290 // With just one thread (doing nothing now), ensure a clean shutdown.
291 EXPECT_TRUE(testing_master.ShutdownSlaves());
300 } 292 }
301 293
302 TEST_F(DnsMasterTest, ConcurrentLookupTest) { 294 TEST(DnsMasterTest, DISABLED_MultiThreadedLookupTest) {
303 DnsMaster testing_master; 295 SetupNetworkInfrastructure();
296 net::EnsureWinsockInit();
297 DnsMaster testing_master(TimeDelta::FromSeconds(30));
298 DnsPrefetcherInit dns_init(NULL);
304 299
305 std::string goog("www.google.com"), 300 std::string goog("www.google.com"),
306 goog2("gmail.google.com.com"), 301 goog2("gmail.google.com.com"),
307 goog3("mail.google.com"), 302 goog3("mail.google.com"),
308 goog4("gmail.com"); 303 goog4("gmail.com");
309 std::string bad1(GetNonexistantDomain()), 304 std::string bad1(GetNonexistantDomain()),
310 bad2(GetNonexistantDomain()); 305 bad2(GetNonexistantDomain());
311 306
312 NameList names; 307 NameList names;
313 names.insert(names.end(), goog); 308 names.insert(names.end(), goog);
314 names.insert(names.end(), goog3); 309 names.insert(names.end(), goog3);
315 names.insert(names.end(), bad1); 310 names.insert(names.end(), bad1);
316 names.insert(names.end(), goog2); 311 names.insert(names.end(), goog2);
317 names.insert(names.end(), bad2); 312 names.insert(names.end(), bad2);
318 names.insert(names.end(), goog4); 313 names.insert(names.end(), goog4);
319 names.insert(names.end(), goog); 314 names.insert(names.end(), goog);
320 315
321 // Warm up the *OS* cache for all the goog domains. 316 // Warm up the *OS* cache for all the goog domains.
322 BlockingDnsLookup(goog); 317 BlockingDnsLookup(goog);
323 BlockingDnsLookup(goog2); 318 BlockingDnsLookup(goog2);
324 BlockingDnsLookup(goog3); 319 BlockingDnsLookup(goog3);
325 BlockingDnsLookup(goog4); 320 BlockingDnsLookup(goog4);
326 321
327 // Try to flood the master with many concurrent requests. 322 // Get all 8 threads running by calling many times before queue is handled.
328 for (int i = 0; i < 10; i++) 323 for (int i = 0; i < 10; i++) {
329 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED); 324 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
325 }
330 326
331 WaitForResolution(&testing_master, names); 327 Sleep(10); // Allow time for async DNS to get answers.
332 328
333 EXPECT_TRUE(testing_master.WasFound(goog)); 329 EXPECT_TRUE(testing_master.WasFound(goog));
334 EXPECT_TRUE(testing_master.WasFound(goog3)); 330 EXPECT_TRUE(testing_master.WasFound(goog3));
335 EXPECT_TRUE(testing_master.WasFound(goog2)); 331 EXPECT_TRUE(testing_master.WasFound(goog2));
336 EXPECT_TRUE(testing_master.WasFound(goog4)); 332 EXPECT_TRUE(testing_master.WasFound(goog4));
337 EXPECT_FALSE(testing_master.WasFound(bad1)); 333 EXPECT_FALSE(testing_master.WasFound(bad1));
338 EXPECT_FALSE(testing_master.WasFound(bad2)); 334 EXPECT_FALSE(testing_master.WasFound(bad2));
339 335
340 MessageLoop::current()->RunAllPending(); 336 EXPECT_EQ(8U, testing_master.running_slave_count());
337
338 EXPECT_TRUE(testing_master.ShutdownSlaves());
339 }
340
341 TEST(DnsMasterTest, DISABLED_MultiThreadedSpeedupTest) {
342 SetupNetworkInfrastructure();
343 net::EnsureWinsockInit();
344 DnsMaster testing_master(TimeDelta::FromSeconds(30));
345 DnsPrefetcherInit dns_init(NULL);
346
347 std::string goog("www.google.com"),
348 goog2("gmail.google.com.com"),
349 goog3("mail.google.com"),
350 goog4("gmail.com");
351 std::string bad1(GetNonexistantDomain()),
352 bad2(GetNonexistantDomain()),
353 bad3(GetNonexistantDomain()),
354 bad4(GetNonexistantDomain());
355
356 NameList names;
357 names.insert(names.end(), goog);
358 names.insert(names.end(), bad1);
359 names.insert(names.end(), bad2);
360 names.insert(names.end(), goog3);
361 names.insert(names.end(), goog2);
362 names.insert(names.end(), bad3);
363 names.insert(names.end(), bad4);
364 names.insert(names.end(), goog4);
365
366 // First cause a lookup using a single thread.
367 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
368
369 // Wait for some resoultion for google.
370 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
371 testing_master.GetResolutionDuration(goog).InMilliseconds());
372
373 EXPECT_TRUE(testing_master.WasFound(goog));
374 EXPECT_FALSE(testing_master.WasFound(bad1));
375 EXPECT_FALSE(testing_master.WasFound(bad2));
376 // ...and due to delay in geting resolution of bad names, the single slave
377 // thread won't have time to finish the list.
378 EXPECT_FALSE(testing_master.WasFound(goog3));
379 EXPECT_FALSE(testing_master.WasFound(goog2));
380 EXPECT_FALSE(testing_master.WasFound(goog4));
381
382 EXPECT_EQ(1U, testing_master.running_slave_count());
383
384 // Get all 8 threads running by calling many times before queue is handled.
385 names.clear();
386 for (int i = 0; i < 10; i++)
387 testing_master.Resolve(GetNonexistantDomain(),
388 DnsHostInfo::PAGE_SCAN_MOTIVATED);
389
390 // Wait long enough for all the goog's to be resolved.
391 // They should all take about the same time, and run in parallel.
392 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
393 testing_master.GetResolutionDuration(goog2).InMilliseconds());
394 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
395 testing_master.GetResolutionDuration(goog3).InMilliseconds());
396 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
397 testing_master.GetResolutionDuration(goog4).InMilliseconds());
398
399 EXPECT_TRUE(testing_master.WasFound(goog3));
400 EXPECT_TRUE(testing_master.WasFound(goog2));
401 EXPECT_TRUE(testing_master.WasFound(goog4));
341 402
342 EXPECT_FALSE(testing_master.WasFound(bad1)); 403 EXPECT_FALSE(testing_master.WasFound(bad1));
343 EXPECT_FALSE(testing_master.WasFound(bad2)); 404 EXPECT_FALSE(testing_master.WasFound(bad2)); // Perhaps not even decided.
344 405
345 EXPECT_GT(testing_master.peak_pending_lookups(), names.size() / 2); 406 // Queue durations should be distinct from when 1 slave was working.
346 EXPECT_LE(testing_master.peak_pending_lookups(), names.size()); 407 EXPECT_GT(testing_master.GetQueueDuration(goog3).InMilliseconds(),
347 EXPECT_LE(testing_master.peak_pending_lookups(), 408 testing_master.GetQueueDuration(goog).InMilliseconds());
348 DnsMaster::kMaxConcurrentLookups); 409 EXPECT_GT(testing_master.GetQueueDuration(goog4).InMilliseconds(),
410 testing_master.GetQueueDuration(goog).InMilliseconds());
411
412 // Give bad names a chance to be determined as unresolved.
413 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
414 testing_master.GetResolutionDuration(bad1).InMilliseconds());
415 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
416 testing_master.GetResolutionDuration(bad2).InMilliseconds());
417
418
419 // Well known names should resolve faster than bad names.
420 EXPECT_GE(testing_master.GetResolutionDuration(bad1).InMilliseconds(),
421 testing_master.GetResolutionDuration(goog).InMilliseconds());
422
423 EXPECT_GE(testing_master.GetResolutionDuration(bad2).InMilliseconds(),
424 testing_master.GetResolutionDuration(goog4).InMilliseconds());
425
426 EXPECT_EQ(8U, testing_master.running_slave_count());
427
428 EXPECT_TRUE(testing_master.ShutdownSlaves());
349 } 429 }
350 430
351 TEST_F(DnsMasterTest, MassiveConcurrentLookupTest) { 431 } // namespace
352 DnsMaster testing_master;
353 432
354 NameList names;
355 for (int i = 0; i < 100; i++)
356 names.push_back(GetNonexistantDomain());
357
358 // Try to flood the master with many concurrent requests.
359 for (int i = 0; i < 10; i++)
360 testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
361
362 WaitForResolution(&testing_master, names);
363
364 MessageLoop::current()->RunAllPending();
365
366 EXPECT_LE(testing_master.peak_pending_lookups(), names.size());
367 EXPECT_LE(testing_master.peak_pending_lookups(),
368 DnsMaster::kMaxConcurrentLookups);
369 }
370
371 } // namespace chrome_browser_net
OLDNEW
« no previous file with comments | « chrome/browser/net/dns_master.cc ('k') | chrome/browser/net/dns_slave.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698