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 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 that a transaction is currently in headers phase and is destroyed |
| 2020 // leading to destroying the entry. |
| 2021 TEST(HttpCache, SimpleGET_ParallelValidationCancelHeaders) { |
| 2022 MockHttpCache cache; |
| 2023 |
| 2024 MockHttpRequest request(kSimpleGET_Transaction); |
| 2025 |
| 2026 const int kNumTransactions = 2; |
| 2027 std::vector<std::unique_ptr<Context>> context_list; |
| 2028 |
| 2029 for (int i = 0; i < kNumTransactions; ++i) { |
| 2030 context_list.push_back(base::MakeUnique<Context>()); |
| 2031 auto& c = context_list[i]; |
| 2032 |
| 2033 c->result = cache.CreateTransaction(&c->trans); |
| 2034 ASSERT_THAT(c->result, IsOk()); |
| 2035 |
| 2036 if (i == 0) |
| 2037 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); |
| 2038 |
| 2039 c->result = |
| 2040 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 2041 } |
| 2042 |
| 2043 base::RunLoop().RunUntilIdle(); |
| 2044 |
| 2045 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); |
| 2046 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); |
| 2047 |
| 2048 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 2049 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 2050 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 2051 |
| 2052 // Delete the headers transaction. |
| 2053 context_list[0].reset(); |
| 2054 |
| 2055 base::RunLoop().RunUntilIdle(); |
| 2056 |
| 2057 // Complete the rest of the transactions. |
| 2058 for (auto& context : context_list) { |
| 2059 if (!context) |
| 2060 continue; |
| 2061 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); |
| 2062 } |
| 2063 |
| 2064 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 2065 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 2066 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 2067 } |
| 2068 |
| 2069 // Similar to the above test, except here cache write fails and the |
| 2070 // validated transactions should be restarted. |
| 2071 TEST(HttpCache, SimpleGET_ParallelValidationFailWrite) { |
| 2072 MockHttpCache cache; |
| 2073 |
| 2074 MockHttpRequest request(kSimpleGET_Transaction); |
| 2075 |
| 2076 const int kNumTransactions = 5; |
| 2077 std::vector<std::unique_ptr<Context>> context_list; |
| 2078 |
| 2079 for (int i = 0; i < kNumTransactions; ++i) { |
| 2080 context_list.push_back(base::MakeUnique<Context>()); |
| 2081 auto& c = context_list[i]; |
| 2082 |
| 2083 c->result = cache.CreateTransaction(&c->trans); |
| 2084 ASSERT_THAT(c->result, IsOk()); |
1356 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); | 2085 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
1357 | 2086 |
1358 c->result = | 2087 c->result = |
1359 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); | 2088 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
1360 } | 2089 } |
1361 | 2090 |
1362 // All requests are waiting for the active entry. | 2091 // All requests are waiting for the active entry. |
1363 for (int i = 0; i < kNumTransactions; ++i) { | 2092 for (auto& context : context_list) { |
1364 Context* c = context_list[i].get(); | 2093 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); |
1365 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState()); | |
1366 } | 2094 } |
1367 | 2095 |
1368 // Allow all requests to move from the Create queue to the active entry. | 2096 // Allow all requests to move from the Create queue to the active entry. |
1369 base::RunLoop().RunUntilIdle(); | 2097 base::RunLoop().RunUntilIdle(); |
1370 | 2098 |
1371 // The first request should be a writer at this point, and the subsequent | 2099 // The first request should be a writer at this point, and the subsequent |
1372 // requests should be pending. | 2100 // requests should have passed the validation phase and waiting for the |
| 2101 // response to be written to the cache before they can read. |
| 2102 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 2103 EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 2104 |
| 2105 // All requests depend on the writer, and the writer is between Start and |
| 2106 // Read, i.e. idle. |
| 2107 for (auto& context : context_list) { |
| 2108 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); |
| 2109 } |
| 2110 |
| 2111 // The first request should be a writer at this point, and the subsequent |
| 2112 // requests should have passed the validation phase and waiting for the |
| 2113 // response to be written to the cache before they can read. |
1373 | 2114 |
1374 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 2115 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
1375 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2116 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
1376 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2117 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
1377 | 2118 |
1378 // All requests depend on the writer, and the writer is between Start and | 2119 // Fail the request. |
1379 // Read, i.e. idle. | 2120 cache.disk_cache()->set_soft_failures(true); |
1380 for (int i = 0; i < kNumTransactions; ++i) { | 2121 // We have to open the entry again to propagate the failure flag. |
1381 Context* c = context_list[i].get(); | 2122 disk_cache::Entry* en; |
1382 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); | 2123 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en); |
1383 } | 2124 en->Close(); |
1384 | 2125 |
1385 for (int i = 0; i < kNumTransactions; ++i) { | 2126 for (int i = 0; i < kNumTransactions; ++i) { |
1386 Context* c = context_list[i].get(); | 2127 auto& c = context_list[i]; |
1387 if (c->result == ERR_IO_PENDING) | 2128 if (c->result == ERR_IO_PENDING) |
1388 c->result = c->callback.WaitForResult(); | 2129 c->result = c->callback.WaitForResult(); |
| 2130 if (i == 1) { |
| 2131 // The earlier entry must be destroyed and its disk entry doomed. |
| 2132 EXPECT_TRUE( |
| 2133 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url)); |
| 2134 } |
1389 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2135 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
1390 } | 2136 } |
1391 | 2137 |
1392 // We should not have had to re-open the disk entry | 2138 // Since validated transactions were restarted and new entry read/write |
1393 | 2139 // operations would also fail, all requests would have gone to the network. |
1394 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 2140 EXPECT_EQ(5, cache.network_layer()->transaction_count()); |
1395 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2141 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
1396 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2142 EXPECT_EQ(5, cache.disk_cache()->create_count()); |
1397 } | 2143 } |
1398 | 2144 |
1399 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. | 2145 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. |
1400 // If cancelling a request is racing with another request for the same resource | 2146 // If cancelling a request is racing with another request for the same resource |
1401 // finishing, we have to make sure that we remove both transactions from the | 2147 // finishing, we have to make sure that we remove both transactions from the |
1402 // entry. | 2148 // entry. |
1403 TEST(HttpCache, SimpleGET_RacingReaders) { | 2149 TEST(HttpCache, SimpleGET_RacingReaders) { |
1404 MockHttpCache cache; | 2150 MockHttpCache cache; |
1405 | 2151 |
1406 MockHttpRequest request(kSimpleGET_Transaction); | 2152 MockHttpRequest request(kSimpleGET_Transaction); |
(...skipping 26 matching lines...) Expand all Loading... |
1433 | 2179 |
1434 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 2180 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
1435 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2181 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
1436 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2182 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
1437 | 2183 |
1438 Context* c = context_list[0].get(); | 2184 Context* c = context_list[0].get(); |
1439 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 2185 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
1440 c->result = c->callback.WaitForResult(); | 2186 c->result = c->callback.WaitForResult(); |
1441 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2187 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
1442 | 2188 |
1443 // Now we have 2 active readers and two queued transactions. | 2189 // Now all transactions should be waiting for read to be invoked. Two readers |
1444 | 2190 // are because of the load flags and remaining two transactions were converted |
| 2191 // to readers after skipping validation. Note that the remaining two went on |
| 2192 // to process the headers in parallel with readers present on the entry. |
1445 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); | 2193 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); |
1446 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, | 2194 EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState()); |
1447 context_list[3]->trans->GetLoadState()); | |
1448 | 2195 |
1449 c = context_list[1].get(); | 2196 c = context_list[1].get(); |
1450 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 2197 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
1451 c->result = c->callback.WaitForResult(); | 2198 c->result = c->callback.WaitForResult(); |
1452 if (c->result == OK) | 2199 if (c->result == OK) |
1453 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2200 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
1454 | 2201 |
1455 // At this point we have one reader, two pending transactions and a task on | 2202 // At this point we have one reader, two pending transactions and a task on |
1456 // the queue to move to the next transaction. Now we cancel the request that | 2203 // the queue to move to the next transaction. Now we cancel the request that |
1457 // is the current reader, and expect the queued task to be able to start the | 2204 // is the current reader, and expect the queued task to be able to start the |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1497 ASSERT_THAT(c->result, IsOk()); | 2244 ASSERT_THAT(c->result, IsOk()); |
1498 | 2245 |
1499 MockHttpRequest* this_request = &request; | 2246 MockHttpRequest* this_request = &request; |
1500 if (i == 3) | 2247 if (i == 3) |
1501 this_request = &writer_request; | 2248 this_request = &writer_request; |
1502 | 2249 |
1503 c->result = c->trans->Start(this_request, c->callback.callback(), | 2250 c->result = c->trans->Start(this_request, c->callback.callback(), |
1504 NetLogWithSource()); | 2251 NetLogWithSource()); |
1505 } | 2252 } |
1506 | 2253 |
| 2254 base::RunLoop().RunUntilIdle(); |
| 2255 |
1507 // The first request should be a writer at this point, and the two subsequent | 2256 // The first request should be a writer at this point, and the two subsequent |
1508 // requests should be pending. The last request doomed the first entry. | 2257 // requests should be pending. The last request doomed the first entry. |
1509 | 2258 |
1510 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 2259 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
1511 | 2260 |
1512 // Cancel the first queued transaction. | 2261 // Cancel the second transaction. Note that this and the 3rd transactions |
| 2262 // would have completed their headers phase and would be waiting in the |
| 2263 // done_headers_queue when the 2nd transaction is cancelled. |
1513 context_list[1].reset(); | 2264 context_list[1].reset(); |
1514 | 2265 |
1515 for (int i = 0; i < kNumTransactions; ++i) { | 2266 for (int i = 0; i < kNumTransactions; ++i) { |
1516 if (i == 1) | 2267 if (i == 1) |
1517 continue; | 2268 continue; |
1518 Context* c = context_list[i].get(); | 2269 Context* c = context_list[i].get(); |
1519 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 2270 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
1520 c->result = c->callback.WaitForResult(); | 2271 c->result = c->callback.WaitForResult(); |
1521 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2272 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
1522 } | 2273 } |
(...skipping 21 matching lines...) Expand all Loading... |
1544 ASSERT_THAT(c->result, IsOk()); | 2295 ASSERT_THAT(c->result, IsOk()); |
1545 | 2296 |
1546 c->result = | 2297 c->result = |
1547 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); | 2298 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
1548 } | 2299 } |
1549 | 2300 |
1550 // Allow all requests to move from the Create queue to the active entry. | 2301 // Allow all requests to move from the Create queue to the active entry. |
1551 base::RunLoop().RunUntilIdle(); | 2302 base::RunLoop().RunUntilIdle(); |
1552 | 2303 |
1553 // The first request should be a writer at this point, and the subsequent | 2304 // The first request should be a writer at this point, and the subsequent |
1554 // requests should be pending. | 2305 // requests should have completed validation. Since the validation does not |
| 2306 // result in a match, a new entry would be created. |
1555 | 2307 |
1556 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 2308 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
1557 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2309 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
1558 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2310 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
1559 | 2311 |
1560 // Now, make sure that the second request asks for the entry not to be stored. | 2312 // Now, make sure that the second request asks for the entry not to be stored. |
1561 request_handler.set_no_store(true); | 2313 request_handler.set_no_store(true); |
1562 | 2314 |
1563 for (int i = 0; i < kNumTransactions; ++i) { | 2315 for (int i = 0; i < kNumTransactions; ++i) { |
1564 Context* c = context_list[i].get(); | 2316 Context* c = context_list[i].get(); |
1565 if (c->result == ERR_IO_PENDING) | 2317 if (c->result == ERR_IO_PENDING) |
1566 c->result = c->callback.WaitForResult(); | 2318 c->result = c->callback.WaitForResult(); |
1567 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); | 2319 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); |
1568 context_list[i].reset(); | 2320 context_list[i].reset(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1602 | 2354 |
1603 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 2355 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
1604 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2356 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
1605 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2357 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
1606 | 2358 |
1607 for (int i = 0; i < kNumTransactions; ++i) { | 2359 for (int i = 0; i < kNumTransactions; ++i) { |
1608 Context* c = context_list[i].get(); | 2360 Context* c = context_list[i].get(); |
1609 if (c->result == ERR_IO_PENDING) | 2361 if (c->result == ERR_IO_PENDING) |
1610 c->result = c->callback.WaitForResult(); | 2362 c->result = c->callback.WaitForResult(); |
1611 // Destroy only the first transaction. | 2363 // Destroy only the first transaction. |
| 2364 // This should lead to all transactions to restart, even those that have |
| 2365 // validated themselves and were waiting for the writer transaction to |
| 2366 // complete writing to the cache. |
1612 if (i == 0) { | 2367 if (i == 0) { |
1613 context_list[i].reset(); | 2368 context_list[i].reset(); |
1614 } | 2369 } |
1615 } | 2370 } |
1616 | 2371 |
1617 // Complete the rest of the transactions. | 2372 // Complete the rest of the transactions. |
1618 for (int i = 1; i < kNumTransactions; ++i) { | 2373 for (int i = 1; i < kNumTransactions; ++i) { |
1619 Context* c = context_list[i].get(); | 2374 Context* c = context_list[i].get(); |
1620 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2375 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
1621 } | 2376 } |
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2490 } | 3245 } |
2491 | 3246 |
2492 // Helper that does 4 requests using HttpCache: | 3247 // Helper that does 4 requests using HttpCache: |
2493 // | 3248 // |
2494 // (1) loads |kUrl| -- expects |net_response_1| to be returned. | 3249 // (1) loads |kUrl| -- expects |net_response_1| to be returned. |
2495 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. | 3250 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. |
2496 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to | 3251 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to |
2497 // be returned. | 3252 // be returned. |
2498 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be | 3253 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be |
2499 // returned. | 3254 // returned. |
| 3255 // The entry will be created once and will be opened for the 3 subsequent |
| 3256 // requests. |
2500 static void ConditionalizedRequestUpdatesCacheHelper( | 3257 static void ConditionalizedRequestUpdatesCacheHelper( |
2501 const Response& net_response_1, | 3258 const Response& net_response_1, |
2502 const Response& net_response_2, | 3259 const Response& net_response_2, |
2503 const Response& cached_response_2, | 3260 const Response& cached_response_2, |
2504 const char* extra_request_headers) { | 3261 const char* extra_request_headers) { |
2505 MockHttpCache cache; | 3262 MockHttpCache cache; |
2506 | 3263 |
2507 // The URL we will be requesting. | 3264 // The URL we will be requesting. |
2508 const char kUrl[] = "http://foobar.com/main.css"; | 3265 const char kUrl[] = "http://foobar.com/main.css"; |
2509 | 3266 |
(...skipping 3552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6062 EXPECT_EQ(ERR_IO_PENDING, | 6819 EXPECT_EQ(ERR_IO_PENDING, |
6063 pending->trans->Start(&request, pending->callback.callback(), | 6820 pending->trans->Start(&request, pending->callback.callback(), |
6064 NetLogWithSource())); | 6821 NetLogWithSource())); |
6065 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); | 6822 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); |
6066 | 6823 |
6067 // Make sure that the entry has some data stored. | 6824 // Make sure that the entry has some data stored. |
6068 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); | 6825 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); |
6069 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); | 6826 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); |
6070 EXPECT_EQ(5, c->callback.GetResult(rv)); | 6827 EXPECT_EQ(5, c->callback.GetResult(rv)); |
6071 | 6828 |
6072 // Cancel the requests. | 6829 // Since |pending| is currently validating the already written headers |
| 6830 // it will be restarted as well. |
6073 c.reset(); | 6831 c.reset(); |
6074 pending.reset(); | 6832 pending.reset(); |
6075 | 6833 |
6076 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6834 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
6077 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 6835 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
6078 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 6836 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
6079 | 6837 |
6080 base::RunLoop().RunUntilIdle(); | 6838 base::RunLoop().RunUntilIdle(); |
6081 RemoveMockTransaction(&transaction); | 6839 RemoveMockTransaction(&transaction); |
6082 } | 6840 } |
6083 | 6841 |
6084 // Tests that we delete truncated entries if the server changes its mind midway. | 6842 // Tests that we delete truncated entries if the server changes its mind midway. |
6085 TEST(HttpCache, GET_IncompleteResource2) { | 6843 TEST(HttpCache, GET_IncompleteResource2) { |
6086 MockHttpCache cache; | 6844 MockHttpCache cache; |
6087 AddMockTransaction(&kRangeGET_TransactionOK); | 6845 AddMockTransaction(&kRangeGET_TransactionOK); |
6088 | 6846 |
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6793 | 7551 |
6794 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, | 7552 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, |
6795 &response); | 7553 &response); |
6796 EXPECT_TRUE(response.metadata.get() == NULL); | 7554 EXPECT_TRUE(response.metadata.get() == NULL); |
6797 | 7555 |
6798 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 7556 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
6799 EXPECT_EQ(2, cache.disk_cache()->open_count()); | 7557 EXPECT_EQ(2, cache.disk_cache()->open_count()); |
6800 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 7558 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
6801 } | 7559 } |
6802 | 7560 |
6803 // Tests that if a metadata writer transaction hits cache lock timeout, it will | |
6804 // error out. | |
6805 TEST(HttpCache, WriteMetadata_CacheLockTimeout) { | |
6806 MockHttpCache cache; | |
6807 | |
6808 // Write to the cache | |
6809 HttpResponseInfo response; | |
6810 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, | |
6811 &response); | |
6812 EXPECT_FALSE(response.metadata.get()); | |
6813 | |
6814 MockHttpRequest request(kSimpleGET_Transaction); | |
6815 Context c1; | |
6816 ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk()); | |
6817 ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(), | |
6818 NetLogWithSource())); | |
6819 | |
6820 cache.SimulateCacheLockTimeout(); | |
6821 | |
6822 // Write meta data to the same entry. | |
6823 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50)); | |
6824 memset(buf->data(), 0, buf->size()); | |
6825 base::strlcpy(buf->data(), "Hi there", buf->size()); | |
6826 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url), | |
6827 DEFAULT_PRIORITY, response.response_time, | |
6828 buf.get(), buf->size()); | |
6829 | |
6830 // Release the buffer before the operation takes place. | |
6831 buf = NULL; | |
6832 | |
6833 // Makes sure we finish pending operations. | |
6834 base::RunLoop().RunUntilIdle(); | |
6835 | |
6836 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, | |
6837 &response); | |
6838 | |
6839 // The writer transaction should fail due to cache lock timeout. | |
6840 ASSERT_FALSE(response.metadata.get()); | |
6841 } | |
6842 | |
6843 // Tests that we ignore VARY checks when writing metadata since the request | 7561 // Tests that we ignore VARY checks when writing metadata since the request |
6844 // headers for the WriteMetadata transaction are made up. | 7562 // headers for the WriteMetadata transaction are made up. |
6845 TEST(HttpCache, WriteMetadata_IgnoreVary) { | 7563 TEST(HttpCache, WriteMetadata_IgnoreVary) { |
6846 MockHttpCache cache; | 7564 MockHttpCache cache; |
6847 | 7565 |
6848 // Write to the cache | 7566 // Write to the cache |
6849 HttpResponseInfo response; | 7567 HttpResponseInfo response; |
6850 ScopedMockTransaction transaction(kSimpleGET_Transaction); | 7568 ScopedMockTransaction transaction(kSimpleGET_Transaction); |
6851 transaction.request_headers = "accept-encoding: gzip\r\n"; | 7569 transaction.request_headers = "accept-encoding: gzip\r\n"; |
6852 transaction.response_headers = | 7570 transaction.response_headers = |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7160 MockHttpRequest request(mock_transaction); | 7878 MockHttpRequest request(mock_transaction); |
7161 | 7879 |
7162 { | 7880 { |
7163 std::unique_ptr<HttpTransaction> trans; | 7881 std::unique_ptr<HttpTransaction> trans; |
7164 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); | 7882 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); |
7165 | 7883 |
7166 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); | 7884 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); |
7167 EXPECT_THAT(callback.GetResult(rv), IsOk()); | 7885 EXPECT_THAT(callback.GetResult(rv), IsOk()); |
7168 | 7886 |
7169 trans->StopCaching(); | 7887 trans->StopCaching(); |
7170 | |
7171 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | |
7172 rv = trans->Read(buf.get(), 10, callback.callback()); | |
7173 EXPECT_EQ(callback.GetResult(rv), 10); | |
7174 } | 7888 } |
7175 RemoveMockTransaction(&mock_transaction); | 7889 RemoveMockTransaction(&mock_transaction); |
7176 | 7890 |
7177 // Make sure that the ActiveEntry is gone. | 7891 // Make sure that the ActiveEntry is gone. |
7178 base::RunLoop().RunUntilIdle(); | 7892 base::RunLoop().RunUntilIdle(); |
7179 | 7893 |
7180 // Verify that the entry is gone. | 7894 // Verify that the entry is gone. |
7181 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | 7895 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
7182 | 7896 |
7183 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 7897 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8216 ASSERT_TRUE(attrs->GetDictionary( | 8930 ASSERT_TRUE(attrs->GetDictionary( |
8217 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); | 8931 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); |
8218 std::string size; | 8932 std::string size; |
8219 ASSERT_TRUE(size_attrs->GetString("value", &size)); | 8933 ASSERT_TRUE(size_attrs->GetString("value", &size)); |
8220 int actual_size = 0; | 8934 int actual_size = 0; |
8221 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); | 8935 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); |
8222 ASSERT_LT(0, actual_size); | 8936 ASSERT_LT(0, actual_size); |
8223 } | 8937 } |
8224 | 8938 |
8225 } // namespace net | 8939 } // namespace net |
OLD | NEW |