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(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 | |
OLD | NEW |