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