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",
38 const MockTransaction kHostInfoTransaction2
= {
39 "quicserverinfo:http://www.google.com:80",
53 class DeleteCacheCompletionCallback
: public TestCompletionCallbackBase
{
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_
; }
63 void OnComplete(int result
) {
68 QuicServerInfo
* server_info_
;
69 CompletionCallback callback_
;
71 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
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
) {
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
) {
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
) {
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
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
) {
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
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
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
) {
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
;
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
) {
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
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
) {
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
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
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
));