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 net::TestCompletionCallbackBase
{
55 explicit DeleteCacheCompletionCallback(QuicServerInfo
* server_info
)
56 : server_info_(server_info
),
57 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
58 base::Unretained(this))) {}
60 const net::CompletionCallback
& callback() const { return callback_
; }
63 void OnComplete(int result
) {
68 QuicServerInfo
* server_info_
;
69 net::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 Start() followed by Persist() without calling WaitForDataReady.
422 TEST(DiskCacheBasedQuicServerInfo
, StartAndPersist
) {
424 AddMockTransaction(&kHostInfoTransaction1
);
426 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
427 scoped_ptr
<QuicServerInfo
> quic_server_info(
428 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
429 EXPECT_FALSE(quic_server_info
->IsDataReady());
430 quic_server_info
->Start();
431 // Wait until Start() does the work.
432 base::MessageLoop::current()->RunUntilIdle();
434 EXPECT_TRUE(quic_server_info
->IsDataReady());
436 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
437 EXPECT_TRUE(state
->certs
.empty());
438 const string server_config_a
= "server_config_a";
439 const string source_address_token_a
= "source_address_token_a";
440 const string server_config_sig_a
= "server_config_sig_a";
441 const string cert_a
= "cert_a";
443 state
->server_config
= server_config_a
;
444 state
->source_address_token
= source_address_token_a
;
445 state
->server_config_sig
= server_config_sig_a
;
446 state
->certs
.push_back(cert_a
);
447 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
448 quic_server_info
->Persist();
449 quic_server_info
->OnExternalCacheHit();
451 // Once we call Persist, IsReadyToPersist should return false until Persist
453 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
455 // Wait until Persist() does the work.
456 base::MessageLoop::current()->RunUntilIdle();
458 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
460 // Verify that the state was updated.
461 quic_server_info
.reset(
462 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
463 quic_server_info
->Start();
464 TestCompletionCallback callback
;
465 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
466 EXPECT_EQ(OK
, callback
.GetResult(rv
));
467 EXPECT_TRUE(quic_server_info
->IsDataReady());
469 const QuicServerInfo::State
& state1
= quic_server_info
->state();
470 EXPECT_EQ(server_config_a
, state1
.server_config
);
471 EXPECT_EQ(source_address_token_a
, state1
.source_address_token
);
472 EXPECT_EQ(server_config_sig_a
, state1
.server_config_sig
);
473 EXPECT_EQ(1U, state1
.certs
.size());
474 EXPECT_EQ(cert_a
, state1
.certs
[0]);
476 RemoveMockTransaction(&kHostInfoTransaction1
);
479 // Test Persisting data when we are not ready to persist and then verify it
480 // persists the data when Start() finishes.
481 TEST(DiskCacheBasedQuicServerInfo
, PersistWhenNotReadyToPersist
) {
482 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
483 MockHttpCache
cache(factory
);
484 AddMockTransaction(&kHostInfoTransaction1
);
485 TestCompletionCallback callback
;
487 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
488 scoped_ptr
<QuicServerInfo
> quic_server_info(
489 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
490 EXPECT_FALSE(quic_server_info
->IsDataReady());
491 // We do a Start(), but don't call WaitForDataReady(). Because we haven't
492 // created the backend, we will wait and data wouldn't be ready.
493 quic_server_info
->Start();
494 EXPECT_FALSE(quic_server_info
->IsDataReady());
496 // Persist data once, even though the backend is not ready.
497 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
498 EXPECT_TRUE(state
->certs
.empty());
499 const string server_config_init
= "server_config_init";
500 const string source_address_token_init
= "source_address_token_init";
501 const string server_config_sig_init
= "server_config_sig_init";
502 const string cert_init
= "cert_init";
504 state
->server_config
= server_config_init
;
505 state
->source_address_token
= source_address_token_init
;
506 state
->server_config_sig
= server_config_sig_init
;
507 state
->certs
.push_back(cert_init
);
508 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
509 quic_server_info
->Persist();
510 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
512 // Now complete the backend creation and let the callback run.
513 factory
->FinishCreation();
514 EXPECT_TRUE(quic_server_info
->IsDataReady());
516 // Wait until Persist() does the work.
517 base::MessageLoop::current()->RunUntilIdle();
519 // Verify that the state was updated.
520 quic_server_info
.reset(
521 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
522 quic_server_info
->Start();
523 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
524 EXPECT_EQ(OK
, callback
.GetResult(rv
));
525 EXPECT_TRUE(quic_server_info
->IsDataReady());
527 const QuicServerInfo::State
& state1
= quic_server_info
->state();
528 EXPECT_EQ(server_config_init
, state1
.server_config
);
529 EXPECT_EQ(source_address_token_init
, state1
.source_address_token
);
530 EXPECT_EQ(server_config_sig_init
, state1
.server_config_sig
);
531 EXPECT_EQ(1U, state1
.certs
.size());
532 EXPECT_EQ(cert_init
, state1
.certs
[0]);
533 RemoveMockTransaction(&kHostInfoTransaction1
);
536 // Test multiple calls to Persist without waiting for the data to be written.
537 TEST(DiskCacheBasedQuicServerInfo
, MultiplePersistsWithoutWaiting
) {
539 AddMockTransaction(&kHostInfoTransaction1
);
540 TestCompletionCallback callback
;
542 QuicServerId
server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED
);
543 scoped_ptr
<QuicServerInfo
> quic_server_info(
544 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
545 EXPECT_FALSE(quic_server_info
->IsDataReady());
546 quic_server_info
->Start();
547 int rv
= quic_server_info
->WaitForDataReady(callback
.callback());
548 EXPECT_EQ(OK
, callback
.GetResult(rv
));
549 EXPECT_TRUE(quic_server_info
->IsDataReady());
551 // Persist data once.
552 QuicServerInfo::State
* state
= quic_server_info
->mutable_state();
553 EXPECT_TRUE(state
->certs
.empty());
554 const string server_config_init
= "server_config_init";
555 const string source_address_token_init
= "source_address_token_init";
556 const string server_config_sig_init
= "server_config_sig_init";
557 const string cert_init
= "cert_init";
559 state
->server_config
= server_config_init
;
560 state
->source_address_token
= source_address_token_init
;
561 state
->server_config_sig
= server_config_sig_init
;
562 state
->certs
.push_back(cert_init
);
563 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
564 quic_server_info
->Persist();
566 // Once we call Persist, IsReadyToPersist should return false until Persist
568 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
570 // Persist one more time using the same |quic_server_info| object and without
571 // doing another Start() and WaitForDataReady.
572 const string server_config_a
= "server_config_a";
573 const string source_address_token_a
= "source_address_token_a";
574 const string server_config_sig_a
= "server_config_sig_a";
575 const string cert_a
= "cert_a";
577 state
->server_config
= server_config_a
;
578 state
->source_address_token
= source_address_token_a
;
579 state
->server_config_sig
= server_config_sig_a
;
580 state
->certs
.push_back(cert_a
);
581 EXPECT_FALSE(quic_server_info
->IsReadyToPersist());
582 quic_server_info
->Persist();
584 // Wait until Persist() does the work.
585 base::MessageLoop::current()->RunUntilIdle();
587 EXPECT_TRUE(quic_server_info
->IsReadyToPersist());
589 // Verify that the state was updated.
590 quic_server_info
.reset(
591 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache()));
592 quic_server_info
->Start();
593 rv
= quic_server_info
->WaitForDataReady(callback
.callback());
594 EXPECT_EQ(OK
, callback
.GetResult(rv
));
595 EXPECT_TRUE(quic_server_info
->IsDataReady());
597 // Verify the second time persisted data is persisted.
598 const QuicServerInfo::State
& state1
= quic_server_info
->state();
599 EXPECT_EQ(server_config_a
, state1
.server_config
);
600 EXPECT_EQ(source_address_token_a
, state1
.source_address_token
);
601 EXPECT_EQ(server_config_sig_a
, state1
.server_config_sig
);
602 EXPECT_EQ(1U, state1
.certs
.size());
603 EXPECT_EQ(cert_a
, state1
.certs
[0]);
605 RemoveMockTransaction(&kHostInfoTransaction1
);
608 // crbug.com/439209: test deletion of QuicServerInfo object in the callback
610 TEST(DiskCacheBasedQuicServerInfo
, DeleteServerInfoInCallback
) {
611 // Use the blocking mock backend factory to force asynchronous completion
612 // of quic_server_info->WaitForDataReady(), so that the callback will run.
613 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
614 MockHttpCache
cache(factory
);
615 QuicServerId
server_id("www.verisign.com", 443, true, PRIVACY_MODE_DISABLED
);
616 QuicServerInfo
* quic_server_info
=
617 new DiskCacheBasedQuicServerInfo(server_id
, cache
.http_cache());
618 // |cb| takes owndership and deletes |quic_server_info| when it is called.
619 DeleteCacheCompletionCallback
cb(quic_server_info
);
620 quic_server_info
->Start();
621 int rv
= quic_server_info
->WaitForDataReady(cb
.callback());
622 EXPECT_EQ(ERR_IO_PENDING
, rv
);
623 // Now complete the backend creation and let the callback run.
624 factory
->FinishCreation();
625 EXPECT_EQ(OK
, cb
.GetResult(rv
));