Include all dupe types (event when value is zero) in scan stats.
[chromium-blink-merge.git] / net / http / disk_cache_based_quic_server_info_unittest.cc
blobd4ddfc253f5d94d08df02c098b2f3ca585a7c3a2
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/disk_cache_based_quic_server_info.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
10 #include "base/message_loop/message_loop.h"
11 #include "net/base/net_errors.h"
12 #include "net/http/mock_http_cache.h"
13 #include "net/quic/crypto/quic_server_info.h"
14 #include "net/quic/quic_server_id.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 using std::string;
19 namespace net {
20 namespace {
22 // This is an empty transaction, needed to register the URL and the test mode.
23 const MockTransaction kHostInfoTransaction1 = {
24 "quicserverinfo:https://www.google.com:443",
25 "",
26 base::Time(),
27 "",
28 LOAD_NORMAL,
29 "",
30 "",
31 base::Time(),
32 "",
33 TEST_MODE_NORMAL,
34 NULL,
38 const MockTransaction kHostInfoTransaction2 = {
39 "quicserverinfo:http://www.google.com:80",
40 "",
41 base::Time(),
42 "",
43 LOAD_NORMAL,
44 "",
45 "",
46 base::Time(),
47 "",
48 TEST_MODE_NORMAL,
49 NULL,
53 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
54 public:
55 explicit DeleteCacheCompletionCallback(QuicServerInfo* server_info)
56 : server_info_(server_info),
57 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
58 base::Unretained(this))) {}
60 const CompletionCallback& callback() const { return callback_; }
62 private:
63 void OnComplete(int result) {
64 delete server_info_;
65 SetResult(result);
68 QuicServerInfo* server_info_;
69 CompletionCallback callback_;
71 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
74 } // namespace
76 // Tests that we can delete a DiskCacheBasedQuicServerInfo object in a
77 // completion callback for DiskCacheBasedQuicServerInfo::WaitForDataReady.
78 TEST(DiskCacheBasedQuicServerInfo, DeleteInCallback) {
79 // Use the blocking mock backend factory to force asynchronous completion
80 // of quic_server_info->WaitForDataReady(), so that the callback will run.
81 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
82 MockHttpCache cache(factory);
83 QuicServerId server_id("www.verisign.com", 443, true, PRIVACY_MODE_DISABLED);
84 scoped_ptr<QuicServerInfo> quic_server_info(
85 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
86 quic_server_info->Start();
87 TestCompletionCallback callback;
88 int rv = quic_server_info->WaitForDataReady(callback.callback());
89 EXPECT_EQ(ERR_IO_PENDING, rv);
90 // Now complete the backend creation and let the callback run.
91 factory->FinishCreation();
92 EXPECT_EQ(OK, callback.GetResult(rv));
95 // Tests the basic logic of storing, retrieving and updating data.
96 TEST(DiskCacheBasedQuicServerInfo, Update) {
97 MockHttpCache cache;
98 AddMockTransaction(&kHostInfoTransaction1);
99 TestCompletionCallback callback;
101 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
102 scoped_ptr<QuicServerInfo> quic_server_info(
103 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
104 quic_server_info->Start();
105 int rv = quic_server_info->WaitForDataReady(callback.callback());
106 EXPECT_EQ(OK, callback.GetResult(rv));
108 QuicServerInfo::State* state = quic_server_info->mutable_state();
109 EXPECT_TRUE(state->certs.empty());
110 const string server_config_a = "server_config_a";
111 const string source_address_token_a = "source_address_token_a";
112 const string server_config_sig_a = "server_config_sig_a";
113 const string cert_a = "cert_a";
114 const string cert_b = "cert_b";
116 state->server_config = server_config_a;
117 state->source_address_token = source_address_token_a;
118 state->server_config_sig = server_config_sig_a;
119 state->certs.push_back(cert_a);
120 quic_server_info->Persist();
122 // Wait until Persist() does the work.
123 base::MessageLoop::current()->RunUntilIdle();
125 // Open the stored QuicServerInfo.
126 quic_server_info.reset(
127 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
128 quic_server_info->Start();
129 rv = quic_server_info->WaitForDataReady(callback.callback());
130 EXPECT_EQ(OK, callback.GetResult(rv));
132 // And now update the data.
133 state = quic_server_info->mutable_state();
134 state->certs.push_back(cert_b);
136 // Fail instead of DCHECKing double creates.
137 cache.disk_cache()->set_double_create_check(false);
138 quic_server_info->Persist();
139 base::MessageLoop::current()->RunUntilIdle();
141 // Verify that the state was updated.
142 quic_server_info.reset(
143 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
144 quic_server_info->Start();
145 rv = quic_server_info->WaitForDataReady(callback.callback());
146 EXPECT_EQ(OK, callback.GetResult(rv));
147 EXPECT_TRUE(quic_server_info->IsDataReady());
149 const QuicServerInfo::State& state1 = quic_server_info->state();
150 EXPECT_EQ(server_config_a, state1.server_config);
151 EXPECT_EQ(source_address_token_a, state1.source_address_token);
152 EXPECT_EQ(server_config_sig_a, state1.server_config_sig);
153 EXPECT_EQ(2U, state1.certs.size());
154 EXPECT_EQ(cert_a, state1.certs[0]);
155 EXPECT_EQ(cert_b, state1.certs[1]);
157 RemoveMockTransaction(&kHostInfoTransaction1);
160 // Test that demonstrates different info is returned when the ports differ.
161 TEST(DiskCacheBasedQuicServerInfo, UpdateDifferentPorts) {
162 MockHttpCache cache;
163 AddMockTransaction(&kHostInfoTransaction1);
164 AddMockTransaction(&kHostInfoTransaction2);
165 TestCompletionCallback callback;
167 // Persist data for port 443.
168 QuicServerId server_id1("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
169 scoped_ptr<QuicServerInfo> quic_server_info1(
170 new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache()));
171 quic_server_info1->Start();
172 int rv = quic_server_info1->WaitForDataReady(callback.callback());
173 EXPECT_EQ(OK, callback.GetResult(rv));
175 QuicServerInfo::State* state1 = quic_server_info1->mutable_state();
176 EXPECT_TRUE(state1->certs.empty());
177 const string server_config_a = "server_config_a";
178 const string source_address_token_a = "source_address_token_a";
179 const string server_config_sig_a = "server_config_sig_a";
180 const string cert_a = "cert_a";
182 state1->server_config = server_config_a;
183 state1->source_address_token = source_address_token_a;
184 state1->server_config_sig = server_config_sig_a;
185 state1->certs.push_back(cert_a);
186 quic_server_info1->Persist();
188 // Wait until Persist() does the work.
189 base::MessageLoop::current()->RunUntilIdle();
191 // Persist data for port 80.
192 QuicServerId server_id2("www.google.com", 80, false, PRIVACY_MODE_DISABLED);
193 scoped_ptr<QuicServerInfo> quic_server_info2(
194 new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache()));
195 quic_server_info2->Start();
196 rv = quic_server_info2->WaitForDataReady(callback.callback());
197 EXPECT_EQ(OK, callback.GetResult(rv));
199 QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
200 EXPECT_TRUE(state2->certs.empty());
201 const string server_config_b = "server_config_b";
202 const string source_address_token_b = "source_address_token_b";
203 const string server_config_sig_b = "server_config_sig_b";
204 const string cert_b = "cert_b";
206 state2->server_config = server_config_b;
207 state2->source_address_token = source_address_token_b;
208 state2->server_config_sig = server_config_sig_b;
209 state2->certs.push_back(cert_b);
210 quic_server_info2->Persist();
212 // Wait until Persist() does the work.
213 base::MessageLoop::current()->RunUntilIdle();
215 // Verify the stored QuicServerInfo for port 443.
216 scoped_ptr<QuicServerInfo> quic_server_info(
217 new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache()));
218 quic_server_info->Start();
219 rv = quic_server_info->WaitForDataReady(callback.callback());
220 EXPECT_EQ(OK, callback.GetResult(rv));
221 EXPECT_TRUE(quic_server_info->IsDataReady());
223 const QuicServerInfo::State& state_a = quic_server_info->state();
224 EXPECT_EQ(server_config_a, state_a.server_config);
225 EXPECT_EQ(source_address_token_a, state_a.source_address_token);
226 EXPECT_EQ(server_config_sig_a, state_a.server_config_sig);
227 EXPECT_EQ(1U, state_a.certs.size());
228 EXPECT_EQ(cert_a, state_a.certs[0]);
230 // Verify the stored QuicServerInfo for port 80.
231 quic_server_info.reset(
232 new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache()));
233 quic_server_info->Start();
234 rv = quic_server_info->WaitForDataReady(callback.callback());
235 EXPECT_EQ(OK, callback.GetResult(rv));
236 EXPECT_TRUE(quic_server_info->IsDataReady());
238 const QuicServerInfo::State& state_b = quic_server_info->state();
239 EXPECT_EQ(server_config_b, state_b.server_config);
240 EXPECT_EQ(source_address_token_b, state_b.source_address_token);
241 EXPECT_EQ(server_config_sig_b, state_b.server_config_sig);
242 EXPECT_EQ(1U, state_b.certs.size());
243 EXPECT_EQ(cert_b, state_b.certs[0]);
245 RemoveMockTransaction(&kHostInfoTransaction2);
246 RemoveMockTransaction(&kHostInfoTransaction1);
249 // Test IsReadyToPersist when there is a pending write.
250 TEST(DiskCacheBasedQuicServerInfo, IsReadyToPersist) {
251 MockHttpCache cache;
252 AddMockTransaction(&kHostInfoTransaction1);
253 TestCompletionCallback callback;
255 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
256 scoped_ptr<QuicServerInfo> quic_server_info(
257 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
258 EXPECT_FALSE(quic_server_info->IsDataReady());
259 quic_server_info->Start();
260 int rv = quic_server_info->WaitForDataReady(callback.callback());
261 EXPECT_EQ(OK, callback.GetResult(rv));
262 EXPECT_TRUE(quic_server_info->IsDataReady());
264 QuicServerInfo::State* state = quic_server_info->mutable_state();
265 EXPECT_TRUE(state->certs.empty());
266 const string server_config_a = "server_config_a";
267 const string source_address_token_a = "source_address_token_a";
268 const string server_config_sig_a = "server_config_sig_a";
269 const string cert_a = "cert_a";
271 state->server_config = server_config_a;
272 state->source_address_token = source_address_token_a;
273 state->server_config_sig = server_config_sig_a;
274 state->certs.push_back(cert_a);
275 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
276 quic_server_info->Persist();
278 // Once we call Persist, IsReadyToPersist should return false until Persist
279 // has completed.
280 EXPECT_FALSE(quic_server_info->IsReadyToPersist());
282 // Wait until Persist() does the work.
283 base::MessageLoop::current()->RunUntilIdle();
285 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
287 // Verify that the state was updated.
288 quic_server_info.reset(
289 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
290 quic_server_info->Start();
291 rv = quic_server_info->WaitForDataReady(callback.callback());
292 EXPECT_EQ(OK, callback.GetResult(rv));
293 EXPECT_TRUE(quic_server_info->IsDataReady());
295 const QuicServerInfo::State& state1 = quic_server_info->state();
296 EXPECT_EQ(server_config_a, state1.server_config);
297 EXPECT_EQ(source_address_token_a, state1.source_address_token);
298 EXPECT_EQ(server_config_sig_a, state1.server_config_sig);
299 EXPECT_EQ(1U, state1.certs.size());
300 EXPECT_EQ(cert_a, state1.certs[0]);
302 RemoveMockTransaction(&kHostInfoTransaction1);
305 // Test multiple calls to Persist.
306 TEST(DiskCacheBasedQuicServerInfo, MultiplePersist) {
307 MockHttpCache cache;
308 AddMockTransaction(&kHostInfoTransaction1);
309 TestCompletionCallback callback;
311 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
312 scoped_ptr<QuicServerInfo> quic_server_info(
313 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
314 EXPECT_FALSE(quic_server_info->IsDataReady());
315 quic_server_info->Start();
316 int rv = quic_server_info->WaitForDataReady(callback.callback());
317 EXPECT_EQ(OK, callback.GetResult(rv));
318 EXPECT_TRUE(quic_server_info->IsDataReady());
320 // Persist data once.
321 QuicServerInfo::State* state = quic_server_info->mutable_state();
322 EXPECT_TRUE(state->certs.empty());
323 const string server_config_init = "server_config_init";
324 const string source_address_token_init = "source_address_token_init";
325 const string server_config_sig_init = "server_config_sig_init";
326 const string cert_init = "cert_init";
328 state->server_config = server_config_init;
329 state->source_address_token = source_address_token_init;
330 state->server_config_sig = server_config_sig_init;
331 state->certs.push_back(cert_init);
332 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
333 quic_server_info->Persist();
335 // Once we call Persist, IsReadyToPersist should return false until Persist
336 // has completed.
337 EXPECT_FALSE(quic_server_info->IsReadyToPersist());
339 // Wait until Persist() does the work.
340 base::MessageLoop::current()->RunUntilIdle();
342 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
344 // Persist one more time using the same |quic_server_info| object and without
345 // doing another Start() and WaitForDataReady.
346 const string server_config_a = "server_config_a";
347 const string source_address_token_a = "source_address_token_a";
348 const string server_config_sig_a = "server_config_sig_a";
349 const string cert_a = "cert_a";
351 state->server_config = server_config_a;
352 state->source_address_token = source_address_token_a;
353 state->server_config_sig = server_config_sig_a;
354 state->certs.push_back(cert_a);
355 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
356 quic_server_info->Persist();
358 // Once we call Persist, IsReadyToPersist should return false until Persist
359 // has completed.
360 EXPECT_FALSE(quic_server_info->IsReadyToPersist());
362 // Wait until Persist() does the work.
363 base::MessageLoop::current()->RunUntilIdle();
365 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
367 // Verify that the state was updated.
368 quic_server_info.reset(
369 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
370 quic_server_info->Start();
371 rv = quic_server_info->WaitForDataReady(callback.callback());
372 EXPECT_EQ(OK, callback.GetResult(rv));
373 EXPECT_TRUE(quic_server_info->IsDataReady());
375 const QuicServerInfo::State& state1 = quic_server_info->state();
376 EXPECT_EQ(server_config_a, state1.server_config);
377 EXPECT_EQ(source_address_token_a, state1.source_address_token);
378 EXPECT_EQ(server_config_sig_a, state1.server_config_sig);
379 EXPECT_EQ(1U, state1.certs.size());
380 EXPECT_EQ(cert_a, state1.certs[0]);
382 RemoveMockTransaction(&kHostInfoTransaction1);
385 TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReady) {
386 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
387 MockHttpCache cache(factory);
388 TestCompletionCallback callback;
389 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
390 scoped_ptr<QuicServerInfo> quic_server_info(
391 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
392 EXPECT_FALSE(quic_server_info->IsDataReady());
393 quic_server_info->Start();
394 int rv = quic_server_info->WaitForDataReady(callback.callback());
395 EXPECT_EQ(ERR_IO_PENDING, rv);
396 // Now cancel the callback.
397 quic_server_info->CancelWaitForDataReadyCallback();
398 EXPECT_FALSE(quic_server_info->IsDataReady());
399 // Now complete the backend creation and let the callback run.
400 factory->FinishCreation();
401 EXPECT_TRUE(quic_server_info->IsDataReady());
404 TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyButDataIsReady) {
405 MockHttpCache cache;
406 AddMockTransaction(&kHostInfoTransaction1);
407 TestCompletionCallback callback;
409 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
410 scoped_ptr<QuicServerInfo> quic_server_info(
411 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
412 EXPECT_FALSE(quic_server_info->IsDataReady());
413 quic_server_info->Start();
414 int rv = quic_server_info->WaitForDataReady(callback.callback());
415 quic_server_info->CancelWaitForDataReadyCallback();
416 EXPECT_EQ(OK, callback.GetResult(rv));
417 EXPECT_TRUE(quic_server_info->IsDataReady());
418 RemoveMockTransaction(&kHostInfoTransaction1);
421 TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyAfterDeleteCache) {
422 scoped_ptr<QuicServerInfo> quic_server_info;
424 MockHttpCache cache;
425 AddMockTransaction(&kHostInfoTransaction1);
426 TestCompletionCallback callback;
428 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
429 quic_server_info.reset(
430 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
431 EXPECT_FALSE(quic_server_info->IsDataReady());
432 quic_server_info->Start();
433 int rv = quic_server_info->WaitForDataReady(callback.callback());
434 quic_server_info->CancelWaitForDataReadyCallback();
435 EXPECT_EQ(OK, callback.GetResult(rv));
436 EXPECT_TRUE(quic_server_info->IsDataReady());
437 RemoveMockTransaction(&kHostInfoTransaction1);
439 // Cancel the callback after Cache is deleted.
440 quic_server_info->ResetWaitForDataReadyCallback();
443 // Test Start() followed by Persist() without calling WaitForDataReady.
444 TEST(DiskCacheBasedQuicServerInfo, StartAndPersist) {
445 MockHttpCache cache;
446 AddMockTransaction(&kHostInfoTransaction1);
448 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
449 scoped_ptr<QuicServerInfo> quic_server_info(
450 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
451 EXPECT_FALSE(quic_server_info->IsDataReady());
452 quic_server_info->Start();
453 // Wait until Start() does the work.
454 base::MessageLoop::current()->RunUntilIdle();
456 EXPECT_TRUE(quic_server_info->IsDataReady());
458 QuicServerInfo::State* state = quic_server_info->mutable_state();
459 EXPECT_TRUE(state->certs.empty());
460 const string server_config_a = "server_config_a";
461 const string source_address_token_a = "source_address_token_a";
462 const string server_config_sig_a = "server_config_sig_a";
463 const string cert_a = "cert_a";
465 state->server_config = server_config_a;
466 state->source_address_token = source_address_token_a;
467 state->server_config_sig = server_config_sig_a;
468 state->certs.push_back(cert_a);
469 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
470 quic_server_info->Persist();
471 quic_server_info->OnExternalCacheHit();
473 // Once we call Persist, IsReadyToPersist should return false until Persist
474 // has completed.
475 EXPECT_FALSE(quic_server_info->IsReadyToPersist());
477 // Wait until Persist() does the work.
478 base::MessageLoop::current()->RunUntilIdle();
480 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
482 // Verify that the state was updated.
483 quic_server_info.reset(
484 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
485 quic_server_info->Start();
486 TestCompletionCallback callback;
487 int rv = quic_server_info->WaitForDataReady(callback.callback());
488 EXPECT_EQ(OK, callback.GetResult(rv));
489 EXPECT_TRUE(quic_server_info->IsDataReady());
491 const QuicServerInfo::State& state1 = quic_server_info->state();
492 EXPECT_EQ(server_config_a, state1.server_config);
493 EXPECT_EQ(source_address_token_a, state1.source_address_token);
494 EXPECT_EQ(server_config_sig_a, state1.server_config_sig);
495 EXPECT_EQ(1U, state1.certs.size());
496 EXPECT_EQ(cert_a, state1.certs[0]);
498 RemoveMockTransaction(&kHostInfoTransaction1);
501 // Test Persisting data when we are not ready to persist and then verify it
502 // persists the data when Start() finishes.
503 TEST(DiskCacheBasedQuicServerInfo, PersistWhenNotReadyToPersist) {
504 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
505 MockHttpCache cache(factory);
506 AddMockTransaction(&kHostInfoTransaction1);
507 TestCompletionCallback callback;
509 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
510 scoped_ptr<QuicServerInfo> quic_server_info(
511 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
512 EXPECT_FALSE(quic_server_info->IsDataReady());
513 // We do a Start(), but don't call WaitForDataReady(). Because we haven't
514 // created the backend, we will wait and data wouldn't be ready.
515 quic_server_info->Start();
516 EXPECT_FALSE(quic_server_info->IsDataReady());
518 // Persist data once, even though the backend is not ready.
519 QuicServerInfo::State* state = quic_server_info->mutable_state();
520 EXPECT_TRUE(state->certs.empty());
521 const string server_config_init = "server_config_init";
522 const string source_address_token_init = "source_address_token_init";
523 const string server_config_sig_init = "server_config_sig_init";
524 const string cert_init = "cert_init";
526 state->server_config = server_config_init;
527 state->source_address_token = source_address_token_init;
528 state->server_config_sig = server_config_sig_init;
529 state->certs.push_back(cert_init);
530 EXPECT_FALSE(quic_server_info->IsReadyToPersist());
531 quic_server_info->Persist();
532 EXPECT_FALSE(quic_server_info->IsReadyToPersist());
534 // Now complete the backend creation and let the callback run.
535 factory->FinishCreation();
536 EXPECT_TRUE(quic_server_info->IsDataReady());
538 // Wait until Persist() does the work.
539 base::MessageLoop::current()->RunUntilIdle();
541 // Verify that the state was updated.
542 quic_server_info.reset(
543 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
544 quic_server_info->Start();
545 int rv = quic_server_info->WaitForDataReady(callback.callback());
546 EXPECT_EQ(OK, callback.GetResult(rv));
547 EXPECT_TRUE(quic_server_info->IsDataReady());
549 const QuicServerInfo::State& state1 = quic_server_info->state();
550 EXPECT_EQ(server_config_init, state1.server_config);
551 EXPECT_EQ(source_address_token_init, state1.source_address_token);
552 EXPECT_EQ(server_config_sig_init, state1.server_config_sig);
553 EXPECT_EQ(1U, state1.certs.size());
554 EXPECT_EQ(cert_init, state1.certs[0]);
555 RemoveMockTransaction(&kHostInfoTransaction1);
558 // Test multiple calls to Persist without waiting for the data to be written.
559 TEST(DiskCacheBasedQuicServerInfo, MultiplePersistsWithoutWaiting) {
560 MockHttpCache cache;
561 AddMockTransaction(&kHostInfoTransaction1);
562 TestCompletionCallback callback;
564 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
565 scoped_ptr<QuicServerInfo> quic_server_info(
566 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
567 EXPECT_FALSE(quic_server_info->IsDataReady());
568 quic_server_info->Start();
569 int rv = quic_server_info->WaitForDataReady(callback.callback());
570 EXPECT_EQ(OK, callback.GetResult(rv));
571 EXPECT_TRUE(quic_server_info->IsDataReady());
573 // Persist data once.
574 QuicServerInfo::State* state = quic_server_info->mutable_state();
575 EXPECT_TRUE(state->certs.empty());
576 const string server_config_init = "server_config_init";
577 const string source_address_token_init = "source_address_token_init";
578 const string server_config_sig_init = "server_config_sig_init";
579 const string cert_init = "cert_init";
581 state->server_config = server_config_init;
582 state->source_address_token = source_address_token_init;
583 state->server_config_sig = server_config_sig_init;
584 state->certs.push_back(cert_init);
585 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
586 quic_server_info->Persist();
588 // Once we call Persist, IsReadyToPersist should return false until Persist
589 // has completed.
590 EXPECT_FALSE(quic_server_info->IsReadyToPersist());
592 // Persist one more time using the same |quic_server_info| object and without
593 // doing another Start() and WaitForDataReady.
594 const string server_config_a = "server_config_a";
595 const string source_address_token_a = "source_address_token_a";
596 const string server_config_sig_a = "server_config_sig_a";
597 const string cert_a = "cert_a";
599 state->server_config = server_config_a;
600 state->source_address_token = source_address_token_a;
601 state->server_config_sig = server_config_sig_a;
602 state->certs.push_back(cert_a);
603 EXPECT_FALSE(quic_server_info->IsReadyToPersist());
604 quic_server_info->Persist();
606 // Wait until Persist() does the work.
607 base::MessageLoop::current()->RunUntilIdle();
609 EXPECT_TRUE(quic_server_info->IsReadyToPersist());
611 // Verify that the state was updated.
612 quic_server_info.reset(
613 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
614 quic_server_info->Start();
615 rv = quic_server_info->WaitForDataReady(callback.callback());
616 EXPECT_EQ(OK, callback.GetResult(rv));
617 EXPECT_TRUE(quic_server_info->IsDataReady());
619 // Verify the second time persisted data is persisted.
620 const QuicServerInfo::State& state1 = quic_server_info->state();
621 EXPECT_EQ(server_config_a, state1.server_config);
622 EXPECT_EQ(source_address_token_a, state1.source_address_token);
623 EXPECT_EQ(server_config_sig_a, state1.server_config_sig);
624 EXPECT_EQ(1U, state1.certs.size());
625 EXPECT_EQ(cert_a, state1.certs[0]);
627 RemoveMockTransaction(&kHostInfoTransaction1);
630 // crbug.com/439209: test deletion of QuicServerInfo object in the callback
631 // doesn't crash.
632 TEST(DiskCacheBasedQuicServerInfo, DeleteServerInfoInCallback) {
633 // Use the blocking mock backend factory to force asynchronous completion
634 // of quic_server_info->WaitForDataReady(), so that the callback will run.
635 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
636 MockHttpCache cache(factory);
637 QuicServerId server_id("www.verisign.com", 443, true, PRIVACY_MODE_DISABLED);
638 QuicServerInfo* quic_server_info =
639 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache());
640 // |cb| takes owndership and deletes |quic_server_info| when it is called.
641 DeleteCacheCompletionCallback cb(quic_server_info);
642 quic_server_info->Start();
643 int rv = quic_server_info->WaitForDataReady(cb.callback());
644 EXPECT_EQ(ERR_IO_PENDING, rv);
645 // Now complete the backend creation and let the callback run.
646 factory->FinishCreation();
647 EXPECT_EQ(OK, cb.GetResult(rv));
650 } // namespace net