| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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 "base/hash_tables.h" | 7 #include "base/hash_tables.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 //----------------------------------------------------------------------------- | 26 //----------------------------------------------------------------------------- |
| 27 // mock disk cache (a very basic memory cache implementation) | 27 // mock disk cache (a very basic memory cache implementation) |
| 28 | 28 |
| 29 class MockDiskEntry : public disk_cache::Entry, | 29 class MockDiskEntry : public disk_cache::Entry, |
| 30 public base::RefCounted<MockDiskEntry> { | 30 public base::RefCounted<MockDiskEntry> { |
| 31 public: | 31 public: |
| 32 MockDiskEntry() | 32 MockDiskEntry() |
| 33 : test_mode_(0), doomed_(false), sparse_(false) { | 33 : test_mode_(0), doomed_(false), sparse_(false), fail_requests_(false) { |
| 34 } | 34 } |
| 35 | 35 |
| 36 explicit MockDiskEntry(const std::string& key) | 36 explicit MockDiskEntry(const std::string& key) |
| 37 : key_(key), doomed_(false), sparse_(false) { | 37 : key_(key), doomed_(false), sparse_(false), fail_requests_(false) { |
| 38 // | 38 // |
| 39 // 'key' is prefixed with an identifier if it corresponds to a cached POST. | 39 // 'key' is prefixed with an identifier if it corresponds to a cached POST. |
| 40 // Skip past that to locate the actual URL. | 40 // Skip past that to locate the actual URL. |
| 41 // | 41 // |
| 42 // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an | 42 // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an |
| 43 // URL corresponding to a registered MockTransaction. It would be good to | 43 // URL corresponding to a registered MockTransaction. It would be good to |
| 44 // have another way to access the test_mode. | 44 // have another way to access the test_mode. |
| 45 // | 45 // |
| 46 GURL url; | 46 GURL url; |
| 47 if (isdigit(key[0])) { | 47 if (isdigit(key[0])) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 63 | 63 |
| 64 virtual void Doom() { | 64 virtual void Doom() { |
| 65 doomed_ = true; | 65 doomed_ = true; |
| 66 } | 66 } |
| 67 | 67 |
| 68 virtual void Close() { | 68 virtual void Close() { |
| 69 Release(); | 69 Release(); |
| 70 } | 70 } |
| 71 | 71 |
| 72 virtual std::string GetKey() const { | 72 virtual std::string GetKey() const { |
| 73 if (fail_requests_) |
| 74 return std::string(); |
| 73 return key_; | 75 return key_; |
| 74 } | 76 } |
| 75 | 77 |
| 76 virtual Time GetLastUsed() const { | 78 virtual Time GetLastUsed() const { |
| 77 return Time::FromInternalValue(0); | 79 return Time::FromInternalValue(0); |
| 78 } | 80 } |
| 79 | 81 |
| 80 virtual Time GetLastModified() const { | 82 virtual Time GetLastModified() const { |
| 81 return Time::FromInternalValue(0); | 83 return Time::FromInternalValue(0); |
| 82 } | 84 } |
| 83 | 85 |
| 84 virtual int32 GetDataSize(int index) const { | 86 virtual int32 GetDataSize(int index) const { |
| 85 DCHECK(index >= 0 && index < 2); | 87 DCHECK(index >= 0 && index < 2); |
| 86 return static_cast<int32>(data_[index].size()); | 88 return static_cast<int32>(data_[index].size()); |
| 87 } | 89 } |
| 88 | 90 |
| 89 virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, | 91 virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, |
| 90 net::CompletionCallback* callback) { | 92 net::CompletionCallback* callback) { |
| 91 DCHECK(index >= 0 && index < 2); | 93 DCHECK(index >= 0 && index < 2); |
| 92 | 94 |
| 95 if (fail_requests_) |
| 96 return net::ERR_CACHE_READ_FAILURE; |
| 97 |
| 93 if (offset < 0 || offset > static_cast<int>(data_[index].size())) | 98 if (offset < 0 || offset > static_cast<int>(data_[index].size())) |
| 94 return net::ERR_FAILED; | 99 return net::ERR_FAILED; |
| 95 if (static_cast<size_t>(offset) == data_[index].size()) | 100 if (static_cast<size_t>(offset) == data_[index].size()) |
| 96 return 0; | 101 return 0; |
| 97 | 102 |
| 98 int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset); | 103 int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset); |
| 99 memcpy(buf->data(), &data_[index][offset], num); | 104 memcpy(buf->data(), &data_[index][offset], num); |
| 100 | 105 |
| 101 if (!callback || (test_mode_ & TEST_MODE_SYNC_CACHE_READ)) | 106 if (!callback || (test_mode_ & TEST_MODE_SYNC_CACHE_READ)) |
| 102 return num; | 107 return num; |
| 103 | 108 |
| 104 CallbackLater(callback, num); | 109 CallbackLater(callback, num); |
| 105 return net::ERR_IO_PENDING; | 110 return net::ERR_IO_PENDING; |
| 106 } | 111 } |
| 107 | 112 |
| 108 virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, | 113 virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, |
| 109 net::CompletionCallback* callback, bool truncate) { | 114 net::CompletionCallback* callback, bool truncate) { |
| 110 DCHECK(index >= 0 && index < 2); | 115 DCHECK(index >= 0 && index < 2); |
| 111 DCHECK(truncate); | 116 DCHECK(truncate); |
| 112 | 117 |
| 118 if (fail_requests_) |
| 119 return net::ERR_CACHE_READ_FAILURE; |
| 120 |
| 113 if (offset < 0 || offset > static_cast<int>(data_[index].size())) | 121 if (offset < 0 || offset > static_cast<int>(data_[index].size())) |
| 114 return net::ERR_FAILED; | 122 return net::ERR_FAILED; |
| 115 | 123 |
| 116 data_[index].resize(offset + buf_len); | 124 data_[index].resize(offset + buf_len); |
| 117 if (buf_len) | 125 if (buf_len) |
| 118 memcpy(&data_[index][offset], buf->data(), buf_len); | 126 memcpy(&data_[index][offset], buf->data(), buf_len); |
| 119 return buf_len; | 127 return buf_len; |
| 120 } | 128 } |
| 121 | 129 |
| 122 virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, | 130 virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
| 123 net::CompletionCallback* completion_callback) { | 131 net::CompletionCallback* completion_callback) { |
| 124 if (!sparse_) | 132 if (!sparse_) |
| 125 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 133 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 126 if (offset < 0) | 134 if (offset < 0) |
| 127 return net::ERR_FAILED; | 135 return net::ERR_FAILED; |
| 128 | 136 |
| 137 if (fail_requests_) |
| 138 return net::ERR_CACHE_READ_FAILURE; |
| 139 |
| 129 DCHECK(offset < kint32max); | 140 DCHECK(offset < kint32max); |
| 130 int real_offset = static_cast<int>(offset); | 141 int real_offset = static_cast<int>(offset); |
| 131 if (!buf_len) | 142 if (!buf_len) |
| 132 return 0; | 143 return 0; |
| 133 | 144 |
| 134 int num = std::min(static_cast<int>(data_[1].size()) - real_offset, | 145 int num = std::min(static_cast<int>(data_[1].size()) - real_offset, |
| 135 buf_len); | 146 buf_len); |
| 136 memcpy(buf->data(), &data_[1][real_offset], num); | 147 memcpy(buf->data(), &data_[1][real_offset], num); |
| 137 | 148 |
| 138 if (!completion_callback || (test_mode_ & TEST_MODE_SYNC_CACHE_READ)) | 149 if (!completion_callback || (test_mode_ & TEST_MODE_SYNC_CACHE_READ)) |
| 139 return num; | 150 return num; |
| 140 | 151 |
| 141 CallbackLater(completion_callback, num); | 152 CallbackLater(completion_callback, num); |
| 142 return net::ERR_IO_PENDING; | 153 return net::ERR_IO_PENDING; |
| 143 } | 154 } |
| 144 | 155 |
| 145 virtual int WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, | 156 virtual int WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
| 146 net::CompletionCallback* completion_callback) { | 157 net::CompletionCallback* completion_callback) { |
| 147 if (!sparse_) { | 158 if (!sparse_) { |
| 148 if (data_[1].size()) | 159 if (data_[1].size()) |
| 149 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 160 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 150 sparse_ = true; | 161 sparse_ = true; |
| 151 } | 162 } |
| 152 if (offset < 0) | 163 if (offset < 0) |
| 153 return net::ERR_FAILED; | 164 return net::ERR_FAILED; |
| 154 if (!buf_len) | 165 if (!buf_len) |
| 155 return 0; | 166 return 0; |
| 156 | 167 |
| 168 if (fail_requests_) |
| 169 return net::ERR_CACHE_READ_FAILURE; |
| 170 |
| 157 DCHECK(offset < kint32max); | 171 DCHECK(offset < kint32max); |
| 158 int real_offset = static_cast<int>(offset); | 172 int real_offset = static_cast<int>(offset); |
| 159 | 173 |
| 160 if (static_cast<int>(data_[1].size()) < real_offset + buf_len) | 174 if (static_cast<int>(data_[1].size()) < real_offset + buf_len) |
| 161 data_[1].resize(real_offset + buf_len); | 175 data_[1].resize(real_offset + buf_len); |
| 162 | 176 |
| 163 memcpy(&data_[1][real_offset], buf->data(), buf_len); | 177 memcpy(&data_[1][real_offset], buf->data(), buf_len); |
| 164 return buf_len; | 178 return buf_len; |
| 165 } | 179 } |
| 166 | 180 |
| 167 virtual int GetAvailableRange(int64 offset, int len, int64* start) { | 181 virtual int GetAvailableRange(int64 offset, int len, int64* start) { |
| 168 if (!sparse_) | 182 if (!sparse_) |
| 169 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 183 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 170 if (offset < 0) | 184 if (offset < 0) |
| 171 return net::ERR_FAILED; | 185 return net::ERR_FAILED; |
| 172 | 186 |
| 187 if (fail_requests_) |
| 188 return net::ERR_CACHE_READ_FAILURE; |
| 189 |
| 173 *start = offset; | 190 *start = offset; |
| 174 DCHECK(offset < kint32max); | 191 DCHECK(offset < kint32max); |
| 175 int real_offset = static_cast<int>(offset); | 192 int real_offset = static_cast<int>(offset); |
| 176 if (static_cast<int>(data_[1].size()) < real_offset) | 193 if (static_cast<int>(data_[1].size()) < real_offset) |
| 177 return 0; | 194 return 0; |
| 178 | 195 |
| 179 int num = std::min(static_cast<int>(data_[1].size()) - real_offset, len); | 196 int num = std::min(static_cast<int>(data_[1].size()) - real_offset, len); |
| 180 int count = 0; | 197 int count = 0; |
| 181 for (; num > 0; num--, real_offset++) { | 198 for (; num > 0; num--, real_offset++) { |
| 182 if (!count) { | 199 if (!count) { |
| 183 if (data_[1][real_offset]) { | 200 if (data_[1][real_offset]) { |
| 184 count++; | 201 count++; |
| 185 *start = real_offset; | 202 *start = real_offset; |
| 186 } | 203 } |
| 187 } else { | 204 } else { |
| 188 if (!data_[1][real_offset]) | 205 if (!data_[1][real_offset]) |
| 189 break; | 206 break; |
| 190 count++; | 207 count++; |
| 191 } | 208 } |
| 192 } | 209 } |
| 193 return count; | 210 return count; |
| 194 } | 211 } |
| 195 | 212 |
| 213 // Fail most subsequent requests. |
| 214 void set_fail_requests() { fail_requests_ = true; } |
| 215 |
| 196 private: | 216 private: |
| 197 // Unlike the callbacks for MockHttpTransaction, we want this one to run even | 217 // Unlike the callbacks for MockHttpTransaction, we want this one to run even |
| 198 // if the consumer called Close on the MockDiskEntry. We achieve that by | 218 // if the consumer called Close on the MockDiskEntry. We achieve that by |
| 199 // leveraging the fact that this class is reference counted. | 219 // leveraging the fact that this class is reference counted. |
| 200 void CallbackLater(net::CompletionCallback* callback, int result) { | 220 void CallbackLater(net::CompletionCallback* callback, int result) { |
| 201 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this, | 221 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this, |
| 202 &MockDiskEntry::RunCallback, callback, result)); | 222 &MockDiskEntry::RunCallback, callback, result)); |
| 203 } | 223 } |
| 204 void RunCallback(net::CompletionCallback* callback, int result) { | 224 void RunCallback(net::CompletionCallback* callback, int result) { |
| 205 callback->Run(result); | 225 callback->Run(result); |
| 206 } | 226 } |
| 207 | 227 |
| 208 std::string key_; | 228 std::string key_; |
| 209 std::vector<char> data_[2]; | 229 std::vector<char> data_[2]; |
| 210 int test_mode_; | 230 int test_mode_; |
| 211 bool doomed_; | 231 bool doomed_; |
| 212 bool sparse_; | 232 bool sparse_; |
| 233 bool fail_requests_; |
| 213 }; | 234 }; |
| 214 | 235 |
| 215 class MockDiskCache : public disk_cache::Backend { | 236 class MockDiskCache : public disk_cache::Backend { |
| 216 public: | 237 public: |
| 217 MockDiskCache() : open_count_(0), create_count_(0), fail_requests_(0) { | 238 MockDiskCache() |
| 239 : open_count_(0), create_count_(0), fail_requests_(false), |
| 240 soft_failures_(false) { |
| 218 } | 241 } |
| 219 | 242 |
| 220 ~MockDiskCache() { | 243 ~MockDiskCache() { |
| 221 EntryMap::iterator it = entries_.begin(); | 244 EntryMap::iterator it = entries_.begin(); |
| 222 for (; it != entries_.end(); ++it) | 245 for (; it != entries_.end(); ++it) |
| 223 it->second->Release(); | 246 it->second->Release(); |
| 224 } | 247 } |
| 225 | 248 |
| 226 virtual int32 GetEntryCount() const { | 249 virtual int32 GetEntryCount() const { |
| 227 return static_cast<int32>(entries_.size()); | 250 return static_cast<int32>(entries_.size()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 239 it->second->Release(); | 262 it->second->Release(); |
| 240 entries_.erase(it); | 263 entries_.erase(it); |
| 241 return false; | 264 return false; |
| 242 } | 265 } |
| 243 | 266 |
| 244 open_count_++; | 267 open_count_++; |
| 245 | 268 |
| 246 it->second->AddRef(); | 269 it->second->AddRef(); |
| 247 *entry = it->second; | 270 *entry = it->second; |
| 248 | 271 |
| 272 if (soft_failures_) |
| 273 it->second->set_fail_requests(); |
| 274 |
| 249 return true; | 275 return true; |
| 250 } | 276 } |
| 251 | 277 |
| 252 virtual bool CreateEntry(const std::string& key, disk_cache::Entry** entry) { | 278 virtual bool CreateEntry(const std::string& key, disk_cache::Entry** entry) { |
| 253 if (fail_requests_) | 279 if (fail_requests_) |
| 254 return false; | 280 return false; |
| 255 | 281 |
| 256 EntryMap::iterator it = entries_.find(key); | 282 EntryMap::iterator it = entries_.find(key); |
| 257 DCHECK(it == entries_.end()); | 283 DCHECK(it == entries_.end()); |
| 258 | 284 |
| 259 create_count_++; | 285 create_count_++; |
| 260 | 286 |
| 261 MockDiskEntry* new_entry = new MockDiskEntry(key); | 287 MockDiskEntry* new_entry = new MockDiskEntry(key); |
| 262 | 288 |
| 263 new_entry->AddRef(); | 289 new_entry->AddRef(); |
| 264 entries_[key] = new_entry; | 290 entries_[key] = new_entry; |
| 265 | 291 |
| 266 new_entry->AddRef(); | 292 new_entry->AddRef(); |
| 267 *entry = new_entry; | 293 *entry = new_entry; |
| 268 | 294 |
| 295 if (soft_failures_) |
| 296 new_entry->set_fail_requests(); |
| 297 |
| 269 return true; | 298 return true; |
| 270 } | 299 } |
| 271 | 300 |
| 272 virtual bool DoomEntry(const std::string& key) { | 301 virtual bool DoomEntry(const std::string& key) { |
| 273 EntryMap::iterator it = entries_.find(key); | 302 EntryMap::iterator it = entries_.find(key); |
| 274 if (it != entries_.end()) { | 303 if (it != entries_.end()) { |
| 275 it->second->Release(); | 304 it->second->Release(); |
| 276 entries_.erase(it); | 305 entries_.erase(it); |
| 277 } | 306 } |
| 278 return true; | 307 return true; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 303 | 332 |
| 304 // returns number of times a cache entry was successfully opened | 333 // returns number of times a cache entry was successfully opened |
| 305 int open_count() const { return open_count_; } | 334 int open_count() const { return open_count_; } |
| 306 | 335 |
| 307 // returns number of times a cache entry was successfully created | 336 // returns number of times a cache entry was successfully created |
| 308 int create_count() const { return create_count_; } | 337 int create_count() const { return create_count_; } |
| 309 | 338 |
| 310 // Fail any subsequent CreateEntry and OpenEntry. | 339 // Fail any subsequent CreateEntry and OpenEntry. |
| 311 void set_fail_requests() { fail_requests_ = true; } | 340 void set_fail_requests() { fail_requests_ = true; } |
| 312 | 341 |
| 342 // Return entries that fail some of their requests. |
| 343 void set_soft_failures(bool value) { soft_failures_ = value; } |
| 344 |
| 313 private: | 345 private: |
| 314 typedef base::hash_map<std::string, MockDiskEntry*> EntryMap; | 346 typedef base::hash_map<std::string, MockDiskEntry*> EntryMap; |
| 315 EntryMap entries_; | 347 EntryMap entries_; |
| 316 int open_count_; | 348 int open_count_; |
| 317 int create_count_; | 349 int create_count_; |
| 318 bool fail_requests_; | 350 bool fail_requests_; |
| 351 bool soft_failures_; |
| 319 }; | 352 }; |
| 320 | 353 |
| 321 class MockHttpCache { | 354 class MockHttpCache { |
| 322 public: | 355 public: |
| 323 MockHttpCache() : http_cache_(new MockNetworkLayer(), new MockDiskCache()) { | 356 MockHttpCache() : http_cache_(new MockNetworkLayer(), new MockDiskCache()) { |
| 324 } | 357 } |
| 325 | 358 |
| 326 net::HttpCache* http_cache() { return &http_cache_; } | 359 net::HttpCache* http_cache() { return &http_cache_; } |
| 327 | 360 |
| 328 MockNetworkLayer* network_layer() { | 361 MockNetworkLayer* network_layer() { |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 cache.disk_cache()->set_fail_requests(); | 609 cache.disk_cache()->set_fail_requests(); |
| 577 | 610 |
| 578 // Read from the network, and don't use the cache. | 611 // Read from the network, and don't use the cache. |
| 579 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | 612 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
| 580 | 613 |
| 581 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 614 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 582 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 615 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 583 EXPECT_EQ(0, cache.disk_cache()->create_count()); | 616 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
| 584 } | 617 } |
| 585 | 618 |
| 619 TEST(HttpCache, SimpleGETWithDiskFailures) { |
| 620 MockHttpCache cache; |
| 621 |
| 622 cache.disk_cache()->set_soft_failures(true); |
| 623 |
| 624 // Read from the network, and fail to write to the cache. |
| 625 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
| 626 |
| 627 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 628 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 629 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 630 |
| 631 // This one should see an empty cache again. |
| 632 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
| 633 |
| 634 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 635 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 636 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 637 } |
| 638 |
| 586 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) { | 639 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) { |
| 587 MockHttpCache cache; | 640 MockHttpCache cache; |
| 588 | 641 |
| 589 // write to the cache | 642 // write to the cache |
| 590 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | 643 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
| 591 | 644 |
| 592 // force this transaction to read from the cache | 645 // force this transaction to read from the cache |
| 593 MockTransaction transaction(kSimpleGET_Transaction); | 646 MockTransaction transaction(kSimpleGET_Transaction); |
| 594 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; | 647 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; |
| 595 | 648 |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 Context* c = context_list[0]; | 893 Context* c = context_list[0]; |
| 841 ASSERT_EQ(net::ERR_IO_PENDING, c->result); | 894 ASSERT_EQ(net::ERR_IO_PENDING, c->result); |
| 842 c->result = c->callback.WaitForResult(); | 895 c->result = c->callback.WaitForResult(); |
| 843 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 896 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 844 | 897 |
| 845 // Now we have 2 active readers and two queued transactions. | 898 // Now we have 2 active readers and two queued transactions. |
| 846 | 899 |
| 847 c = context_list[1]; | 900 c = context_list[1]; |
| 848 ASSERT_EQ(net::ERR_IO_PENDING, c->result); | 901 ASSERT_EQ(net::ERR_IO_PENDING, c->result); |
| 849 c->result = c->callback.WaitForResult(); | 902 c->result = c->callback.WaitForResult(); |
| 850 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 903 if (c->result == net::OK) |
| 904 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 851 | 905 |
| 852 // At this point we have one reader, two pending transactions and a task on | 906 // At this point we have one reader, two pending transactions and a task on |
| 853 // the queue to move to the next transaction. Now we cancel the request that | 907 // the queue to move to the next transaction. Now we cancel the request that |
| 854 // is the current reader, and expect the queued task to be able to start the | 908 // is the current reader, and expect the queued task to be able to start the |
| 855 // next request. | 909 // next request. |
| 856 | 910 |
| 857 c = context_list[2]; | 911 c = context_list[2]; |
| 858 c->trans.reset(); | 912 c->trans.reset(); |
| 859 | 913 |
| 860 for (int i = 3; i < kNumTransactions; ++i) { | 914 for (int i = 3; i < kNumTransactions; ++i) { |
| 861 Context* c = context_list[i]; | 915 Context* c = context_list[i]; |
| 862 if (c->result == net::ERR_IO_PENDING) | 916 if (c->result == net::ERR_IO_PENDING) |
| 863 c->result = c->callback.WaitForResult(); | 917 c->result = c->callback.WaitForResult(); |
| 864 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 918 if (c->result == net::OK) |
| 919 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 865 } | 920 } |
| 866 | 921 |
| 867 // We should not have had to re-open the disk entry. | 922 // We should not have had to re-open the disk entry. |
| 868 | 923 |
| 869 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 924 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 870 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 925 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 871 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 926 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 872 | 927 |
| 873 for (int i = 0; i < kNumTransactions; ++i) { | 928 for (int i = 0; i < kNumTransactions; ++i) { |
| 874 Context* c = context_list[i]; | 929 Context* c = context_list[i]; |
| (...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1982 | 2037 |
| 1983 // force this transaction to write to the cache again | 2038 // force this transaction to write to the cache again |
| 1984 MockTransaction transaction(kSimpleGET_Transaction); | 2039 MockTransaction transaction(kSimpleGET_Transaction); |
| 1985 | 2040 |
| 1986 RunTransactionTest(cache.http_cache(), transaction); | 2041 RunTransactionTest(cache.http_cache(), transaction); |
| 1987 | 2042 |
| 1988 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 2043 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1989 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2044 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1990 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2045 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1991 } | 2046 } |
| OLD | NEW |