| Index: net/http/http_cache_unittest.cc
|
| ===================================================================
|
| --- net/http/http_cache_unittest.cc (revision 22539)
|
| +++ net/http/http_cache_unittest.cc (working copy)
|
| @@ -30,11 +30,11 @@
|
| public base::RefCounted<MockDiskEntry> {
|
| public:
|
| MockDiskEntry()
|
| - : test_mode_(0), doomed_(false), sparse_(false) {
|
| + : test_mode_(0), doomed_(false), sparse_(false), fail_requests_(false) {
|
| }
|
|
|
| explicit MockDiskEntry(const std::string& key)
|
| - : key_(key), doomed_(false), sparse_(false) {
|
| + : key_(key), doomed_(false), sparse_(false), fail_requests_(false) {
|
| //
|
| // 'key' is prefixed with an identifier if it corresponds to a cached POST.
|
| // Skip past that to locate the actual URL.
|
| @@ -70,6 +70,8 @@
|
| }
|
|
|
| virtual std::string GetKey() const {
|
| + if (fail_requests_)
|
| + return std::string();
|
| return key_;
|
| }
|
|
|
| @@ -90,6 +92,9 @@
|
| net::CompletionCallback* callback) {
|
| DCHECK(index >= 0 && index < 2);
|
|
|
| + if (fail_requests_)
|
| + return net::ERR_CACHE_READ_FAILURE;
|
| +
|
| if (offset < 0 || offset > static_cast<int>(data_[index].size()))
|
| return net::ERR_FAILED;
|
| if (static_cast<size_t>(offset) == data_[index].size())
|
| @@ -110,6 +115,9 @@
|
| DCHECK(index >= 0 && index < 2);
|
| DCHECK(truncate);
|
|
|
| + if (fail_requests_)
|
| + return net::ERR_CACHE_READ_FAILURE;
|
| +
|
| if (offset < 0 || offset > static_cast<int>(data_[index].size()))
|
| return net::ERR_FAILED;
|
|
|
| @@ -126,6 +134,9 @@
|
| if (offset < 0)
|
| return net::ERR_FAILED;
|
|
|
| + if (fail_requests_)
|
| + return net::ERR_CACHE_READ_FAILURE;
|
| +
|
| DCHECK(offset < kint32max);
|
| int real_offset = static_cast<int>(offset);
|
| if (!buf_len)
|
| @@ -154,6 +165,9 @@
|
| if (!buf_len)
|
| return 0;
|
|
|
| + if (fail_requests_)
|
| + return net::ERR_CACHE_READ_FAILURE;
|
| +
|
| DCHECK(offset < kint32max);
|
| int real_offset = static_cast<int>(offset);
|
|
|
| @@ -170,6 +184,9 @@
|
| if (offset < 0)
|
| return net::ERR_FAILED;
|
|
|
| + if (fail_requests_)
|
| + return net::ERR_CACHE_READ_FAILURE;
|
| +
|
| *start = offset;
|
| DCHECK(offset < kint32max);
|
| int real_offset = static_cast<int>(offset);
|
| @@ -193,6 +210,9 @@
|
| return count;
|
| }
|
|
|
| + // Fail most subsequent requests.
|
| + void set_fail_requests() { fail_requests_ = true; }
|
| +
|
| private:
|
| // Unlike the callbacks for MockHttpTransaction, we want this one to run even
|
| // if the consumer called Close on the MockDiskEntry. We achieve that by
|
| @@ -210,11 +230,14 @@
|
| int test_mode_;
|
| bool doomed_;
|
| bool sparse_;
|
| + bool fail_requests_;
|
| };
|
|
|
| class MockDiskCache : public disk_cache::Backend {
|
| public:
|
| - MockDiskCache() : open_count_(0), create_count_(0), fail_requests_(0) {
|
| + MockDiskCache()
|
| + : open_count_(0), create_count_(0), fail_requests_(false),
|
| + soft_failures_(false) {
|
| }
|
|
|
| ~MockDiskCache() {
|
| @@ -246,6 +269,9 @@
|
| it->second->AddRef();
|
| *entry = it->second;
|
|
|
| + if (soft_failures_)
|
| + it->second->set_fail_requests();
|
| +
|
| return true;
|
| }
|
|
|
| @@ -266,6 +292,9 @@
|
| new_entry->AddRef();
|
| *entry = new_entry;
|
|
|
| + if (soft_failures_)
|
| + new_entry->set_fail_requests();
|
| +
|
| return true;
|
| }
|
|
|
| @@ -310,12 +339,16 @@
|
| // Fail any subsequent CreateEntry and OpenEntry.
|
| void set_fail_requests() { fail_requests_ = true; }
|
|
|
| + // Return entries that fail some of their requests.
|
| + void set_soft_failures(bool value) { soft_failures_ = value; }
|
| +
|
| private:
|
| typedef base::hash_map<std::string, MockDiskEntry*> EntryMap;
|
| EntryMap entries_;
|
| int open_count_;
|
| int create_count_;
|
| bool fail_requests_;
|
| + bool soft_failures_;
|
| };
|
|
|
| class MockHttpCache {
|
| @@ -583,6 +616,26 @@
|
| EXPECT_EQ(0, cache.disk_cache()->create_count());
|
| }
|
|
|
| +TEST(HttpCache, SimpleGETWithDiskFailures) {
|
| + MockHttpCache cache;
|
| +
|
| + cache.disk_cache()->set_soft_failures(true);
|
| +
|
| + // Read from the network, and fail to write to the cache.
|
| + RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
|
| +
|
| + EXPECT_EQ(1, cache.network_layer()->transaction_count());
|
| + EXPECT_EQ(0, cache.disk_cache()->open_count());
|
| + EXPECT_EQ(1, cache.disk_cache()->create_count());
|
| +
|
| + // This one should see an empty cache again.
|
| + RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
|
| +
|
| + EXPECT_EQ(2, cache.network_layer()->transaction_count());
|
| + EXPECT_EQ(0, cache.disk_cache()->open_count());
|
| + EXPECT_EQ(2, cache.disk_cache()->create_count());
|
| +}
|
| +
|
| TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
|
| MockHttpCache cache;
|
|
|
| @@ -847,7 +900,8 @@
|
| c = context_list[1];
|
| ASSERT_EQ(net::ERR_IO_PENDING, c->result);
|
| c->result = c->callback.WaitForResult();
|
| - ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
|
| + if (c->result == net::OK)
|
| + ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
|
|
|
| // At this point we have one reader, two pending transactions and a task on
|
| // the queue to move to the next transaction. Now we cancel the request that
|
| @@ -861,7 +915,8 @@
|
| Context* c = context_list[i];
|
| if (c->result == net::ERR_IO_PENDING)
|
| c->result = c->callback.WaitForResult();
|
| - ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
|
| + if (c->result == net::OK)
|
| + ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
|
| }
|
|
|
| // We should not have had to re-open the disk entry.
|
|
|