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

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

Issue 2721933002: HttpCache::Transaction layer allowing parallel validation (Closed)
Patch Set: DoneReadingFromEntry replaced with DoneWithEntry 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 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 1341
1327 // Tests that we don't remove extra headers for conditionalized requests. 1342 // Tests that we don't remove extra headers for conditionalized requests.
1328 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) { 1343 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1329 MockHttpCache cache; 1344 MockHttpCache cache;
1330 1345
1331 // Write to the cache. 1346 // Write to the cache.
1332 RunTransactionTest(cache.http_cache(), kETagGET_Transaction); 1347 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1333 1348
1334 MockTransaction transaction(kETagGET_Transaction); 1349 MockTransaction transaction(kETagGET_Transaction);
1335 transaction.handler = PreserveRequestHeaders_Handler; 1350 transaction.handler = PreserveRequestHeaders_Handler;
1336 transaction.request_headers = "If-None-Match: \"foopy\"\r\n" 1351 transaction.request_headers = "If-None-Match: \"foopy\"\r\n" EXTRA_HEADER;
1337 EXTRA_HEADER;
1338 AddMockTransaction(&transaction); 1352 AddMockTransaction(&transaction);
1339 1353
1340 RunTransactionTest(cache.http_cache(), transaction); 1354 RunTransactionTest(cache.http_cache(), transaction);
1341 1355
1342 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1356 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1343 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1357 EXPECT_EQ(1, cache.disk_cache()->open_count());
1344 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1358 EXPECT_EQ(1, cache.disk_cache()->create_count());
1345 RemoveMockTransaction(&transaction); 1359 RemoveMockTransaction(&transaction);
1346 } 1360 }
1347 1361
1348 TEST(HttpCache, SimpleGET_ManyReaders) { 1362 TEST(HttpCache, SimpleGET_ManyReaders) {
1349 MockHttpCache cache; 1363 MockHttpCache cache;
1350 1364
1351 MockHttpRequest request(kSimpleGET_Transaction); 1365 MockHttpRequest request(kSimpleGET_Transaction);
1352 1366
1353 std::vector<Context*> context_list; 1367 std::vector<std::unique_ptr<Context>> context_list;
1354 const int kNumTransactions = 5; 1368 const int kNumTransactions = 5;
1355 1369
1356 for (int i = 0; i < kNumTransactions; ++i) { 1370 for (int i = 0; i < kNumTransactions; ++i) {
1357 context_list.push_back(new Context()); 1371 context_list.push_back(base::MakeUnique<Context>());
1358 Context* c = context_list[i]; 1372 auto& c = context_list[i];
1359 1373
1360 c->result = cache.CreateTransaction(&c->trans); 1374 c->result = cache.CreateTransaction(&c->trans);
1361 ASSERT_THAT(c->result, IsOk()); 1375 ASSERT_THAT(c->result, IsOk());
1376 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1377
1378 c->result =
1379 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1380 }
1381
1382 // All requests are waiting for the active entry.
1383 for (auto& context : context_list) {
1384 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1385 }
1386
1387 // Allow all requests to move from the Create queue to the active entry.
1388 base::RunLoop().RunUntilIdle();
1389
1390 // The first request should be a writer at this point, and the subsequent
1391 // requests should have passed the validation phase and waiting for the
1392 // response to be written to the cache before they can read.
1393 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1394 EXPECT_EQ(kNumTransactions - 1,
1395 cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1396
1397 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1398 EXPECT_EQ(0, cache.disk_cache()->open_count());
1399 EXPECT_EQ(1, cache.disk_cache()->create_count());
1400
1401 // All requests depend on the writer, and the writer is between Start and
1402 // Read, i.e. idle.
1403 for (auto& context : context_list) {
1404 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1405 }
1406
1407 for (int i = 0; i < kNumTransactions; ++i) {
1408 auto& c = context_list[i];
1409 if (c->result == ERR_IO_PENDING)
1410 c->result = c->callback.WaitForResult();
1411
1412 if (i > 0) {
1413 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1414 EXPECT_EQ(kNumTransactions - i,
1415 cache.GetCountReaders(kSimpleGET_Transaction.url));
1416 }
1417
1418 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1419 }
1420
1421 // We should not have had to re-open the disk entry
1422
1423 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1424 EXPECT_EQ(0, cache.disk_cache()->open_count());
1425 EXPECT_EQ(1, cache.disk_cache()->create_count());
1426 }
1427
1428 // Tests that we can have parallel validation on range requests.
1429 TEST(HttpCache, RangeGET_ParallelValidationNoMatch) {
1430 MockHttpCache cache;
1431
1432 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1433 MockHttpRequest request(transaction);
1434
1435 std::vector<std::unique_ptr<Context>> context_list;
1436 const int kNumTransactions = 5;
1437
1438 for (int i = 0; i < kNumTransactions; ++i) {
1439 context_list.push_back(base::MakeUnique<Context>());
1440 auto& c = context_list[i];
1441
1442 c->result = cache.CreateTransaction(&c->trans);
1443 ASSERT_THAT(c->result, IsOk());
1444 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1445
1446 c->result =
1447 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1448 }
1449
1450 // All requests are waiting for the active entry.
1451 for (auto& context : context_list) {
1452 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1453 }
1454
1455 // Allow all requests to move from the Create queue to the active entry.
1456 base::RunLoop().RunUntilIdle();
1457
1458 // The first entry should have been doomed. Since the 1st transaction has not
1459 // started writing to the cache, MockDiskEntry::CouldBeSparse() returns false
1460 // leading to restarting the dooming the entry and restarting the second
1461 // transaction.
1462 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1463 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1464
1465 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1466 EXPECT_EQ(0, cache.disk_cache()->open_count());
1467 EXPECT_EQ(5, cache.disk_cache()->create_count());
1468
1469 for (auto& context : context_list) {
1470 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1471 }
1472
1473 for (int i = 0; i < kNumTransactions; ++i) {
1474 auto& c = context_list[i];
1475 if (c->result == ERR_IO_PENDING)
1476 c->result = c->callback.WaitForResult();
1477
1478 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
1479 }
1480
1481 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1482 EXPECT_EQ(0, cache.disk_cache()->open_count());
1483 EXPECT_EQ(5, cache.disk_cache()->create_count());
1484 }
1485
1486 // Tests parallel validation on range requests with non-overlapping ranges.
1487 TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) {
1488 MockHttpCache cache;
1489
1490 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1491
1492 std::vector<std::unique_ptr<Context>> context_list;
1493 const int kNumTransactions = 2;
1494
1495 for (int i = 0; i < kNumTransactions; ++i) {
1496 context_list.push_back(base::MakeUnique<Context>());
1497 }
1498
1499 // Let 1st transaction complete headers phase for ranges 40-49.
1500 std::string first_read;
1501 {
1502 MockHttpRequest request(transaction);
1503 auto& c = context_list[0];
1504 c->result = cache.CreateTransaction(&c->trans);
1505 ASSERT_THAT(c->result, IsOk());
1506 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1507
1508 c->result =
1509 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1510 base::RunLoop().RunUntilIdle();
1511
1512 // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
1513 // true.
1514 const int kBufferSize = 5;
1515 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
1516 ReleaseBufferCompletionCallback cb(buffer.get());
1517 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
1518 EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
1519
1520 std::string data_read(buffer->data(), kBufferSize);
1521 first_read = data_read;
1522
1523 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
1524 }
1525
1526 // 2nd transaction requests ranges 30-39.
1527 {
1528 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
1529 MockHttpRequest request(transaction);
1530 auto& c = context_list[1];
1531 c->result = cache.CreateTransaction(&c->trans);
1532 ASSERT_THAT(c->result, IsOk());
1533 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1534
1535 c->result =
1536 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1537 base::RunLoop().RunUntilIdle();
1538
1539 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1540 }
1541
1542 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1543 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1544
1545 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1546 EXPECT_EQ(0, cache.disk_cache()->open_count());
1547 EXPECT_EQ(1, cache.disk_cache()->create_count());
1548
1549 for (int i = 0; i < kNumTransactions; ++i) {
1550 auto& c = context_list[i];
1551 if (c->result == ERR_IO_PENDING)
1552 c->result = c->callback.WaitForResult();
1553
1554 if (i == 0) {
1555 ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
1556 transaction);
1557 continue;
1558 }
1559
1560 transaction.data = "rg: 30-39 ";
1561 ReadAndVerifyTransaction(c->trans.get(), transaction);
1562 }
1563
1564 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1565 EXPECT_EQ(0, cache.disk_cache()->open_count());
1566 EXPECT_EQ(1, cache.disk_cache()->create_count());
1567
1568 // Fetch from the cache to check that ranges 30-49 have been successfully
1569 // cached.
1570 {
1571 MockTransaction transaction(kRangeGET_TransactionOK);
1572 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1573 transaction.data = "rg: 30-39 rg: 40-49 ";
1574 std::string headers;
1575 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
1576 Verify206Response(headers, 30, 49);
1577 }
1578
1579 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1580 EXPECT_EQ(1, cache.disk_cache()->open_count());
1581 EXPECT_EQ(1, cache.disk_cache()->create_count());
1582 }
1583
1584 // Tests parallel validation on range requests with overlapping ranges.
1585 TEST(HttpCache, RangeGET_ParallelValidationOverlappingRanges) {
1586 MockHttpCache cache;
1587
1588 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1589
1590 std::vector<std::unique_ptr<Context>> context_list;
1591 const int kNumTransactions = 2;
1592
1593 for (int i = 0; i < kNumTransactions; ++i) {
1594 context_list.push_back(base::MakeUnique<Context>());
1595 }
1596
1597 // Let 1st transaction complete headers phase for ranges 40-49.
1598 std::string first_read;
1599 {
1600 MockHttpRequest request(transaction);
1601 auto& c = context_list[0];
1602 c->result = cache.CreateTransaction(&c->trans);
1603 ASSERT_THAT(c->result, IsOk());
1604 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1605
1606 c->result =
1607 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1608 base::RunLoop().RunUntilIdle();
1609
1610 // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
1611 // true.
1612 const int kBufferSize = 5;
1613 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
1614 ReleaseBufferCompletionCallback cb(buffer.get());
1615 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
1616 EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
1617
1618 std::string data_read(buffer->data(), kBufferSize);
1619 first_read = data_read;
1620
1621 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
1622 }
1623
1624 // 2nd transaction requests ranges 30-49.
1625 {
1626 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1627 MockHttpRequest request(transaction);
1628 auto& c = context_list[1];
1629 c->result = cache.CreateTransaction(&c->trans);
1630 ASSERT_THAT(c->result, IsOk());
1631 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1632
1633 c->result =
1634 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1635 base::RunLoop().RunUntilIdle();
1636
1637 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1638 }
1639
1640 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1641 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1642
1643 // Should have created another transaction for the uncached range.
1644 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1645 EXPECT_EQ(0, cache.disk_cache()->open_count());
1646 EXPECT_EQ(1, cache.disk_cache()->create_count());
1647
1648 for (int i = 0; i < kNumTransactions; ++i) {
1649 auto& c = context_list[i];
1650 if (c->result == ERR_IO_PENDING)
1651 c->result = c->callback.WaitForResult();
1652
1653 if (i == 0) {
1654 ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
1655 transaction);
1656 continue;
1657 }
1658
1659 transaction.data = "rg: 30-39 rg: 40-49 ";
1660 ReadAndVerifyTransaction(c->trans.get(), transaction);
1661 }
1662
1663 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1664 EXPECT_EQ(0, cache.disk_cache()->open_count());
1665 EXPECT_EQ(1, cache.disk_cache()->create_count());
1666
1667 // Fetch from the cache to check that ranges 30-49 have been successfully
1668 // cached.
1669 {
1670 MockTransaction transaction(kRangeGET_TransactionOK);
1671 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1672 transaction.data = "rg: 30-39 rg: 40-49 ";
1673 std::string headers;
1674 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
1675 Verify206Response(headers, 30, 49);
1676 }
1677
1678 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1679 EXPECT_EQ(0, cache.disk_cache()->open_count());
1680 EXPECT_EQ(1, cache.disk_cache()->create_count());
1681 }
1682
1683 // Parallel validation results in 200.
1684 TEST(HttpCache, SimpleGET_ParallelValidationNoMatch) {
1685 MockHttpCache cache;
1686 MockHttpRequest request(kSimpleGET_Transaction);
1687 request.load_flags |= LOAD_VALIDATE_CACHE;
1688 std::vector<std::unique_ptr<Context>> context_list;
1689 const int kNumTransactions = 5;
1690 for (int i = 0; i < kNumTransactions; ++i) {
1691 context_list.push_back(base::MakeUnique<Context>());
1692 auto& c = context_list[i];
1693 c->result = cache.CreateTransaction(&c->trans);
1694 ASSERT_THAT(c->result, IsOk());
1695 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1696 c->result =
1697 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1698 }
1699
1700 // All requests are waiting for the active entry.
1701 for (auto& context : context_list) {
1702 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1703 }
1704
1705 // Allow all requests to move from the Create queue to the active entry.
1706 base::RunLoop().RunUntilIdle();
1707
1708 // The first request should be a writer at this point, and the subsequent
1709 // requests should have passed the validation phase and created their own
1710 // entries since none of them matched the headers of the earlier one.
1711 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1712
1713 // Note that there are only 3 entries created and not 5 since every other
1714 // transaction would have gone to the network.
1715 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1716 EXPECT_EQ(0, cache.disk_cache()->open_count());
1717 EXPECT_EQ(3, cache.disk_cache()->create_count());
1718
1719 // All requests depend on the writer, and the writer is between Start and
1720 // Read, i.e. idle.
1721 for (auto& context : context_list) {
1722 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1723 }
1724
1725 for (auto& context : context_list) {
1726 if (context->result == ERR_IO_PENDING)
1727 context->result = context->callback.WaitForResult();
1728 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1729 }
1730
1731 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1732 EXPECT_EQ(0, cache.disk_cache()->open_count());
1733 EXPECT_EQ(3, cache.disk_cache()->create_count());
1734 }
1735
1736 // Tests that a GET followed by a DELETE results in DELETE immediately starting
1737 // the headers phase and the entry is doomed.
1738 TEST(HttpCache, SimpleGET_ParallelValidationDelete) {
1739 MockHttpCache cache;
1740
1741 MockHttpRequest request(kSimpleGET_Transaction);
1742 request.load_flags |= LOAD_VALIDATE_CACHE;
1743
1744 MockHttpRequest delete_request(kSimpleGET_Transaction);
1745 delete_request.method = "DELETE";
1746
1747 std::vector<std::unique_ptr<Context>> context_list;
1748 const int kNumTransactions = 2;
1749
1750 for (int i = 0; i < kNumTransactions; ++i) {
1751 context_list.push_back(base::MakeUnique<Context>());
1752 auto& c = context_list[i];
1753
1754 MockHttpRequest* this_request = &request;
1755 if (i == 1)
1756 this_request = &delete_request;
1757
1758 c->result = cache.CreateTransaction(&c->trans);
1759 ASSERT_THAT(c->result, IsOk());
1760 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1761
1762 c->result = c->trans->Start(this_request, c->callback.callback(),
1763 NetLogWithSource());
1764 }
1765
1766 // All requests are waiting for the active entry.
1767 for (auto& context : context_list) {
1768 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1769 }
1770
1771 // Allow all requests to move from the Create queue to the active entry.
1772 base::RunLoop().RunUntilIdle();
1773
1774 // The first request should be a writer at this point, and the subsequent
1775 // request should have passed the validation phase and doomed the existing
1776 // entry.
1777 EXPECT_TRUE(
1778 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
1779
1780 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1781 EXPECT_EQ(0, cache.disk_cache()->open_count());
1782 EXPECT_EQ(1, cache.disk_cache()->create_count());
1783
1784 // All requests depend on the writer, and the writer is between Start and
1785 // Read, i.e. idle.
1786 for (auto& context : context_list) {
1787 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1788 }
1789
1790 for (auto& context : context_list) {
1791 if (context->result == ERR_IO_PENDING)
1792 context->result = context->callback.WaitForResult();
1793 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1794 }
1795
1796 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1797 EXPECT_EQ(0, cache.disk_cache()->open_count());
1798 EXPECT_EQ(1, cache.disk_cache()->create_count());
1799 }
1800
1801 // Tests that a transaction which is in validated queue can be destroyed without
1802 // any impact to other transactions.
1803 TEST(HttpCache, SimpleGET_ParallelValidationCancelValidated) {
1804 MockHttpCache cache;
1805
1806 MockHttpRequest request(kSimpleGET_Transaction);
1807
1808 std::vector<std::unique_ptr<Context>> context_list;
1809 const int kNumTransactions = 2;
1810
1811 for (int i = 0; i < kNumTransactions; ++i) {
1812 context_list.push_back(base::MakeUnique<Context>());
1813 auto& c = context_list[i];
1814
1815 c->result = cache.CreateTransaction(&c->trans);
1816 ASSERT_THAT(c->result, IsOk());
1817
1818 c->result =
1819 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1820 }
1821
1822 // Allow all requests to move from the Create queue to the active entry.
1823 base::RunLoop().RunUntilIdle();
1824
1825 // The first request should be a writer at this point, and the subsequent
1826 // requests should have completed validation.
1827
1828 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1829 EXPECT_EQ(0, cache.disk_cache()->open_count());
1830 EXPECT_EQ(1, cache.disk_cache()->create_count());
1831
1832 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1833 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1834
1835 context_list[1].reset();
1836
1837 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1838
1839 // Complete the rest of the transactions.
1840 for (auto& context : context_list) {
1841 if (!context)
1842 continue;
1843 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1844 }
1845
1846 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1847 EXPECT_EQ(0, cache.disk_cache()->open_count());
1848 EXPECT_EQ(1, cache.disk_cache()->create_count());
1849 }
1850
1851 // Tests that a transaction which is in readers can be destroyed without
1852 // any impact to other transactions.
1853 TEST(HttpCache, SimpleGET_ParallelValidationCancelReader) {
1854 MockHttpCache cache;
1855
1856 MockHttpRequest request(kSimpleGET_Transaction);
1857
1858 MockTransaction transaction(kSimpleGET_Transaction);
1859 transaction.load_flags |= LOAD_VALIDATE_CACHE;
1860 MockHttpRequest validate_request(transaction);
1861
1862 int kNumTransactions = 4;
1863 std::vector<std::unique_ptr<Context>> context_list;
1864
1865 for (int i = 0; i < kNumTransactions; ++i) {
1866 context_list.push_back(base::MakeUnique<Context>());
1867 auto& c = context_list[i];
1868
1869 c->result = cache.CreateTransaction(&c->trans);
1870 ASSERT_THAT(c->result, IsOk());
1871
1872 MockHttpRequest* this_request = &request;
1873 if (i == 3) {
1874 this_request = &validate_request;
1875 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
1876 }
1877
1878 c->result = c->trans->Start(this_request, c->callback.callback(),
1879 NetLogWithSource());
1880 }
1881
1882 // Allow all requests to move from the Create queue to the active entry.
1883 base::RunLoop().RunUntilIdle();
1884
1885 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1886 EXPECT_EQ(0, cache.disk_cache()->open_count());
1887 EXPECT_EQ(1, cache.disk_cache()->create_count());
1888
1889 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1890 EXPECT_EQ(2, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1891 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1892
1893 // Complete the response body.
1894 auto& c = context_list[0];
1895 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1896
1897 // Rest of the transactions should move to readers.
1898 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1899 EXPECT_EQ(2, cache.GetCountReaders(kSimpleGET_Transaction.url));
1900 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1901 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1902
1903 // Add 2 new transactions.
1904 kNumTransactions = 6;
1905
1906 for (int i = 4; i < kNumTransactions; ++i) {
1907 context_list.push_back(base::MakeUnique<Context>());
1908 auto& c = context_list[i];
1909
1910 c->result = cache.CreateTransaction(&c->trans);
1911 ASSERT_THAT(c->result, IsOk());
1912
1913 c->result =
1914 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1915 }
1916
1917 EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
1918
1919 // Delete a reader.
1920 context_list[1].reset();
1921
1922 // Deleting the reader did not impact any other transaction.
1923 EXPECT_EQ(1, cache.GetCountReaders(kSimpleGET_Transaction.url));
1924 EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
1925 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1926
1927 // Resume network start for headers_transaction. It will doom the entry as it
1928 // will be a 200 and will go to network for the response body.
1929 auto& context = context_list[3];
1930 context->trans->ResumeNetworkStart();
1931
1932 // The pending transactions will be added to a new entry.
1933 base::RunLoop().RunUntilIdle();
1934
1935 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1936 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1937
1938 // Complete the rest of the transactions.
1939 for (int i = 2; i < kNumTransactions; ++i) {
1940 auto& c = context_list[i];
1941 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1942 }
1943
1944 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1945 EXPECT_EQ(0, cache.disk_cache()->open_count());
1946 EXPECT_EQ(2, cache.disk_cache()->create_count());
1947 }
1948
1949 // Tests that a transaction is in validated queue and writer is destroyed
1950 // leading to restarting the validated transaction.
1951 TEST(HttpCache, SimpleGET_ParallelValidationCancelWriter) {
1952 MockHttpCache cache;
1953
1954 MockHttpRequest request(kSimpleGET_Transaction);
1955
1956 MockTransaction transaction(kSimpleGET_Transaction);
1957 transaction.load_flags |= LOAD_VALIDATE_CACHE;
1958 MockHttpRequest validate_request(transaction);
1959
1960 const int kNumTransactions = 3;
1961 std::vector<std::unique_ptr<Context>> context_list;
1962
1963 for (int i = 0; i < kNumTransactions; ++i) {
1964 context_list.push_back(base::MakeUnique<Context>());
1965 auto& c = context_list[i];
1966
1967 c->result = cache.CreateTransaction(&c->trans);
1968 ASSERT_THAT(c->result, IsOk());
1969
1970 MockHttpRequest* this_request = &request;
1971 if (i == 2) {
1972 this_request = &validate_request;
1973 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
1974 }
1975
1976 c->result = c->trans->Start(this_request, c->callback.callback(),
1977 NetLogWithSource());
1978 }
1979
1980 // Allow all requests to move from the Create queue to the active entry.
1981 base::RunLoop().RunUntilIdle();
1982
1983 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1984 EXPECT_EQ(0, cache.disk_cache()->open_count());
1985 EXPECT_EQ(1, cache.disk_cache()->create_count());
1986
1987 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1988 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1989 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1990
1991 // Deleting the writer at this point will lead to destroying the entry and
1992 // restarting the remaining transactions which will then create a new entry.
1993 context_list[0].reset();
1994
1995 // Resume network start for headers_transaction. It should be restarted due to
1996 // writer cancellation.
1997 auto& c = context_list[2];
1998 c->trans->ResumeNetworkStart();
1999
2000 base::RunLoop().RunUntilIdle();
2001
2002 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
2003 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
2004
2005 // Resume network start for the transaction the second time.
2006 c->trans->ResumeNetworkStart();
2007 base::RunLoop().RunUntilIdle();
2008
2009 // Headers transaction would have doomed the new entry created.
2010 EXPECT_TRUE(
2011 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
2012
2013 // Complete the rest of the transactions.
2014 for (auto& context : context_list) {
2015 if (!context)
2016 continue;
2017 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
2018 }
2019
2020 EXPECT_EQ(4, cache.network_layer()->transaction_count());
2021 EXPECT_EQ(0, cache.disk_cache()->open_count());
2022 EXPECT_EQ(2, cache.disk_cache()->create_count());
2023 }
2024
2025 // Tests that a transaction is currently in headers phase and is destroyed
2026 // leading to destroying the entry.
2027 TEST(HttpCache, SimpleGET_ParallelValidationCancelHeaders) {
2028 MockHttpCache cache;
2029
2030 MockHttpRequest request(kSimpleGET_Transaction);
2031
2032 const int kNumTransactions = 2;
2033 std::vector<std::unique_ptr<Context>> context_list;
2034
2035 for (int i = 0; i < kNumTransactions; ++i) {
2036 context_list.push_back(base::MakeUnique<Context>());
2037 auto& c = context_list[i];
2038
2039 c->result = cache.CreateTransaction(&c->trans);
2040 ASSERT_THAT(c->result, IsOk());
2041
2042 if (i == 0)
2043 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
2044
2045 c->result =
2046 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2047 }
2048
2049 base::RunLoop().RunUntilIdle();
2050
2051 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
2052 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
2053
2054 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2055 EXPECT_EQ(0, cache.disk_cache()->open_count());
2056 EXPECT_EQ(1, cache.disk_cache()->create_count());
2057
2058 // Delete the headers transaction.
2059 context_list[0].reset();
2060
2061 base::RunLoop().RunUntilIdle();
2062
2063 // Complete the rest of the transactions.
2064 for (auto& context : context_list) {
2065 if (!context)
2066 continue;
2067 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
2068 }
2069
2070 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2071 EXPECT_EQ(0, cache.disk_cache()->open_count());
2072 EXPECT_EQ(2, cache.disk_cache()->create_count());
2073 }
2074
2075 // Similar to the above test, except here cache write fails and the
2076 // validated transactions should be restarted.
2077 TEST(HttpCache, SimpleGET_ParallelValidationFailWrite) {
2078 MockHttpCache cache;
2079
2080 MockHttpRequest request(kSimpleGET_Transaction);
2081
2082 const int kNumTransactions = 5;
2083 std::vector<std::unique_ptr<Context>> context_list;
2084
2085 for (int i = 0; i < kNumTransactions; ++i) {
2086 context_list.push_back(base::MakeUnique<Context>());
2087 auto& c = context_list[i];
2088
2089 c->result = cache.CreateTransaction(&c->trans);
2090 ASSERT_THAT(c->result, IsOk());
1362 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); 2091 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1363 2092
1364 c->result = 2093 c->result =
1365 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 2094 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1366 } 2095 }
1367 2096
1368 // All requests are waiting for the active entry. 2097 // All requests are waiting for the active entry.
1369 for (int i = 0; i < kNumTransactions; ++i) { 2098 for (auto& context : context_list) {
1370 Context* c = context_list[i]; 2099 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1371 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1372 } 2100 }
1373 2101
1374 // Allow all requests to move from the Create queue to the active entry. 2102 // Allow all requests to move from the Create queue to the active entry.
1375 base::RunLoop().RunUntilIdle(); 2103 base::RunLoop().RunUntilIdle();
1376 2104
1377 // The first request should be a writer at this point, and the subsequent 2105 // The first request should be a writer at this point, and the subsequent
1378 // requests should be pending. 2106 // requests should have passed the validation phase and waiting for the
2107 // response to be written to the cache before they can read.
2108 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
2109 EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
2110
2111 // All requests depend on the writer, and the writer is between Start and
2112 // Read, i.e. idle.
2113 for (auto& context : context_list) {
2114 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2115 }
2116
2117 // The first request should be a writer at this point, and the subsequent
2118 // requests should have passed the validation phase and waiting for the
2119 // response to be written to the cache before they can read.
1379 2120
1380 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2121 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1381 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2122 EXPECT_EQ(0, cache.disk_cache()->open_count());
1382 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2123 EXPECT_EQ(1, cache.disk_cache()->create_count());
1383 2124
1384 // All requests depend on the writer, and the writer is between Start and 2125 // Fail the request.
1385 // Read, i.e. idle. 2126 cache.disk_cache()->set_soft_failures(true);
1386 for (int i = 0; i < kNumTransactions; ++i) { 2127 // We have to open the entry again to propagate the failure flag.
1387 Context* c = context_list[i]; 2128 disk_cache::Entry* en;
1388 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); 2129 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en);
1389 } 2130 en->Close();
1390 2131
1391 for (int i = 0; i < kNumTransactions; ++i) { 2132 for (int i = 0; i < kNumTransactions; ++i) {
1392 Context* c = context_list[i]; 2133 auto& c = context_list[i];
1393 if (c->result == ERR_IO_PENDING) 2134 if (c->result == ERR_IO_PENDING)
1394 c->result = c->callback.WaitForResult(); 2135 c->result = c->callback.WaitForResult();
2136 if (i == 1) {
2137 // The earlier entry must be destroyed and its disk entry doomed.
2138 EXPECT_TRUE(
2139 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
2140 }
1395 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2141 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1396 } 2142 }
1397 2143
1398 // We should not have had to re-open the disk entry 2144 // Since validated transactions were restarted and new entry read/write
1399 2145 // operations would also fail, all requests would have gone to the network.
1400 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2146 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1401 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2147 EXPECT_EQ(1, cache.disk_cache()->open_count());
1402 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2148 EXPECT_EQ(5, cache.disk_cache()->create_count());
1403
1404 for (int i = 0; i < kNumTransactions; ++i) {
1405 Context* c = context_list[i];
1406 delete c;
1407 }
1408 } 2149 }
1409 2150
1410 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. 2151 // 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 2152 // 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 2153 // finishing, we have to make sure that we remove both transactions from the
1413 // entry. 2154 // entry.
1414 TEST(HttpCache, SimpleGET_RacingReaders) { 2155 TEST(HttpCache, SimpleGET_RacingReaders) {
1415 MockHttpCache cache; 2156 MockHttpCache cache;
1416 2157
1417 MockHttpRequest request(kSimpleGET_Transaction); 2158 MockHttpRequest request(kSimpleGET_Transaction);
(...skipping 26 matching lines...) Expand all
1444 2185
1445 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2186 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1446 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2187 EXPECT_EQ(0, cache.disk_cache()->open_count());
1447 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2188 EXPECT_EQ(1, cache.disk_cache()->create_count());
1448 2189
1449 Context* c = context_list[0]; 2190 Context* c = context_list[0];
1450 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2191 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1451 c->result = c->callback.WaitForResult(); 2192 c->result = c->callback.WaitForResult();
1452 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2193 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1453 2194
1454 // Now we have 2 active readers and two queued transactions. 2195 // Now all transactions should be waiting for read to be invoked. Two readers
1455 2196 // are because of the load flags and remaining two transactions were converted
2197 // to readers after skipping validation. Note that the remaining two went on
2198 // to process the headers in parallel with readers present on the entry.
1456 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); 2199 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
1457 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, 2200 EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState());
1458 context_list[3]->trans->GetLoadState());
1459 2201
1460 c = context_list[1]; 2202 c = context_list[1];
1461 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2203 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1462 c->result = c->callback.WaitForResult(); 2204 c->result = c->callback.WaitForResult();
1463 if (c->result == OK) 2205 if (c->result == OK)
1464 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2206 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1465 2207
1466 // At this point we have one reader, two pending transactions and a task on 2208 // 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 2209 // 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 2210 // 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()); 2255 ASSERT_THAT(c->result, IsOk());
1514 2256
1515 MockHttpRequest* this_request = &request; 2257 MockHttpRequest* this_request = &request;
1516 if (i == 3) 2258 if (i == 3)
1517 this_request = &writer_request; 2259 this_request = &writer_request;
1518 2260
1519 c->result = c->trans->Start(this_request, c->callback.callback(), 2261 c->result = c->trans->Start(this_request, c->callback.callback(),
1520 NetLogWithSource()); 2262 NetLogWithSource());
1521 } 2263 }
1522 2264
2265 base::RunLoop().RunUntilIdle();
2266
1523 // The first request should be a writer at this point, and the two subsequent 2267 // 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. 2268 // requests should be pending. The last request doomed the first entry.
1525 2269
1526 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2270 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1527 2271
1528 // Cancel the first queued transaction. 2272 // Cancel the second transaction. Note that this and the 3rd transactions
2273 // would have completed their headers phase and would be waiting in the
2274 // done_headers_queue when the 2nd transaction is cancelled.
1529 context_list[1].reset(); 2275 context_list[1].reset();
1530 2276
1531 for (int i = 0; i < kNumTransactions; ++i) { 2277 for (int i = 0; i < kNumTransactions; ++i) {
1532 if (i == 1) 2278 if (i == 1)
1533 continue; 2279 continue;
1534 Context* c = context_list[i].get(); 2280 Context* c = context_list[i].get();
1535 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2281 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1536 c->result = c->callback.WaitForResult(); 2282 c->result = c->callback.WaitForResult();
1537 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2283 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1538 } 2284 }
(...skipping 21 matching lines...) Expand all
1560 ASSERT_THAT(c->result, IsOk()); 2306 ASSERT_THAT(c->result, IsOk());
1561 2307
1562 c->result = 2308 c->result =
1563 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 2309 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1564 } 2310 }
1565 2311
1566 // Allow all requests to move from the Create queue to the active entry. 2312 // Allow all requests to move from the Create queue to the active entry.
1567 base::RunLoop().RunUntilIdle(); 2313 base::RunLoop().RunUntilIdle();
1568 2314
1569 // The first request should be a writer at this point, and the subsequent 2315 // The first request should be a writer at this point, and the subsequent
1570 // requests should be pending. 2316 // requests should have completed validation. Since the validation does not
2317 // result in a match, a new entry would be created.
1571 2318
1572 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2319 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1573 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2320 EXPECT_EQ(0, cache.disk_cache()->open_count());
1574 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2321 EXPECT_EQ(2, cache.disk_cache()->create_count());
1575 2322
1576 // Now, make sure that the second request asks for the entry not to be stored. 2323 // Now, make sure that the second request asks for the entry not to be stored.
1577 request_handler.set_no_store(true); 2324 request_handler.set_no_store(true);
1578 2325
1579 for (int i = 0; i < kNumTransactions; ++i) { 2326 for (int i = 0; i < kNumTransactions; ++i) {
1580 Context* c = context_list[i]; 2327 Context* c = context_list[i];
1581 if (c->result == ERR_IO_PENDING) 2328 if (c->result == ERR_IO_PENDING)
1582 c->result = c->callback.WaitForResult(); 2329 c->result = c->callback.WaitForResult();
1583 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); 2330 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1584 delete c; 2331 delete c;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1618 2365
1619 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2366 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1620 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2367 EXPECT_EQ(0, cache.disk_cache()->open_count());
1621 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2368 EXPECT_EQ(1, cache.disk_cache()->create_count());
1622 2369
1623 for (int i = 0; i < kNumTransactions; ++i) { 2370 for (int i = 0; i < kNumTransactions; ++i) {
1624 Context* c = context_list[i]; 2371 Context* c = context_list[i];
1625 if (c->result == ERR_IO_PENDING) 2372 if (c->result == ERR_IO_PENDING)
1626 c->result = c->callback.WaitForResult(); 2373 c->result = c->callback.WaitForResult();
1627 // Destroy only the first transaction. 2374 // Destroy only the first transaction.
2375 // This should lead to all transactions to restart, even those that have
2376 // validated themselves and were waiting for the writer transaction to
2377 // complete writing to the cache.
1628 if (i == 0) { 2378 if (i == 0) {
1629 delete c; 2379 delete c;
1630 context_list[i] = NULL; 2380 context_list[i] = NULL;
1631 } 2381 }
1632 } 2382 }
1633 2383
1634 // Complete the rest of the transactions. 2384 // Complete the rest of the transactions.
1635 for (int i = 1; i < kNumTransactions; ++i) { 2385 for (int i = 1; i < kNumTransactions; ++i) {
1636 Context* c = context_list[i]; 2386 Context* c = context_list[i];
1637 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2387 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
2533 } 3283 }
2534 3284
2535 // Helper that does 4 requests using HttpCache: 3285 // Helper that does 4 requests using HttpCache:
2536 // 3286 //
2537 // (1) loads |kUrl| -- expects |net_response_1| to be returned. 3287 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2538 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. 3288 // (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 3289 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2540 // be returned. 3290 // be returned.
2541 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be 3291 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2542 // returned. 3292 // returned.
3293 // The entry will be created once and will be opened for the 3 subsequent
3294 // requests.
2543 static void ConditionalizedRequestUpdatesCacheHelper( 3295 static void ConditionalizedRequestUpdatesCacheHelper(
2544 const Response& net_response_1, 3296 const Response& net_response_1,
2545 const Response& net_response_2, 3297 const Response& net_response_2,
2546 const Response& cached_response_2, 3298 const Response& cached_response_2,
2547 const char* extra_request_headers) { 3299 const char* extra_request_headers) {
2548 MockHttpCache cache; 3300 MockHttpCache cache;
2549 3301
2550 // The URL we will be requesting. 3302 // The URL we will be requesting.
2551 const char kUrl[] = "http://foobar.com/main.css"; 3303 const char kUrl[] = "http://foobar.com/main.css";
2552 3304
(...skipping 3555 matching lines...) Expand 10 before | Expand all | Expand 10 after
6108 pending->trans->Start(&request, pending->callback.callback(), 6860 pending->trans->Start(&request, pending->callback.callback(),
6109 NetLogWithSource())); 6861 NetLogWithSource()));
6110 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); 6862 EXPECT_THAT(c->callback.GetResult(rv), IsOk());
6111 6863
6112 // Make sure that the entry has some data stored. 6864 // Make sure that the entry has some data stored.
6113 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); 6865 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
6114 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 6866 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
6115 EXPECT_EQ(5, c->callback.GetResult(rv)); 6867 EXPECT_EQ(5, c->callback.GetResult(rv));
6116 6868
6117 // Cancel the requests. 6869 // Cancel the requests.
6870 // Since |pending| is currently validating the already written headers
6871 // it will be restarted as well.
6118 delete c; 6872 delete c;
6119 delete pending; 6873 delete pending;
6120 6874
6121 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 6875 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6122 EXPECT_EQ(1, cache.disk_cache()->open_count()); 6876 EXPECT_EQ(1, cache.disk_cache()->open_count());
6123 EXPECT_EQ(2, cache.disk_cache()->create_count()); 6877 EXPECT_EQ(1, cache.disk_cache()->create_count());
6124 6878
6125 base::RunLoop().RunUntilIdle(); 6879 base::RunLoop().RunUntilIdle();
6126 RemoveMockTransaction(&transaction); 6880 RemoveMockTransaction(&transaction);
6127 } 6881 }
6128 6882
6129 // Tests that we delete truncated entries if the server changes its mind midway. 6883 // Tests that we delete truncated entries if the server changes its mind midway.
6130 TEST(HttpCache, GET_IncompleteResource2) { 6884 TEST(HttpCache, GET_IncompleteResource2) {
6131 MockHttpCache cache; 6885 MockHttpCache cache;
6132 AddMockTransaction(&kRangeGET_TransactionOK); 6886 AddMockTransaction(&kRangeGET_TransactionOK);
6133 6887
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
6838 7592
6839 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 7593 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6840 &response); 7594 &response);
6841 EXPECT_TRUE(response.metadata.get() == NULL); 7595 EXPECT_TRUE(response.metadata.get() == NULL);
6842 7596
6843 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 7597 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6844 EXPECT_EQ(2, cache.disk_cache()->open_count()); 7598 EXPECT_EQ(2, cache.disk_cache()->open_count());
6845 EXPECT_EQ(1, cache.disk_cache()->create_count()); 7599 EXPECT_EQ(1, cache.disk_cache()->create_count());
6846 } 7600 }
6847 7601
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 7602 // Tests that we ignore VARY checks when writing metadata since the request
6889 // headers for the WriteMetadata transaction are made up. 7603 // headers for the WriteMetadata transaction are made up.
6890 TEST(HttpCache, WriteMetadata_IgnoreVary) { 7604 TEST(HttpCache, WriteMetadata_IgnoreVary) {
6891 MockHttpCache cache; 7605 MockHttpCache cache;
6892 7606
6893 // Write to the cache 7607 // Write to the cache
6894 HttpResponseInfo response; 7608 HttpResponseInfo response;
6895 ScopedMockTransaction transaction(kSimpleGET_Transaction); 7609 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6896 transaction.request_headers = "accept-encoding: gzip\r\n"; 7610 transaction.request_headers = "accept-encoding: gzip\r\n";
6897 transaction.response_headers = 7611 transaction.response_headers =
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
7205 MockHttpRequest request(mock_transaction); 7919 MockHttpRequest request(mock_transaction);
7206 7920
7207 { 7921 {
7208 std::unique_ptr<HttpTransaction> trans; 7922 std::unique_ptr<HttpTransaction> trans;
7209 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); 7923 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7210 7924
7211 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); 7925 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7212 EXPECT_THAT(callback.GetResult(rv), IsOk()); 7926 EXPECT_THAT(callback.GetResult(rv), IsOk());
7213 7927
7214 trans->StopCaching(); 7928 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 } 7929 }
7220 RemoveMockTransaction(&mock_transaction); 7930 RemoveMockTransaction(&mock_transaction);
7221 7931
7222 // Make sure that the ActiveEntry is gone. 7932 // Make sure that the ActiveEntry is gone.
7223 base::RunLoop().RunUntilIdle(); 7933 base::RunLoop().RunUntilIdle();
7224 7934
7225 // Verify that the entry is gone. 7935 // Verify that the entry is gone.
7226 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 7936 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
7227 7937
7228 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 7938 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( 8970 ASSERT_TRUE(attrs->GetDictionary(
8261 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); 8971 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs));
8262 std::string size; 8972 std::string size;
8263 ASSERT_TRUE(size_attrs->GetString("value", &size)); 8973 ASSERT_TRUE(size_attrs->GetString("value", &size));
8264 int actual_size = 0; 8974 int actual_size = 0;
8265 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); 8975 ASSERT_TRUE(base::HexStringToInt(size, &actual_size));
8266 ASSERT_LT(0, actual_size); 8976 ASSERT_LT(0, actual_size);
8267 } 8977 }
8268 8978
8269 } // namespace net 8979 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698