Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Side by Side Diff: net/http/http_cache_writers_unittest.cc

Issue 2886483002: Adds a new class HttpCache::Writers for multiple cache transactions reading from the network. (Closed)
Patch Set: jkarlin@ feedback addressed. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 WritersTest : public testing::Test {
25 public:
26 WritersTest() : disk_entry_(nullptr), request_(kSimpleGET_Transaction) {}
27
28 ~WritersTest() override {
29 if (disk_entry_)
30 disk_entry_->Close();
31 }
32
33 void CreateWriters(const std::string& url) {
34 cache_.CreateBackendEntry(kSimpleGET_Transaction.url, &disk_entry_,
35 nullptr);
36 writers_ = base::MakeUnique<HttpCache::Writers>(disk_entry_);
37 }
38
39 std::unique_ptr<HttpTransaction> CreateNetworkTransaction() {
40 std::unique_ptr<HttpTransaction> transaction;
41 MockNetworkLayer* network_layer = cache_.network_layer();
42 network_layer->CreateTransaction(DEFAULT_PRIORITY, &transaction);
43 return transaction;
44 }
45
46 void CreateWritersAddTransaction(bool is_exclusive = false) {
47 std::unique_ptr<HttpTransaction> transaction;
48 int rv = cache_.CreateTransaction(&transaction);
49 EXPECT_EQ(rv, OK);
50 EXPECT_TRUE(transaction);
51
52 TestCompletionCallback callback;
53
54 CreateWriters(kSimpleGET_Transaction.url);
55
56 // Create and Start a mock network transaction.
57 std::unique_ptr<HttpTransaction> network_transaction;
58 network_transaction = CreateNetworkTransaction();
59 network_transaction->Start(&request_, callback.callback(),
60 NetLogWithSource());
61 base::RunLoop().RunUntilIdle();
62
63 EXPECT_TRUE(writers_->IsEmpty());
64 writers_->AddTransaction(
65 static_cast<HttpCache::Transaction*>(transaction.get()),
66 std::move(network_transaction), is_exclusive);
67 EXPECT_TRUE(writers_->HasTransaction(
68 static_cast<HttpCache::Transaction*>(transaction.get())));
69 transactions_.push_back(std::move(transaction));
70 }
71
72 void CreateWritersAddTransactionPriority(net::RequestPriority priority,
73 bool is_exclusive = false) {
74 CreateWritersAddTransaction(is_exclusive);
75 HttpCache::Transaction* transaction =
76 static_cast<HttpCache::Transaction*>(transactions_.begin()->get());
77 transaction->SetPriority(priority);
78 }
79
80 void AddTransactionToExistingWriters() {
81 std::unique_ptr<HttpTransaction> transaction;
82 int rv = cache_.CreateTransaction(&transaction);
83 EXPECT_EQ(rv, OK);
84 EXPECT_TRUE(transaction);
85
86 EXPECT_TRUE(writers_);
87 writers_->AddTransaction(
88 static_cast<HttpCache::Transaction*>(transaction.get()), nullptr,
89 false);
90 transactions_.push_back(std::move(transaction));
91 }
92
93 int Read(std::string* result) {
94 EXPECT_TRUE(transactions_.size() >= (size_t)1);
95 HttpCache::Transaction* transaction =
96 static_cast<HttpCache::Transaction*>(transactions_.begin()->get());
97 TestCompletionCallback callback;
98
99 std::string content;
100 int rv = 0;
101 do {
102 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
103 rv = writers_->Read(buf.get(), 256, callback.callback(), transaction);
104 if (rv == ERR_IO_PENDING) {
105 rv = callback.WaitForResult();
106 base::RunLoop().RunUntilIdle();
107 }
108
109 if (rv > 0)
110 content.append(buf->data(), rv);
111 else if (rv < 0)
112 return rv;
113 } while (rv > 0);
114
115 result->swap(content);
116 return OK;
117 }
118
119 int ReadAll(std::vector<std::string>* results) {
120 int rv = 0;
121 do {
122 std::vector<scoped_refptr<IOBuffer>> bufs;
123 std::vector<TestCompletionCallback> callbacks(results->size());
124
125 // Multiple transactions should be able to read.
126 for (size_t i = 0; i < transactions_.size(); i++) {
127 bufs.push_back(new IOBuffer(256));
128 rv = writers_->Read(
129 bufs[i].get(), 256, callbacks[i].callback(),
130 static_cast<HttpCache::Transaction*>(transactions_[i].get()));
131 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous.
132 }
133
134 int prev_rv = callbacks[0].WaitForResult();
135 rv = prev_rv;
136 for (size_t i = 1; i < callbacks.size(); i++) {
jkarlin 2017/07/06 18:50:04 Really qequires at least 2 transactions, can you A
shivanisha 2017/07/11 02:10:27 done
137 rv = callbacks[i].WaitForResult();
138 EXPECT_EQ(rv, prev_rv);
139 prev_rv = rv;
140 }
141
142 if (rv > 0) {
143 for (size_t i = 0; i < results->size(); i++)
144 results->at(i).append(bufs[i]->data(), rv);
145 } else if (rv <= 0) {
146 return rv;
147 }
148 } while (rv > 0);
149
150 return OK;
151 }
152
153 void ReadVerifyTwoDifferentBufferLengths(
154 const std::vector<int>& buffer_lengths) {
155 EXPECT_EQ(2u, buffer_lengths.size());
156 EXPECT_EQ(2u, transactions_.size());
157
158 std::vector<std::string> results(buffer_lengths.size());
159
160 // Check only the 1st Read and not the complete response because the smaller
161 // buffer transaction will need to read the remaining response from the
162 // cache which will be tested when integrated with HttpCache::Transaction
163 // layer.
164
165 int rv = 0;
166
167 std::vector<scoped_refptr<IOBuffer>> bufs;
168 for (auto buffer_length : buffer_lengths)
169 bufs.push_back(new IOBuffer(buffer_length));
170
171 std::vector<TestCompletionCallback> callbacks(buffer_lengths.size());
172
173 // Multiple transactions should be able to read with different sized
174 // buffers.
175 for (size_t i = 0; i < transactions_.size(); i++) {
176 rv = writers_->Read(
177 bufs[i].get(), buffer_lengths[i], callbacks[i].callback(),
178 static_cast<HttpCache::Transaction*>(transactions_[i].get()));
179 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous.
jkarlin 2017/07/06 18:50:04 In expect/assert/dcheck/check macros the argument
shivanisha 2017/07/11 02:10:26 done
180 }
181
182 size_t larger = 0;
183 size_t smaller = 1;
184 bool same_length = false;
185 if (buffer_lengths[1] > buffer_lengths[0]) {
186 larger = 1;
187 smaller = 0;
188 // If first buffer is smaller, then the second one will only read the
189 // smaller length as well.
190 same_length = true;
191 }
jkarlin 2017/07/06 18:50:04 How about: std::vector<size_t> expected_lengths =
shivanisha 2017/07/11 02:10:26 Much nicer, thanks.
192
193 for (size_t i = 0; i < callbacks.size(); i++) {
194 rv = callbacks[i].WaitForResult();
195
196 if (same_length) {
197 EXPECT_EQ(rv, buffer_lengths[smaller]);
198 results.at(i).append(bufs[i]->data(), buffer_lengths[smaller]);
199 if (i == 1)
200 EXPECT_EQ(results[larger], results[smaller]);
201 } else {
202 EXPECT_EQ(rv, buffer_lengths[i]);
203 results.at(i).append(bufs[i]->data(), buffer_lengths[i]);
204 if (i == 1) {
205 EXPECT_EQ(results[larger].substr(0, buffer_lengths[smaller]),
206 results[smaller]);
207 }
208 }
209 }
210 }
211
212 int ReadAllDeleteActiveTransaction(std::vector<std::string>* results) {
jkarlin 2017/07/06 18:50:04 Seems like the ReadAllDeleteXTransaction functions
shivanisha 2017/07/11 02:10:26 Done. Happy to remove all the other functions.
213 int rv = 0;
214 bool first_iter = true;
215 do {
216 std::vector<scoped_refptr<IOBuffer>> bufs;
217 std::vector<TestCompletionCallback> callbacks(results->size());
218
219 // Multiple transactions should be able to read.
220 for (size_t i = 0; i < transactions_.size(); i++) {
221 bufs.push_back(new IOBuffer(256));
222 if (!first_iter && i == 0)
223 continue;
224
225 rv = writers_->Read(
226 bufs[i].get(), 256, callbacks[i].callback(),
227 static_cast<HttpCache::Transaction*>(transactions_[i].get()));
228 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous.
229 }
230
231 if (first_iter) {
232 // Delete active transaction.
233 RemoveFirstTransaction();
234 }
235 int prev_rv = callbacks[1].WaitForResult();
236 rv = prev_rv;
237 for (size_t i = 2; i < callbacks.size(); i++) {
jkarlin 2017/07/06 18:50:04 This really requires at least 3 transactions, can
shivanisha 2017/07/11 02:10:26 done
238 rv = callbacks[i].WaitForResult();
239 EXPECT_EQ(rv, prev_rv);
240 prev_rv = rv;
241 }
242
243 if (rv > 0) {
244 for (size_t i = 0; i < results->size(); i++)
245 results->at(i).append(bufs[i]->data(), rv);
246 }
247 first_iter = false;
248 } while (rv > 0);
249
250 return rv;
251 }
252
253 int ReadAllDeleteWaitingTransaction(size_t waiting_index,
254 std::vector<std::string>* results) {
255 int rv = 0;
256 bool first_iter = true;
257 do {
258 std::vector<scoped_refptr<IOBuffer>> bufs;
259 std::vector<TestCompletionCallback> callbacks(results->size());
260
261 // Multiple transactions should be able to read.
262 for (size_t i = 0; i < transactions_.size(); i++) {
263 bufs.push_back(new IOBuffer(256));
264 if (!first_iter && i == waiting_index)
265 continue;
266
267 rv = writers_->Read(
268 bufs[i].get(), 256, callbacks[i].callback(),
269 static_cast<HttpCache::Transaction*>(transactions_[i].get()));
270 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous.
271 }
272
273 if (first_iter) {
274 // Delete waiting transaction.
275 writers_->RemoveTransaction(static_cast<HttpCache::Transaction*>(
276 transactions_.at(waiting_index).get()));
277 }
278 int prev_rv = callbacks[0].WaitForResult();
279 rv = prev_rv;
280 for (size_t i = 1; i < callbacks.size(); i++) {
281 if (i == waiting_index)
282 continue;
283 rv = callbacks[i].WaitForResult();
284 EXPECT_EQ(rv, prev_rv);
285 prev_rv = rv;
286 }
287
288 if (rv > 0) {
289 for (size_t i = 0; i < results->size(); i++) {
290 if (i == waiting_index)
291 continue;
292 results->at(i).append(bufs[i]->data(), rv);
293 }
294 }
295 first_iter = false;
296 } while (rv > 0);
297
298 return rv;
299 }
300
301 int ReadAllDeleteIdleTransaction(size_t idle_index,
302 std::vector<std::string>* results) {
303 int rv = 0;
304 bool first_iter = true;
305 do {
306 std::vector<scoped_refptr<IOBuffer>> bufs;
307 std::vector<TestCompletionCallback> callbacks(results->size());
308
309 // Multiple transactions should be able to read.
310 for (size_t i = 0; i < transactions_.size(); i++) {
311 bufs.push_back(new IOBuffer(256));
312 if (i == idle_index)
313 continue;
314
315 rv = writers_->Read(
316 bufs[i].get(), 256, callbacks[i].callback(),
317 static_cast<HttpCache::Transaction*>(transactions_[i].get()));
318 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous.
319 }
320
321 if (first_iter) {
322 // Delete idle transaction.
323 writers_->RemoveTransaction(static_cast<HttpCache::Transaction*>(
324 transactions_.at(idle_index).get()));
325 }
326 int prev_rv = callbacks[0].WaitForResult();
327 rv = prev_rv;
328 for (size_t i = 1; i < callbacks.size(); i++) {
329 if (i == idle_index)
330 continue;
331 rv = callbacks[i].WaitForResult();
332 EXPECT_EQ(rv, prev_rv);
333 prev_rv = rv;
334 }
335
336 if (rv > 0) {
337 for (size_t i = 0; i < results->size(); i++) {
338 if (i == idle_index)
339 continue;
340 results->at(i).append(bufs[i]->data(), rv);
341 }
342 }
343 first_iter = false;
344 } while (rv > 0);
345
346 return rv;
347 }
348
349 int ReadCacheWriteFailure(std::vector<std::string>* results) {
350 int rv = 0;
351 int active_transaction_rv = 0;
352 bool first_iter = true;
353 do {
354 std::vector<scoped_refptr<IOBuffer>> bufs;
355 std::vector<TestCompletionCallback> callbacks(results->size());
356
357 // Fail the request.
358 cache_.disk_cache()->set_soft_failures(true);
359
360 // We have to open the entry again to propagate the failure flag.
361 disk_cache::Entry* en;
362 cache_.OpenBackendEntry(kSimpleGET_Transaction.url, &en);
363 en->Close();
364
365 for (size_t i = 0; i < transactions_.size(); i++) {
366 bufs.push_back(new IOBuffer(30));
367
368 if (!first_iter && i > 0)
369 break;
370 rv = writers_->Read(
371 bufs[i].get(), 30, callbacks[i].callback(),
372 static_cast<HttpCache::Transaction*>(transactions_[i].get()));
373 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous.
374 }
375
376 for (size_t i = 0; i < callbacks.size(); i++) {
377 // Only active transaction should succeed.
378 if (i == 0) {
379 active_transaction_rv = callbacks[i].WaitForResult();
380 EXPECT_TRUE(active_transaction_rv >= 0);
381 results->at(0).append(bufs[i]->data(), active_transaction_rv);
382 } else if (first_iter) {
383 rv = callbacks[i].WaitForResult();
384 EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, rv);
385 }
386 }
387
388 first_iter = false;
389 } while (active_transaction_rv > 0);
390
391 return active_transaction_rv;
392 }
393
394 int ReadNetworkFailure(std::vector<std::string>* results, Error error) {
395 int rv = 0;
396 std::vector<scoped_refptr<IOBuffer>> bufs;
397 std::vector<TestCompletionCallback> callbacks(results->size());
398
399 for (size_t i = 0; i < transactions_.size(); i++) {
400 bufs.push_back(new IOBuffer(30));
401
402 rv = writers_->Read(
403 bufs[i].get(), 30, callbacks[i].callback(),
404 static_cast<HttpCache::Transaction*>(transactions_[i].get()));
405 EXPECT_EQ(rv, ERR_IO_PENDING); // Since the default is asynchronous.
406 }
407
408 for (auto& callback : callbacks) {
409 rv = callback.WaitForResult();
410 EXPECT_EQ(error, rv);
411 }
412
413 return error;
414 }
415
416 bool StopCaching() {
417 HttpCache::Transaction* transaction =
418 static_cast<HttpCache::Transaction*>(transactions_.begin()->get());
419 EXPECT_TRUE(transaction);
420 return writers_->StopCaching(transaction);
421 }
422
423 void RemoveFirstTransaction() {
424 HttpCache::Transaction* transaction =
425 static_cast<HttpCache::Transaction*>(transactions_.begin()->get());
426 EXPECT_TRUE(transaction);
427 writers_->RemoveTransaction(transaction);
428 }
429
430 void UpdateAndVerifyPriority(RequestPriority priority) {
431 writers_->UpdatePriority();
432 EXPECT_EQ(writers_->priority_, priority);
433 }
434
435 MockHttpCache cache_;
436 std::unique_ptr<HttpCache::Writers> writers_;
437 disk_cache::Entry* disk_entry_;
438
439 // Should be before transactions_ since it is accessed in the network
440 // transaction's destructor.
441 MockHttpRequest request_;
442
443 std::vector<std::unique_ptr<HttpTransaction>> transactions_;
444 };
445
446 // Tests successful addition of a transaction.
447 TEST_F(WritersTest, AddTransaction) {
448 CreateWritersAddTransaction();
449 EXPECT_FALSE(writers_->IsEmpty());
450 }
451
452 // Tests successful addition of multiple transaction.
jkarlin 2017/07/06 18:50:04 s/transaction/transactions/
shivanisha 2017/07/11 02:10:26 done
453 TEST_F(WritersTest, AddManyTransactions) {
454 CreateWritersAddTransaction();
455 EXPECT_FALSE(writers_->IsEmpty());
456
457 for (int i = 0; i < 5; i++)
458 AddTransactionToExistingWriters();
459
460 EXPECT_EQ(writers_->CountTransactionsForTesting(), 6);
461 }
462
463 // Tests that CanAddWriters should return false if it is exclusive writing.
jkarlin 2017/07/06 18:50:04 s/exclusive writing/writing exclusively/
shivanisha 2017/07/11 02:10:26 done
464 TEST_F(WritersTest, AddTransactionsExclusive) {
465 CreateWritersAddTransaction(true /* is_exclusive */);
466 EXPECT_FALSE(writers_->IsEmpty());
467
468 EXPECT_FALSE(writers_->CanAddWriters());
469 }
470
471 // Tests StopCaching should not stop caching if there are multiple writers.
472 TEST_F(WritersTest, StopCachingMultipleWriters) {
473 CreateWritersAddTransaction();
474 EXPECT_FALSE(writers_->IsEmpty());
475
476 EXPECT_TRUE(writers_->CanAddWriters());
477 AddTransactionToExistingWriters();
478
479 EXPECT_FALSE(StopCaching());
480 EXPECT_TRUE(writers_->CanAddWriters());
481 }
482
483 // Tests StopCaching should stop caching if there is a single writer.
484 TEST_F(WritersTest, StopCaching) {
485 CreateWritersAddTransaction();
486 EXPECT_FALSE(writers_->IsEmpty());
487
488 EXPECT_TRUE(StopCaching());
489 EXPECT_FALSE(writers_->CanAddWriters());
490 }
491
492 // Tests removing of an idle transaction and change in priority.
493 TEST_F(WritersTest, RemoveIdleTransaction) {
494 CreateWritersAddTransactionPriority(HIGHEST);
495 UpdateAndVerifyPriority(HIGHEST);
496
497 AddTransactionToExistingWriters();
498 UpdateAndVerifyPriority(HIGHEST);
499
500 EXPECT_FALSE(writers_->IsEmpty());
501 EXPECT_EQ(2, writers_->CountTransactionsForTesting());
502
503 RemoveFirstTransaction();
504 EXPECT_EQ(1, writers_->CountTransactionsForTesting());
505
506 UpdateAndVerifyPriority(DEFAULT_PRIORITY);
507 }
508
509 // Tests that Read is successful.
510 TEST_F(WritersTest, Read) {
511 CreateWritersAddTransaction();
512 EXPECT_FALSE(writers_->IsEmpty());
513
514 std::string content;
515 int rv = Read(&content);
516
517 EXPECT_THAT(rv, IsOk());
518 std::string expected(kSimpleGET_Transaction.data);
519 EXPECT_EQ(expected, content);
520 }
521
522 // Tests that multiple transactions can read the same data simultaneously.
523 TEST_F(WritersTest, ReadMultiple) {
524 CreateWritersAddTransaction();
525 EXPECT_FALSE(writers_->IsEmpty());
526
527 EXPECT_TRUE(writers_->CanAddWriters());
528 AddTransactionToExistingWriters();
529
530 std::vector<std::string> contents(2);
531 int rv = ReadAll(&contents);
532
533 EXPECT_THAT(rv, IsOk());
534 std::string expected(kSimpleGET_Transaction.data);
535
536 for (auto content : contents)
537 EXPECT_EQ(expected, content);
538 }
539
540 // Tests that multiple transactions can read the same data simultaneously.
541 TEST_F(WritersTest, ReadMultipleDifferentBufferSizes) {
542 CreateWritersAddTransaction();
543 EXPECT_FALSE(writers_->IsEmpty());
544
545 EXPECT_TRUE(writers_->CanAddWriters());
546 AddTransactionToExistingWriters();
547
548 std::vector<int> buffer_lengths;
jkarlin 2017/07/06 18:50:04 std::vector<int> buffer_lengths {20, 10};
shivanisha 2017/07/11 02:10:26 done
549 buffer_lengths.push_back(20);
550 buffer_lengths.push_back(10);
551 ReadVerifyTwoDifferentBufferLengths(buffer_lengths);
552 }
553
554 // Same as above but tests the first transaction having smaller buffer size
555 // than the next.
556 TEST_F(WritersTest, ReadMultipleDifferentBufferSizes1) {
557 CreateWritersAddTransaction();
558 EXPECT_FALSE(writers_->IsEmpty());
559
560 EXPECT_TRUE(writers_->CanAddWriters());
561 AddTransactionToExistingWriters();
562
563 std::vector<int> buffer_lengths;
jkarlin 2017/07/06 18:50:04 std::vector<int> buffer_lengths {10, 20};
shivanisha 2017/07/11 02:10:26 done
564 buffer_lengths.push_back(10);
565 buffer_lengths.push_back(20);
566 ReadVerifyTwoDifferentBufferLengths(buffer_lengths);
567 }
568
569 // Tests that ongoing Read completes even when active transaction is deleted
570 // mid-read. Any transactions waiting should be able to get the read buffer.
571 TEST_F(WritersTest, ReadMultipleDeleteActiveTransaction) {
572 CreateWritersAddTransaction();
573 EXPECT_FALSE(writers_->IsEmpty());
574
575 EXPECT_TRUE(writers_->CanAddWriters());
576 AddTransactionToExistingWriters();
577 AddTransactionToExistingWriters();
578
579 std::vector<std::string> contents(3);
580 int rv = ReadAllDeleteActiveTransaction(&contents);
581
582 EXPECT_THAT(rv, IsOk());
583 std::string expected(kSimpleGET_Transaction.data);
584
585 for (auto content : contents)
586 EXPECT_EQ(expected, content);
587 }
588
589 // Tests that removing a waiting for read transaction does not impact other
590 // transactions.
591 TEST_F(WritersTest, ReadMultipleDeleteWaitingTransaction) {
592 CreateWritersAddTransaction();
593 EXPECT_FALSE(writers_->IsEmpty());
594
595 EXPECT_TRUE(writers_->CanAddWriters());
596 AddTransactionToExistingWriters();
597 AddTransactionToExistingWriters();
598 AddTransactionToExistingWriters();
599
600 std::vector<std::string> contents(4);
601 size_t waiting_index = 1;
602 int rv = ReadAllDeleteWaitingTransaction(waiting_index, &contents);
603
604 EXPECT_THAT(rv, IsOk());
605 std::string expected(kSimpleGET_Transaction.data);
606
607 size_t i = 0;
608 for (auto content : contents) {
609 if (i == waiting_index)
610 EXPECT_EQ("", content);
611 else
612 EXPECT_EQ(expected, content);
613 i++;
614 }
615 }
616
617 // Tests that removing an idle transaction does not impact other transactions.
618 TEST_F(WritersTest, ReadMultipleDeleteIdleTransaction) {
619 CreateWritersAddTransaction();
620 EXPECT_FALSE(writers_->IsEmpty());
621
622 EXPECT_TRUE(writers_->CanAddWriters());
623 AddTransactionToExistingWriters();
624 AddTransactionToExistingWriters();
625
626 std::vector<std::string> contents(3);
627 size_t idle_index = 1;
628 int rv = ReadAllDeleteIdleTransaction(idle_index, &contents);
629
630 EXPECT_THAT(rv, IsOk());
631 std::string expected(kSimpleGET_Transaction.data);
632
633 size_t i = 0;
634 for (auto content : contents) {
635 if (i == idle_index) {
636 i++;
637 continue;
638 }
639 EXPECT_EQ(expected, content);
640 i++;
641 }
642 }
643
644 // Tests cache write failure.
645 TEST_F(WritersTest, ReadMultipleCacheWriteFailed) {
646 CreateWritersAddTransaction();
647 EXPECT_FALSE(writers_->IsEmpty());
648
649 EXPECT_TRUE(writers_->CanAddWriters());
650 AddTransactionToExistingWriters();
651 AddTransactionToExistingWriters();
652
653 std::vector<std::string> contents(3);
654 int rv = ReadCacheWriteFailure(&contents);
655
656 EXPECT_THAT(rv, IsOk());
657 std::string expected(kSimpleGET_Transaction.data);
658
659 // Only active_transaction_ should succeed.
660 EXPECT_EQ(expected, contents.at(0));
661
662 // No new transactions should now be added.
663 EXPECT_FALSE(writers_->CanAddWriters());
664 }
665
666 // Tests that network read failure fails all transactions: active, waiting and
667 // idle.
668 TEST_F(WritersTest, ReadMultipleNetworkReadFailed) {
669 ScopedMockTransaction transaction(kSimpleGET_Transaction);
670 transaction.read_return_code = ERR_INTERNET_DISCONNECTED;
671 MockHttpRequest request(transaction);
672 request_ = request;
673
674 CreateWritersAddTransaction();
675 EXPECT_FALSE(writers_->IsEmpty());
676
677 EXPECT_TRUE(writers_->CanAddWriters());
678 AddTransactionToExistingWriters();
679 AddTransactionToExistingWriters();
680
681 std::vector<std::string> contents(3);
682 int rv = ReadNetworkFailure(&contents, ERR_INTERNET_DISCONNECTED);
683
684 EXPECT_EQ(rv, ERR_INTERNET_DISCONNECTED);
685 }
686
687 // Tests moving idle writers to readers.
688 TEST_F(WritersTest, MoveIdleWritersToReaders) {
689 CreateWritersAddTransaction();
690 EXPECT_FALSE(writers_->IsEmpty());
691
692 EXPECT_TRUE(writers_->CanAddWriters());
693 AddTransactionToExistingWriters();
694 AddTransactionToExistingWriters();
695
696 EXPECT_FALSE(writers_->IsEmpty());
697 writers_->RemoveAllIdleWriters();
698 EXPECT_TRUE(writers_->IsEmpty());
699 }
700
701 // Tests GetWriterLoadState.
702 TEST_F(WritersTest, GetWriterLoadState) {
703 CreateWritersAddTransaction();
704 EXPECT_FALSE(writers_->IsEmpty());
705
706 EXPECT_EQ(LOAD_STATE_IDLE, writers_->GetWriterLoadState());
707 }
708
709 // Tests truncating the entry via Writers.
710 TEST_F(WritersTest, TruncateEntry) {
711 CreateWritersAddTransaction();
712 EXPECT_FALSE(writers_->IsEmpty());
713
714 std::string content;
715 int rv = Read(&content);
716
717 EXPECT_THAT(rv, IsOk());
718 std::string expected(kSimpleGET_Transaction.data);
719 EXPECT_EQ(expected, content);
720
721 writers_->TruncateEntry();
722 base::RunLoop().RunUntilIdle();
723 EXPECT_TRUE(writers_->IsTruncatedForTesting());
724 }
725
726 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698