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