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

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

Issue 2721933002: HttpCache::Transaction layer allowing parallel validation (Closed)
Patch Set: Rebased with refs/heads/master@{#475007} Created 3 years, 6 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
« no previous file with comments | « net/http/http_cache_transaction.cc ('k') | net/http/http_transaction.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 1183
1169 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) { 1184 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1170 MockHttpCache cache; 1185 MockHttpCache cache;
1171 1186
1172 // write to the cache 1187 // write to the cache
1173 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1188 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1174 1189
1175 // force this transaction to write to the cache again 1190 // force this transaction to write to the cache again
1176 MockTransaction transaction(kSimpleGET_Transaction); 1191 MockTransaction transaction(kSimpleGET_Transaction);
1177 transaction.request_headers = "pragma: no-cache\r\n"; 1192 transaction.request_headers = "pragma: no-cache\r\n";
1178 1193
shivanisha 2017/05/26 16:10:37 Starting from here till my next comment, these tes
1179 RunTransactionTest(cache.http_cache(), transaction); 1194 RunTransactionTest(cache.http_cache(), transaction);
1180 1195
1181 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1196 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1182 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1197 EXPECT_EQ(0, cache.disk_cache()->open_count());
1183 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1198 EXPECT_EQ(2, cache.disk_cache()->create_count());
1184 } 1199 }
1185 1200
1186 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) { 1201 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1187 MockHttpCache cache; 1202 MockHttpCache cache;
1188 1203
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 1335
1321 // Tests that we don't remove extra headers for conditionalized requests. 1336 // Tests that we don't remove extra headers for conditionalized requests.
1322 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) { 1337 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1323 MockHttpCache cache; 1338 MockHttpCache cache;
1324 1339
1325 // Write to the cache. 1340 // Write to the cache.
1326 RunTransactionTest(cache.http_cache(), kETagGET_Transaction); 1341 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1327 1342
1328 MockTransaction transaction(kETagGET_Transaction); 1343 MockTransaction transaction(kETagGET_Transaction);
1329 transaction.handler = PreserveRequestHeaders_Handler; 1344 transaction.handler = PreserveRequestHeaders_Handler;
1330 transaction.request_headers = "If-None-Match: \"foopy\"\r\n" 1345 transaction.request_headers = "If-None-Match: \"foopy\"\r\n" EXTRA_HEADER;
1331 EXTRA_HEADER;
1332 AddMockTransaction(&transaction); 1346 AddMockTransaction(&transaction);
1333 1347
1334 RunTransactionTest(cache.http_cache(), transaction); 1348 RunTransactionTest(cache.http_cache(), transaction);
1335 1349
1336 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1350 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1337 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1351 EXPECT_EQ(1, cache.disk_cache()->open_count());
1338 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1352 EXPECT_EQ(1, cache.disk_cache()->create_count());
1339 RemoveMockTransaction(&transaction); 1353 RemoveMockTransaction(&transaction);
1340 } 1354 }
1341 1355
shivanisha 2017/05/26 16:10:37 Starting from my last comment till here, these tes
1342 TEST(HttpCache, SimpleGET_ManyReaders) { 1356 TEST(HttpCache, SimpleGET_ManyReaders) {
1343 MockHttpCache cache; 1357 MockHttpCache cache;
1344 1358
1345 MockHttpRequest request(kSimpleGET_Transaction); 1359 MockHttpRequest request(kSimpleGET_Transaction);
1346 1360
1347 std::vector<std::unique_ptr<Context>> context_list; 1361 std::vector<std::unique_ptr<Context>> context_list;
1348 const int kNumTransactions = 5; 1362 const int kNumTransactions = 5;
1349 1363
1350 for (int i = 0; i < kNumTransactions; ++i) { 1364 for (int i = 0; i < kNumTransactions; ++i) {
1351 context_list.push_back(base::MakeUnique<Context>()); 1365 context_list.push_back(base::MakeUnique<Context>());
1352 Context* c = context_list[i].get(); 1366 auto& c = context_list[i];
1353 1367
1354 c->result = cache.CreateTransaction(&c->trans); 1368 c->result = cache.CreateTransaction(&c->trans);
1355 ASSERT_THAT(c->result, IsOk()); 1369 ASSERT_THAT(c->result, IsOk());
1370 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1371
1372 c->result =
1373 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1374 }
1375
1376 // All requests are waiting for the active entry.
1377 for (auto& context : context_list) {
1378 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1379 }
1380
1381 // Allow all requests to move from the Create queue to the active entry.
1382 base::RunLoop().RunUntilIdle();
1383
1384 // The first request should be a writer at this point, and the subsequent
1385 // requests should have passed the validation phase and waiting for the
1386 // response to be written to the cache before they can read.
1387 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1388 EXPECT_EQ(kNumTransactions - 1,
1389 cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1390
1391 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1392 EXPECT_EQ(0, cache.disk_cache()->open_count());
1393 EXPECT_EQ(1, cache.disk_cache()->create_count());
1394
1395 // All requests depend on the writer, and the writer is between Start and
1396 // Read, i.e. idle.
1397 for (auto& context : context_list) {
1398 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1399 }
1400
1401 for (int i = 0; i < kNumTransactions; ++i) {
1402 auto& c = context_list[i];
1403 if (c->result == ERR_IO_PENDING)
1404 c->result = c->callback.WaitForResult();
1405
1406 if (i > 0) {
1407 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1408 EXPECT_EQ(kNumTransactions - i,
1409 cache.GetCountReaders(kSimpleGET_Transaction.url));
1410 }
1411
1412 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1413 }
1414
1415 // We should not have had to re-open the disk entry
1416
1417 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1418 EXPECT_EQ(0, cache.disk_cache()->open_count());
1419 EXPECT_EQ(1, cache.disk_cache()->create_count());
1420 }
1421
1422 // Tests that we can have parallel validation on range requests.
1423 TEST(HttpCache, RangeGET_ParallelValidationNoMatch) {
1424 MockHttpCache cache;
1425
1426 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1427 MockHttpRequest request(transaction);
1428
1429 std::vector<std::unique_ptr<Context>> context_list;
1430 const int kNumTransactions = 5;
1431
1432 for (int i = 0; i < kNumTransactions; ++i) {
1433 context_list.push_back(base::MakeUnique<Context>());
1434 auto& c = context_list[i];
1435
1436 c->result = cache.CreateTransaction(&c->trans);
1437 ASSERT_THAT(c->result, IsOk());
1438 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1439
1440 c->result =
1441 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1442 }
1443
1444 // All requests are waiting for the active entry.
1445 for (auto& context : context_list) {
1446 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1447 }
1448
1449 // Allow all requests to move from the Create queue to the active entry.
1450 base::RunLoop().RunUntilIdle();
1451
1452 // The first entry should have been doomed. Since the 1st transaction has not
1453 // started writing to the cache, MockDiskEntry::CouldBeSparse() returns false
1454 // leading to restarting the dooming the entry and restarting the second
1455 // transaction.
1456 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1457 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1458
1459 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1460 EXPECT_EQ(0, cache.disk_cache()->open_count());
1461 EXPECT_EQ(5, cache.disk_cache()->create_count());
1462
1463 for (auto& context : context_list) {
1464 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1465 }
1466
1467 for (int i = 0; i < kNumTransactions; ++i) {
1468 auto& c = context_list[i];
1469 if (c->result == ERR_IO_PENDING)
1470 c->result = c->callback.WaitForResult();
1471
1472 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
1473 }
1474
1475 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1476 EXPECT_EQ(0, cache.disk_cache()->open_count());
1477 EXPECT_EQ(5, cache.disk_cache()->create_count());
1478 }
1479
1480 // Tests parallel validation on range requests with non-overlapping ranges.
1481 TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) {
1482 MockHttpCache cache;
1483
1484 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1485
1486 std::vector<std::unique_ptr<Context>> context_list;
1487 const int kNumTransactions = 2;
1488
1489 for (int i = 0; i < kNumTransactions; ++i) {
1490 context_list.push_back(base::MakeUnique<Context>());
1491 }
1492
1493 // Let 1st transaction complete headers phase for ranges 40-49.
1494 std::string first_read;
1495 {
1496 MockHttpRequest request(transaction);
1497 auto& c = context_list[0];
1498 c->result = cache.CreateTransaction(&c->trans);
1499 ASSERT_THAT(c->result, IsOk());
1500 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1501
1502 c->result =
1503 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1504 base::RunLoop().RunUntilIdle();
1505
1506 // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
1507 // true.
1508 const int kBufferSize = 5;
1509 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
1510 ReleaseBufferCompletionCallback cb(buffer.get());
1511 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
1512 EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
1513
1514 std::string data_read(buffer->data(), kBufferSize);
1515 first_read = data_read;
1516
1517 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
1518 }
1519
1520 // 2nd transaction requests ranges 30-39.
1521 {
1522 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
1523 MockHttpRequest request(transaction);
1524 auto& c = context_list[1];
1525 c->result = cache.CreateTransaction(&c->trans);
1526 ASSERT_THAT(c->result, IsOk());
1527 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1528
1529 c->result =
1530 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1531 base::RunLoop().RunUntilIdle();
1532
1533 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1534 }
1535
1536 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1537 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1538
1539 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1540 EXPECT_EQ(0, cache.disk_cache()->open_count());
1541 EXPECT_EQ(1, cache.disk_cache()->create_count());
1542
1543 for (int i = 0; i < kNumTransactions; ++i) {
1544 auto& c = context_list[i];
1545 if (c->result == ERR_IO_PENDING)
1546 c->result = c->callback.WaitForResult();
1547
1548 if (i == 0) {
1549 ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
1550 transaction);
1551 continue;
1552 }
1553
1554 transaction.data = "rg: 30-39 ";
1555 ReadAndVerifyTransaction(c->trans.get(), transaction);
1556 }
1557
1558 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1559 EXPECT_EQ(0, cache.disk_cache()->open_count());
1560 EXPECT_EQ(1, cache.disk_cache()->create_count());
1561
1562 // Fetch from the cache to check that ranges 30-49 have been successfully
1563 // cached.
1564 {
1565 MockTransaction transaction(kRangeGET_TransactionOK);
1566 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1567 transaction.data = "rg: 30-39 rg: 40-49 ";
1568 std::string headers;
1569 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
1570 Verify206Response(headers, 30, 49);
1571 }
1572
1573 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1574 EXPECT_EQ(1, cache.disk_cache()->open_count());
1575 EXPECT_EQ(1, cache.disk_cache()->create_count());
1576 }
1577
1578 // Tests parallel validation on range requests with overlapping ranges.
1579 TEST(HttpCache, RangeGET_ParallelValidationOverlappingRanges) {
1580 MockHttpCache cache;
1581
1582 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1583
1584 std::vector<std::unique_ptr<Context>> context_list;
1585 const int kNumTransactions = 2;
1586
1587 for (int i = 0; i < kNumTransactions; ++i) {
1588 context_list.push_back(base::MakeUnique<Context>());
1589 }
1590
1591 // Let 1st transaction complete headers phase for ranges 40-49.
1592 std::string first_read;
1593 {
1594 MockHttpRequest request(transaction);
1595 auto& c = context_list[0];
1596 c->result = cache.CreateTransaction(&c->trans);
1597 ASSERT_THAT(c->result, IsOk());
1598 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1599
1600 c->result =
1601 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1602 base::RunLoop().RunUntilIdle();
1603
1604 // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
1605 // true.
1606 const int kBufferSize = 5;
1607 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
1608 ReleaseBufferCompletionCallback cb(buffer.get());
1609 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
1610 EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
1611
1612 std::string data_read(buffer->data(), kBufferSize);
1613 first_read = data_read;
1614
1615 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
1616 }
1617
1618 // 2nd transaction requests ranges 30-49.
1619 {
1620 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1621 MockHttpRequest request(transaction);
1622 auto& c = context_list[1];
1623 c->result = cache.CreateTransaction(&c->trans);
1624 ASSERT_THAT(c->result, IsOk());
1625 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1626
1627 c->result =
1628 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1629 base::RunLoop().RunUntilIdle();
1630
1631 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1632 }
1633
1634 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
1635 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
1636
1637 // Should have created another transaction for the uncached range.
1638 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1639 EXPECT_EQ(0, cache.disk_cache()->open_count());
1640 EXPECT_EQ(1, cache.disk_cache()->create_count());
1641
1642 for (int i = 0; i < kNumTransactions; ++i) {
1643 auto& c = context_list[i];
1644 if (c->result == ERR_IO_PENDING)
1645 c->result = c->callback.WaitForResult();
1646
1647 if (i == 0) {
1648 ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
1649 transaction);
1650 continue;
1651 }
1652
1653 transaction.data = "rg: 30-39 rg: 40-49 ";
1654 ReadAndVerifyTransaction(c->trans.get(), transaction);
1655 }
1656
1657 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1658 EXPECT_EQ(0, cache.disk_cache()->open_count());
1659 EXPECT_EQ(1, cache.disk_cache()->create_count());
1660
1661 // Fetch from the cache to check that ranges 30-49 have been successfully
1662 // cached.
1663 {
1664 MockTransaction transaction(kRangeGET_TransactionOK);
1665 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
1666 transaction.data = "rg: 30-39 rg: 40-49 ";
1667 std::string headers;
1668 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
1669 Verify206Response(headers, 30, 49);
1670 }
1671
1672 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1673 EXPECT_EQ(0, cache.disk_cache()->open_count());
1674 EXPECT_EQ(1, cache.disk_cache()->create_count());
1675 }
1676
1677 // Parallel validation results in 200.
1678 TEST(HttpCache, SimpleGET_ParallelValidationNoMatch) {
1679 MockHttpCache cache;
1680 MockHttpRequest request(kSimpleGET_Transaction);
1681 request.load_flags |= LOAD_VALIDATE_CACHE;
1682 std::vector<std::unique_ptr<Context>> context_list;
1683 const int kNumTransactions = 5;
1684 for (int i = 0; i < kNumTransactions; ++i) {
1685 context_list.push_back(base::MakeUnique<Context>());
1686 auto& c = context_list[i];
1687 c->result = cache.CreateTransaction(&c->trans);
1688 ASSERT_THAT(c->result, IsOk());
1689 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1690 c->result =
1691 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1692 }
1693
1694 // All requests are waiting for the active entry.
1695 for (auto& context : context_list) {
1696 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1697 }
1698
1699 // Allow all requests to move from the Create queue to the active entry.
1700 base::RunLoop().RunUntilIdle();
1701
1702 // The first request should be a writer at this point, and the subsequent
1703 // requests should have passed the validation phase and created their own
1704 // entries since none of them matched the headers of the earlier one.
1705 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1706
1707 // Note that there are only 3 entries created and not 5 since every other
1708 // transaction would have gone to the network.
1709 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1710 EXPECT_EQ(0, cache.disk_cache()->open_count());
1711 EXPECT_EQ(3, cache.disk_cache()->create_count());
1712
1713 // All requests depend on the writer, and the writer is between Start and
1714 // Read, i.e. idle.
1715 for (auto& context : context_list) {
1716 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1717 }
1718
1719 for (auto& context : context_list) {
1720 if (context->result == ERR_IO_PENDING)
1721 context->result = context->callback.WaitForResult();
1722 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1723 }
1724
1725 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1726 EXPECT_EQ(0, cache.disk_cache()->open_count());
1727 EXPECT_EQ(3, cache.disk_cache()->create_count());
1728 }
1729
1730 // Tests that a GET followed by a DELETE results in DELETE immediately starting
1731 // the headers phase and the entry is doomed.
1732 TEST(HttpCache, SimpleGET_ParallelValidationDelete) {
1733 MockHttpCache cache;
1734
1735 MockHttpRequest request(kSimpleGET_Transaction);
1736 request.load_flags |= LOAD_VALIDATE_CACHE;
1737
1738 MockHttpRequest delete_request(kSimpleGET_Transaction);
1739 delete_request.method = "DELETE";
1740
1741 std::vector<std::unique_ptr<Context>> context_list;
1742 const int kNumTransactions = 2;
1743
1744 for (int i = 0; i < kNumTransactions; ++i) {
1745 context_list.push_back(base::MakeUnique<Context>());
1746 auto& c = context_list[i];
1747
1748 MockHttpRequest* this_request = &request;
1749 if (i == 1)
1750 this_request = &delete_request;
1751
1752 c->result = cache.CreateTransaction(&c->trans);
1753 ASSERT_THAT(c->result, IsOk());
1754 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1755
1756 c->result = c->trans->Start(this_request, c->callback.callback(),
1757 NetLogWithSource());
1758 }
1759
1760 // All requests are waiting for the active entry.
1761 for (auto& context : context_list) {
1762 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1763 }
1764
1765 // Allow all requests to move from the Create queue to the active entry.
1766 base::RunLoop().RunUntilIdle();
1767
1768 // The first request should be a writer at this point, and the subsequent
1769 // request should have passed the validation phase and doomed the existing
1770 // entry.
1771 EXPECT_TRUE(
1772 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
1773
1774 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1775 EXPECT_EQ(0, cache.disk_cache()->open_count());
1776 EXPECT_EQ(1, cache.disk_cache()->create_count());
1777
1778 // All requests depend on the writer, and the writer is between Start and
1779 // Read, i.e. idle.
1780 for (auto& context : context_list) {
1781 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1782 }
1783
1784 for (auto& context : context_list) {
1785 if (context->result == ERR_IO_PENDING)
1786 context->result = context->callback.WaitForResult();
1787 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1788 }
1789
1790 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1791 EXPECT_EQ(0, cache.disk_cache()->open_count());
1792 EXPECT_EQ(1, cache.disk_cache()->create_count());
1793 }
1794
1795 // Tests that a transaction which is in validated queue can be destroyed without
1796 // any impact to other transactions.
1797 TEST(HttpCache, SimpleGET_ParallelValidationCancelValidated) {
1798 MockHttpCache cache;
1799
1800 MockHttpRequest request(kSimpleGET_Transaction);
1801
1802 std::vector<std::unique_ptr<Context>> context_list;
1803 const int kNumTransactions = 2;
1804
1805 for (int i = 0; i < kNumTransactions; ++i) {
1806 context_list.push_back(base::MakeUnique<Context>());
1807 auto& c = context_list[i];
1808
1809 c->result = cache.CreateTransaction(&c->trans);
1810 ASSERT_THAT(c->result, IsOk());
1811
1812 c->result =
1813 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1814 }
1815
1816 // Allow all requests to move from the Create queue to the active entry.
1817 base::RunLoop().RunUntilIdle();
1818
1819 // The first request should be a writer at this point, and the subsequent
1820 // requests should have completed validation.
1821
1822 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1823 EXPECT_EQ(0, cache.disk_cache()->open_count());
1824 EXPECT_EQ(1, cache.disk_cache()->create_count());
1825
1826 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1827 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1828
1829 context_list[1].reset();
1830
1831 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1832
1833 // Complete the rest of the transactions.
1834 for (auto& context : context_list) {
1835 if (!context)
1836 continue;
1837 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
1838 }
1839
1840 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1841 EXPECT_EQ(0, cache.disk_cache()->open_count());
1842 EXPECT_EQ(1, cache.disk_cache()->create_count());
1843 }
1844
1845 // Tests that a transaction which is in readers can be destroyed without
1846 // any impact to other transactions.
1847 TEST(HttpCache, SimpleGET_ParallelValidationCancelReader) {
1848 MockHttpCache cache;
1849
1850 MockHttpRequest request(kSimpleGET_Transaction);
1851
1852 MockTransaction transaction(kSimpleGET_Transaction);
1853 transaction.load_flags |= LOAD_VALIDATE_CACHE;
1854 MockHttpRequest validate_request(transaction);
1855
1856 int kNumTransactions = 4;
1857 std::vector<std::unique_ptr<Context>> context_list;
1858
1859 for (int i = 0; i < kNumTransactions; ++i) {
1860 context_list.push_back(base::MakeUnique<Context>());
1861 auto& c = context_list[i];
1862
1863 c->result = cache.CreateTransaction(&c->trans);
1864 ASSERT_THAT(c->result, IsOk());
1865
1866 MockHttpRequest* this_request = &request;
1867 if (i == 3) {
1868 this_request = &validate_request;
1869 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
1870 }
1871
1872 c->result = c->trans->Start(this_request, c->callback.callback(),
1873 NetLogWithSource());
1874 }
1875
1876 // Allow all requests to move from the Create queue to the active entry.
1877 base::RunLoop().RunUntilIdle();
1878
1879 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1880 EXPECT_EQ(0, cache.disk_cache()->open_count());
1881 EXPECT_EQ(1, cache.disk_cache()->create_count());
1882
1883 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1884 EXPECT_EQ(2, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1885 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1886
1887 // Complete the response body.
1888 auto& c = context_list[0];
1889 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1890
1891 // Rest of the transactions should move to readers.
1892 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1893 EXPECT_EQ(2, cache.GetCountReaders(kSimpleGET_Transaction.url));
1894 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1895 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1896
1897 // Add 2 new transactions.
1898 kNumTransactions = 6;
1899
1900 for (int i = 4; i < kNumTransactions; ++i) {
1901 context_list.push_back(base::MakeUnique<Context>());
1902 auto& c = context_list[i];
1903
1904 c->result = cache.CreateTransaction(&c->trans);
1905 ASSERT_THAT(c->result, IsOk());
1906
1907 c->result =
1908 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1909 }
1910
1911 EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
1912
1913 // Delete a reader.
1914 context_list[1].reset();
1915
1916 // Deleting the reader did not impact any other transaction.
1917 EXPECT_EQ(1, cache.GetCountReaders(kSimpleGET_Transaction.url));
1918 EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
1919 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1920
1921 // Resume network start for headers_transaction. It will doom the entry as it
1922 // will be a 200 and will go to network for the response body.
1923 auto& context = context_list[3];
1924 context->trans->ResumeNetworkStart();
1925
1926 // The pending transactions will be added to a new entry.
1927 base::RunLoop().RunUntilIdle();
1928
1929 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1930 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1931
1932 // Complete the rest of the transactions.
1933 for (int i = 2; i < kNumTransactions; ++i) {
1934 auto& c = context_list[i];
1935 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1936 }
1937
1938 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1939 EXPECT_EQ(0, cache.disk_cache()->open_count());
1940 EXPECT_EQ(2, cache.disk_cache()->create_count());
1941 }
1942
1943 // Tests that a transaction is in validated queue and writer is destroyed
1944 // leading to restarting the validated transaction.
1945 TEST(HttpCache, SimpleGET_ParallelValidationCancelWriter) {
1946 MockHttpCache cache;
1947
1948 MockHttpRequest request(kSimpleGET_Transaction);
1949
1950 MockTransaction transaction(kSimpleGET_Transaction);
1951 transaction.load_flags |= LOAD_VALIDATE_CACHE;
1952 MockHttpRequest validate_request(transaction);
1953
1954 const int kNumTransactions = 3;
1955 std::vector<std::unique_ptr<Context>> context_list;
1956
1957 for (int i = 0; i < kNumTransactions; ++i) {
1958 context_list.push_back(base::MakeUnique<Context>());
1959 auto& c = context_list[i];
1960
1961 c->result = cache.CreateTransaction(&c->trans);
1962 ASSERT_THAT(c->result, IsOk());
1963
1964 MockHttpRequest* this_request = &request;
1965 if (i == 2) {
1966 this_request = &validate_request;
1967 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
1968 }
1969
1970 c->result = c->trans->Start(this_request, c->callback.callback(),
1971 NetLogWithSource());
1972 }
1973
1974 // Allow all requests to move from the Create queue to the active entry.
1975 base::RunLoop().RunUntilIdle();
1976
1977 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1978 EXPECT_EQ(0, cache.disk_cache()->open_count());
1979 EXPECT_EQ(1, cache.disk_cache()->create_count());
1980
1981 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1982 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1983 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
1984
1985 // Deleting the writer at this point will lead to destroying the entry and
1986 // restarting the remaining transactions which will then create a new entry.
1987 context_list[0].reset();
1988
1989 // Resume network start for headers_transaction. It should be restarted due to
1990 // writer cancellation.
1991 auto& c = context_list[2];
1992 c->trans->ResumeNetworkStart();
1993
1994 base::RunLoop().RunUntilIdle();
1995
1996 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
1997 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
1998
1999 // Resume network start for the transaction the second time.
2000 c->trans->ResumeNetworkStart();
2001 base::RunLoop().RunUntilIdle();
2002
2003 // Headers transaction would have doomed the new entry created.
2004 EXPECT_TRUE(
2005 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
2006
2007 // Complete the rest of the transactions.
2008 for (auto& context : context_list) {
2009 if (!context)
2010 continue;
2011 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
2012 }
2013
2014 EXPECT_EQ(4, cache.network_layer()->transaction_count());
2015 EXPECT_EQ(0, cache.disk_cache()->open_count());
2016 EXPECT_EQ(2, cache.disk_cache()->create_count());
2017 }
2018
2019 // Tests that a transaction is currently in headers phase and is destroyed
2020 // leading to destroying the entry.
2021 TEST(HttpCache, SimpleGET_ParallelValidationCancelHeaders) {
2022 MockHttpCache cache;
2023
2024 MockHttpRequest request(kSimpleGET_Transaction);
2025
2026 const int kNumTransactions = 2;
2027 std::vector<std::unique_ptr<Context>> context_list;
2028
2029 for (int i = 0; i < kNumTransactions; ++i) {
2030 context_list.push_back(base::MakeUnique<Context>());
2031 auto& c = context_list[i];
2032
2033 c->result = cache.CreateTransaction(&c->trans);
2034 ASSERT_THAT(c->result, IsOk());
2035
2036 if (i == 0)
2037 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
2038
2039 c->result =
2040 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2041 }
2042
2043 base::RunLoop().RunUntilIdle();
2044
2045 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
2046 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
2047
2048 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2049 EXPECT_EQ(0, cache.disk_cache()->open_count());
2050 EXPECT_EQ(1, cache.disk_cache()->create_count());
2051
2052 // Delete the headers transaction.
2053 context_list[0].reset();
2054
2055 base::RunLoop().RunUntilIdle();
2056
2057 // Complete the rest of the transactions.
2058 for (auto& context : context_list) {
2059 if (!context)
2060 continue;
2061 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
2062 }
2063
2064 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2065 EXPECT_EQ(0, cache.disk_cache()->open_count());
2066 EXPECT_EQ(2, cache.disk_cache()->create_count());
2067 }
2068
2069 // Similar to the above test, except here cache write fails and the
2070 // validated transactions should be restarted.
2071 TEST(HttpCache, SimpleGET_ParallelValidationFailWrite) {
2072 MockHttpCache cache;
2073
2074 MockHttpRequest request(kSimpleGET_Transaction);
2075
2076 const int kNumTransactions = 5;
2077 std::vector<std::unique_ptr<Context>> context_list;
2078
2079 for (int i = 0; i < kNumTransactions; ++i) {
2080 context_list.push_back(base::MakeUnique<Context>());
2081 auto& c = context_list[i];
2082
2083 c->result = cache.CreateTransaction(&c->trans);
2084 ASSERT_THAT(c->result, IsOk());
1356 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); 2085 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1357 2086
1358 c->result = 2087 c->result =
1359 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 2088 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1360 } 2089 }
1361 2090
1362 // All requests are waiting for the active entry. 2091 // All requests are waiting for the active entry.
1363 for (int i = 0; i < kNumTransactions; ++i) { 2092 for (auto& context : context_list) {
1364 Context* c = context_list[i].get(); 2093 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1365 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1366 } 2094 }
1367 2095
1368 // Allow all requests to move from the Create queue to the active entry. 2096 // Allow all requests to move from the Create queue to the active entry.
1369 base::RunLoop().RunUntilIdle(); 2097 base::RunLoop().RunUntilIdle();
1370 2098
1371 // The first request should be a writer at this point, and the subsequent 2099 // The first request should be a writer at this point, and the subsequent
1372 // requests should be pending. 2100 // requests should have passed the validation phase and waiting for the
2101 // response to be written to the cache before they can read.
2102 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
2103 EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
2104
2105 // All requests depend on the writer, and the writer is between Start and
2106 // Read, i.e. idle.
2107 for (auto& context : context_list) {
2108 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2109 }
2110
2111 // The first request should be a writer at this point, and the subsequent
2112 // requests should have passed the validation phase and waiting for the
2113 // response to be written to the cache before they can read.
1373 2114
1374 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2115 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1375 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2116 EXPECT_EQ(0, cache.disk_cache()->open_count());
1376 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2117 EXPECT_EQ(1, cache.disk_cache()->create_count());
1377 2118
1378 // All requests depend on the writer, and the writer is between Start and 2119 // Fail the request.
1379 // Read, i.e. idle. 2120 cache.disk_cache()->set_soft_failures(true);
1380 for (int i = 0; i < kNumTransactions; ++i) { 2121 // We have to open the entry again to propagate the failure flag.
1381 Context* c = context_list[i].get(); 2122 disk_cache::Entry* en;
1382 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); 2123 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en);
1383 } 2124 en->Close();
1384 2125
1385 for (int i = 0; i < kNumTransactions; ++i) { 2126 for (int i = 0; i < kNumTransactions; ++i) {
1386 Context* c = context_list[i].get(); 2127 auto& c = context_list[i];
1387 if (c->result == ERR_IO_PENDING) 2128 if (c->result == ERR_IO_PENDING)
1388 c->result = c->callback.WaitForResult(); 2129 c->result = c->callback.WaitForResult();
2130 if (i == 1) {
2131 // The earlier entry must be destroyed and its disk entry doomed.
2132 EXPECT_TRUE(
2133 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
2134 }
1389 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2135 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1390 } 2136 }
1391 2137
1392 // We should not have had to re-open the disk entry 2138 // Since validated transactions were restarted and new entry read/write
1393 2139 // operations would also fail, all requests would have gone to the network.
1394 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2140 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1395 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2141 EXPECT_EQ(1, cache.disk_cache()->open_count());
1396 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2142 EXPECT_EQ(5, cache.disk_cache()->create_count());
1397 } 2143 }
1398 2144
1399 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. 2145 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1400 // If cancelling a request is racing with another request for the same resource 2146 // If cancelling a request is racing with another request for the same resource
1401 // finishing, we have to make sure that we remove both transactions from the 2147 // finishing, we have to make sure that we remove both transactions from the
1402 // entry. 2148 // entry.
1403 TEST(HttpCache, SimpleGET_RacingReaders) { 2149 TEST(HttpCache, SimpleGET_RacingReaders) {
1404 MockHttpCache cache; 2150 MockHttpCache cache;
1405 2151
1406 MockHttpRequest request(kSimpleGET_Transaction); 2152 MockHttpRequest request(kSimpleGET_Transaction);
(...skipping 26 matching lines...) Expand all
1433 2179
1434 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2180 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1435 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2181 EXPECT_EQ(0, cache.disk_cache()->open_count());
1436 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2182 EXPECT_EQ(1, cache.disk_cache()->create_count());
1437 2183
1438 Context* c = context_list[0].get(); 2184 Context* c = context_list[0].get();
1439 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2185 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1440 c->result = c->callback.WaitForResult(); 2186 c->result = c->callback.WaitForResult();
1441 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2187 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1442 2188
1443 // Now we have 2 active readers and two queued transactions. 2189 // Now all transactions should be waiting for read to be invoked. Two readers
1444 2190 // are because of the load flags and remaining two transactions were converted
2191 // to readers after skipping validation. Note that the remaining two went on
2192 // to process the headers in parallel with readers present on the entry.
1445 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); 2193 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
1446 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, 2194 EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState());
1447 context_list[3]->trans->GetLoadState());
1448 2195
1449 c = context_list[1].get(); 2196 c = context_list[1].get();
1450 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2197 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1451 c->result = c->callback.WaitForResult(); 2198 c->result = c->callback.WaitForResult();
1452 if (c->result == OK) 2199 if (c->result == OK)
1453 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2200 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1454 2201
1455 // At this point we have one reader, two pending transactions and a task on 2202 // At this point we have one reader, two pending transactions and a task on
1456 // the queue to move to the next transaction. Now we cancel the request that 2203 // the queue to move to the next transaction. Now we cancel the request that
1457 // is the current reader, and expect the queued task to be able to start the 2204 // is the current reader, and expect the queued task to be able to start the
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 ASSERT_THAT(c->result, IsOk()); 2244 ASSERT_THAT(c->result, IsOk());
1498 2245
1499 MockHttpRequest* this_request = &request; 2246 MockHttpRequest* this_request = &request;
1500 if (i == 3) 2247 if (i == 3)
1501 this_request = &writer_request; 2248 this_request = &writer_request;
1502 2249
1503 c->result = c->trans->Start(this_request, c->callback.callback(), 2250 c->result = c->trans->Start(this_request, c->callback.callback(),
1504 NetLogWithSource()); 2251 NetLogWithSource());
1505 } 2252 }
1506 2253
2254 base::RunLoop().RunUntilIdle();
2255
1507 // The first request should be a writer at this point, and the two subsequent 2256 // The first request should be a writer at this point, and the two subsequent
1508 // requests should be pending. The last request doomed the first entry. 2257 // requests should be pending. The last request doomed the first entry.
1509 2258
1510 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2259 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1511 2260
1512 // Cancel the first queued transaction. 2261 // Cancel the second transaction. Note that this and the 3rd transactions
2262 // would have completed their headers phase and would be waiting in the
2263 // done_headers_queue when the 2nd transaction is cancelled.
1513 context_list[1].reset(); 2264 context_list[1].reset();
1514 2265
1515 for (int i = 0; i < kNumTransactions; ++i) { 2266 for (int i = 0; i < kNumTransactions; ++i) {
1516 if (i == 1) 2267 if (i == 1)
1517 continue; 2268 continue;
1518 Context* c = context_list[i].get(); 2269 Context* c = context_list[i].get();
1519 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2270 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1520 c->result = c->callback.WaitForResult(); 2271 c->result = c->callback.WaitForResult();
1521 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2272 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1522 } 2273 }
(...skipping 21 matching lines...) Expand all
1544 ASSERT_THAT(c->result, IsOk()); 2295 ASSERT_THAT(c->result, IsOk());
1545 2296
1546 c->result = 2297 c->result =
1547 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 2298 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1548 } 2299 }
1549 2300
1550 // Allow all requests to move from the Create queue to the active entry. 2301 // Allow all requests to move from the Create queue to the active entry.
1551 base::RunLoop().RunUntilIdle(); 2302 base::RunLoop().RunUntilIdle();
1552 2303
1553 // The first request should be a writer at this point, and the subsequent 2304 // The first request should be a writer at this point, and the subsequent
1554 // requests should be pending. 2305 // requests should have completed validation. Since the validation does not
2306 // result in a match, a new entry would be created.
1555 2307
1556 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2308 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1557 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2309 EXPECT_EQ(0, cache.disk_cache()->open_count());
1558 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2310 EXPECT_EQ(2, cache.disk_cache()->create_count());
1559 2311
1560 // Now, make sure that the second request asks for the entry not to be stored. 2312 // Now, make sure that the second request asks for the entry not to be stored.
1561 request_handler.set_no_store(true); 2313 request_handler.set_no_store(true);
1562 2314
1563 for (int i = 0; i < kNumTransactions; ++i) { 2315 for (int i = 0; i < kNumTransactions; ++i) {
1564 Context* c = context_list[i].get(); 2316 Context* c = context_list[i].get();
1565 if (c->result == ERR_IO_PENDING) 2317 if (c->result == ERR_IO_PENDING)
1566 c->result = c->callback.WaitForResult(); 2318 c->result = c->callback.WaitForResult();
1567 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); 2319 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1568 context_list[i].reset(); 2320 context_list[i].reset();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 2354
1603 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2355 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1604 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2356 EXPECT_EQ(0, cache.disk_cache()->open_count());
1605 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2357 EXPECT_EQ(1, cache.disk_cache()->create_count());
1606 2358
1607 for (int i = 0; i < kNumTransactions; ++i) { 2359 for (int i = 0; i < kNumTransactions; ++i) {
1608 Context* c = context_list[i].get(); 2360 Context* c = context_list[i].get();
1609 if (c->result == ERR_IO_PENDING) 2361 if (c->result == ERR_IO_PENDING)
1610 c->result = c->callback.WaitForResult(); 2362 c->result = c->callback.WaitForResult();
1611 // Destroy only the first transaction. 2363 // Destroy only the first transaction.
2364 // This should lead to all transactions to restart, even those that have
2365 // validated themselves and were waiting for the writer transaction to
2366 // complete writing to the cache.
1612 if (i == 0) { 2367 if (i == 0) {
1613 context_list[i].reset(); 2368 context_list[i].reset();
1614 } 2369 }
1615 } 2370 }
1616 2371
1617 // Complete the rest of the transactions. 2372 // Complete the rest of the transactions.
1618 for (int i = 1; i < kNumTransactions; ++i) { 2373 for (int i = 1; i < kNumTransactions; ++i) {
1619 Context* c = context_list[i].get(); 2374 Context* c = context_list[i].get();
1620 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2375 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1621 } 2376 }
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 } 3245 }
2491 3246
2492 // Helper that does 4 requests using HttpCache: 3247 // Helper that does 4 requests using HttpCache:
2493 // 3248 //
2494 // (1) loads |kUrl| -- expects |net_response_1| to be returned. 3249 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2495 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. 3250 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2496 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to 3251 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2497 // be returned. 3252 // be returned.
2498 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be 3253 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2499 // returned. 3254 // returned.
3255 // The entry will be created once and will be opened for the 3 subsequent
3256 // requests.
2500 static void ConditionalizedRequestUpdatesCacheHelper( 3257 static void ConditionalizedRequestUpdatesCacheHelper(
2501 const Response& net_response_1, 3258 const Response& net_response_1,
2502 const Response& net_response_2, 3259 const Response& net_response_2,
2503 const Response& cached_response_2, 3260 const Response& cached_response_2,
2504 const char* extra_request_headers) { 3261 const char* extra_request_headers) {
2505 MockHttpCache cache; 3262 MockHttpCache cache;
2506 3263
2507 // The URL we will be requesting. 3264 // The URL we will be requesting.
2508 const char kUrl[] = "http://foobar.com/main.css"; 3265 const char kUrl[] = "http://foobar.com/main.css";
2509 3266
(...skipping 3552 matching lines...) Expand 10 before | Expand all | Expand 10 after
6062 EXPECT_EQ(ERR_IO_PENDING, 6819 EXPECT_EQ(ERR_IO_PENDING,
6063 pending->trans->Start(&request, pending->callback.callback(), 6820 pending->trans->Start(&request, pending->callback.callback(),
6064 NetLogWithSource())); 6821 NetLogWithSource()));
6065 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); 6822 EXPECT_THAT(c->callback.GetResult(rv), IsOk());
6066 6823
6067 // Make sure that the entry has some data stored. 6824 // Make sure that the entry has some data stored.
6068 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); 6825 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
6069 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 6826 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
6070 EXPECT_EQ(5, c->callback.GetResult(rv)); 6827 EXPECT_EQ(5, c->callback.GetResult(rv));
6071 6828
6072 // Cancel the requests. 6829 // Since |pending| is currently validating the already written headers
6830 // it will be restarted as well.
6073 c.reset(); 6831 c.reset();
6074 pending.reset(); 6832 pending.reset();
6075 6833
6076 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 6834 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6077 EXPECT_EQ(1, cache.disk_cache()->open_count()); 6835 EXPECT_EQ(1, cache.disk_cache()->open_count());
6078 EXPECT_EQ(2, cache.disk_cache()->create_count()); 6836 EXPECT_EQ(1, cache.disk_cache()->create_count());
6079 6837
6080 base::RunLoop().RunUntilIdle(); 6838 base::RunLoop().RunUntilIdle();
6081 RemoveMockTransaction(&transaction); 6839 RemoveMockTransaction(&transaction);
6082 } 6840 }
6083 6841
6084 // Tests that we delete truncated entries if the server changes its mind midway. 6842 // Tests that we delete truncated entries if the server changes its mind midway.
6085 TEST(HttpCache, GET_IncompleteResource2) { 6843 TEST(HttpCache, GET_IncompleteResource2) {
6086 MockHttpCache cache; 6844 MockHttpCache cache;
6087 AddMockTransaction(&kRangeGET_TransactionOK); 6845 AddMockTransaction(&kRangeGET_TransactionOK);
6088 6846
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
6793 7551
6794 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 7552 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6795 &response); 7553 &response);
6796 EXPECT_TRUE(response.metadata.get() == NULL); 7554 EXPECT_TRUE(response.metadata.get() == NULL);
6797 7555
6798 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 7556 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6799 EXPECT_EQ(2, cache.disk_cache()->open_count()); 7557 EXPECT_EQ(2, cache.disk_cache()->open_count());
6800 EXPECT_EQ(1, cache.disk_cache()->create_count()); 7558 EXPECT_EQ(1, cache.disk_cache()->create_count());
6801 } 7559 }
6802 7560
6803 // Tests that if a metadata writer transaction hits cache lock timeout, it will
6804 // error out.
6805 TEST(HttpCache, WriteMetadata_CacheLockTimeout) {
6806 MockHttpCache cache;
6807
6808 // Write to the cache
6809 HttpResponseInfo response;
6810 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6811 &response);
6812 EXPECT_FALSE(response.metadata.get());
6813
6814 MockHttpRequest request(kSimpleGET_Transaction);
6815 Context c1;
6816 ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
6817 ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
6818 NetLogWithSource()));
6819
6820 cache.SimulateCacheLockTimeout();
6821
6822 // Write meta data to the same entry.
6823 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
6824 memset(buf->data(), 0, buf->size());
6825 base::strlcpy(buf->data(), "Hi there", buf->size());
6826 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6827 DEFAULT_PRIORITY, response.response_time,
6828 buf.get(), buf->size());
6829
6830 // Release the buffer before the operation takes place.
6831 buf = NULL;
6832
6833 // Makes sure we finish pending operations.
6834 base::RunLoop().RunUntilIdle();
6835
6836 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6837 &response);
6838
6839 // The writer transaction should fail due to cache lock timeout.
6840 ASSERT_FALSE(response.metadata.get());
6841 }
6842
6843 // Tests that we ignore VARY checks when writing metadata since the request 7561 // Tests that we ignore VARY checks when writing metadata since the request
6844 // headers for the WriteMetadata transaction are made up. 7562 // headers for the WriteMetadata transaction are made up.
6845 TEST(HttpCache, WriteMetadata_IgnoreVary) { 7563 TEST(HttpCache, WriteMetadata_IgnoreVary) {
6846 MockHttpCache cache; 7564 MockHttpCache cache;
6847 7565
6848 // Write to the cache 7566 // Write to the cache
6849 HttpResponseInfo response; 7567 HttpResponseInfo response;
6850 ScopedMockTransaction transaction(kSimpleGET_Transaction); 7568 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6851 transaction.request_headers = "accept-encoding: gzip\r\n"; 7569 transaction.request_headers = "accept-encoding: gzip\r\n";
6852 transaction.response_headers = 7570 transaction.response_headers =
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
7160 MockHttpRequest request(mock_transaction); 7878 MockHttpRequest request(mock_transaction);
7161 7879
7162 { 7880 {
7163 std::unique_ptr<HttpTransaction> trans; 7881 std::unique_ptr<HttpTransaction> trans;
7164 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); 7882 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7165 7883
7166 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); 7884 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7167 EXPECT_THAT(callback.GetResult(rv), IsOk()); 7885 EXPECT_THAT(callback.GetResult(rv), IsOk());
7168 7886
7169 trans->StopCaching(); 7887 trans->StopCaching();
7170
7171 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
7172 rv = trans->Read(buf.get(), 10, callback.callback());
7173 EXPECT_EQ(callback.GetResult(rv), 10);
7174 } 7888 }
7175 RemoveMockTransaction(&mock_transaction); 7889 RemoveMockTransaction(&mock_transaction);
7176 7890
7177 // Make sure that the ActiveEntry is gone. 7891 // Make sure that the ActiveEntry is gone.
7178 base::RunLoop().RunUntilIdle(); 7892 base::RunLoop().RunUntilIdle();
7179 7893
7180 // Verify that the entry is gone. 7894 // Verify that the entry is gone.
7181 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 7895 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
7182 7896
7183 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 7897 EXPECT_EQ(2, cache.network_layer()->transaction_count());
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
8216 ASSERT_TRUE(attrs->GetDictionary( 8930 ASSERT_TRUE(attrs->GetDictionary(
8217 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); 8931 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs));
8218 std::string size; 8932 std::string size;
8219 ASSERT_TRUE(size_attrs->GetString("value", &size)); 8933 ASSERT_TRUE(size_attrs->GetString("value", &size));
8220 int actual_size = 0; 8934 int actual_size = 0;
8221 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); 8935 ASSERT_TRUE(base::HexStringToInt(size, &actual_size));
8222 ASSERT_LT(0, actual_size); 8936 ASSERT_LT(0, actual_size);
8223 } 8937 }
8224 8938
8225 } // namespace net 8939 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_cache_transaction.cc ('k') | net/http/http_transaction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698