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

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

Issue 2721933002: HttpCache::Transaction layer allowing parallel validation (Closed)
Patch Set: nit addressed 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 1125 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
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 when a writer is destroyed mid-read and entry is marked as truncated,
2020 // it should lead to restarting the dependent transactions.
2021 TEST(HttpCache, SimpleGET_ParallelValidationCancelWriterTruncateEntry) {
2022 MockHttpCache cache;
2023
2024 ScopedMockTransaction transaction(kSimpleGET_Transaction);
2025 transaction.response_headers =
2026 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2027 "Content-Length: 22\n"
2028 "Etag: \"foopy\"\n";
2029 MockHttpRequest request(transaction);
2030
2031 const int kNumTransactions = 3;
2032 std::vector<std::unique_ptr<Context>> context_list;
2033
2034 for (int i = 0; i < kNumTransactions; ++i) {
2035 context_list.push_back(base::MakeUnique<Context>());
2036 auto& c = context_list[i];
2037
2038 c->result = cache.CreateTransaction(&c->trans);
2039 ASSERT_THAT(c->result, IsOk());
2040
2041 c->result =
2042 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2043 }
2044
2045 // Allow all requests to move from the Create queue to the active entry.
2046 base::RunLoop().RunUntilIdle();
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 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
2053 EXPECT_EQ(2, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
2054
2055 // Let first transaction read some bytes, so that entry can be marked as
2056 // truncated.
2057 {
2058 auto& c = context_list[0];
2059 const int kBufferSize = 5;
2060 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
2061 ReleaseBufferCompletionCallback cb(buffer.get());
2062 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
2063 EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
2064 }
2065
2066 // Deleting the writer at this point will lead to restarting the remaining
2067 // transactions which will then be able to read the truncated status of the
2068 // entry.
2069 context_list[0].reset();
2070
2071 base::RunLoop().RunUntilIdle();
2072
2073 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2074 EXPECT_EQ(0, cache.disk_cache()->open_count());
2075 EXPECT_EQ(1, cache.disk_cache()->create_count());
2076
2077 // Complete the rest of the transactions.
2078 for (auto& context : context_list) {
2079 if (!context)
2080 continue;
2081 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
2082 }
2083 }
2084
2085 // Tests that when StopCaching is invoked on a writer, dependent transactions
2086 // are restarted.
2087 TEST(HttpCache, SimpleGET_ParallelValidationStopCaching) {
2088 MockHttpCache cache;
2089
2090 MockHttpRequest request(kSimpleGET_Transaction);
2091
2092 MockTransaction transaction(kSimpleGET_Transaction);
2093 transaction.load_flags |= LOAD_VALIDATE_CACHE;
2094 MockHttpRequest validate_request(transaction);
2095
2096 const int kNumTransactions = 3;
2097 std::vector<std::unique_ptr<Context>> context_list;
2098
2099 for (int i = 0; i < kNumTransactions; ++i) {
2100 context_list.push_back(base::MakeUnique<Context>());
2101 auto& c = context_list[i];
2102
2103 c->result = cache.CreateTransaction(&c->trans);
2104 ASSERT_THAT(c->result, IsOk());
2105
2106 MockHttpRequest* this_request = &request;
2107 if (i == 2) {
2108 this_request = &validate_request;
2109 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
2110 }
2111
2112 c->result = c->trans->Start(this_request, c->callback.callback(),
2113 NetLogWithSource());
2114 }
2115
2116 // Allow all requests to move from the Create queue to the active entry.
2117 base::RunLoop().RunUntilIdle();
2118
2119 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2120 EXPECT_EQ(0, cache.disk_cache()->open_count());
2121 EXPECT_EQ(1, cache.disk_cache()->create_count());
2122
2123 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
2124 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
2125 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
2126
2127 // Invoking StopCaching on the writer will lead to dooming the entry and
2128 // restarting the remaining transactions which will then create a new entry.
2129 context_list[0]->trans->StopCaching();
2130
2131 // Resume network start for headers_transaction. It should be restarted due to
2132 // writer cancellation.
2133 auto& c = context_list[2];
2134 c->trans->ResumeNetworkStart();
2135
2136 base::RunLoop().RunUntilIdle();
2137
2138 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
2139 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
2140
2141 // Resume network start for the transaction the second time.
2142 c->trans->ResumeNetworkStart();
2143 base::RunLoop().RunUntilIdle();
2144
2145 // Headers transaction would have doomed the new entry created.
2146 EXPECT_TRUE(
2147 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
2148
2149 // Complete the rest of the transactions.
2150 for (auto& context : context_list) {
2151 if (!context)
2152 continue;
2153 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
2154 }
2155
2156 EXPECT_EQ(4, cache.network_layer()->transaction_count());
2157 EXPECT_EQ(0, cache.disk_cache()->open_count());
2158 EXPECT_EQ(2, cache.disk_cache()->create_count());
2159 }
2160
2161 // Tests that a transaction is currently in headers phase and is destroyed
2162 // leading to destroying the entry.
2163 TEST(HttpCache, SimpleGET_ParallelValidationCancelHeaders) {
2164 MockHttpCache cache;
2165
2166 MockHttpRequest request(kSimpleGET_Transaction);
2167
2168 const int kNumTransactions = 2;
2169 std::vector<std::unique_ptr<Context>> context_list;
2170
2171 for (int i = 0; i < kNumTransactions; ++i) {
2172 context_list.push_back(base::MakeUnique<Context>());
2173 auto& c = context_list[i];
2174
2175 c->result = cache.CreateTransaction(&c->trans);
2176 ASSERT_THAT(c->result, IsOk());
2177
2178 if (i == 0)
2179 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart));
2180
2181 c->result =
2182 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2183 }
2184
2185 base::RunLoop().RunUntilIdle();
2186
2187 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
2188 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
2189
2190 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2191 EXPECT_EQ(0, cache.disk_cache()->open_count());
2192 EXPECT_EQ(1, cache.disk_cache()->create_count());
2193
2194 // Delete the headers transaction.
2195 context_list[0].reset();
2196
2197 base::RunLoop().RunUntilIdle();
2198
2199 // Complete the rest of the transactions.
2200 for (auto& context : context_list) {
2201 if (!context)
2202 continue;
2203 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
2204 }
2205
2206 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2207 EXPECT_EQ(0, cache.disk_cache()->open_count());
2208 EXPECT_EQ(2, cache.disk_cache()->create_count());
2209 }
2210
2211 // Similar to the above test, except here cache write fails and the
2212 // validated transactions should be restarted.
2213 TEST(HttpCache, SimpleGET_ParallelValidationFailWrite) {
2214 MockHttpCache cache;
2215
2216 MockHttpRequest request(kSimpleGET_Transaction);
2217
2218 const int kNumTransactions = 5;
2219 std::vector<std::unique_ptr<Context>> context_list;
2220
2221 for (int i = 0; i < kNumTransactions; ++i) {
2222 context_list.push_back(base::MakeUnique<Context>());
2223 auto& c = context_list[i];
2224
2225 c->result = cache.CreateTransaction(&c->trans);
2226 ASSERT_THAT(c->result, IsOk());
1356 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); 2227 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1357 2228
1358 c->result = 2229 c->result =
1359 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 2230 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1360 } 2231 }
1361 2232
1362 // All requests are waiting for the active entry. 2233 // All requests are waiting for the active entry.
1363 for (int i = 0; i < kNumTransactions; ++i) { 2234 for (auto& context : context_list) {
1364 Context* c = context_list[i].get(); 2235 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
1365 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1366 } 2236 }
1367 2237
1368 // Allow all requests to move from the Create queue to the active entry. 2238 // Allow all requests to move from the Create queue to the active entry.
1369 base::RunLoop().RunUntilIdle(); 2239 base::RunLoop().RunUntilIdle();
1370 2240
1371 // The first request should be a writer at this point, and the subsequent 2241 // The first request should be a writer at this point, and the subsequent
1372 // requests should be pending. 2242 // requests should have passed the validation phase and waiting for the
2243 // response to be written to the cache before they can read.
2244 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
2245 EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
2246
2247 // All requests depend on the writer, and the writer is between Start and
2248 // Read, i.e. idle.
2249 for (auto& context : context_list) {
2250 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2251 }
2252
2253 // The first request should be a writer at this point, and the subsequent
2254 // requests should have passed the validation phase and waiting for the
2255 // response to be written to the cache before they can read.
1373 2256
1374 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2257 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1375 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2258 EXPECT_EQ(0, cache.disk_cache()->open_count());
1376 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2259 EXPECT_EQ(1, cache.disk_cache()->create_count());
1377 2260
1378 // All requests depend on the writer, and the writer is between Start and 2261 // Fail the request.
1379 // Read, i.e. idle. 2262 cache.disk_cache()->set_soft_failures(true);
1380 for (int i = 0; i < kNumTransactions; ++i) { 2263 // We have to open the entry again to propagate the failure flag.
1381 Context* c = context_list[i].get(); 2264 disk_cache::Entry* en;
1382 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); 2265 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en);
1383 } 2266 en->Close();
1384 2267
1385 for (int i = 0; i < kNumTransactions; ++i) { 2268 for (int i = 0; i < kNumTransactions; ++i) {
1386 Context* c = context_list[i].get(); 2269 auto& c = context_list[i];
1387 if (c->result == ERR_IO_PENDING) 2270 if (c->result == ERR_IO_PENDING)
1388 c->result = c->callback.WaitForResult(); 2271 c->result = c->callback.WaitForResult();
2272 if (i == 1) {
2273 // The earlier entry must be destroyed and its disk entry doomed.
2274 EXPECT_TRUE(
2275 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url));
2276 }
1389 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2277 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1390 } 2278 }
1391 2279
1392 // We should not have had to re-open the disk entry 2280 // Since validated transactions were restarted and new entry read/write
1393 2281 // operations would also fail, all requests would have gone to the network.
1394 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2282 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1395 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2283 EXPECT_EQ(1, cache.disk_cache()->open_count());
1396 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2284 EXPECT_EQ(5, cache.disk_cache()->create_count());
1397 } 2285 }
1398 2286
1399 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. 2287 // 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 2288 // 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 2289 // finishing, we have to make sure that we remove both transactions from the
1402 // entry. 2290 // entry.
1403 TEST(HttpCache, SimpleGET_RacingReaders) { 2291 TEST(HttpCache, SimpleGET_RacingReaders) {
1404 MockHttpCache cache; 2292 MockHttpCache cache;
1405 2293
1406 MockHttpRequest request(kSimpleGET_Transaction); 2294 MockHttpRequest request(kSimpleGET_Transaction);
(...skipping 26 matching lines...) Expand all
1433 2321
1434 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2322 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1435 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2323 EXPECT_EQ(0, cache.disk_cache()->open_count());
1436 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2324 EXPECT_EQ(1, cache.disk_cache()->create_count());
1437 2325
1438 Context* c = context_list[0].get(); 2326 Context* c = context_list[0].get();
1439 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2327 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1440 c->result = c->callback.WaitForResult(); 2328 c->result = c->callback.WaitForResult();
1441 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2329 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1442 2330
1443 // Now we have 2 active readers and two queued transactions. 2331 // Now all transactions should be waiting for read to be invoked. Two readers
1444 2332 // are because of the load flags and remaining two transactions were converted
2333 // to readers after skipping validation. Note that the remaining two went on
2334 // to process the headers in parallel with readers present on the entry.
1445 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); 2335 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
1446 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, 2336 EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState());
1447 context_list[3]->trans->GetLoadState());
1448 2337
1449 c = context_list[1].get(); 2338 c = context_list[1].get();
1450 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2339 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1451 c->result = c->callback.WaitForResult(); 2340 c->result = c->callback.WaitForResult();
1452 if (c->result == OK) 2341 if (c->result == OK)
1453 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2342 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1454 2343
1455 // At this point we have one reader, two pending transactions and a task on 2344 // 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 2345 // 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 2346 // 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()); 2386 ASSERT_THAT(c->result, IsOk());
1498 2387
1499 MockHttpRequest* this_request = &request; 2388 MockHttpRequest* this_request = &request;
1500 if (i == 3) 2389 if (i == 3)
1501 this_request = &writer_request; 2390 this_request = &writer_request;
1502 2391
1503 c->result = c->trans->Start(this_request, c->callback.callback(), 2392 c->result = c->trans->Start(this_request, c->callback.callback(),
1504 NetLogWithSource()); 2393 NetLogWithSource());
1505 } 2394 }
1506 2395
2396 base::RunLoop().RunUntilIdle();
2397
1507 // The first request should be a writer at this point, and the two subsequent 2398 // 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. 2399 // requests should be pending. The last request doomed the first entry.
1509 2400
1510 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2401 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1511 2402
1512 // Cancel the first queued transaction. 2403 // Cancel the second transaction. Note that this and the 3rd transactions
2404 // would have completed their headers phase and would be waiting in the
2405 // done_headers_queue when the 2nd transaction is cancelled.
1513 context_list[1].reset(); 2406 context_list[1].reset();
1514 2407
1515 for (int i = 0; i < kNumTransactions; ++i) { 2408 for (int i = 0; i < kNumTransactions; ++i) {
1516 if (i == 1) 2409 if (i == 1)
1517 continue; 2410 continue;
1518 Context* c = context_list[i].get(); 2411 Context* c = context_list[i].get();
1519 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); 2412 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
1520 c->result = c->callback.WaitForResult(); 2413 c->result = c->callback.WaitForResult();
1521 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2414 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1522 } 2415 }
(...skipping 21 matching lines...) Expand all
1544 ASSERT_THAT(c->result, IsOk()); 2437 ASSERT_THAT(c->result, IsOk());
1545 2438
1546 c->result = 2439 c->result =
1547 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 2440 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1548 } 2441 }
1549 2442
1550 // Allow all requests to move from the Create queue to the active entry. 2443 // Allow all requests to move from the Create queue to the active entry.
1551 base::RunLoop().RunUntilIdle(); 2444 base::RunLoop().RunUntilIdle();
1552 2445
1553 // The first request should be a writer at this point, and the subsequent 2446 // The first request should be a writer at this point, and the subsequent
1554 // requests should be pending. 2447 // requests should have completed validation. Since the validation does not
2448 // result in a match, a new entry would be created.
1555 2449
1556 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2450 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1557 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2451 EXPECT_EQ(0, cache.disk_cache()->open_count());
1558 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2452 EXPECT_EQ(2, cache.disk_cache()->create_count());
1559 2453
1560 // Now, make sure that the second request asks for the entry not to be stored. 2454 // Now, make sure that the second request asks for the entry not to be stored.
1561 request_handler.set_no_store(true); 2455 request_handler.set_no_store(true);
1562 2456
1563 for (int i = 0; i < kNumTransactions; ++i) { 2457 for (int i = 0; i < kNumTransactions; ++i) {
1564 Context* c = context_list[i].get(); 2458 Context* c = context_list[i].get();
1565 if (c->result == ERR_IO_PENDING) 2459 if (c->result == ERR_IO_PENDING)
1566 c->result = c->callback.WaitForResult(); 2460 c->result = c->callback.WaitForResult();
1567 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); 2461 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1568 context_list[i].reset(); 2462 context_list[i].reset();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 2496
1603 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2497 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1604 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2498 EXPECT_EQ(0, cache.disk_cache()->open_count());
1605 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2499 EXPECT_EQ(1, cache.disk_cache()->create_count());
1606 2500
1607 for (int i = 0; i < kNumTransactions; ++i) { 2501 for (int i = 0; i < kNumTransactions; ++i) {
1608 Context* c = context_list[i].get(); 2502 Context* c = context_list[i].get();
1609 if (c->result == ERR_IO_PENDING) 2503 if (c->result == ERR_IO_PENDING)
1610 c->result = c->callback.WaitForResult(); 2504 c->result = c->callback.WaitForResult();
1611 // Destroy only the first transaction. 2505 // Destroy only the first transaction.
2506 // This should lead to all transactions to restart, even those that have
2507 // validated themselves and were waiting for the writer transaction to
2508 // complete writing to the cache.
1612 if (i == 0) { 2509 if (i == 0) {
1613 context_list[i].reset(); 2510 context_list[i].reset();
1614 } 2511 }
1615 } 2512 }
1616 2513
1617 // Complete the rest of the transactions. 2514 // Complete the rest of the transactions.
1618 for (int i = 1; i < kNumTransactions; ++i) { 2515 for (int i = 1; i < kNumTransactions; ++i) {
1619 Context* c = context_list[i].get(); 2516 Context* c = context_list[i].get();
1620 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 2517 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1621 } 2518 }
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 } 3387 }
2491 3388
2492 // Helper that does 4 requests using HttpCache: 3389 // Helper that does 4 requests using HttpCache:
2493 // 3390 //
2494 // (1) loads |kUrl| -- expects |net_response_1| to be returned. 3391 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2495 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. 3392 // (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 3393 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2497 // be returned. 3394 // be returned.
2498 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be 3395 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2499 // returned. 3396 // returned.
3397 // The entry will be created once and will be opened for the 3 subsequent
3398 // requests.
2500 static void ConditionalizedRequestUpdatesCacheHelper( 3399 static void ConditionalizedRequestUpdatesCacheHelper(
2501 const Response& net_response_1, 3400 const Response& net_response_1,
2502 const Response& net_response_2, 3401 const Response& net_response_2,
2503 const Response& cached_response_2, 3402 const Response& cached_response_2,
2504 const char* extra_request_headers) { 3403 const char* extra_request_headers) {
2505 MockHttpCache cache; 3404 MockHttpCache cache;
2506 3405
2507 // The URL we will be requesting. 3406 // The URL we will be requesting.
2508 const char kUrl[] = "http://foobar.com/main.css"; 3407 const char kUrl[] = "http://foobar.com/main.css";
2509 3408
(...skipping 3552 matching lines...) Expand 10 before | Expand all | Expand 10 after
6062 EXPECT_EQ(ERR_IO_PENDING, 6961 EXPECT_EQ(ERR_IO_PENDING,
6063 pending->trans->Start(&request, pending->callback.callback(), 6962 pending->trans->Start(&request, pending->callback.callback(),
6064 NetLogWithSource())); 6963 NetLogWithSource()));
6065 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); 6964 EXPECT_THAT(c->callback.GetResult(rv), IsOk());
6066 6965
6067 // Make sure that the entry has some data stored. 6966 // Make sure that the entry has some data stored.
6068 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); 6967 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
6069 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 6968 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
6070 EXPECT_EQ(5, c->callback.GetResult(rv)); 6969 EXPECT_EQ(5, c->callback.GetResult(rv));
6071 6970
6072 // Cancel the requests. 6971 // Since |pending| is currently validating the already written headers
6972 // it will be restarted as well.
6073 c.reset(); 6973 c.reset();
6074 pending.reset(); 6974 pending.reset();
6075 6975
6076 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 6976 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6077 EXPECT_EQ(1, cache.disk_cache()->open_count()); 6977 EXPECT_EQ(1, cache.disk_cache()->open_count());
6078 EXPECT_EQ(2, cache.disk_cache()->create_count()); 6978 EXPECT_EQ(1, cache.disk_cache()->create_count());
6079 6979
6080 base::RunLoop().RunUntilIdle(); 6980 base::RunLoop().RunUntilIdle();
6081 RemoveMockTransaction(&transaction); 6981 RemoveMockTransaction(&transaction);
6082 } 6982 }
6083 6983
6084 // Tests that we delete truncated entries if the server changes its mind midway. 6984 // Tests that we delete truncated entries if the server changes its mind midway.
6085 TEST(HttpCache, GET_IncompleteResource2) { 6985 TEST(HttpCache, GET_IncompleteResource2) {
6086 MockHttpCache cache; 6986 MockHttpCache cache;
6087 AddMockTransaction(&kRangeGET_TransactionOK); 6987 AddMockTransaction(&kRangeGET_TransactionOK);
6088 6988
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
6793 7693
6794 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 7694 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6795 &response); 7695 &response);
6796 EXPECT_TRUE(response.metadata.get() == NULL); 7696 EXPECT_TRUE(response.metadata.get() == NULL);
6797 7697
6798 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 7698 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6799 EXPECT_EQ(2, cache.disk_cache()->open_count()); 7699 EXPECT_EQ(2, cache.disk_cache()->open_count());
6800 EXPECT_EQ(1, cache.disk_cache()->create_count()); 7700 EXPECT_EQ(1, cache.disk_cache()->create_count());
6801 } 7701 }
6802 7702
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 7703 // Tests that we ignore VARY checks when writing metadata since the request
6844 // headers for the WriteMetadata transaction are made up. 7704 // headers for the WriteMetadata transaction are made up.
6845 TEST(HttpCache, WriteMetadata_IgnoreVary) { 7705 TEST(HttpCache, WriteMetadata_IgnoreVary) {
6846 MockHttpCache cache; 7706 MockHttpCache cache;
6847 7707
6848 // Write to the cache 7708 // Write to the cache
6849 HttpResponseInfo response; 7709 HttpResponseInfo response;
6850 ScopedMockTransaction transaction(kSimpleGET_Transaction); 7710 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6851 transaction.request_headers = "accept-encoding: gzip\r\n"; 7711 transaction.request_headers = "accept-encoding: gzip\r\n";
6852 transaction.response_headers = 7712 transaction.response_headers =
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
7160 MockHttpRequest request(mock_transaction); 8020 MockHttpRequest request(mock_transaction);
7161 8021
7162 { 8022 {
7163 std::unique_ptr<HttpTransaction> trans; 8023 std::unique_ptr<HttpTransaction> trans;
7164 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); 8024 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7165 8025
7166 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); 8026 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7167 EXPECT_THAT(callback.GetResult(rv), IsOk()); 8027 EXPECT_THAT(callback.GetResult(rv), IsOk());
7168 8028
7169 trans->StopCaching(); 8029 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 } 8030 }
7175 RemoveMockTransaction(&mock_transaction); 8031 RemoveMockTransaction(&mock_transaction);
7176 8032
7177 // Make sure that the ActiveEntry is gone. 8033 // Make sure that the ActiveEntry is gone.
7178 base::RunLoop().RunUntilIdle(); 8034 base::RunLoop().RunUntilIdle();
7179 8035
7180 // Verify that the entry is gone. 8036 // Verify that the entry is gone.
7181 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 8037 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
7182 8038
7183 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 8039 EXPECT_EQ(2, cache.network_layer()->transaction_count());
(...skipping 28 matching lines...) Expand all
7212 trans->StopCaching(); 8068 trans->StopCaching();
7213 8069
7214 // We should be able to keep reading. 8070 // We should be able to keep reading.
7215 rv = trans->Read(buf.get(), 256, callback.callback()); 8071 rv = trans->Read(buf.get(), 256, callback.callback());
7216 EXPECT_GT(callback.GetResult(rv), 0); 8072 EXPECT_GT(callback.GetResult(rv), 0);
7217 rv = trans->Read(buf.get(), 256, callback.callback()); 8073 rv = trans->Read(buf.get(), 256, callback.callback());
7218 EXPECT_EQ(callback.GetResult(rv), 0); 8074 EXPECT_EQ(callback.GetResult(rv), 0);
7219 } 8075 }
7220 8076
7221 // Verify that the entry is marked as incomplete. 8077 // Verify that the entry is marked as incomplete.
7222 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0); 8078 // VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
8079 // Verify that the entry is doomed.
8080 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url);
7223 } 8081 }
7224 8082
7225 // Tests that we handle truncated enries when StopCaching is called. 8083 // Tests that we handle truncated enries when StopCaching is called.
7226 TEST(HttpCache, StopCachingTruncatedEntry) { 8084 TEST(HttpCache, StopCachingTruncatedEntry) {
7227 MockHttpCache cache; 8085 MockHttpCache cache;
7228 TestCompletionCallback callback; 8086 TestCompletionCallback callback;
7229 MockHttpRequest request(kRangeGET_TransactionOK); 8087 MockHttpRequest request(kRangeGET_TransactionOK);
7230 request.extra_headers.Clear(); 8088 request.extra_headers.Clear();
7231 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); 8089 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
7232 AddMockTransaction(&kRangeGET_TransactionOK); 8090 AddMockTransaction(&kRangeGET_TransactionOK);
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
8216 ASSERT_TRUE(attrs->GetDictionary( 9074 ASSERT_TRUE(attrs->GetDictionary(
8217 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); 9075 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs));
8218 std::string size; 9076 std::string size;
8219 ASSERT_TRUE(size_attrs->GetString("value", &size)); 9077 ASSERT_TRUE(size_attrs->GetString("value", &size));
8220 int actual_size = 0; 9078 int actual_size = 0;
8221 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); 9079 ASSERT_TRUE(base::HexStringToInt(size, &actual_size));
8222 ASSERT_LT(0, actual_size); 9080 ASSERT_LT(0, actual_size);
8223 } 9081 }
8224 9082
8225 } // namespace net 9083 } // 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