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

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

Issue 2721933002: HttpCache::Transaction layer allowing parallel validation (Closed)
Patch Set: Convert DCHECK -> CHECK for important invariants. Created 3 years, 7 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_cache.h" 5 #include "net/http/http_cache.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory> 10 #include <memory>
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 // same value. 140 // same value.
141 EXPECT_FALSE(load_timing_info.send_start.is_null()); 141 EXPECT_FALSE(load_timing_info.send_start.is_null());
142 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end); 142 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
143 143
144 // Set by URLRequest / URLRequestHttpJob, at a higher level. 144 // Set by URLRequest / URLRequestHttpJob, at a higher level.
145 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 145 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
146 EXPECT_TRUE(load_timing_info.request_start.is_null()); 146 EXPECT_TRUE(load_timing_info.request_start.is_null());
147 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 147 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
148 } 148 }
149 149
150 void DeferNetworkStart(bool* defer) {
151 *defer = true;
152 }
153
150 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { 154 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
151 public: 155 public:
152 explicit DeleteCacheCompletionCallback(MockHttpCache* cache) 156 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
153 : cache_(cache), 157 : cache_(cache),
154 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete, 158 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
155 base::Unretained(this))) { 159 base::Unretained(this))) {
156 } 160 }
157 161
158 const CompletionCallback& callback() const { return callback_; } 162 const CompletionCallback& callback() const { return callback_; }
159 163
(...skipping 15 matching lines...) Expand all
175 void ReadAndVerifyTransaction(HttpTransaction* trans, 179 void ReadAndVerifyTransaction(HttpTransaction* trans,
176 const MockTransaction& trans_info) { 180 const MockTransaction& trans_info) {
177 std::string content; 181 std::string content;
178 int rv = ReadTransaction(trans, &content); 182 int rv = ReadTransaction(trans, &content);
179 183
180 EXPECT_THAT(rv, IsOk()); 184 EXPECT_THAT(rv, IsOk());
181 std::string expected(trans_info.data); 185 std::string expected(trans_info.data);
182 EXPECT_EQ(expected, content); 186 EXPECT_EQ(expected, content);
183 } 187 }
184 188
189 void ReadRemainingAndVerifyTransaction(HttpTransaction* trans,
190 std::string& already_read,
191 const MockTransaction& trans_info) {
192 std::string content;
193 int rv = ReadTransaction(trans, &content);
194 EXPECT_THAT(rv, IsOk());
195
196 std::string expected(trans_info.data);
197 EXPECT_EQ(expected, already_read + content);
198 }
199
185 void RunTransactionTestBase(HttpCache* cache, 200 void RunTransactionTestBase(HttpCache* cache,
186 const MockTransaction& trans_info, 201 const MockTransaction& trans_info,
187 const MockHttpRequest& request, 202 const MockHttpRequest& request,
188 HttpResponseInfo* response_info, 203 HttpResponseInfo* response_info,
189 const NetLogWithSource& net_log, 204 const NetLogWithSource& net_log,
190 LoadTimingInfo* load_timing_info, 205 LoadTimingInfo* load_timing_info,
191 int64_t* sent_bytes, 206 int64_t* sent_bytes,
192 int64_t* received_bytes, 207 int64_t* received_bytes,
193 IPEndPoint* remote_endpoint) { 208 IPEndPoint* remote_endpoint) {
194 TestCompletionCallback callback; 209 TestCompletionCallback callback;
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1358 EXPECT_EQ(1, cache.disk_cache()->open_count());
1344 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1359 EXPECT_EQ(1, cache.disk_cache()->create_count());
1345 RemoveMockTransaction(&transaction); 1360 RemoveMockTransaction(&transaction);
1346 } 1361 }
1347 1362
1348 TEST(HttpCache, SimpleGET_ManyReaders) { 1363 TEST(HttpCache, SimpleGET_ManyReaders) {
1349 MockHttpCache cache; 1364 MockHttpCache cache;
1350 1365
1351 MockHttpRequest request(kSimpleGET_Transaction); 1366 MockHttpRequest request(kSimpleGET_Transaction);
1352 1367
1353 std::vector<Context*> context_list; 1368 std::vector<std::unique_ptr<Context>> context_list;
1354 const int kNumTransactions = 5; 1369 const int kNumTransactions = 5;
1355 1370
1356 for (int i = 0; i < kNumTransactions; ++i) { 1371 for (int i = 0; i < kNumTransactions; ++i) {
1357 context_list.push_back(new Context()); 1372 context_list.push_back(base::MakeUnique<Context>());
1358 Context* c = context_list[i]; 1373 auto& c = context_list[i];
1359 1374
1360 c->result = cache.CreateTransaction(&c->trans); 1375 c->result = cache.CreateTransaction(&c->trans);
1361 ASSERT_THAT(c->result, IsOk()); 1376 ASSERT_THAT(c->result, IsOk());
1362 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); 1377 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1363 1378
1364 c->result = 1379 c->result =
1365 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 1380 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1366 } 1381 }
1367 1382
1368 // All requests are waiting for the active entry. 1383 // All requests are waiting for the active entry.
1369 for (int i = 0; i < kNumTransactions; ++i) { 1384 for (auto& context : context_list) {
1370 Context* c = context_list[i]; 1385 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1371 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1372 } 1386 }
1373 1387
1374 // Allow all requests to move from the Create queue to the active entry. 1388 // Allow all requests to move from the Create queue to the active entry.
1375 base::RunLoop().RunUntilIdle(); 1389 base::RunLoop().RunUntilIdle();
1376 1390
1377 // The first request should be a writer at this point, and the subsequent 1391 // The first request should be a writer at this point, and the subsequent
1378 // requests should be pending. 1392 // requests should have passed the validation phase and waiting for the
1393 // response to be written to the cache before they can read.
1394 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1395 EXPECT_EQ(kNumTransactions - 1,
1396 cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1379 1397
1380 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1398 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1381 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1399 EXPECT_EQ(0, cache.disk_cache()->open_count());
1382 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1400 EXPECT_EQ(1, cache.disk_cache()->create_count());
1383 1401
1384 // All requests depend on the writer, and the writer is between Start and 1402 // All requests depend on the writer, and the writer is between Start and
1385 // Read, i.e. idle. 1403 // Read, i.e. idle.
1386 for (int i = 0; i < kNumTransactions; ++i) { 1404 for (auto& context : context_list) {
1387 Context* c = context_list[i]; 1405 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1388 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); 1406 }
1389 } 1407
1390 1408 for (int i = 0; i < kNumTransactions; ++i) {
1391 for (int i = 0; i < kNumTransactions; ++i) { 1409 auto& c = context_list[i];
1392 Context* c = context_list[i];
1393 if (c->result == ERR_IO_PENDING) 1410 if (c->result == ERR_IO_PENDING)
1394 c->result = c->callback.WaitForResult(); 1411 c->result = c->callback.WaitForResult();
1412
1413 if (i > 0) {
1414 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1415 EXPECT_EQ(kNumTransactions - i,
1416 cache.GetCountReaders(kSimpleGET_Transaction.url));
1417 }
1418
1395 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1419 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1396 } 1420 }
1397 1421
1398 // We should not have had to re-open the disk entry 1422 // We should not have had to re-open the disk entry
1399 1423
1400 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1424 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1401 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1425 EXPECT_EQ(0, cache.disk_cache()->open_count());
1402 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1426 EXPECT_EQ(1, cache.disk_cache()->create_count());
1403 1427 }
1404 for (int i = 0; i < kNumTransactions; ++i) { 1428
1405 Context* c = context_list[i]; 1429 // Tests that we can have parallel validation on range requests.
1406 delete c; 1430 TEST(HttpCache, RangeGET_ParallelValidationNoMatch) {
1407 } 1431 MockHttpCache cache;
1432
1433 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1434 MockHttpRequest request(transaction);
1435
1436 std::vector<std::unique_ptr<Context>> context_list;
1437 const int kNumTransactions = 5;
1438
1439 for (int i = 0; i < kNumTransactions; ++i) {
1440 context_list.push_back(base::MakeUnique<Context>());
1441 auto& c = context_list[i];
1442
1443 c->result = cache.CreateTransaction(&c->trans);
1444 ASSERT_THAT(c->result, IsOk());
1445 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1446
1447 c->result =
1448 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1449 }
1450
1451 // All requests are waiting for the active entry.
1452 for (auto& context : context_list) {
1453 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1454 }
1455
1456 // Allow all requests to move from the Create queue to the active entry.
1457 base::RunLoop().RunUntilIdle();
1458
1459 // The first entry should have been doomed. Since the 1st transaction has not
1460 // started writing to the cache, MockDiskEntry::CouldBeSparse() returns false
1461 // leading to restarting the dooming the entry and restarting the second
1462 // transaction.
1463 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1464 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1465
1466 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1467 EXPECT_EQ(0, cache.disk_cache()->open_count());
1468 EXPECT_EQ(5, cache.disk_cache()->create_count());
1469
1470 for (auto& context : context_list) {
1471 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1472 }
1473
1474 for (int i = 0; i < kNumTransactions; ++i) {
1475 auto& c = context_list[i];
1476 if (c->result == ERR_IO_PENDING)
1477 c->result = c->callback.WaitForResult();
1478
1479 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
1480 }
1481
1482 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1483 EXPECT_EQ(0, cache.disk_cache()->open_count());
1484 EXPECT_EQ(5, cache.disk_cache()->create_count());
1485 }
1486
1487 // Tests parallel validation on range requests with non-overlapping ranges.
1488 TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) {
1489 MockHttpCache cache;
1490
1491 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1492
1493 std::vector<std::unique_ptr<Context>> context_list;
1494 const int kNumTransactions = 2;
1495
1496 for (int i = 0; i < kNumTransactions; ++i) {
1497 context_list.push_back(base::MakeUnique<Context>());
1498 }
1499
1500 // Let 1st transaction complete headers phase for ranges 40-49.
1501 std::string first_read;
1502 {
1503 MockHttpRequest request(transaction);
1504 auto& c = context_list[0];
1505 c->result = cache.CreateTransaction(&c->trans);
1506 ASSERT_THAT(c->result, IsOk());
1507 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1508
1509 c->result =
1510 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1511 base::RunLoop().RunUntilIdle();
1512
1513 // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
1514 // true.
1515 const int kBufferSize = 5;
1516 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
1517 ReleaseBufferCompletionCallback cb(buffer.get());
1518 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
1519 EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
1520
1521 std::string data_read(buffer->data(), kBufferSize);
1522 first_read = data_read;
1523
1524 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
1525 }
1526
1527 // 2nd transaction requests ranges 30-39.
1528 {
1529 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
1530 MockHttpRequest request(transaction);
1531 auto& c = context_list[1];
1532 c->result = cache.CreateTransaction(&c->trans);
1533 ASSERT_THAT(c->result, IsOk());
1534 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1535
1536 c->result =
1537 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1538 base::RunLoop().RunUntilIdle();
1539
1540 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1541 }
1542
1543 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1544 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1545
1546 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1547 EXPECT_EQ(0, cache.disk_cache()->open_count());
1548 EXPECT_EQ(1, cache.disk_cache()->create_count());
1549
1550 for (int i = 0; i < kNumTransactions; ++i) {
1551 auto& c = context_list[i];
1552 if (c->result == ERR_IO_PENDING)
1553 c->result = c->callback.WaitForResult();
1554
1555 if (i == 0) {
1556 ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
1557 transaction);
1558 continue;
1559 }
1560
1561 transaction.data = "rg: 30-39 ";
1562 ReadAndVerifyTransaction(c->trans.get(), transaction);
1563 }
1564
1565 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1566 EXPECT_EQ(0, cache.disk_cache()->open_count());
1567 EXPECT_EQ(1, cache.disk_cache()->create_count());
1568
1569 // Fetch from the cache to check that ranges 30-49 have been successfully
1570 // cached.
1571 {
1572 MockTransaction transaction(kRangeGET_TransactionOK);
1573 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1574 transaction.data = "rg: 30-39 rg: 40-49 ";
1575 std::string headers;
1576 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
1577 Verify206Response(headers, 30, 49);
1578 }
1579
1580 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1581 EXPECT_EQ(1, cache.disk_cache()->open_count());
1582 EXPECT_EQ(1, cache.disk_cache()->create_count());
1583 }
1584
1585 // Tests parallel validation on range requests with overlapping ranges.
1586 TEST(HttpCache, RangeGET_ParallelValidationOverlappingRanges) {
1587 MockHttpCache cache;
1588
1589 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1590
1591 std::vector<std::unique_ptr<Context>> context_list;
1592 const int kNumTransactions = 2;
1593
1594 for (int i = 0; i < kNumTransactions; ++i) {
1595 context_list.push_back(base::MakeUnique<Context>());
1596 }
1597
1598 // Let 1st transaction complete headers phase for ranges 40-49.
1599 std::string first_read;
1600 {
1601 MockHttpRequest request(transaction);
1602 auto& c = context_list[0];
1603 c->result = cache.CreateTransaction(&c->trans);
1604 ASSERT_THAT(c->result, IsOk());
1605 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1606
1607 c->result =
1608 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1609 base::RunLoop().RunUntilIdle();
1610
1611 // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
1612 // true.
1613 const int kBufferSize = 5;
1614 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
1615 ReleaseBufferCompletionCallback cb(buffer.get());
1616 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
1617 EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
1618
1619 std::string data_read(buffer->data(), kBufferSize);
1620 first_read = data_read;
1621
1622 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
1623 }
1624
1625 // 2nd transaction requests ranges 30-49.
1626 {
1627 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1628 MockHttpRequest request(transaction);
1629 auto& c = context_list[1];
1630 c->result = cache.CreateTransaction(&c->trans);
1631 ASSERT_THAT(c->result, IsOk());
1632 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1633
1634 c->result =
1635 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1636 base::RunLoop().RunUntilIdle();
1637
1638 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1639 }
1640
1641 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1642 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1643
1644 // Should have created another transaction for the uncached range.
1645 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1646 EXPECT_EQ(0, cache.disk_cache()->open_count());
1647 EXPECT_EQ(1, cache.disk_cache()->create_count());
1648
1649 for (int i = 0; i < kNumTransactions; ++i) {
1650 auto& c = context_list[i];
1651 if (c->result == ERR_IO_PENDING)
1652 c->result = c->callback.WaitForResult();
1653
1654 if (i == 0) {
1655 ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
1656 transaction);
1657 continue;
1658 }
1659
1660 transaction.data = "rg: 30-39 rg: 40-49 ";
1661 ReadAndVerifyTransaction(c->trans.get(), transaction);
1662 }
1663
1664 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1665 EXPECT_EQ(0, cache.disk_cache()->open_count());
1666 EXPECT_EQ(1, cache.disk_cache()->create_count());
1667
1668 // Fetch from the cache to check that ranges 30-49 have been successfully
1669 // cached.
1670 {
1671 MockTransaction transaction(kRangeGET_TransactionOK);
1672 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1673 transaction.data = "rg: 30-39 rg: 40-49 ";
1674 std::string headers;
1675 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
1676 Verify206Response(headers, 30, 49);
1677 }
1678
1679 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1680 EXPECT_EQ(0, cache.disk_cache()->open_count());
1681 EXPECT_EQ(1, cache.disk_cache()->create_count());
1682 }
1683
1684 // Tests that a GET followed by a DELETE results in DELETE immediately starting
1685 // the headers phase and the entry is doomed.
1686 TEST(HttpCache, SimpleGET_ParallelValidationDelete) {
1687 MockHttpCache cache;
1688
1689 MockHttpRequest request(kSimpleGET_Transaction);
1690 request.load_flags |= LOAD_VALIDATE_CACHE;
1691
1692 MockHttpRequest delete_request(kSimpleGET_Transaction);
1693 delete_request.method = "DELETE";
1694
1695 std::vector<std::unique_ptr<Context>> context_list;
1696 const int kNumTransactions = 2;
1697
1698 for (int i = 0; i < kNumTransactions; ++i) {
1699 context_list.push_back(base::MakeUnique<Context>());
1700 auto& c = context_list[i];
1701
1702 MockHttpRequest* this_request = &request;
1703 if (i == 1)
1704 this_request = &delete_request;
1705
1706 c->result = cache.CreateTransaction(&c->trans);
1707 ASSERT_THAT(c->result, IsOk());
1708 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1709
1710 c->result = c->trans->Start(this_request, c->callback.callback(),
1711 NetLogWithSource());
1712 }
1713
1714 // All requests are waiting for the active entry.
1715 for (auto& context : context_list) {
1716 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1717 }
1718
1719 // Allow all requests to move from the Create queue to the active entry.
1720 base::RunLoop().RunUntilIdle();
1721
1722 // The first request should be a writer at this point, and the subsequent
1723 // request should have passed the validation phase and doomed the existing
1724 // entry.
1725 EXPECT_TRUE(
1726 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
1727
1728 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1729 EXPECT_EQ(0, cache.disk_cache()->open_count());
1730 EXPECT_EQ(1, cache.disk_cache()->create_count());
1731
1732 // All requests depend on the writer, and the writer is between Start and
1733 // Read, i.e. idle.
1734 for (auto& context : context_list) {
1735 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1736 }
1737
1738 for (auto& context : context_list) {
1739 if (context->result == ERR_IO_PENDING)
1740 context->result = context->callback.WaitForResult();
1741 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1742 }
1743
1744 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1745 EXPECT_EQ(0, cache.disk_cache()->open_count());
1746 EXPECT_EQ(1, cache.disk_cache()->create_count());
1747 }
1748
1749 // Tests that a transaction which is in validated queue can be destroyed without
1750 // any impact to other transactions.
1751 TEST(HttpCache, SimpleGET_ParallelValidationCancelValidated) {
1752 MockHttpCache cache;
1753
1754 MockHttpRequest request(kSimpleGET_Transaction);
1755
1756 std::vector<std::unique_ptr<Context>> context_list;
1757 const int kNumTransactions = 2;
1758
1759 for (int i = 0; i < kNumTransactions; ++i) {
1760 context_list.push_back(base::MakeUnique<Context>());
1761 auto& c = context_list[i];
1762
1763 c->result = cache.CreateTransaction(&c->trans);
1764 ASSERT_THAT(c->result, IsOk());
1765
1766 c->result =
1767 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1768 }
1769
1770 // Allow all requests to move from the Create queue to the active entry.
1771 base::RunLoop().RunUntilIdle();
1772
1773 // The first request should be a writer at this point, and the subsequent
1774 // requests should have completed validation.
1775
1776 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1777 EXPECT_EQ(0, cache.disk_cache()->open_count());
1778 EXPECT_EQ(1, cache.disk_cache()->create_count());
1779
1780 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1781 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1782
1783 context_list[1].reset();
1784
1785 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1786
1787 // Complete the rest of the transactions.
1788 for (auto& context : context_list) {
1789 if (!context)
1790 continue;
1791 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1792 }
1793
1794 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1795 EXPECT_EQ(0, cache.disk_cache()->open_count());
1796 EXPECT_EQ(1, cache.disk_cache()->create_count());
1797 }
1798
1799 // Tests that a transaction which is in readers can be destroyed without
1800 // any impact to other transactions.
1801 TEST(HttpCache, SimpleGET_ParallelValidationCancelReader) {
1802 MockHttpCache cache;
1803
1804 MockHttpRequest request(kSimpleGET_Transaction);
1805
1806 MockTransaction transaction(kSimpleGET_Transaction);
1807 transaction.load_flags |= LOAD_VALIDATE_CACHE;
1808 MockHttpRequest validate_request(transaction);
1809
1810 int kNumTransactions = 4;
1811 std::vector<std::unique_ptr<Context>> context_list;
1812
1813 for (int i = 0; i < kNumTransactions; ++i) {
1814 context_list.push_back(base::MakeUnique<Context>());
1815 auto& c = context_list[i];
1816
1817 c->result = cache.CreateTransaction(&c->trans);
1818 ASSERT_THAT(c->result, IsOk());
1819
1820 MockHttpRequest* this_request = &request;
1821 if (i == 3) {
1822 this_request = &validate_request;
1823 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
1824 }
1825
1826 c->result = c->trans->Start(this_request, c->callback.callback(),
1827 NetLogWithSource());
1828 }
1829
1830 // Allow all requests to move from the Create queue to the active entry.
1831 base::RunLoop().RunUntilIdle();
1832
1833 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1834 EXPECT_EQ(0, cache.disk_cache()->open_count());
1835 EXPECT_EQ(1, cache.disk_cache()->create_count());
1836
1837 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1838 EXPECT_EQ(2, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1839 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1840
1841 // Complete the response body.
1842 auto& c = context_list[0];
1843 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1844
1845 // Rest of the transactions should move to readers.
1846 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1847 EXPECT_EQ(2, cache.GetCountReaders(kSimpleGET_Transaction.url));
1848 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1849 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1850
1851 // Add 2 new transactions.
1852 kNumTransactions = 6;
1853
1854 for (int i = 4; i < kNumTransactions; ++i) {
1855 context_list.push_back(base::MakeUnique<Context>());
1856 auto& c = context_list[i];
1857
1858 c->result = cache.CreateTransaction(&c->trans);
1859 ASSERT_THAT(c->result, IsOk());
1860
1861 c->result =
1862 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1863 }
1864
1865 EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
1866
1867 // Delete a reader.
1868 context_list[1].reset();
1869
1870 // Deleting the reader did not impact any other transaction.
1871 EXPECT_EQ(1, cache.GetCountReaders(kSimpleGET_Transaction.url));
1872 EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
1873 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1874
1875 // Resume network start for headers_transaction. It will doom the entry as it
1876 // will be a 200 and will go to network for the response body.
1877 auto& context = context_list[3];
1878 context->trans->ResumeNetworkStart();
1879
1880 // The pending transactions will be added to a new entry.
1881 base::RunLoop().RunUntilIdle();
1882
1883 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1884 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1885
1886 // Complete the rest of the transactions.
1887 for (int i = 2; i < kNumTransactions; ++i) {
1888 auto& c = context_list[i];
1889 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1890 }
1891
1892 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1893 EXPECT_EQ(0, cache.disk_cache()->open_count());
1894 EXPECT_EQ(2, cache.disk_cache()->create_count());
1895 }
1896
1897 // Tests that a transaction is in validated queue and writer is destroyed
1898 // leading to restarting the validated transaction.
1899 TEST(HttpCache, SimpleGET_ParallelValidationCancelWriter) {
1900 MockHttpCache cache;
1901
1902 MockHttpRequest request(kSimpleGET_Transaction);
1903
1904 MockTransaction transaction(kSimpleGET_Transaction);
1905 transaction.load_flags |= LOAD_VALIDATE_CACHE;
1906 MockHttpRequest validate_request(transaction);
1907
1908 const int kNumTransactions = 3;
1909 std::vector<std::unique_ptr<Context>> context_list;
1910
1911 for (int i = 0; i < kNumTransactions; ++i) {
1912 context_list.push_back(base::MakeUnique<Context>());
1913 auto& c = context_list[i];
1914
1915 c->result = cache.CreateTransaction(&c->trans);
1916 ASSERT_THAT(c->result, IsOk());
1917
1918 MockHttpRequest* this_request = &request;
1919 if (i == 2) {
1920 this_request = &validate_request;
1921 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
1922 }
1923
1924 c->result = c->trans->Start(this_request, c->callback.callback(),
1925 NetLogWithSource());
1926 }
1927
1928 // Allow all requests to move from the Create queue to the active entry.
1929 base::RunLoop().RunUntilIdle();
1930
1931 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1932 EXPECT_EQ(0, cache.disk_cache()->open_count());
1933 EXPECT_EQ(1, cache.disk_cache()->create_count());
1934
1935 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1936 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1937 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1938
1939 // Deleting the writer at this point will lead to destroying the entry and
1940 // restarting the remaining transactions which will then create a new entry.
1941 context_list[0].reset();
1942
1943 // Resume network start for headers_transaction. It should be restarted due to
1944 // writer cancellation.
1945 auto& c = context_list[2];
1946 c->trans->ResumeNetworkStart();
1947
1948 base::RunLoop().RunUntilIdle();
1949
1950 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1951 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1952
1953 // Resume network start for the transaction the second time.
1954 c->trans->ResumeNetworkStart();
1955 base::RunLoop().RunUntilIdle();
1956
1957 // Headers transaction would have doomed the new entry created.
1958 EXPECT_TRUE(
1959 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
1960
1961 // Complete the rest of the transactions.
1962 for (auto& context : context_list) {
1963 if (!context)
1964 continue;
1965 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1966 }
1967
1968 EXPECT_EQ(4, cache.network_layer()->transaction_count());
1969 EXPECT_EQ(0, cache.disk_cache()->open_count());
1970 EXPECT_EQ(2, cache.disk_cache()->create_count());
1971 }
1972
1973 // Tests that a transaction is currently in headers phase and is destroyed
1974 // leading to destroying the entry.
1975 TEST(HttpCache, SimpleGET_ParallelValidationCancelHeaders) {
1976 MockHttpCache cache;
1977
1978 MockHttpRequest request(kSimpleGET_Transaction);
1979
1980 const int kNumTransactions = 2;
1981 std::vector<std::unique_ptr<Context>> context_list;
1982
1983 for (int i = 0; i < kNumTransactions; ++i) {
1984 context_list.push_back(base::MakeUnique<Context>());
1985 auto& c = context_list[i];
1986
1987 c->result = cache.CreateTransaction(&c->trans);
1988 ASSERT_THAT(c->result, IsOk());
1989
1990 if (i == 0)
1991 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
1992
1993 c->result =
1994 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1995 }
1996
1997 base::RunLoop().RunUntilIdle();
1998
1999 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
2000 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
2001
2002 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2003 EXPECT_EQ(0, cache.disk_cache()->open_count());
2004 EXPECT_EQ(1, cache.disk_cache()->create_count());
2005
2006 // Delete the headers transaction.
2007 context_list[0].reset();
2008
2009 base::RunLoop().RunUntilIdle();
2010
2011 // Complete the rest of the transactions.
2012 for (auto& context : context_list) {
2013 if (!context)
2014 continue;
2015 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
2016 }
2017
2018 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2019 EXPECT_EQ(0, cache.disk_cache()->open_count());
2020 EXPECT_EQ(2, cache.disk_cache()->create_count());
2021 }
2022
2023 // Similar to the above test, except here cache write fails and the
2024 // validated transactions should be restarted.
2025 TEST(HttpCache, SimpleGET_ParallelValidationFailWrite) {
2026 MockHttpCache cache;
2027
2028 MockHttpRequest request(kSimpleGET_Transaction);
2029
2030 const int kNumTransactions = 5;
2031 std::vector<std::unique_ptr<Context>> context_list;
2032
2033 for (int i = 0; i < kNumTransactions; ++i) {
2034 context_list.push_back(base::MakeUnique<Context>());
2035 auto& c = context_list[i];
2036
2037 c->result = cache.CreateTransaction(&c->trans);
2038 ASSERT_THAT(c->result, IsOk());
2039 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2040
2041 c->result =
2042 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2043 }
2044
2045 // All requests are waiting for the active entry.
2046 for (auto& context : context_list) {
2047 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2048 }
2049
2050 // Allow all requests to move from the Create queue to the active entry.
2051 base::RunLoop().RunUntilIdle();
2052
2053 // The first request should be a writer at this point, and the subsequent
2054 // requests should have passed the validation phase and waiting for the
2055 // response to be written to the cache before they can read.
2056 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
2057 EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
2058
2059 // All requests depend on the writer, and the writer is between Start and
2060 // Read, i.e. idle.
2061 for (auto& context : context_list) {
2062 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2063 }
2064
2065 // The first request should be a writer at this point, and the subsequent
2066 // requests should have passed the validation phase and waiting for the
2067 // response to be written to the cache before they can read.
2068
2069 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2070 EXPECT_EQ(0, cache.disk_cache()->open_count());
2071 EXPECT_EQ(1, cache.disk_cache()->create_count());
2072
2073 // Fail the request.
2074 cache.disk_cache()->set_soft_failures(true);
2075 // We have to open the entry again to propagate the failure flag.
2076 disk_cache::Entry* en;
2077 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en);
2078 en->Close();
2079
2080 for (int i = 0; i < kNumTransactions; ++i) {
2081 auto& c = context_list[i];
2082 if (c->result == ERR_IO_PENDING)
2083 c->result = c->callback.WaitForResult();
2084 if (i == 1) {
2085 // The earlier entry must be destroyed and its disk entry doomed.
2086 EXPECT_TRUE(
2087 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
2088 }
2089 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
2090 }
2091
2092 // Since validated transactions were restarted and new entry read/write
2093 // operations would also fail, all requests would have gone to the network.
2094 EXPECT_EQ(5, cache.network_layer()->transaction_count());
2095 EXPECT_EQ(1, cache.disk_cache()->open_count());
2096 EXPECT_EQ(5, cache.disk_cache()->create_count());
1408 } 2097 }
1409 2098
1410 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. 2099 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1411 // If cancelling a request is racing with another request for the same resource 2100 // If cancelling a request is racing with another request for the same resource
1412 // finishing, we have to make sure that we remove both transactions from the 2101 // finishing, we have to make sure that we remove both transactions from the
1413 // entry. 2102 // entry.
1414 TEST(HttpCache, SimpleGET_RacingReaders) { 2103 TEST(HttpCache, SimpleGET_RacingReaders) {
1415 MockHttpCache cache; 2104 MockHttpCache cache;
1416 2105
1417 MockHttpRequest request(kSimpleGET_Transaction); 2106 MockHttpRequest request(kSimpleGET_Transaction);
(...skipping 26 matching lines...) Expand all
1444 2133
1445 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2134 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1446 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2135 EXPECT_EQ(0, cache.disk_cache()->open_count());
1447 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2136 EXPECT_EQ(1, cache.disk_cache()->create_count());
1448 2137
1449 Context* c = context_list[0]; 2138 Context* c = context_list[0];
1450 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2139 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1451 c->result = c->callback.WaitForResult(); 2140 c->result = c->callback.WaitForResult();
1452 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2141 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1453 2142
1454 // Now we have 2 active readers and two queued transactions. 2143 // Now all transactions should be waiting for read to be invoked. Two readers
1455 2144 // are because of the load flags and remaining two transactions were converted
2145 // to readers after skipping validation. Note that the remaining two went on
2146 // to process the headers in parallel with readers present on the entry.
1456 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); 2147 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
1457 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, 2148 EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState());
1458 context_list[3]->trans->GetLoadState());
1459 2149
1460 c = context_list[1]; 2150 c = context_list[1];
1461 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2151 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1462 c->result = c->callback.WaitForResult(); 2152 c->result = c->callback.WaitForResult();
1463 if (c->result == OK) 2153 if (c->result == OK)
1464 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2154 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1465 2155
1466 // At this point we have one reader, two pending transactions and a task on 2156 // At this point we have one reader, two pending transactions and a task on
1467 // the queue to move to the next transaction. Now we cancel the request that 2157 // the queue to move to the next transaction. Now we cancel the request that
1468 // is the current reader, and expect the queued task to be able to start the 2158 // is the current reader, and expect the queued task to be able to start the
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 ASSERT_THAT(c->result, IsOk()); 2203 ASSERT_THAT(c->result, IsOk());
1514 2204
1515 MockHttpRequest* this_request = &request; 2205 MockHttpRequest* this_request = &request;
1516 if (i == 3) 2206 if (i == 3)
1517 this_request = &writer_request; 2207 this_request = &writer_request;
1518 2208
1519 c->result = c->trans->Start(this_request, c->callback.callback(), 2209 c->result = c->trans->Start(this_request, c->callback.callback(),
1520 NetLogWithSource()); 2210 NetLogWithSource());
1521 } 2211 }
1522 2212
2213 base::RunLoop().RunUntilIdle();
2214
1523 // The first request should be a writer at this point, and the two subsequent 2215 // The first request should be a writer at this point, and the two subsequent
1524 // requests should be pending. The last request doomed the first entry. 2216 // requests should be pending. The last request doomed the first entry.
1525 2217
1526 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2218 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1527 2219
1528 // Cancel the first queued transaction. 2220 // Cancel the second transaction. Note that this and the 3rd transactions
2221 // would have completed their headers phase and would be waiting in the
2222 // done_headers_queue when the 2nd transaction is cancelled.
1529 context_list[1].reset(); 2223 context_list[1].reset();
1530 2224
1531 for (int i = 0; i < kNumTransactions; ++i) { 2225 for (int i = 0; i < kNumTransactions; ++i) {
1532 if (i == 1) 2226 if (i == 1)
1533 continue; 2227 continue;
1534 Context* c = context_list[i].get(); 2228 Context* c = context_list[i].get();
1535 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2229 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1536 c->result = c->callback.WaitForResult(); 2230 c->result = c->callback.WaitForResult();
1537 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2231 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1538 } 2232 }
(...skipping 21 matching lines...) Expand all
1560 ASSERT_THAT(c->result, IsOk()); 2254 ASSERT_THAT(c->result, IsOk());
1561 2255
1562 c->result = 2256 c->result =
1563 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 2257 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1564 } 2258 }
1565 2259
1566 // Allow all requests to move from the Create queue to the active entry. 2260 // Allow all requests to move from the Create queue to the active entry.
1567 base::RunLoop().RunUntilIdle(); 2261 base::RunLoop().RunUntilIdle();
1568 2262
1569 // The first request should be a writer at this point, and the subsequent 2263 // The first request should be a writer at this point, and the subsequent
1570 // requests should be pending. 2264 // requests should have completed validation. Since the validation does not
2265 // result in a match, a new entry would be created.
1571 2266
1572 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2267 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1573 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2268 EXPECT_EQ(0, cache.disk_cache()->open_count());
1574 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2269 EXPECT_EQ(2, cache.disk_cache()->create_count());
1575 2270
1576 // Now, make sure that the second request asks for the entry not to be stored. 2271 // Now, make sure that the second request asks for the entry not to be stored.
1577 request_handler.set_no_store(true); 2272 request_handler.set_no_store(true);
1578 2273
1579 for (int i = 0; i < kNumTransactions; ++i) { 2274 for (int i = 0; i < kNumTransactions; ++i) {
1580 Context* c = context_list[i]; 2275 Context* c = context_list[i];
1581 if (c->result == ERR_IO_PENDING) 2276 if (c->result == ERR_IO_PENDING)
1582 c->result = c->callback.WaitForResult(); 2277 c->result = c->callback.WaitForResult();
1583 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); 2278 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1584 delete c; 2279 delete c;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1618 2313
1619 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2314 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1620 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2315 EXPECT_EQ(0, cache.disk_cache()->open_count());
1621 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2316 EXPECT_EQ(1, cache.disk_cache()->create_count());
1622 2317
1623 for (int i = 0; i < kNumTransactions; ++i) { 2318 for (int i = 0; i < kNumTransactions; ++i) {
1624 Context* c = context_list[i]; 2319 Context* c = context_list[i];
1625 if (c->result == ERR_IO_PENDING) 2320 if (c->result == ERR_IO_PENDING)
1626 c->result = c->callback.WaitForResult(); 2321 c->result = c->callback.WaitForResult();
1627 // Destroy only the first transaction. 2322 // Destroy only the first transaction.
2323 // This should lead to all transactions to restart, even those that have
2324 // validated themselves and were waiting for the writer transaction to
2325 // complete writing to the cache.
1628 if (i == 0) { 2326 if (i == 0) {
1629 delete c; 2327 delete c;
1630 context_list[i] = NULL; 2328 context_list[i] = NULL;
1631 } 2329 }
1632 } 2330 }
1633 2331
1634 // Complete the rest of the transactions. 2332 // Complete the rest of the transactions.
1635 for (int i = 1; i < kNumTransactions; ++i) { 2333 for (int i = 1; i < kNumTransactions; ++i) {
1636 Context* c = context_list[i]; 2334 Context* c = context_list[i];
1637 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2335 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
2533 } 3231 }
2534 3232
2535 // Helper that does 4 requests using HttpCache: 3233 // Helper that does 4 requests using HttpCache:
2536 // 3234 //
2537 // (1) loads |kUrl| -- expects |net_response_1| to be returned. 3235 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2538 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. 3236 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2539 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to 3237 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2540 // be returned. 3238 // be returned.
2541 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be 3239 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2542 // returned. 3240 // returned.
3241 // The entry will be created once and will be opened for the 3 subsequent
3242 // requests.
2543 static void ConditionalizedRequestUpdatesCacheHelper( 3243 static void ConditionalizedRequestUpdatesCacheHelper(
2544 const Response& net_response_1, 3244 const Response& net_response_1,
2545 const Response& net_response_2, 3245 const Response& net_response_2,
2546 const Response& cached_response_2, 3246 const Response& cached_response_2,
2547 const char* extra_request_headers) { 3247 const char* extra_request_headers) {
2548 MockHttpCache cache; 3248 MockHttpCache cache;
2549 3249
2550 // The URL we will be requesting. 3250 // The URL we will be requesting.
2551 const char kUrl[] = "http://foobar.com/main.css"; 3251 const char kUrl[] = "http://foobar.com/main.css";
2552 3252
(...skipping 3555 matching lines...) Expand 10 before | Expand all | Expand 10 after
6108 pending->trans->Start(&request, pending->callback.callback(), 6808 pending->trans->Start(&request, pending->callback.callback(),
6109 NetLogWithSource())); 6809 NetLogWithSource()));
6110 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); 6810 EXPECT_THAT(c->callback.GetResult(rv), IsOk());
6111 6811
6112 // Make sure that the entry has some data stored. 6812 // Make sure that the entry has some data stored.
6113 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); 6813 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
6114 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 6814 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
6115 EXPECT_EQ(5, c->callback.GetResult(rv)); 6815 EXPECT_EQ(5, c->callback.GetResult(rv));
6116 6816
6117 // Cancel the requests. 6817 // Cancel the requests.
6818 // Since |pending| is currently validating the already written headers
6819 // it will be restarted as well.
6118 delete c; 6820 delete c;
6119 delete pending; 6821 delete pending;
6120 6822
6121 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 6823 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6122 EXPECT_EQ(1, cache.disk_cache()->open_count()); 6824 EXPECT_EQ(1, cache.disk_cache()->open_count());
6123 EXPECT_EQ(2, cache.disk_cache()->create_count()); 6825 EXPECT_EQ(1, cache.disk_cache()->create_count());
6124 6826
6125 base::RunLoop().RunUntilIdle(); 6827 base::RunLoop().RunUntilIdle();
6126 RemoveMockTransaction(&transaction); 6828 RemoveMockTransaction(&transaction);
6127 } 6829 }
6128 6830
6129 // Tests that we delete truncated entries if the server changes its mind midway. 6831 // Tests that we delete truncated entries if the server changes its mind midway.
6130 TEST(HttpCache, GET_IncompleteResource2) { 6832 TEST(HttpCache, GET_IncompleteResource2) {
6131 MockHttpCache cache; 6833 MockHttpCache cache;
6132 AddMockTransaction(&kRangeGET_TransactionOK); 6834 AddMockTransaction(&kRangeGET_TransactionOK);
6133 6835
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
6838 7540
6839 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 7541 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6840 &response); 7542 &response);
6841 EXPECT_TRUE(response.metadata.get() == NULL); 7543 EXPECT_TRUE(response.metadata.get() == NULL);
6842 7544
6843 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 7545 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6844 EXPECT_EQ(2, cache.disk_cache()->open_count()); 7546 EXPECT_EQ(2, cache.disk_cache()->open_count());
6845 EXPECT_EQ(1, cache.disk_cache()->create_count()); 7547 EXPECT_EQ(1, cache.disk_cache()->create_count());
6846 } 7548 }
6847 7549
6848 // Tests that if a metadata writer transaction hits cache lock timeout, it will
6849 // error out.
6850 TEST(HttpCache, WriteMetadata_CacheLockTimeout) {
6851 MockHttpCache cache;
6852
6853 // Write to the cache
6854 HttpResponseInfo response;
6855 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6856 &response);
6857 EXPECT_FALSE(response.metadata.get());
6858
6859 MockHttpRequest request(kSimpleGET_Transaction);
6860 Context c1;
6861 ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
6862 ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
6863 NetLogWithSource()));
6864
6865 cache.SimulateCacheLockTimeout();
6866
6867 // Write meta data to the same entry.
6868 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
6869 memset(buf->data(), 0, buf->size());
6870 base::strlcpy(buf->data(), "Hi there", buf->size());
6871 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6872 DEFAULT_PRIORITY, response.response_time,
6873 buf.get(), buf->size());
6874
6875 // Release the buffer before the operation takes place.
6876 buf = NULL;
6877
6878 // Makes sure we finish pending operations.
6879 base::RunLoop().RunUntilIdle();
6880
6881 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6882 &response);
6883
6884 // The writer transaction should fail due to cache lock timeout.
6885 ASSERT_FALSE(response.metadata.get());
6886 }
6887
6888 // Tests that we ignore VARY checks when writing metadata since the request 7550 // Tests that we ignore VARY checks when writing metadata since the request
6889 // headers for the WriteMetadata transaction are made up. 7551 // headers for the WriteMetadata transaction are made up.
6890 TEST(HttpCache, WriteMetadata_IgnoreVary) { 7552 TEST(HttpCache, WriteMetadata_IgnoreVary) {
6891 MockHttpCache cache; 7553 MockHttpCache cache;
6892 7554
6893 // Write to the cache 7555 // Write to the cache
6894 HttpResponseInfo response; 7556 HttpResponseInfo response;
6895 ScopedMockTransaction transaction(kSimpleGET_Transaction); 7557 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6896 transaction.request_headers = "accept-encoding: gzip\r\n"; 7558 transaction.request_headers = "accept-encoding: gzip\r\n";
6897 transaction.response_headers = 7559 transaction.response_headers =
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
7205 MockHttpRequest request(mock_transaction); 7867 MockHttpRequest request(mock_transaction);
7206 7868
7207 { 7869 {
7208 std::unique_ptr<HttpTransaction> trans; 7870 std::unique_ptr<HttpTransaction> trans;
7209 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); 7871 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7210 7872
7211 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); 7873 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7212 EXPECT_THAT(callback.GetResult(rv), IsOk()); 7874 EXPECT_THAT(callback.GetResult(rv), IsOk());
7213 7875
7214 trans->StopCaching(); 7876 trans->StopCaching();
7215
7216 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
7217 rv = trans->Read(buf.get(), 10, callback.callback());
7218 EXPECT_EQ(callback.GetResult(rv), 10);
7219 } 7877 }
7220 RemoveMockTransaction(&mock_transaction); 7878 RemoveMockTransaction(&mock_transaction);
7221 7879
7222 // Make sure that the ActiveEntry is gone. 7880 // Make sure that the ActiveEntry is gone.
7223 base::RunLoop().RunUntilIdle(); 7881 base::RunLoop().RunUntilIdle();
7224 7882
7225 // Verify that the entry is gone. 7883 // Verify that the entry is gone.
7226 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 7884 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
7227 7885
7228 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 7886 EXPECT_EQ(2, cache.network_layer()->transaction_count());
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after
8260 ASSERT_TRUE(attrs->GetDictionary( 8918 ASSERT_TRUE(attrs->GetDictionary(
8261 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); 8919 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs));
8262 std::string size; 8920 std::string size;
8263 ASSERT_TRUE(size_attrs->GetString("value", &size)); 8921 ASSERT_TRUE(size_attrs->GetString("value", &size));
8264 int actual_size = 0; 8922 int actual_size = 0;
8265 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); 8923 ASSERT_TRUE(base::HexStringToInt(size, &actual_size));
8266 ASSERT_LT(0, actual_size); 8924 ASSERT_LT(0, actual_size);
8267 } 8925 }
8268 8926
8269 } // namespace net 8927 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698