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"
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"
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",
41 const MockTransaction kHostInfoTransaction2
= {
42 "quicserverinfo:http://www.google.com:80",
59 class DeleteCacheCompletionCallback
: public TestCompletionCallbackBase
{
61 explicit DeleteCacheCompletionCallback(QuicServerInfo
* server_info
)
62 : server_info_(server_info
),
63 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
64 base::Unretained(this))) {}
66 const CompletionCallback
& callback() const { return callback_
; }
69 void OnComplete(int result
) {
74 QuicServerInfo
* server_info_
;
75 CompletionCallback callback_
;
77 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
82 // Tests that we can delete a DiskCacheBasedQuicServerInfo object in a
83 // completion callback for DiskCacheBasedQuicServerInfo::WaitForDataReady.
84 TEST(DiskCacheBasedQuicServerInfo
, DeleteInCallback
) {
85 // Use the blocking mock backend factory to force asynchronous completion
86 // of quic_server_info->WaitForDataReady(), so that the callback will run.
87 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
88 MockHttpCache
cache(factory
);
89 QuicServerId
server_id("www.verisign.com", 443, true, PRIVACY_MODE_DISABLED
);
90 scoped_ptr
<QuicServerInfo
> quic_server_info(
91 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
92 quic_server_info
->Start();
93 TestCompletionCallback callback
;
94 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
95 EXPECT_EQ(ERR_IO_PENDING
, rv
);
96 // Now complete the backend creation and let the callback run.
97 factory
->FinishCreation();
98 EXPECT_EQ(OK
, callback
.GetResult(rv
));
101 // Tests the basic logic of storing, retrieving and updating data.
102 TEST(DiskCacheBasedQuicServerInfo
, Update
) {
104 AddMockTransaction(&kHostInfoTransaction1
);
105 TestCompletionCallback callback
;
107 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
108 scoped_ptr
<QuicServerInfo
> quic_server_info(
109 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
110 quic_server_info
->Start();
111 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
112 EXPECT_EQ(OK
, callback
.GetResult(rv
));
114 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
115 EXPECT_TRUE(state
->certs
.empty());
116 const string server_config_a
= "server_config_a";
117 const string source_address_token_a
= "source_address_token_a";
118 const string server_config_sig_a
= "server_config_sig_a";
119 const string cert_a
= "cert_a";
120 const string cert_b
= "cert_b";
122 state
->server_config
= server_config_a
;
123 state
->source_address_token
= source_address_token_a
;
124 state
->server_config_sig
= server_config_sig_a
;
125 state
->certs
.push_back(cert_a
);
126 quic_server_info
->Persist();
128 // Wait until Persist() does the work.
129 base::MessageLoop::current()->RunUntilIdle();
131 // Open the stored QuicServerInfo.
132 quic_server_info
.reset(
133 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
134 quic_server_info
->Start();
135 rv
= quic_server_info
->WaitForDataReady(callback
.callback());
136 EXPECT_EQ(OK
, callback
.GetResult(rv
));
138 // And now update the data.
139 state
= quic_server_info
->mutable_state();
140 state
->certs
.push_back(cert_b
);
142 // Fail instead of DCHECKing double creates.
143 cache
.disk_cache()->set_double_create_check(false);
144 quic_server_info
->Persist();
145 base::MessageLoop::current()->RunUntilIdle();
147 // Verify that the state was updated.
148 quic_server_info
.reset(
149 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
150 quic_server_info
->Start();
151 rv
= quic_server_info
->WaitForDataReady(callback
.callback());
152 EXPECT_EQ(OK
, callback
.GetResult(rv
));
153 EXPECT_TRUE(quic_server_info
->IsDataReady());
155 const QuicServerInfo::State
& state1
= quic_server_info
->state();
156 EXPECT_EQ(server_config_a
, state1
.server_config
);
157 EXPECT_EQ(source_address_token_a
, state1
.source_address_token
);
158 EXPECT_EQ(server_config_sig_a
, state1
.server_config_sig
);
159 EXPECT_EQ(2U, state1
.certs
.size());
160 EXPECT_EQ(cert_a
, state1
.certs
[0]);
161 EXPECT_EQ(cert_b
, state1
.certs
[1]);
163 RemoveMockTransaction(&kHostInfoTransaction1
);
166 // Test that demonstrates different info is returned when the ports differ.
167 TEST(DiskCacheBasedQuicServerInfo
, UpdateDifferentPorts
) {
169 AddMockTransaction(&kHostInfoTransaction1
);
170 AddMockTransaction(&kHostInfoTransaction2
);
171 TestCompletionCallback callback
;
173 // Persist data for port 443.
174 QuicServerId
server_id1("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
175 scoped_ptr
<QuicServerInfo
> quic_server_info1(
176 new DiskCacheBasedQuicServerInfo(server_id1
, cache
.http_cache()));
177 quic_server_info1
->Start();
178 int rv
= quic_server_info1
->WaitForDataReady(callback
.callback());
179 EXPECT_EQ(OK
, callback
.GetResult(rv
));
181 QuicServerInfo::State
* state1
= quic_server_info1
->mutable_state();
182 EXPECT_TRUE(state1
->certs
.empty());
183 const string server_config_a
= "server_config_a";
184 const string source_address_token_a
= "source_address_token_a";
185 const string server_config_sig_a
= "server_config_sig_a";
186 const string cert_a
= "cert_a";
188 state1
->server_config
= server_config_a
;
189 state1
->source_address_token
= source_address_token_a
;
190 state1
->server_config_sig
= server_config_sig_a
;
191 state1
->certs
.push_back(cert_a
);
192 quic_server_info1
->Persist();
194 // Wait until Persist() does the work.
195 base::MessageLoop::current()->RunUntilIdle();
197 // Persist data for port 80.
198 QuicServerId
server_id2("www.google.com", 80, false, PRIVACY_MODE_DISABLED
);
199 scoped_ptr
<QuicServerInfo
> quic_server_info2(
200 new DiskCacheBasedQuicServerInfo(server_id2
, cache
.http_cache()));
201 quic_server_info2
->Start();
202 rv
= quic_server_info2
->WaitForDataReady(callback
.callback());
203 EXPECT_EQ(OK
, callback
.GetResult(rv
));
205 QuicServerInfo::State
* state2
= quic_server_info2
->mutable_state();
206 EXPECT_TRUE(state2
->certs
.empty());
207 const string server_config_b
= "server_config_b";
208 const string source_address_token_b
= "source_address_token_b";
209 const string server_config_sig_b
= "server_config_sig_b";
210 const string cert_b
= "cert_b";
212 state2
->server_config
= server_config_b
;
213 state2
->source_address_token
= source_address_token_b
;
214 state2
->server_config_sig
= server_config_sig_b
;
215 state2
->certs
.push_back(cert_b
);
216 quic_server_info2
->Persist();
218 // Wait until Persist() does the work.
219 base::MessageLoop::current()->RunUntilIdle();
221 // Verify the stored QuicServerInfo for port 443.
222 scoped_ptr
<QuicServerInfo
> quic_server_info(
223 new DiskCacheBasedQuicServerInfo(server_id1
, cache
.http_cache()));
224 quic_server_info
->Start();
225 rv
= quic_server_info
->WaitForDataReady(callback
.callback());
226 EXPECT_EQ(OK
, callback
.GetResult(rv
));
227 EXPECT_TRUE(quic_server_info
->IsDataReady());
229 const QuicServerInfo::State
& state_a
= quic_server_info
->state();
230 EXPECT_EQ(server_config_a
, state_a
.server_config
);
231 EXPECT_EQ(source_address_token_a
, state_a
.source_address_token
);
232 EXPECT_EQ(server_config_sig_a
, state_a
.server_config_sig
);
233 EXPECT_EQ(1U, state_a
.certs
.size());
234 EXPECT_EQ(cert_a
, state_a
.certs
[0]);
236 // Verify the stored QuicServerInfo for port 80.
237 quic_server_info
.reset(
238 new DiskCacheBasedQuicServerInfo(server_id2
, cache
.http_cache()));
239 quic_server_info
->Start();
240 rv
= quic_server_info
->WaitForDataReady(callback
.callback());
241 EXPECT_EQ(OK
, callback
.GetResult(rv
));
242 EXPECT_TRUE(quic_server_info
->IsDataReady());
244 const QuicServerInfo::State
& state_b
= quic_server_info
->state();
245 EXPECT_EQ(server_config_b
, state_b
.server_config
);
246 EXPECT_EQ(source_address_token_b
, state_b
.source_address_token
);
247 EXPECT_EQ(server_config_sig_b
, state_b
.server_config_sig
);
248 EXPECT_EQ(1U, state_b
.certs
.size());
249 EXPECT_EQ(cert_b
, state_b
.certs
[0]);
251 RemoveMockTransaction(&kHostInfoTransaction2
);
252 RemoveMockTransaction(&kHostInfoTransaction1
);
255 // Test IsReadyToPersist when there is a pending write.
256 TEST(DiskCacheBasedQuicServerInfo
, IsReadyToPersist
) {
258 AddMockTransaction(&kHostInfoTransaction1
);
259 TestCompletionCallback callback
;
261 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
262 scoped_ptr
<QuicServerInfo
> quic_server_info(
263 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
264 EXPECT_FALSE(quic_server_info
->IsDataReady());
265 quic_server_info
->Start();
266 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
267 EXPECT_EQ(OK
, callback
.GetResult(rv
));
268 EXPECT_TRUE(quic_server_info
->IsDataReady());
270 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
271 EXPECT_TRUE(state
->certs
.empty());
272 const string server_config_a
= "server_config_a";
273 const string source_address_token_a
= "source_address_token_a";
274 const string server_config_sig_a
= "server_config_sig_a";
275 const string cert_a
= "cert_a";
277 state
->server_config
= server_config_a
;
278 state
->source_address_token
= source_address_token_a
;
279 state
->server_config_sig
= server_config_sig_a
;
280 state
->certs
.push_back(cert_a
);
281 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
282 quic_server_info
->Persist();
284 // Once we call Persist, IsReadyToPersist should return false until Persist
286 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
288 // Wait until Persist() does the work.
289 base::MessageLoop::current()->RunUntilIdle();
291 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
293 // Verify that the state was updated.
294 quic_server_info
.reset(
295 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
296 quic_server_info
->Start();
297 rv
= quic_server_info
->WaitForDataReady(callback
.callback());
298 EXPECT_EQ(OK
, callback
.GetResult(rv
));
299 EXPECT_TRUE(quic_server_info
->IsDataReady());
301 const QuicServerInfo::State
& state1
= quic_server_info
->state();
302 EXPECT_EQ(server_config_a
, state1
.server_config
);
303 EXPECT_EQ(source_address_token_a
, state1
.source_address_token
);
304 EXPECT_EQ(server_config_sig_a
, state1
.server_config_sig
);
305 EXPECT_EQ(1U, state1
.certs
.size());
306 EXPECT_EQ(cert_a
, state1
.certs
[0]);
308 RemoveMockTransaction(&kHostInfoTransaction1
);
311 // Test multiple calls to Persist.
312 TEST(DiskCacheBasedQuicServerInfo
, MultiplePersist
) {
314 AddMockTransaction(&kHostInfoTransaction1
);
315 TestCompletionCallback callback
;
317 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
318 scoped_ptr
<QuicServerInfo
> quic_server_info(
319 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
320 EXPECT_FALSE(quic_server_info
->IsDataReady());
321 quic_server_info
->Start();
322 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
323 EXPECT_EQ(OK
, callback
.GetResult(rv
));
324 EXPECT_TRUE(quic_server_info
->IsDataReady());
326 // Persist data once.
327 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
328 EXPECT_TRUE(state
->certs
.empty());
329 const string server_config_init
= "server_config_init";
330 const string source_address_token_init
= "source_address_token_init";
331 const string server_config_sig_init
= "server_config_sig_init";
332 const string cert_init
= "cert_init";
334 state
->server_config
= server_config_init
;
335 state
->source_address_token
= source_address_token_init
;
336 state
->server_config_sig
= server_config_sig_init
;
337 state
->certs
.push_back(cert_init
);
338 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
339 quic_server_info
->Persist();
341 // Once we call Persist, IsReadyToPersist should return false until Persist
343 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
345 // Wait until Persist() does the work.
346 base::MessageLoop::current()->RunUntilIdle();
348 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
350 // Persist one more time using the same |quic_server_info| object and without
351 // doing another Start() and WaitForDataReady.
352 const string server_config_a
= "server_config_a";
353 const string source_address_token_a
= "source_address_token_a";
354 const string server_config_sig_a
= "server_config_sig_a";
355 const string cert_a
= "cert_a";
357 state
->server_config
= server_config_a
;
358 state
->source_address_token
= source_address_token_a
;
359 state
->server_config_sig
= server_config_sig_a
;
360 state
->certs
.push_back(cert_a
);
361 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
362 quic_server_info
->Persist();
364 // Once we call Persist, IsReadyToPersist should return false until Persist
366 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
368 // Wait until Persist() does the work.
369 base::MessageLoop::current()->RunUntilIdle();
371 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
373 // Verify that the state was updated.
374 quic_server_info
.reset(
375 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
376 quic_server_info
->Start();
377 rv
= quic_server_info
->WaitForDataReady(callback
.callback());
378 EXPECT_EQ(OK
, callback
.GetResult(rv
));
379 EXPECT_TRUE(quic_server_info
->IsDataReady());
381 const QuicServerInfo::State
& state1
= quic_server_info
->state();
382 EXPECT_EQ(server_config_a
, state1
.server_config
);
383 EXPECT_EQ(source_address_token_a
, state1
.source_address_token
);
384 EXPECT_EQ(server_config_sig_a
, state1
.server_config_sig
);
385 EXPECT_EQ(1U, state1
.certs
.size());
386 EXPECT_EQ(cert_a
, state1
.certs
[0]);
388 RemoveMockTransaction(&kHostInfoTransaction1
);
391 TEST(DiskCacheBasedQuicServerInfo
, CancelWaitForDataReady
) {
392 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
393 MockHttpCache
cache(factory
);
394 TestCompletionCallback callback
;
395 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
396 scoped_ptr
<QuicServerInfo
> quic_server_info(
397 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
398 EXPECT_FALSE(quic_server_info
->IsDataReady());
399 quic_server_info
->Start();
400 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
401 EXPECT_EQ(ERR_IO_PENDING
, rv
);
402 // Now cancel the callback.
403 quic_server_info
->CancelWaitForDataReadyCallback();
404 EXPECT_FALSE(quic_server_info
->IsDataReady());
405 // Now complete the backend creation and let the callback run.
406 factory
->FinishCreation();
407 EXPECT_TRUE(quic_server_info
->IsDataReady());
410 TEST(DiskCacheBasedQuicServerInfo
, CancelWaitForDataReadyButDataIsReady
) {
412 AddMockTransaction(&kHostInfoTransaction1
);
413 TestCompletionCallback callback
;
415 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
416 scoped_ptr
<QuicServerInfo
> quic_server_info(
417 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
418 EXPECT_FALSE(quic_server_info
->IsDataReady());
419 quic_server_info
->Start();
420 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
421 quic_server_info
->CancelWaitForDataReadyCallback();
422 EXPECT_EQ(OK
, callback
.GetResult(rv
));
423 EXPECT_TRUE(quic_server_info
->IsDataReady());
424 RemoveMockTransaction(&kHostInfoTransaction1
);
427 TEST(DiskCacheBasedQuicServerInfo
, CancelWaitForDataReadyAfterDeleteCache
) {
428 scoped_ptr
<QuicServerInfo
> quic_server_info
;
431 AddMockTransaction(&kHostInfoTransaction1
);
432 TestCompletionCallback callback
;
434 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
435 quic_server_info
.reset(
436 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
437 EXPECT_FALSE(quic_server_info
->IsDataReady());
438 quic_server_info
->Start();
439 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
440 quic_server_info
->CancelWaitForDataReadyCallback();
441 EXPECT_EQ(OK
, callback
.GetResult(rv
));
442 EXPECT_TRUE(quic_server_info
->IsDataReady());
443 RemoveMockTransaction(&kHostInfoTransaction1
);
445 // Cancel the callback after Cache is deleted.
446 quic_server_info
->ResetWaitForDataReadyCallback();
449 // Test Start() followed by Persist() without calling WaitForDataReady.
450 TEST(DiskCacheBasedQuicServerInfo
, StartAndPersist
) {
452 AddMockTransaction(&kHostInfoTransaction1
);
454 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
455 scoped_ptr
<QuicServerInfo
> quic_server_info(
456 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
457 EXPECT_FALSE(quic_server_info
->IsDataReady());
458 quic_server_info
->Start();
459 // Wait until Start() does the work.
460 base::MessageLoop::current()->RunUntilIdle();
462 EXPECT_TRUE(quic_server_info
->IsDataReady());
464 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
465 EXPECT_TRUE(state
->certs
.empty());
466 const string server_config_a
= "server_config_a";
467 const string source_address_token_a
= "source_address_token_a";
468 const string server_config_sig_a
= "server_config_sig_a";
469 const string cert_a
= "cert_a";
471 state
->server_config
= server_config_a
;
472 state
->source_address_token
= source_address_token_a
;
473 state
->server_config_sig
= server_config_sig_a
;
474 state
->certs
.push_back(cert_a
);
475 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
476 quic_server_info
->Persist();
477 quic_server_info
->OnExternalCacheHit();
479 // Once we call Persist, IsReadyToPersist should return false until Persist
481 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
483 // Wait until Persist() does the work.
484 base::MessageLoop::current()->RunUntilIdle();
486 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
488 // Verify that the state was updated.
489 quic_server_info
.reset(
490 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
491 quic_server_info
->Start();
492 TestCompletionCallback callback
;
493 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
494 EXPECT_EQ(OK
, callback
.GetResult(rv
));
495 EXPECT_TRUE(quic_server_info
->IsDataReady());
497 const QuicServerInfo::State
& state1
= quic_server_info
->state();
498 EXPECT_EQ(server_config_a
, state1
.server_config
);
499 EXPECT_EQ(source_address_token_a
, state1
.source_address_token
);
500 EXPECT_EQ(server_config_sig_a
, state1
.server_config_sig
);
501 EXPECT_EQ(1U, state1
.certs
.size());
502 EXPECT_EQ(cert_a
, state1
.certs
[0]);
504 RemoveMockTransaction(&kHostInfoTransaction1
);
507 // Test Persisting data when we are not ready to persist and then verify it
508 // persists the data when Start() finishes.
509 TEST(DiskCacheBasedQuicServerInfo
, PersistWhenNotReadyToPersist
) {
510 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
511 MockHttpCache
cache(factory
);
512 AddMockTransaction(&kHostInfoTransaction1
);
513 TestCompletionCallback callback
;
515 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
516 scoped_ptr
<QuicServerInfo
> quic_server_info(
517 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
518 EXPECT_FALSE(quic_server_info
->IsDataReady());
519 // We do a Start(), but don't call WaitForDataReady(). Because we haven't
520 // created the backend, we will wait and data wouldn't be ready.
521 quic_server_info
->Start();
522 EXPECT_FALSE(quic_server_info
->IsDataReady());
524 // Persist data once, even though the backend is not ready.
525 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
526 EXPECT_TRUE(state
->certs
.empty());
527 const string server_config_init
= "server_config_init";
528 const string source_address_token_init
= "source_address_token_init";
529 const string server_config_sig_init
= "server_config_sig_init";
530 const string cert_init
= "cert_init";
532 state
->server_config
= server_config_init
;
533 state
->source_address_token
= source_address_token_init
;
534 state
->server_config_sig
= server_config_sig_init
;
535 state
->certs
.push_back(cert_init
);
536 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
537 quic_server_info
->Persist();
538 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
540 // Now complete the backend creation and let the callback run.
541 factory
->FinishCreation();
542 EXPECT_TRUE(quic_server_info
->IsDataReady());
544 // Wait until Persist() does the work.
545 base::MessageLoop::current()->RunUntilIdle();
547 // Verify that the state was updated.
548 quic_server_info
.reset(
549 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
550 quic_server_info
->Start();
551 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
552 EXPECT_EQ(OK
, callback
.GetResult(rv
));
553 EXPECT_TRUE(quic_server_info
->IsDataReady());
555 const QuicServerInfo::State
& state1
= quic_server_info
->state();
556 EXPECT_EQ(server_config_init
, state1
.server_config
);
557 EXPECT_EQ(source_address_token_init
, state1
.source_address_token
);
558 EXPECT_EQ(server_config_sig_init
, state1
.server_config_sig
);
559 EXPECT_EQ(1U, state1
.certs
.size());
560 EXPECT_EQ(cert_init
, state1
.certs
[0]);
561 RemoveMockTransaction(&kHostInfoTransaction1
);
564 // Test multiple calls to Persist without waiting for the data to be written.
565 TEST(DiskCacheBasedQuicServerInfo
, MultiplePersistsWithoutWaiting
) {
567 AddMockTransaction(&kHostInfoTransaction1
);
568 TestCompletionCallback callback
;
570 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
571 scoped_ptr
<QuicServerInfo
> quic_server_info(
572 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
573 EXPECT_FALSE(quic_server_info
->IsDataReady());
574 quic_server_info
->Start();
575 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
576 EXPECT_EQ(OK
, callback
.GetResult(rv
));
577 EXPECT_TRUE(quic_server_info
->IsDataReady());
579 // Persist data once.
580 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
581 EXPECT_TRUE(state
->certs
.empty());
582 const string server_config_init
= "server_config_init";
583 const string source_address_token_init
= "source_address_token_init";
584 const string server_config_sig_init
= "server_config_sig_init";
585 const string cert_init
= "cert_init";
587 state
->server_config
= server_config_init
;
588 state
->source_address_token
= source_address_token_init
;
589 state
->server_config_sig
= server_config_sig_init
;
590 state
->certs
.push_back(cert_init
);
591 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
592 quic_server_info
->Persist();
594 // Once we call Persist, IsReadyToPersist should return false until Persist
596 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
598 // Persist one more time using the same |quic_server_info| object and without
599 // doing another Start() and WaitForDataReady.
600 const string server_config_a
= "server_config_a";
601 const string source_address_token_a
= "source_address_token_a";
602 const string server_config_sig_a
= "server_config_sig_a";
603 const string cert_a
= "cert_a";
605 state
->server_config
= server_config_a
;
606 state
->source_address_token
= source_address_token_a
;
607 state
->server_config_sig
= server_config_sig_a
;
608 state
->certs
.push_back(cert_a
);
609 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
610 quic_server_info
->Persist();
612 // Wait until Persist() does the work.
613 base::MessageLoop::current()->RunUntilIdle();
615 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
617 // Verify that the state was updated.
618 quic_server_info
.reset(
619 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
620 quic_server_info
->Start();
621 rv
= quic_server_info
->WaitForDataReady(callback
.callback());
622 EXPECT_EQ(OK
, callback
.GetResult(rv
));
623 EXPECT_TRUE(quic_server_info
->IsDataReady());
625 // Verify the second time persisted data is persisted.
626 const QuicServerInfo::State
& state1
= quic_server_info
->state();
627 EXPECT_EQ(server_config_a
, state1
.server_config
);
628 EXPECT_EQ(source_address_token_a
, state1
.source_address_token
);
629 EXPECT_EQ(server_config_sig_a
, state1
.server_config_sig
);
630 EXPECT_EQ(1U, state1
.certs
.size());
631 EXPECT_EQ(cert_a
, state1
.certs
[0]);
633 RemoveMockTransaction(&kHostInfoTransaction1
);
636 // crbug.com/439209: test deletion of QuicServerInfo object in the callback
638 TEST(DiskCacheBasedQuicServerInfo
, DeleteServerInfoInCallback
) {
639 // Use the blocking mock backend factory to force asynchronous completion
640 // of quic_server_info->WaitForDataReady(), so that the callback will run.
641 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
642 MockHttpCache
cache(factory
);
643 QuicServerId
server_id("www.verisign.com", 443, true, PRIVACY_MODE_DISABLED
);
644 QuicServerInfo
* quic_server_info
=
645 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache());
646 // |cb| takes owndership and deletes |quic_server_info| when it is called.
647 DeleteCacheCompletionCallback
cb(quic_server_info
);
648 quic_server_info
->Start();
649 int rv
= quic_server_info
->WaitForDataReady(cb
.callback());
650 EXPECT_EQ(ERR_IO_PENDING
, rv
);
651 // Now complete the backend creation and let the callback run.
652 factory
->FinishCreation();
653 EXPECT_EQ(OK
, cb
.GetResult(rv
));