OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2017 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/http_cache_writers.h" | |
6 | |
7 #include <memory> | |
8 #include <string> | |
9 #include <vector> | |
10 | |
11 #include "base/run_loop.h" | |
12 #include "net/http/http_cache.h" | |
13 #include "net/http/http_cache_transaction.h" | |
14 #include "net/http/http_transaction.h" | |
15 #include "net/http/http_transaction_test_util.h" | |
16 #include "net/http/mock_http_cache.h" | |
17 #include "net/test/gtest_util.h" | |
18 | |
19 using net::test::IsError; | |
20 using net::test::IsOk; | |
21 | |
22 namespace net { | |
23 | |
24 class HttpCache::WritersTest { | |
25 public: | |
26 WritersTest() {} | |
27 | |
28 // Since ActiveEntry and Transaction are private classes of HttpCache, | |
29 // accessing those only in this class instead of in tests. | |
30 | |
31 void CreateWriters(const std::string& url) { | |
32 HttpCache* cache = cache_.http_cache(); | |
33 ActiveEntry* entry = cache->FindActiveEntry(url); | |
34 writers_ = base::MakeUnique<Writers>(cache, entry->disk_entry); | |
35 } | |
36 | |
37 std::unique_ptr<HttpTransaction> CreateNetworkTransaction() { | |
38 std::unique_ptr<HttpTransaction> transaction; | |
39 MockNetworkLayer* network_layer = cache_.network_layer(); | |
40 network_layer->CreateTransaction(DEFAULT_PRIORITY, &transaction); | |
41 return transaction; | |
42 } | |
43 | |
44 void CreateWritersAddTransaction(MockTransaction transaction_info, | |
45 bool is_exclusive = false) { | |
46 MockHttpRequest request(transaction_info); | |
47 std::unique_ptr<HttpTransaction> transaction; | |
48 int rv = cache_.CreateTransaction(&transaction); | |
49 DCHECK_EQ(rv, OK); | |
50 DCHECK(transaction.get()); | |
51 | |
52 // Create an ActiveEntry. | |
53 TestCompletionCallback callback; | |
54 rv = transaction->Start(&request, callback.callback(), NetLogWithSource()); | |
55 base::RunLoop().RunUntilIdle(); | |
56 | |
57 CreateWriters(kSimpleGET_Transaction.url); | |
58 | |
59 // Create and Start a mock network transaction. | |
60 std::unique_ptr<HttpTransaction> network_transaction; | |
61 network_transaction = CreateNetworkTransaction(); | |
62 network_transaction->Start(&request, callback.callback(), | |
63 NetLogWithSource()); | |
64 base::RunLoop().RunUntilIdle(); | |
65 | |
66 DCHECK(writers_->IsEmpty()); | |
67 writers_->AddTransaction((Transaction*)(transaction.get()), | |
68 std::move(network_transaction), is_exclusive); | |
69 transactions_.push_back(std::move(transaction)); | |
70 } | |
71 | |
72 void AddTransactionToExistingWriters() { | |
73 std::unique_ptr<HttpTransaction> transaction; | |
74 int rv = cache_.CreateTransaction(&transaction); | |
75 DCHECK_EQ(rv, OK); | |
76 DCHECK(transaction.get()); | |
77 | |
78 DCHECK(writers_); | |
79 writers_->AddTransaction((Transaction*)(transaction.get()), nullptr, false); | |
80 transactions_.push_back(std::move(transaction)); | |
81 } | |
82 | |
83 int Read(std::string* result) { | |
84 Transaction* transaction = (Transaction*)(transactions_.begin()->get()); | |
Randy Smith (Not in Mondays)
2017/06/22 21:45:05
DCHECK that there's at least one transaction in tr
shivanisha
2017/06/26 20:45:35
done
| |
85 TestCompletionCallback callback; | |
86 | |
87 std::string content; | |
88 int rv; | |
89 do { | |
90 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | |
91 rv = writers_->Read(buf.get(), 256, callback.callback(), transaction); | |
92 if (rv == ERR_IO_PENDING) { | |
93 rv = callback.WaitForResult(); | |
94 base::RunLoop().RunUntilIdle(); | |
95 } | |
96 | |
97 if (rv > 0) | |
98 content.append(buf->data(), rv); | |
99 else if (rv < 0) | |
100 return rv; | |
101 } while (rv > 0); | |
102 | |
103 result->swap(content); | |
104 return OK; | |
105 } | |
106 | |
107 int ReadAll(std::vector<std::string>& results) { | |
108 int rv; | |
109 do { | |
110 std::vector<scoped_refptr<IOBuffer>> bufs; | |
111 std::vector<TestCompletionCallback> callbacks(results.size()); | |
112 | |
113 // Multiple transactions should be able to read. | |
114 int i = 0; | |
115 for (auto& transaction : transactions_) { | |
116 bufs.push_back(new IOBuffer(256)); | |
117 rv = writers_->Read(bufs[i].get(), 256, callbacks[i].callback(), | |
118 (Transaction*)transaction.get()); | |
119 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous. | |
120 i++; | |
121 } | |
122 | |
123 if (rv == ERR_IO_PENDING) { | |
124 int prev_rv = callbacks[0].WaitForResult(); | |
125 for (size_t i = 1; i < callbacks.size(); i++) { | |
126 rv = callbacks[i].WaitForResult(); | |
127 EXPECT_EQ(rv, prev_rv); | |
128 prev_rv = rv; | |
129 } | |
130 } | |
131 | |
132 if (rv > 0) { | |
133 int i = 0; | |
134 for (auto& result : results) { | |
Randy Smith (Not in Mondays)
2017/06/22 21:45:05
suggestion-but-I'd-prefer-it: Using *both* the aut
shivanisha
2017/06/26 20:45:35
done
| |
135 result.append(bufs[i]->data(), rv); | |
136 i++; | |
137 } | |
138 } else if (rv <= 0) { | |
139 return rv; | |
140 } | |
141 } while (rv > 0); | |
142 | |
143 return OK; | |
144 } | |
145 | |
146 int ReadAllDeleteActiveTransaction(std::vector<std::string>& results) { | |
147 int rv; | |
148 bool first_iter = true; | |
149 do { | |
150 std::vector<scoped_refptr<IOBuffer>> bufs; | |
151 std::vector<TestCompletionCallback> callbacks(results.size()); | |
152 | |
153 // Multiple transactions should be able to read. | |
154 int i = 0; | |
155 for (auto& transaction : transactions_) { | |
156 bufs.push_back(new IOBuffer(256)); | |
157 if (!first_iter && i == 0) { | |
158 i++; | |
159 continue; | |
160 } | |
161 rv = writers_->Read(bufs[i].get(), 256, callbacks[i].callback(), | |
162 (Transaction*)transaction.get()); | |
163 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous. | |
164 i++; | |
165 } | |
166 | |
167 if (rv == ERR_IO_PENDING) { | |
168 if (first_iter) { | |
169 // Delete active transaction. | |
170 RemoveFirstTransaction(); | |
171 } | |
172 int prev_rv = callbacks[1].WaitForResult(); | |
173 for (size_t i = 2; i < callbacks.size(); i++) { | |
174 rv = callbacks[i].WaitForResult(); | |
175 EXPECT_EQ(rv, prev_rv); | |
176 prev_rv = rv; | |
177 } | |
178 } | |
179 | |
180 if (rv > 0) { | |
181 int i = 0; | |
182 for (auto& result : results) { | |
183 result.append(bufs[i]->data(), rv); | |
184 i++; | |
185 } | |
186 } else if (rv <= 0) { | |
Randy Smith (Not in Mondays)
2017/06/22 21:45:05
suggestion: If you eliminate this conditional and
shivanisha
2017/06/26 20:45:34
done
| |
187 return rv; | |
188 } | |
189 first_iter = false; | |
190 } while (rv > 0); | |
191 | |
192 return OK; | |
193 } | |
194 | |
195 int ReadAllDeleteWaitingTransaction(std::vector<std::string>& results, | |
196 size_t waiting_index) { | |
197 int rv; | |
198 bool first_iter = true; | |
199 do { | |
200 std::vector<scoped_refptr<IOBuffer>> bufs; | |
201 std::vector<TestCompletionCallback> callbacks(results.size()); | |
202 | |
203 // Multiple transactions should be able to read. | |
204 size_t i = 0; | |
205 for (auto& transaction : transactions_) { | |
206 bufs.push_back(new IOBuffer(256)); | |
207 if (!first_iter && i == waiting_index) { | |
208 i++; | |
209 continue; | |
210 } | |
211 rv = writers_->Read(bufs[i].get(), 256, callbacks[i].callback(), | |
212 (Transaction*)transaction.get()); | |
213 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous. | |
214 i++; | |
215 } | |
216 | |
217 if (rv == ERR_IO_PENDING) { | |
218 if (first_iter) { | |
219 // Delete waiting transaction. | |
220 writers_->RemoveTransaction( | |
221 (Transaction*)transactions_.at(waiting_index).get()); | |
222 } | |
223 for (size_t j = 0; j < callbacks.size(); j++) { | |
224 if (j == waiting_index) | |
225 continue; | |
226 rv = callbacks[j].WaitForResult(); | |
227 } | |
228 } | |
229 | |
230 if (rv > 0) { | |
231 size_t i = 0; | |
232 for (auto& result : results) { | |
Randy Smith (Not in Mondays)
2017/06/22 21:45:05
Same request as above--if the loop is going to be
shivanisha
2017/06/26 20:45:34
done
| |
233 if (i == waiting_index) { | |
234 i++; | |
235 continue; | |
236 } | |
237 result.append(bufs[i]->data(), rv); | |
238 i++; | |
239 } | |
240 } else if (rv <= 0) { | |
241 return rv; | |
Randy Smith (Not in Mondays)
2017/06/22 21:45:05
Same suggestion as above; delete this clause and r
shivanisha
2017/06/26 20:45:34
done
| |
242 } | |
243 first_iter = false; | |
244 } while (rv > 0); | |
245 | |
246 return OK; | |
247 } | |
248 | |
249 int ReadAllDeleteIdleTransaction(std::vector<std::string>& results, | |
250 size_t idle_index) { | |
251 int rv; | |
252 bool first_iter = true; | |
253 do { | |
254 std::vector<scoped_refptr<IOBuffer>> bufs; | |
255 std::vector<TestCompletionCallback> callbacks(results.size()); | |
256 | |
257 // Multiple transactions should be able to read. | |
258 size_t i = 0; | |
259 for (auto& transaction : transactions_) { | |
260 bufs.push_back(new IOBuffer(256)); | |
261 if (i == idle_index) { | |
262 i++; | |
263 continue; | |
264 } | |
265 rv = writers_->Read(bufs[i].get(), 256, callbacks[i].callback(), | |
266 (Transaction*)transaction.get()); | |
267 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous. | |
268 i++; | |
269 } | |
270 | |
271 if (rv == ERR_IO_PENDING) { | |
272 if (first_iter) { | |
273 // Delete idle transaction. | |
274 writers_->RemoveTransaction( | |
275 (Transaction*)transactions_.at(idle_index).get()); | |
276 } | |
277 for (size_t j = 0; j < callbacks.size(); j++) { | |
278 if (j == idle_index) | |
279 continue; | |
280 rv = callbacks[j].WaitForResult(); | |
281 } | |
282 } | |
283 | |
284 if (rv > 0) { | |
285 size_t i = 0; | |
286 for (auto& result : results) { | |
287 if (i == idle_index) { | |
288 i++; | |
289 continue; | |
290 } | |
291 result.append(bufs[i]->data(), rv); | |
292 i++; | |
293 } | |
294 } else if (rv <= 0) { | |
295 return rv; | |
296 } | |
297 first_iter = false; | |
298 } while (rv > 0); | |
299 | |
300 return OK; | |
301 } | |
302 | |
303 int ReadCacheWriteFailure(std::vector<std::string>& results) { | |
304 int rv; | |
305 bool first_iter = true; | |
306 do { | |
307 std::vector<scoped_refptr<IOBuffer>> bufs; | |
308 std::vector<TestCompletionCallback> callbacks(results.size()); | |
309 | |
310 // Fail the request. | |
311 cache_.disk_cache()->set_soft_failures(true); | |
312 | |
313 // We have to open the entry again to propagate the failure flag. | |
314 disk_cache::Entry* en; | |
315 cache_.OpenBackendEntry(kSimpleGET_Transaction.url, &en); | |
316 en->Close(); | |
317 | |
318 size_t i = 0; | |
319 for (auto& transaction : transactions_) { | |
320 bufs.push_back(new IOBuffer(30)); | |
321 | |
322 if (!first_iter && i > 0) | |
323 break; | |
324 rv = writers_->Read(bufs[i].get(), 30, callbacks[i].callback(), | |
325 (Transaction*)transaction.get()); | |
326 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous. | |
327 i++; | |
328 } | |
329 | |
330 if (rv == ERR_IO_PENDING) { | |
331 int i = 0; | |
332 for (auto& callback : callbacks) { | |
333 // Only active transaction should succeed. | |
334 if (i == 0) { | |
335 rv = callback.WaitForResult(); | |
336 EXPECT_TRUE(rv >= 0); | |
337 results[0].append(bufs[i]->data(), rv); | |
338 if (rv == 0) | |
339 return rv; | |
340 } else if (first_iter) { | |
341 rv = callback.WaitForResult(); | |
342 EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, rv); | |
343 } | |
344 i++; | |
345 } | |
346 } | |
347 | |
348 first_iter = false; | |
349 } while (true); | |
350 | |
351 return OK; | |
352 } | |
353 | |
354 int ReadNetworkFailure(std::vector<std::string>& results) { | |
355 int rv; | |
356 do { | |
357 std::vector<scoped_refptr<IOBuffer>> bufs; | |
358 std::vector<TestCompletionCallback> callbacks(results.size()); | |
359 | |
360 // Fail the request. | |
361 MockNetworkTransaction* network_transaction = | |
362 (MockNetworkTransaction*)(writers_->network_transaction()); | |
363 network_transaction->SetReadError(ERR_INTERNET_DISCONNECTED); | |
364 | |
365 size_t i = 0; | |
366 for (auto& transaction : transactions_) { | |
367 bufs.push_back(new IOBuffer(30)); | |
368 | |
369 rv = writers_->Read(bufs[i].get(), 30, callbacks[i].callback(), | |
370 (Transaction*)transaction.get()); | |
371 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous. | |
372 i++; | |
373 } | |
374 | |
375 if (rv == ERR_IO_PENDING) { | |
376 for (auto& callback : callbacks) { | |
377 rv = callback.WaitForResult(); | |
378 EXPECT_EQ(ERR_INTERNET_DISCONNECTED, rv); | |
379 } | |
380 } | |
381 } while (rv > 0); | |
382 | |
383 return rv; | |
384 } | |
385 | |
386 bool StopCaching() { | |
387 Transaction* transaction = (Transaction*)(transactions_.begin()->get()); | |
388 DCHECK(transaction); | |
389 return writers_->StopCaching(transaction); | |
390 } | |
391 | |
392 void RemoveFirstTransaction() { | |
393 Transaction* transaction = (Transaction*)(transactions_.begin()->get()); | |
394 DCHECK(transaction); | |
395 writers_->RemoveTransaction(transaction); | |
396 } | |
397 | |
398 MockHttpCache cache_; | |
399 std::unique_ptr<Writers> writers_; | |
400 std::vector<std::unique_ptr<HttpTransaction>> transactions_; | |
401 }; | |
402 | |
403 // Tests successful addition of a transaction. | |
404 TEST(HttpCacheWriters, AddTransaction) { | |
405 HttpCache::WritersTest writersTest; | |
406 | |
407 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
408 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
409 } | |
410 | |
411 // Tests successful addition of multiple transaction. | |
412 TEST(HttpCacheWriters, AddManyTransactions) { | |
413 HttpCache::WritersTest writersTest; | |
414 | |
415 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
416 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
417 | |
418 for (int i = 0; i < 5; i++) | |
419 writersTest.AddTransactionToExistingWriters(); | |
420 | |
421 EXPECT_EQ(writersTest.writers_->CountTransactionsForTesting(), 6); | |
422 } | |
423 | |
424 // Tests that CanAddWriters should return false if it is exclusive writing. | |
425 TEST(HttpCacheWriters, AddTransactionsExclusive) { | |
426 HttpCache::WritersTest writersTest; | |
427 | |
428 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction, true); | |
429 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
430 | |
431 EXPECT_FALSE(writersTest.writers_->CanAddWriters()); | |
432 } | |
433 | |
434 // Tests StopCaching should not stop caching if there are multiple writers. | |
435 TEST(HttpCacheWriters, StopCachingMultipleWriters) { | |
436 HttpCache::WritersTest writersTest; | |
437 | |
438 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
439 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
440 | |
441 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
442 writersTest.AddTransactionToExistingWriters(); | |
443 | |
444 EXPECT_FALSE(writersTest.StopCaching()); | |
445 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
446 } | |
447 | |
448 // Tests StopCaching should stop caching if there is a single writer. | |
449 TEST(HttpCacheWriters, StopCaching) { | |
450 HttpCache::WritersTest writersTest; | |
451 | |
452 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
453 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
454 | |
455 EXPECT_TRUE(writersTest.StopCaching()); | |
456 EXPECT_FALSE(writersTest.writers_->CanAddWriters()); | |
457 } | |
458 | |
459 // Tests removing of an idle transaction. | |
460 TEST(HttpCacheWriters, RemoveIdleTransaction) { | |
461 HttpCache::WritersTest writersTest; | |
462 | |
463 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
464 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
465 | |
466 writersTest.RemoveFirstTransaction(); | |
467 EXPECT_TRUE(writersTest.writers_->IsEmpty()); | |
468 } | |
469 | |
470 // Tests that Read is successful. | |
471 TEST(HttpCacheWriters, Read) { | |
472 HttpCache::WritersTest writersTest; | |
473 | |
474 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
475 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
476 | |
477 std::string content; | |
478 int rv = writersTest.Read(&content); | |
479 | |
480 EXPECT_THAT(rv, IsOk()); | |
481 std::string expected(kSimpleGET_Transaction.data); | |
482 EXPECT_EQ(expected, content); | |
483 } | |
484 | |
485 // Tests that multiple transactions can read the same data simultaneously. | |
486 TEST(HttpCacheWriters, ReadMultiple) { | |
487 HttpCache::WritersTest writersTest; | |
488 | |
489 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
490 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
491 | |
492 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
493 writersTest.AddTransactionToExistingWriters(); | |
494 | |
495 std::vector<std::string> contents(2); | |
496 int rv = writersTest.ReadAll(contents); | |
497 | |
498 EXPECT_THAT(rv, IsOk()); | |
499 std::string expected(kSimpleGET_Transaction.data); | |
500 | |
501 for (auto content : contents) | |
502 EXPECT_EQ(expected, content); | |
503 } | |
504 | |
505 // Tests that ongoing Read completes even when active transaction is deleted | |
506 // mid-read. Any transactions waiting should be able to get the read buffer. | |
507 TEST(HttpCacheWriters, ReadMultipleDeleteActiveTransaction) { | |
508 HttpCache::WritersTest writersTest; | |
509 | |
510 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
511 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
512 | |
513 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
514 writersTest.AddTransactionToExistingWriters(); | |
515 writersTest.AddTransactionToExistingWriters(); | |
516 | |
517 std::vector<std::string> contents(3); | |
518 int rv = writersTest.ReadAllDeleteActiveTransaction(contents); | |
519 | |
520 EXPECT_THAT(rv, IsOk()); | |
521 std::string expected(kSimpleGET_Transaction.data); | |
522 | |
523 for (auto content : contents) | |
524 EXPECT_EQ(expected, content); | |
525 } | |
526 | |
527 // Tests that removing a waiting for read transaction does not impact other | |
528 // transactions. | |
529 TEST(HttpCacheWriters, ReadMultipleDeleteWaitingTransaction) { | |
530 HttpCache::WritersTest writersTest; | |
531 | |
532 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
533 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
534 | |
535 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
536 writersTest.AddTransactionToExistingWriters(); | |
537 writersTest.AddTransactionToExistingWriters(); | |
538 writersTest.AddTransactionToExistingWriters(); | |
539 | |
540 std::vector<std::string> contents(4); | |
541 size_t waiting_index = 1; | |
542 int rv = writersTest.ReadAllDeleteWaitingTransaction(contents, waiting_index); | |
543 | |
544 EXPECT_THAT(rv, IsOk()); | |
545 std::string expected(kSimpleGET_Transaction.data); | |
546 | |
547 size_t i = 0; | |
548 for (auto content : contents) { | |
549 if (i == waiting_index) | |
550 EXPECT_EQ("", content); | |
551 else | |
552 EXPECT_EQ(expected, content); | |
553 i++; | |
554 } | |
555 } | |
556 | |
557 // Tests that removing an idle transaction does not impact other transactions. | |
558 TEST(HttpCacheWriters, ReadMultipleDeleteIdleTransaction) { | |
559 HttpCache::WritersTest writersTest; | |
560 | |
561 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
562 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
563 | |
564 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
565 writersTest.AddTransactionToExistingWriters(); | |
566 writersTest.AddTransactionToExistingWriters(); | |
567 | |
568 std::vector<std::string> contents(3); | |
569 size_t idle_index = 1; | |
570 int rv = writersTest.ReadAllDeleteIdleTransaction(contents, idle_index); | |
571 | |
572 EXPECT_THAT(rv, IsOk()); | |
573 std::string expected(kSimpleGET_Transaction.data); | |
574 | |
575 size_t i = 0; | |
576 for (auto content : contents) { | |
577 if (i == idle_index) { | |
578 i++; | |
579 continue; | |
580 } | |
581 EXPECT_EQ(expected, content); | |
582 i++; | |
583 } | |
584 } | |
585 | |
586 // Tests cache write failure. | |
587 TEST(HttpCacheWriters, ReadMultipleCacheWriteFailed) { | |
588 HttpCache::WritersTest writersTest; | |
589 | |
590 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
591 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
592 | |
593 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
594 writersTest.AddTransactionToExistingWriters(); | |
595 writersTest.AddTransactionToExistingWriters(); | |
596 | |
597 std::vector<std::string> contents(3); | |
598 int rv = writersTest.ReadCacheWriteFailure(contents); | |
599 | |
600 EXPECT_THAT(rv, IsOk()); | |
601 std::string expected(kSimpleGET_Transaction.data); | |
602 | |
603 // Only active_transaction_ should succeed. | |
604 EXPECT_EQ(expected, contents.at(0)); | |
605 | |
606 // No new transactions should now be added. | |
607 EXPECT_FALSE(writersTest.writers_->CanAddWriters()); | |
608 } | |
609 | |
610 // Tests that network read failure fails all transactions: active, waiting and | |
611 // idle. | |
612 TEST(HttpCacheWriters, ReadMultipleNetworkReadFailed) { | |
613 HttpCache::WritersTest writersTest; | |
614 | |
615 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
616 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
617 | |
618 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
619 writersTest.AddTransactionToExistingWriters(); | |
620 writersTest.AddTransactionToExistingWriters(); | |
621 | |
622 std::vector<std::string> contents(3); | |
623 int rv = writersTest.ReadNetworkFailure(contents); | |
624 | |
625 EXPECT_EQ(rv, ERR_INTERNET_DISCONNECTED); | |
626 } | |
627 | |
628 // Tests moving idle writers to readers. | |
629 TEST(HttpCacheWriters, MoveIdleWritersToReaders) { | |
630 HttpCache::WritersTest writersTest; | |
631 | |
632 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
633 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
634 | |
635 EXPECT_TRUE(writersTest.writers_->CanAddWriters()); | |
636 writersTest.AddTransactionToExistingWriters(); | |
637 writersTest.AddTransactionToExistingWriters(); | |
638 | |
639 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
640 writersTest.writers_->RemoveAllIdleWriters(); | |
641 EXPECT_TRUE(writersTest.writers_->IsEmpty()); | |
642 } | |
643 | |
644 // Tests GetWriterLoadState. | |
645 TEST(HttpCacheWriters, GetWriterLoadState) { | |
646 HttpCache::WritersTest writersTest; | |
647 | |
648 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
649 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
650 | |
651 EXPECT_EQ(LOAD_STATE_IDLE, writersTest.writers_->GetWriterLoadState()); | |
652 } | |
653 | |
654 // Tests truncating the entry via Writers. | |
655 TEST(HttpCacheWriters, TruncateEntry) { | |
656 HttpCache::WritersTest writersTest; | |
657 | |
658 writersTest.CreateWritersAddTransaction(kSimpleGET_Transaction); | |
659 EXPECT_FALSE(writersTest.writers_->IsEmpty()); | |
660 | |
661 std::string content; | |
662 int rv = writersTest.Read(&content); | |
663 | |
664 EXPECT_THAT(rv, IsOk()); | |
665 std::string expected(kSimpleGET_Transaction.data); | |
666 EXPECT_EQ(expected, content); | |
667 | |
668 writersTest.writers_->TruncateEntry(); | |
669 base::RunLoop().RunUntilIdle(); | |
670 EXPECT_TRUE(writersTest.writers_->IsTruncatedForTesting()); | |
671 } | |
672 | |
673 } // namespace net | |
OLD | NEW |