OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/http/disk_cache_based_quic_server_info.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/compiler_specific.h" | |
10 #include "base/macros.h" | |
11 #include "base/memory/ptr_util.h" | |
12 #include "base/run_loop.h" | |
13 #include "net/base/net_errors.h" | |
14 #include "net/http/mock_http_cache.h" | |
15 #include "net/quic/chromium/quic_server_info.h" | |
16 #include "net/quic/core/quic_server_id.h" | |
17 #include "net/test/gtest_util.h" | |
18 #include "testing/gmock/include/gmock/gmock.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 using net::test::IsError; | |
22 using net::test::IsOk; | |
23 | |
24 using std::string; | |
25 | |
26 namespace net { | |
27 namespace { | |
28 | |
29 // This is an empty transaction, needed to register the URL and the test mode. | |
30 const MockTransaction kHostInfoTransaction1 = { | |
31 "quicserverinfo:https://www.google.com:443", | |
32 "", | |
33 base::Time(), | |
34 "", | |
35 LOAD_NORMAL, | |
36 "", | |
37 "", | |
38 base::Time(), | |
39 "", | |
40 TEST_MODE_NORMAL, | |
41 nullptr, | |
42 nullptr, | |
43 nullptr, | |
44 0, | |
45 0, | |
46 OK, | |
47 }; | |
48 | |
49 const MockTransaction kHostInfoTransaction2 = { | |
50 "quicserverinfo:https://www.google.com:80", | |
51 "", | |
52 base::Time(), | |
53 "", | |
54 LOAD_NORMAL, | |
55 "", | |
56 "", | |
57 base::Time(), | |
58 "", | |
59 TEST_MODE_NORMAL, | |
60 nullptr, | |
61 nullptr, | |
62 nullptr, | |
63 0, | |
64 0, | |
65 OK, | |
66 }; | |
67 | |
68 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { | |
69 public: | |
70 explicit DeleteCacheCompletionCallback(QuicServerInfo* server_info) | |
71 : server_info_(server_info), | |
72 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete, | |
73 base::Unretained(this))) {} | |
74 | |
75 const CompletionCallback& callback() const { return callback_; } | |
76 | |
77 private: | |
78 void OnComplete(int result) { | |
79 delete server_info_; | |
80 SetResult(result); | |
81 } | |
82 | |
83 QuicServerInfo* server_info_; | |
84 CompletionCallback callback_; | |
85 | |
86 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback); | |
87 }; | |
88 | |
89 } // namespace | |
90 | |
91 // Tests that we can delete a DiskCacheBasedQuicServerInfo object in a | |
92 // completion callback for DiskCacheBasedQuicServerInfo::WaitForDataReady. | |
93 TEST(DiskCacheBasedQuicServerInfo, DeleteInCallback) { | |
94 // Use the blocking mock backend factory to force asynchronous completion | |
95 // of quic_server_info->WaitForDataReady(), so that the callback will run. | |
96 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); | |
97 MockHttpCache cache(base::WrapUnique(factory), true); | |
98 QuicServerId server_id("www.verisign.com", 443, PRIVACY_MODE_DISABLED); | |
99 std::unique_ptr<QuicServerInfo> quic_server_info( | |
100 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
101 quic_server_info->Start(); | |
102 TestCompletionCallback callback; | |
103 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
104 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
105 // Now complete the backend creation and let the callback run. | |
106 factory->FinishCreation(); | |
107 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
108 } | |
109 | |
110 // Tests the basic logic of storing, retrieving and updating data. | |
111 TEST(DiskCacheBasedQuicServerInfo, Update) { | |
112 MockHttpCache cache(true); | |
113 AddMockTransaction(&kHostInfoTransaction1); | |
114 TestCompletionCallback callback; | |
115 | |
116 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
117 std::unique_ptr<QuicServerInfo> quic_server_info( | |
118 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
119 quic_server_info->Start(); | |
120 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
121 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
122 | |
123 QuicServerInfo::State* state = quic_server_info->mutable_state(); | |
124 EXPECT_TRUE(state->certs.empty()); | |
125 const string server_config_a = "server_config_a"; | |
126 const string source_address_token_a = "source_address_token_a"; | |
127 const string cert_sct_a = "cert_sct_a"; | |
128 const string chlo_hash_a = "chlo_hash_a"; | |
129 const string server_config_sig_a = "server_config_sig_a"; | |
130 const string cert_a = "cert_a"; | |
131 const string cert_b = "cert_b"; | |
132 | |
133 state->server_config = server_config_a; | |
134 state->source_address_token = source_address_token_a; | |
135 state->cert_sct = cert_sct_a; | |
136 state->chlo_hash = chlo_hash_a; | |
137 state->server_config_sig = server_config_sig_a; | |
138 state->certs.push_back(cert_a); | |
139 quic_server_info->Persist(); | |
140 | |
141 // Wait until Persist() does the work. | |
142 base::RunLoop().RunUntilIdle(); | |
143 | |
144 // Open the stored QuicServerInfo. | |
145 quic_server_info.reset( | |
146 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
147 quic_server_info->Start(); | |
148 rv = quic_server_info->WaitForDataReady(callback.callback()); | |
149 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
150 | |
151 // And now update the data. | |
152 state = quic_server_info->mutable_state(); | |
153 state->certs.push_back(cert_b); | |
154 | |
155 // Fail instead of DCHECKing double creates. | |
156 cache.disk_cache()->set_double_create_check(false); | |
157 quic_server_info->Persist(); | |
158 base::RunLoop().RunUntilIdle(); | |
159 | |
160 // Verify that the state was updated. | |
161 quic_server_info.reset( | |
162 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
163 quic_server_info->Start(); | |
164 rv = quic_server_info->WaitForDataReady(callback.callback()); | |
165 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
166 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
167 | |
168 const QuicServerInfo::State& state1 = quic_server_info->state(); | |
169 EXPECT_EQ(server_config_a, state1.server_config); | |
170 EXPECT_EQ(source_address_token_a, state1.source_address_token); | |
171 EXPECT_EQ(cert_sct_a, state1.cert_sct); | |
172 EXPECT_EQ(chlo_hash_a, state1.chlo_hash); | |
173 EXPECT_EQ(server_config_sig_a, state1.server_config_sig); | |
174 EXPECT_EQ(2U, state1.certs.size()); | |
175 EXPECT_EQ(cert_a, state1.certs[0]); | |
176 EXPECT_EQ(cert_b, state1.certs[1]); | |
177 | |
178 RemoveMockTransaction(&kHostInfoTransaction1); | |
179 } | |
180 | |
181 // Test that demonstrates different info is returned when the ports differ. | |
182 TEST(DiskCacheBasedQuicServerInfo, UpdateDifferentPorts) { | |
183 MockHttpCache cache(true); | |
184 AddMockTransaction(&kHostInfoTransaction1); | |
185 AddMockTransaction(&kHostInfoTransaction2); | |
186 TestCompletionCallback callback; | |
187 | |
188 // Persist data for port 443. | |
189 QuicServerId server_id1("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
190 std::unique_ptr<QuicServerInfo> quic_server_info1( | |
191 new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache())); | |
192 quic_server_info1->Start(); | |
193 int rv = quic_server_info1->WaitForDataReady(callback.callback()); | |
194 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
195 | |
196 QuicServerInfo::State* state1 = quic_server_info1->mutable_state(); | |
197 EXPECT_TRUE(state1->certs.empty()); | |
198 const string server_config_a = "server_config_a"; | |
199 const string source_address_token_a = "source_address_token_a"; | |
200 const string cert_sct_a = "cert_sct_a"; | |
201 const string chlo_hash_a = "chlo_hash_a"; | |
202 const string server_config_sig_a = "server_config_sig_a"; | |
203 const string cert_a = "cert_a"; | |
204 | |
205 state1->server_config = server_config_a; | |
206 state1->source_address_token = source_address_token_a; | |
207 state1->cert_sct = cert_sct_a; | |
208 state1->chlo_hash = chlo_hash_a; | |
209 state1->server_config_sig = server_config_sig_a; | |
210 state1->certs.push_back(cert_a); | |
211 quic_server_info1->Persist(); | |
212 | |
213 // Wait until Persist() does the work. | |
214 base::RunLoop().RunUntilIdle(); | |
215 | |
216 // Persist data for port 80. | |
217 QuicServerId server_id2("www.google.com", 80, PRIVACY_MODE_DISABLED); | |
218 std::unique_ptr<QuicServerInfo> quic_server_info2( | |
219 new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache())); | |
220 quic_server_info2->Start(); | |
221 rv = quic_server_info2->WaitForDataReady(callback.callback()); | |
222 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
223 | |
224 QuicServerInfo::State* state2 = quic_server_info2->mutable_state(); | |
225 EXPECT_TRUE(state2->certs.empty()); | |
226 const string server_config_b = "server_config_b"; | |
227 const string source_address_token_b = "source_address_token_b"; | |
228 const string cert_sct_b = "cert_sct_b"; | |
229 const string chlo_hash_b = "chlo_hash_b"; | |
230 const string server_config_sig_b = "server_config_sig_b"; | |
231 const string cert_b = "cert_b"; | |
232 | |
233 state2->server_config = server_config_b; | |
234 state2->source_address_token = source_address_token_b; | |
235 state2->cert_sct = cert_sct_b; | |
236 state2->chlo_hash = chlo_hash_b; | |
237 state2->server_config_sig = server_config_sig_b; | |
238 state2->certs.push_back(cert_b); | |
239 quic_server_info2->Persist(); | |
240 | |
241 // Wait until Persist() does the work. | |
242 base::RunLoop().RunUntilIdle(); | |
243 | |
244 // Verify the stored QuicServerInfo for port 443. | |
245 std::unique_ptr<QuicServerInfo> quic_server_info( | |
246 new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache())); | |
247 quic_server_info->Start(); | |
248 rv = quic_server_info->WaitForDataReady(callback.callback()); | |
249 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
250 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
251 | |
252 const QuicServerInfo::State& state_a = quic_server_info->state(); | |
253 EXPECT_EQ(server_config_a, state_a.server_config); | |
254 EXPECT_EQ(source_address_token_a, state_a.source_address_token); | |
255 EXPECT_EQ(cert_sct_a, state_a.cert_sct); | |
256 EXPECT_EQ(chlo_hash_a, state_a.chlo_hash); | |
257 EXPECT_EQ(server_config_sig_a, state_a.server_config_sig); | |
258 EXPECT_EQ(1U, state_a.certs.size()); | |
259 EXPECT_EQ(cert_a, state_a.certs[0]); | |
260 | |
261 // Verify the stored QuicServerInfo for port 80. | |
262 quic_server_info.reset( | |
263 new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache())); | |
264 quic_server_info->Start(); | |
265 rv = quic_server_info->WaitForDataReady(callback.callback()); | |
266 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
267 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
268 | |
269 const QuicServerInfo::State& state_b = quic_server_info->state(); | |
270 EXPECT_EQ(server_config_b, state_b.server_config); | |
271 EXPECT_EQ(source_address_token_b, state_b.source_address_token); | |
272 EXPECT_EQ(cert_sct_b, state_b.cert_sct); | |
273 EXPECT_EQ(chlo_hash_b, state_b.chlo_hash); | |
274 EXPECT_EQ(server_config_sig_b, state_b.server_config_sig); | |
275 EXPECT_EQ(1U, state_b.certs.size()); | |
276 EXPECT_EQ(cert_b, state_b.certs[0]); | |
277 | |
278 RemoveMockTransaction(&kHostInfoTransaction2); | |
279 RemoveMockTransaction(&kHostInfoTransaction1); | |
280 } | |
281 | |
282 // Test IsReadyToPersist when there is a pending write. | |
283 TEST(DiskCacheBasedQuicServerInfo, IsReadyToPersist) { | |
284 MockHttpCache cache(true); | |
285 AddMockTransaction(&kHostInfoTransaction1); | |
286 TestCompletionCallback callback; | |
287 | |
288 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
289 std::unique_ptr<QuicServerInfo> quic_server_info( | |
290 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
291 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
292 quic_server_info->Start(); | |
293 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
294 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
295 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
296 | |
297 QuicServerInfo::State* state = quic_server_info->mutable_state(); | |
298 EXPECT_TRUE(state->certs.empty()); | |
299 const string server_config_a = "server_config_a"; | |
300 const string source_address_token_a = "source_address_token_a"; | |
301 const string cert_sct_a = "cert_sct_a"; | |
302 const string chlo_hash_a = "chlo_hash_a"; | |
303 const string server_config_sig_a = "server_config_sig_a"; | |
304 const string cert_a = "cert_a"; | |
305 | |
306 state->server_config = server_config_a; | |
307 state->source_address_token = source_address_token_a; | |
308 state->cert_sct = cert_sct_a; | |
309 state->chlo_hash = chlo_hash_a; | |
310 state->server_config_sig = server_config_sig_a; | |
311 state->certs.push_back(cert_a); | |
312 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
313 quic_server_info->Persist(); | |
314 | |
315 // Once we call Persist, IsReadyToPersist should return false until Persist | |
316 // has completed. | |
317 EXPECT_FALSE(quic_server_info->IsReadyToPersist()); | |
318 | |
319 // Wait until Persist() does the work. | |
320 base::RunLoop().RunUntilIdle(); | |
321 | |
322 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
323 | |
324 // Verify that the state was updated. | |
325 quic_server_info.reset( | |
326 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
327 quic_server_info->Start(); | |
328 rv = quic_server_info->WaitForDataReady(callback.callback()); | |
329 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
330 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
331 | |
332 const QuicServerInfo::State& state1 = quic_server_info->state(); | |
333 EXPECT_EQ(server_config_a, state1.server_config); | |
334 EXPECT_EQ(source_address_token_a, state1.source_address_token); | |
335 EXPECT_EQ(cert_sct_a, state1.cert_sct); | |
336 EXPECT_EQ(chlo_hash_a, state1.chlo_hash); | |
337 EXPECT_EQ(server_config_sig_a, state1.server_config_sig); | |
338 EXPECT_EQ(1U, state1.certs.size()); | |
339 EXPECT_EQ(cert_a, state1.certs[0]); | |
340 | |
341 RemoveMockTransaction(&kHostInfoTransaction1); | |
342 } | |
343 | |
344 // Test multiple calls to Persist. | |
345 TEST(DiskCacheBasedQuicServerInfo, MultiplePersist) { | |
346 MockHttpCache cache(true); | |
347 AddMockTransaction(&kHostInfoTransaction1); | |
348 TestCompletionCallback callback; | |
349 | |
350 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
351 std::unique_ptr<QuicServerInfo> quic_server_info( | |
352 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
353 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
354 quic_server_info->Start(); | |
355 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
356 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
357 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
358 | |
359 // Persist data once. | |
360 QuicServerInfo::State* state = quic_server_info->mutable_state(); | |
361 EXPECT_TRUE(state->certs.empty()); | |
362 const string server_config_init = "server_config_init"; | |
363 const string source_address_token_init = "source_address_token_init"; | |
364 const string cert_sct_init = "cert_sct_init"; | |
365 const string chlo_hash_init = "chlo_hash_init"; | |
366 const string server_config_sig_init = "server_config_sig_init"; | |
367 const string cert_init = "cert_init"; | |
368 | |
369 state->server_config = server_config_init; | |
370 state->source_address_token = source_address_token_init; | |
371 state->cert_sct = cert_sct_init; | |
372 state->chlo_hash = chlo_hash_init; | |
373 state->server_config_sig = server_config_sig_init; | |
374 state->certs.push_back(cert_init); | |
375 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
376 quic_server_info->Persist(); | |
377 | |
378 // Once we call Persist, IsReadyToPersist should return false until Persist | |
379 // has completed. | |
380 EXPECT_FALSE(quic_server_info->IsReadyToPersist()); | |
381 | |
382 // Wait until Persist() does the work. | |
383 base::RunLoop().RunUntilIdle(); | |
384 | |
385 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
386 | |
387 // Persist one more time using the same |quic_server_info| object and without | |
388 // doing another Start() and WaitForDataReady. | |
389 const string server_config_a = "server_config_a"; | |
390 const string source_address_token_a = "source_address_token_a"; | |
391 const string cert_sct_a = "cert_sct_a"; | |
392 const string chlo_hash_a = "chlo_hash_a"; | |
393 const string server_config_sig_a = "server_config_sig_a"; | |
394 const string cert_a = "cert_a"; | |
395 | |
396 state->server_config = server_config_a; | |
397 state->source_address_token = source_address_token_a; | |
398 state->cert_sct = cert_sct_a; | |
399 state->chlo_hash = chlo_hash_a; | |
400 state->server_config_sig = server_config_sig_a; | |
401 state->certs.push_back(cert_a); | |
402 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
403 quic_server_info->Persist(); | |
404 | |
405 // Once we call Persist, IsReadyToPersist should return false until Persist | |
406 // has completed. | |
407 EXPECT_FALSE(quic_server_info->IsReadyToPersist()); | |
408 | |
409 // Wait until Persist() does the work. | |
410 base::RunLoop().RunUntilIdle(); | |
411 | |
412 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
413 | |
414 // Verify that the state was updated. | |
415 quic_server_info.reset( | |
416 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
417 quic_server_info->Start(); | |
418 rv = quic_server_info->WaitForDataReady(callback.callback()); | |
419 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
420 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
421 | |
422 const QuicServerInfo::State& state1 = quic_server_info->state(); | |
423 EXPECT_EQ(server_config_a, state1.server_config); | |
424 EXPECT_EQ(source_address_token_a, state1.source_address_token); | |
425 EXPECT_EQ(cert_sct_a, state1.cert_sct); | |
426 EXPECT_EQ(chlo_hash_a, state1.chlo_hash); | |
427 EXPECT_EQ(server_config_sig_a, state1.server_config_sig); | |
428 EXPECT_EQ(1U, state1.certs.size()); | |
429 EXPECT_EQ(cert_a, state1.certs[0]); | |
430 | |
431 RemoveMockTransaction(&kHostInfoTransaction1); | |
432 } | |
433 | |
434 TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReady) { | |
435 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); | |
436 MockHttpCache cache(base::WrapUnique(factory), true); | |
437 TestCompletionCallback callback; | |
438 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
439 std::unique_ptr<QuicServerInfo> quic_server_info( | |
440 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
441 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
442 quic_server_info->Start(); | |
443 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
445 // Now cancel the callback. | |
446 quic_server_info->CancelWaitForDataReadyCallback(); | |
447 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
448 // Now complete the backend creation and let the callback run. | |
449 factory->FinishCreation(); | |
450 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
451 } | |
452 | |
453 TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyButDataIsReady) { | |
454 MockHttpCache cache(true); | |
455 AddMockTransaction(&kHostInfoTransaction1); | |
456 TestCompletionCallback callback; | |
457 | |
458 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
459 std::unique_ptr<QuicServerInfo> quic_server_info( | |
460 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
461 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
462 quic_server_info->Start(); | |
463 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
464 quic_server_info->CancelWaitForDataReadyCallback(); | |
465 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
466 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
467 RemoveMockTransaction(&kHostInfoTransaction1); | |
468 } | |
469 | |
470 TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyAfterDeleteCache) { | |
471 std::unique_ptr<QuicServerInfo> quic_server_info; | |
472 { | |
473 MockHttpCache cache(true); | |
474 AddMockTransaction(&kHostInfoTransaction1); | |
475 TestCompletionCallback callback; | |
476 | |
477 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
478 quic_server_info.reset( | |
479 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
480 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
481 quic_server_info->Start(); | |
482 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
483 quic_server_info->CancelWaitForDataReadyCallback(); | |
484 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
485 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
486 RemoveMockTransaction(&kHostInfoTransaction1); | |
487 } | |
488 // Cancel the callback after Cache is deleted. | |
489 quic_server_info->ResetWaitForDataReadyCallback(); | |
490 } | |
491 | |
492 // Test Start() followed by Persist() without calling WaitForDataReady. | |
493 TEST(DiskCacheBasedQuicServerInfo, StartAndPersist) { | |
494 MockHttpCache cache(true); | |
495 AddMockTransaction(&kHostInfoTransaction1); | |
496 | |
497 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
498 std::unique_ptr<QuicServerInfo> quic_server_info( | |
499 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
500 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
501 quic_server_info->Start(); | |
502 // Wait until Start() does the work. | |
503 base::RunLoop().RunUntilIdle(); | |
504 | |
505 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
506 | |
507 QuicServerInfo::State* state = quic_server_info->mutable_state(); | |
508 EXPECT_TRUE(state->certs.empty()); | |
509 const string server_config_a = "server_config_a"; | |
510 const string source_address_token_a = "source_address_token_a"; | |
511 const string cert_sct_a = "cert_sct_a"; | |
512 const string chlo_hash_a = "chlo_hash_a"; | |
513 const string server_config_sig_a = "server_config_sig_a"; | |
514 const string cert_a = "cert_a"; | |
515 | |
516 state->server_config = server_config_a; | |
517 state->source_address_token = source_address_token_a; | |
518 state->cert_sct = cert_sct_a; | |
519 state->chlo_hash = chlo_hash_a; | |
520 state->server_config_sig = server_config_sig_a; | |
521 state->certs.push_back(cert_a); | |
522 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
523 quic_server_info->Persist(); | |
524 quic_server_info->OnExternalCacheHit(); | |
525 | |
526 // Once we call Persist, IsReadyToPersist should return false until Persist | |
527 // has completed. | |
528 EXPECT_FALSE(quic_server_info->IsReadyToPersist()); | |
529 | |
530 // Wait until Persist() does the work. | |
531 base::RunLoop().RunUntilIdle(); | |
532 | |
533 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
534 | |
535 // Verify that the state was updated. | |
536 quic_server_info.reset( | |
537 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
538 quic_server_info->Start(); | |
539 TestCompletionCallback callback; | |
540 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
541 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
542 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
543 | |
544 const QuicServerInfo::State& state1 = quic_server_info->state(); | |
545 EXPECT_EQ(server_config_a, state1.server_config); | |
546 EXPECT_EQ(source_address_token_a, state1.source_address_token); | |
547 EXPECT_EQ(cert_sct_a, state1.cert_sct); | |
548 EXPECT_EQ(chlo_hash_a, state1.chlo_hash); | |
549 EXPECT_EQ(server_config_sig_a, state1.server_config_sig); | |
550 EXPECT_EQ(1U, state1.certs.size()); | |
551 EXPECT_EQ(cert_a, state1.certs[0]); | |
552 | |
553 RemoveMockTransaction(&kHostInfoTransaction1); | |
554 } | |
555 | |
556 // Test Persisting data when we are not ready to persist and then verify it | |
557 // persists the data when Start() finishes. | |
558 TEST(DiskCacheBasedQuicServerInfo, PersistWhenNotReadyToPersist) { | |
559 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); | |
560 MockHttpCache cache(base::WrapUnique(factory), true); | |
561 AddMockTransaction(&kHostInfoTransaction1); | |
562 TestCompletionCallback callback; | |
563 | |
564 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
565 std::unique_ptr<QuicServerInfo> quic_server_info( | |
566 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
567 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
568 // We do a Start(), but don't call WaitForDataReady(). Because we haven't | |
569 // created the backend, we will wait and data wouldn't be ready. | |
570 quic_server_info->Start(); | |
571 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
572 | |
573 // Persist data once, even though the backend is not ready. | |
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 cert_sct_init = "cert_sct_init"; | |
579 const string chlo_hash_init = "chlo_hash_init"; | |
580 const string server_config_sig_init = "server_config_sig_init"; | |
581 const string cert_init = "cert_init"; | |
582 | |
583 state->server_config = server_config_init; | |
584 state->source_address_token = source_address_token_init; | |
585 state->cert_sct = cert_sct_init; | |
586 state->chlo_hash = chlo_hash_init; | |
587 state->server_config_sig = server_config_sig_init; | |
588 state->certs.push_back(cert_init); | |
589 EXPECT_FALSE(quic_server_info->IsReadyToPersist()); | |
590 quic_server_info->Persist(); | |
591 EXPECT_FALSE(quic_server_info->IsReadyToPersist()); | |
592 | |
593 // Now complete the backend creation and let the callback run. | |
594 factory->FinishCreation(); | |
595 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
596 | |
597 // Wait until Persist() does the work. | |
598 base::RunLoop().RunUntilIdle(); | |
599 | |
600 // Verify that the state was updated. | |
601 quic_server_info.reset( | |
602 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
603 quic_server_info->Start(); | |
604 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
605 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
606 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
607 | |
608 const QuicServerInfo::State& state1 = quic_server_info->state(); | |
609 EXPECT_EQ(server_config_init, state1.server_config); | |
610 EXPECT_EQ(source_address_token_init, state1.source_address_token); | |
611 EXPECT_EQ(cert_sct_init, state1.cert_sct); | |
612 EXPECT_EQ(chlo_hash_init, state1.chlo_hash); | |
613 EXPECT_EQ(server_config_sig_init, state1.server_config_sig); | |
614 EXPECT_EQ(1U, state1.certs.size()); | |
615 EXPECT_EQ(cert_init, state1.certs[0]); | |
616 RemoveMockTransaction(&kHostInfoTransaction1); | |
617 } | |
618 | |
619 // Test multiple calls to Persist without waiting for the data to be written. | |
620 TEST(DiskCacheBasedQuicServerInfo, MultiplePersistsWithoutWaiting) { | |
621 MockHttpCache cache(true); | |
622 AddMockTransaction(&kHostInfoTransaction1); | |
623 TestCompletionCallback callback; | |
624 | |
625 QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); | |
626 std::unique_ptr<QuicServerInfo> quic_server_info( | |
627 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
628 EXPECT_FALSE(quic_server_info->IsDataReady()); | |
629 quic_server_info->Start(); | |
630 int rv = quic_server_info->WaitForDataReady(callback.callback()); | |
631 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
632 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
633 | |
634 // Persist data once. | |
635 QuicServerInfo::State* state = quic_server_info->mutable_state(); | |
636 EXPECT_TRUE(state->certs.empty()); | |
637 const string server_config_init = "server_config_init"; | |
638 const string source_address_token_init = "source_address_token_init"; | |
639 const string cert_sct_init = "cert_sct_init"; | |
640 const string chlo_hash_init = "chlo_hash_init"; | |
641 const string server_config_sig_init = "server_config_sig_init"; | |
642 const string cert_init = "cert_init"; | |
643 | |
644 state->server_config = server_config_init; | |
645 state->source_address_token = source_address_token_init; | |
646 state->cert_sct = cert_sct_init; | |
647 state->chlo_hash = chlo_hash_init; | |
648 state->server_config_sig = server_config_sig_init; | |
649 state->certs.push_back(cert_init); | |
650 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
651 quic_server_info->Persist(); | |
652 | |
653 // Once we call Persist, IsReadyToPersist should return false until Persist | |
654 // has completed. | |
655 EXPECT_FALSE(quic_server_info->IsReadyToPersist()); | |
656 | |
657 // Persist one more time using the same |quic_server_info| object and without | |
658 // doing another Start() and WaitForDataReady. | |
659 const string server_config_a = "server_config_a"; | |
660 const string source_address_token_a = "source_address_token_a"; | |
661 const string cert_sct_a = "cert_sct_a"; | |
662 const string chlo_hash_a = "chlo_hash_a"; | |
663 const string server_config_sig_a = "server_config_sig_a"; | |
664 const string cert_a = "cert_a"; | |
665 | |
666 state->server_config = server_config_a; | |
667 state->source_address_token = source_address_token_a; | |
668 state->cert_sct = cert_sct_a; | |
669 state->chlo_hash = chlo_hash_a; | |
670 state->server_config_sig = server_config_sig_a; | |
671 state->certs.push_back(cert_a); | |
672 EXPECT_FALSE(quic_server_info->IsReadyToPersist()); | |
673 quic_server_info->Persist(); | |
674 | |
675 // Wait until Persist() does the work. | |
676 base::RunLoop().RunUntilIdle(); | |
677 | |
678 EXPECT_TRUE(quic_server_info->IsReadyToPersist()); | |
679 | |
680 // Verify that the state was updated. | |
681 quic_server_info.reset( | |
682 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); | |
683 quic_server_info->Start(); | |
684 rv = quic_server_info->WaitForDataReady(callback.callback()); | |
685 EXPECT_THAT(callback.GetResult(rv), IsOk()); | |
686 EXPECT_TRUE(quic_server_info->IsDataReady()); | |
687 | |
688 // Verify the second time persisted data is persisted. | |
689 const QuicServerInfo::State& state1 = quic_server_info->state(); | |
690 EXPECT_EQ(server_config_a, state1.server_config); | |
691 EXPECT_EQ(source_address_token_a, state1.source_address_token); | |
692 EXPECT_EQ(cert_sct_a, state1.cert_sct); | |
693 EXPECT_EQ(chlo_hash_a, state1.chlo_hash); | |
694 EXPECT_EQ(server_config_sig_a, state1.server_config_sig); | |
695 EXPECT_EQ(1U, state1.certs.size()); | |
696 EXPECT_EQ(cert_a, state1.certs[0]); | |
697 | |
698 RemoveMockTransaction(&kHostInfoTransaction1); | |
699 } | |
700 | |
701 // crbug.com/439209: test deletion of QuicServerInfo object in the callback | |
702 // doesn't crash. | |
703 TEST(DiskCacheBasedQuicServerInfo, DeleteServerInfoInCallback) { | |
704 // Use the blocking mock backend factory to force asynchronous completion | |
705 // of quic_server_info->WaitForDataReady(), so that the callback will run. | |
706 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); | |
707 MockHttpCache cache(base::WrapUnique(factory), true); | |
708 QuicServerId server_id("www.verisign.com", 443, PRIVACY_MODE_DISABLED); | |
709 QuicServerInfo* quic_server_info = | |
710 new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()); | |
711 // |cb| takes owndership and deletes |quic_server_info| when it is called. | |
712 DeleteCacheCompletionCallback cb(quic_server_info); | |
713 quic_server_info->Start(); | |
714 int rv = quic_server_info->WaitForDataReady(cb.callback()); | |
715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
716 // Now complete the backend creation and let the callback run. | |
717 factory->FinishCreation(); | |
718 EXPECT_THAT(cb.GetResult(rv), IsOk()); | |
719 } | |
720 | |
721 } // namespace net | |
OLD | NEW |