summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 18:40:10 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 18:40:10 +0000
commitf870252fda3d5724feeda33aeb6deaf502643a31 (patch)
treeac8b4391c15be1d0bb3af6def8cba95d0587caae /net/http
parent2c9be01dc74d1b0edff9c9288abcb66516083af0 (diff)
downloadchromium_src-f870252fda3d5724feeda33aeb6deaf502643a31.zip
chromium_src-f870252fda3d5724feeda33aeb6deaf502643a31.tar.gz
chromium_src-f870252fda3d5724feeda33aeb6deaf502643a31.tar.bz2
Http Cache: Add a backend factory class so that the caller
has more control about the backend instantiation. BUG=none TEST=current unit tests. Review URL: http://codereview.chromium.org/2000011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47050 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_cache.cc113
-rw-r--r--net/http/http_cache.h100
-rw-r--r--net/http/http_cache_unittest.cc357
3 files changed, 268 insertions, 302 deletions
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index 08b9aa6..d6624be 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -33,6 +33,23 @@
namespace net {
+int HttpCache::DefaultBackend::CreateBackend(disk_cache::Backend** backend,
+ CompletionCallback* callback) {
+ DCHECK_GE(max_bytes_, 0);
+ if (callback)
+ return disk_cache::CreateCacheBackend(type_, path_, max_bytes_, true,
+ thread_, backend, callback);
+
+ // This is just old code needed to support synchronous cache creation.
+ // TODO(rvargas): Remove this once all callers provide a callback.
+ if (type_ == MEMORY_CACHE) {
+ *backend = disk_cache::CreateInMemoryCacheBackend(max_bytes_);
+ } else {
+ *backend = disk_cache::CreateCacheBackend(path_, true, max_bytes_, type_);
+ }
+ return (*backend ? OK : ERR_FAILED);
+}
+
//-----------------------------------------------------------------------------
HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* e)
@@ -215,78 +232,41 @@ void HttpCache::MetadataWriter::OnIOComplete(int result) {
//-----------------------------------------------------------------------------
HttpCache::HttpCache(NetworkChangeNotifier* network_change_notifier,
- HostResolver* host_resolver,
- ProxyService* proxy_service,
+ HostResolver* host_resolver, ProxyService* proxy_service,
SSLConfigService* ssl_config_service,
HttpAuthHandlerFactory* http_auth_handler_factory,
- const FilePath& cache_dir,
- MessageLoop* cache_thread,
- int cache_size)
- : disk_cache_dir_(cache_dir),
- cache_thread_(cache_thread),
+ BackendFactory* backend_factory)
+ : backend_factory_(backend_factory),
temp_backend_(NULL),
building_backend_(false),
mode_(NORMAL),
- type_(DISK_CACHE),
network_layer_(HttpNetworkLayer::CreateFactory(
network_change_notifier, host_resolver, proxy_service,
ssl_config_service, http_auth_handler_factory)),
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
- enable_range_support_(true),
- cache_size_(cache_size),
- create_backend_fn_(NULL) {
+ enable_range_support_(true) {
}
HttpCache::HttpCache(HttpNetworkSession* session,
- const FilePath& cache_dir,
- MessageLoop* cache_thread,
- int cache_size)
- : disk_cache_dir_(cache_dir),
- cache_thread_(cache_thread),
+ BackendFactory* backend_factory)
+ : backend_factory_(backend_factory),
temp_backend_(NULL),
building_backend_(false),
mode_(NORMAL),
- type_(DISK_CACHE),
network_layer_(HttpNetworkLayer::CreateFactory(session)),
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
- enable_range_support_(true),
- cache_size_(cache_size),
- create_backend_fn_(NULL) {
-}
-
-HttpCache::HttpCache(NetworkChangeNotifier* network_change_notifier,
- HostResolver* host_resolver,
- ProxyService* proxy_service,
- SSLConfigService* ssl_config_service,
- HttpAuthHandlerFactory* http_auth_handler_factory,
- int cache_size)
- : cache_thread_(NULL),
- temp_backend_(NULL),
- building_backend_(false),
- mode_(NORMAL),
- type_(MEMORY_CACHE),
- network_layer_(HttpNetworkLayer::CreateFactory(
- network_change_notifier, host_resolver, proxy_service,
- ssl_config_service, http_auth_handler_factory)),
- ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
- enable_range_support_(true),
- cache_size_(cache_size),
- create_backend_fn_(NULL) {
+ enable_range_support_(true) {
}
HttpCache::HttpCache(HttpTransactionFactory* network_layer,
- disk_cache::Backend* disk_cache)
- : cache_thread_(NULL),
+ BackendFactory* backend_factory)
+ : backend_factory_(backend_factory),
temp_backend_(NULL),
building_backend_(false),
mode_(NORMAL),
- type_(DISK_CACHE),
network_layer_(network_layer),
- disk_cache_(disk_cache),
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
- enable_range_support_(true),
- cache_size_(0),
- create_backend_fn_(NULL) {
+ enable_range_support_(true) {
}
HttpCache::~HttpCache() {
@@ -322,16 +302,11 @@ disk_cache::Backend* HttpCache::GetBackend() {
if (disk_cache_.get())
return disk_cache_.get();
- DCHECK_GE(cache_size_, 0);
- if (type_ == MEMORY_CACHE) {
- // We may end up with no folder name and no cache if the initialization
- // of the disk cache fails. We want to be sure that what we wanted to have
- // was an in-memory cache.
- disk_cache_.reset(disk_cache::CreateInMemoryCacheBackend(cache_size_));
- } else if (!disk_cache_dir_.empty()) {
- disk_cache_.reset(disk_cache::CreateCacheBackend(disk_cache_dir_, true,
- cache_size_, type_));
- disk_cache_dir_ = FilePath(); // Reclaim memory.
+ if (backend_factory_.get()) {
+ disk_cache::Backend* backend;
+ if (OK == backend_factory_->CreateBackend(&backend, NULL))
+ disk_cache_.reset(backend);
+ backend_factory_.reset(); // Reclaim memory.
}
return disk_cache_.get();
}
@@ -345,7 +320,6 @@ int HttpCache::GetBackend(disk_cache::Backend** backend,
return OK;
}
- DCHECK_GE(cache_size_, 0);
return CreateBackend(backend, callback);
}
@@ -445,12 +419,9 @@ void HttpCache::CloseCurrentConnections() {
int HttpCache::CreateBackend(disk_cache::Backend** backend,
CompletionCallback* callback) {
- // We may end up with no folder name and no cache if the initialization
- // of the disk cache fails.
- if (type_ != MEMORY_CACHE && disk_cache_dir_.empty())
+ if (!backend_factory_.get())
return ERR_FAILED;
- DCHECK_GE(cache_size_, 0);
building_backend_ = true;
scoped_ptr<WorkItem> item(new WorkItem(WI_CREATE_BACKEND, NULL, callback,
@@ -471,18 +442,7 @@ int HttpCache::CreateBackend(disk_cache::Backend** backend,
BackendCallback* my_callback = new BackendCallback(this, pending_op);
pending_op->callback = my_callback;
- // See if this is a unit test. TODO(rvargas): Cleanup this after removing the
- // overloaded method.
- int rv;
- if (create_backend_fn_) {
- rv = create_backend_fn_(type_, disk_cache_dir_, cache_size_, true,
- cache_thread_, &temp_backend_, my_callback);
- } else {
- rv = disk_cache::CreateCacheBackend(type_, disk_cache_dir_, cache_size_,
- true, cache_thread_, &temp_backend_,
- my_callback);
- }
-
+ int rv = backend_factory_->CreateBackend(&temp_backend_, my_callback);
if (rv != ERR_IO_PENDING) {
pending_op->writer->ClearCallback();
my_callback->Run(rv);
@@ -1060,15 +1020,14 @@ void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) {
WorkItemOperation op = item->operation();
DCHECK_EQ(WI_CREATE_BACKEND, op);
- if (type_ != MEMORY_CACHE)
- disk_cache_dir_ = FilePath(); // Reclaim memory.
+ backend_factory_.reset(); // Reclaim memory.
if (result == OK)
disk_cache_.reset(temp_backend_);
item->DoCallback(result, temp_backend_);
- // Notify and all callers and delete all pending work items.
+ // Notify all callers and delete all pending work items.
while (!pending_op->pending_queue.empty()) {
scoped_ptr<WorkItem> pending_item(pending_op->pending_queue.front());
pending_op->pending_queue.pop_front();
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index bb2bf48..c82dc4e 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -26,7 +26,6 @@
#include "net/base/cache_type.h"
#include "net/base/completion_callback.h"
#include "net/http/http_transaction_factory.h"
-#include "testing/gtest/include/gtest/gtest_prod.h"
class GURL;
class MessageLoop;
@@ -68,45 +67,68 @@ class HttpCache : public HttpTransactionFactory,
DISABLE
};
- // Initialize the cache from the directory where its data is stored. The
- // disk cache is initialized lazily (by CreateTransaction) in this case. If
- // |cache_size| is zero, a default value will be calculated automatically.
- // The |cache_thread| is the thread where disk operations should take place.
+ // A BackendFactory creates a backend object to be used by the HttpCache.
+ class BackendFactory {
+ public:
+ virtual ~BackendFactory() {}
+
+ // The actual method to build the backend. Returns a net error code. If
+ // ERR_IO_PENDING is returned, the |callback| will be notified when the
+ // operation completes, and |backend| must remain valid until the
+ // notification arrives.
+ // The implementation must not access the factory object after invoking the
+ // |callback| because the object can be deleted from within the callback.
+ virtual int CreateBackend(disk_cache::Backend** backend,
+ CompletionCallback* callback) = 0;
+ };
+
+ // A default backend factory for the common use cases.
+ class DefaultBackend : public BackendFactory {
+ public:
+ // |path| is the destination for any files used by the backend, and
+ // |cache_thread| is the thread where disk operations should take place. If
+ // |max_bytes| is zero, a default value will be calculated automatically.
+ DefaultBackend(CacheType type, const FilePath& path, int max_bytes,
+ MessageLoop* thread)
+ : type_(type), path_(path), max_bytes_(max_bytes), thread_(thread) {}
+
+ // Returns a factory for an in-memory cache.
+ static BackendFactory* InMemory(int max_bytes) {
+ return new DefaultBackend(MEMORY_CACHE, FilePath(), max_bytes, NULL);
+ }
+
+ // BackendFactory implementation.
+ virtual int CreateBackend(disk_cache::Backend** backend,
+ CompletionCallback* callback);
+
+ private:
+ CacheType type_;
+ const FilePath path_;
+ int max_bytes_;
+ MessageLoop* thread_;
+ };
+
+ // The disk cache is initialized lazily (by CreateTransaction) in this case.
+ // The HttpCache takes ownership of the |backend_factory|.
HttpCache(NetworkChangeNotifier* network_change_notifier,
- HostResolver* host_resolver,
- ProxyService* proxy_service,
+ HostResolver* host_resolver, ProxyService* proxy_service,
SSLConfigService* ssl_config_service,
HttpAuthHandlerFactory* http_auth_handler_factory,
- const FilePath& cache_dir,
- MessageLoop* cache_thread,
- int cache_size);
+ BackendFactory* backend_factory);
- // Initialize the cache from the directory where its data is stored. The
- // disk cache is initialized lazily (by CreateTransaction) in this case. If
- // |cache_size| is zero, a default value will be calculated automatically.
+ // The disk cache is initialized lazily (by CreateTransaction) in this case.
// Provide an existing HttpNetworkSession, the cache can construct a
// network layer with a shared HttpNetworkSession in order for multiple
- // network layers to share information (e.g. authenication data).
- // The |cache_thread| is the thread where disk operations should take place.
- HttpCache(HttpNetworkSession* session, const FilePath& cache_dir,
- MessageLoop* cache_thread, int cache_size);
-
- // Initialize using an in-memory cache. The cache is initialized lazily
- // (by CreateTransaction) in this case. If |cache_size| is zero, a default
- // value will be calculated automatically.
- HttpCache(NetworkChangeNotifier* network_change_notifier,
- HostResolver* host_resolver,
- ProxyService* proxy_service,
- SSLConfigService* ssl_config_service,
- HttpAuthHandlerFactory* http_auth_handler_factory,
- int cache_size);
+ // network layers to share information (e.g. authenication data). The
+ // HttpCache takes ownership of the |backend_factory|.
+ HttpCache(HttpNetworkSession* session, BackendFactory* backend_factory);
// Initialize the cache from its component parts, which is useful for
- // testing. The lifetime of the network_layer and disk_cache are managed by
- // the HttpCache and will be destroyed using |delete| when the HttpCache is
+ // testing. The lifetime of the network_layer and backend_factory are managed
+ // by the HttpCache and will be destroyed using |delete| when the HttpCache is
// destroyed.
HttpCache(HttpTransactionFactory* network_layer,
- disk_cache::Backend* disk_cache);
+ BackendFactory* backend_factory);
HttpTransactionFactory* network_layer() { return network_layer_.get(); }
@@ -160,9 +182,6 @@ class HttpCache : public HttpTransactionFactory,
void set_mode(Mode value) { mode_ = value; }
Mode mode() { return mode_; }
- void set_type(CacheType type) { type_ = type; }
- CacheType type() { return type_; }
-
// Close currently active sockets so that fresh page loads will not use any
// recycled connections. For sockets currently in use, they may not close
// immediately, but they will not be reusable. This is for debugging.
@@ -185,9 +204,6 @@ class HttpCache : public HttpTransactionFactory,
friend class ::ViewCacheHelper;
private:
- FRIEND_TEST(HttpCacheTest, SimpleGET_WaitForBackend);
- FRIEND_TEST(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate);
-
// Types --------------------------------------------------------------------
class BackendCallback;
@@ -216,10 +232,6 @@ class HttpCache : public HttpTransactionFactory,
typedef base::hash_map<std::string, PendingOp*> PendingOpsMap;
typedef std::set<ActiveEntry*> ActiveEntriesSet;
- typedef int (*CreateCacheBackendFn)(CacheType, const FilePath&, int,
- bool, MessageLoop*, disk_cache::Backend**,
- CompletionCallback*);
-
// Methods ------------------------------------------------------------------
// Creates the |backend| object and notifies the |callback| when the operation
@@ -341,13 +353,11 @@ class HttpCache : public HttpTransactionFactory,
// Variables ----------------------------------------------------------------
// Used when lazily constructing the disk_cache_.
- FilePath disk_cache_dir_;
- MessageLoop* cache_thread_;
+ scoped_ptr<BackendFactory> backend_factory_;
disk_cache::Backend* temp_backend_;
bool building_backend_;
Mode mode_;
- CacheType type_;
scoped_ptr<HttpTransactionFactory> network_layer_;
scoped_ptr<disk_cache::Backend> disk_cache_;
@@ -364,14 +374,10 @@ class HttpCache : public HttpTransactionFactory,
ScopedRunnableMethodFactory<HttpCache> task_factory_;
bool enable_range_support_;
- int cache_size_;
typedef base::hash_map<std::string, int> PlaybackCacheMap;
scoped_ptr<PlaybackCacheMap> playback_cache_map_;
- // Used for unit tests.
- CreateCacheBackendFn create_backend_fn_;
-
DISALLOW_COPY_AND_ASSIGN(HttpCache);
};
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index 4508446..75fdc68 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -551,13 +551,23 @@ class MockDiskCache : public disk_cache::Backend {
bool soft_failures_;
};
+class MockBackendFactory : public net::HttpCache::BackendFactory {
+ public:
+ virtual int CreateBackend(disk_cache::Backend** backend,
+ net::CompletionCallback* callback) {
+ *backend = new MockDiskCache();
+ return net::OK;
+ }
+};
+
class MockHttpCache {
public:
- MockHttpCache() : http_cache_(new MockNetworkLayer(), new MockDiskCache()) {
+ MockHttpCache()
+ : http_cache_(new MockNetworkLayer(), new MockBackendFactory()) {
}
- explicit MockHttpCache(disk_cache::Backend* disk_cache)
- : http_cache_(new MockNetworkLayer(), disk_cache) {
+ explicit MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory)
+ : http_cache_(new MockNetworkLayer(), disk_cache_factory) {
}
net::HttpCache* http_cache() { return &http_cache_; }
@@ -631,6 +641,58 @@ class MockDiskCacheNoCB : public MockDiskCache {
}
};
+class MockBackendNoCbFactory : public net::HttpCache::BackendFactory {
+ public:
+ virtual int CreateBackend(disk_cache::Backend** backend,
+ net::CompletionCallback* callback) {
+ *backend = new MockDiskCacheNoCB();
+ return net::OK;
+ }
+};
+
+// This backend factory allows us to control the backend instantiation.
+class MockBlockingBackendFactory : public net::HttpCache::BackendFactory {
+ public:
+ MockBlockingBackendFactory()
+ : backend_(NULL), callback_(NULL), block_(true), fail_(false) {}
+
+ virtual int CreateBackend(disk_cache::Backend** backend,
+ net::CompletionCallback* callback) {
+ if (!block_) {
+ if (!fail_)
+ *backend = new MockDiskCache();
+ return Result();
+ }
+
+ backend_ = backend;
+ callback_ = callback;
+ return net::ERR_IO_PENDING;
+ }
+
+ // Completes the backend creation. Any blocked call will be notified via the
+ // provided callback.
+ void FinishCreation() {
+ block_ = false;
+ if (callback_) {
+ if (!fail_)
+ *backend_ = new MockDiskCache();
+ net::CompletionCallback* cb = callback_;
+ callback_ = NULL;
+ cb->Run(Result()); // This object can be deleted here.
+ }
+ }
+
+ void set_fail(bool fail) { fail_ = fail; }
+
+ private:
+ int Result() { return fail_ ? net::ERR_FAILED : net::OK; }
+
+ disk_cache::Backend** backend_;
+ net::CompletionCallback* callback_;
+ bool block_;
+ bool fail_;
+};
+
//-----------------------------------------------------------------------------
// helpers
@@ -929,169 +991,6 @@ struct Context {
//-----------------------------------------------------------------------------
// tests
-namespace net {
-
-// This is a friend class of the HttpCache so that we can interact with it to
-// perform a few internal tests. We override the backend factory method so that
-// we can test the logic of backend instantiation.
-class HttpCacheTest : public testing::Test {
- public:
- // Controls whether to block the backend instantiation or not. If |block| is
- // true, any blocked call will be notified via the provided callback.
- void BlockCacheCreation(bool block) {
- block_ = block;
- if (!block_ && callback_) {
- *backend_ = new MockDiskCache();
- callback_->Run(OK);
- callback_ = NULL;
- }
- }
-
- protected:
- virtual void SetUp() {
- current_test_ = this;
- backend_ = NULL;
- callback_ = NULL;
- block_ = false;
- }
-
- virtual void TearDown() { current_test_ = NULL; }
-
- // Implements disk_cache::CreateCacheBackend().
- static int MockCreateBackend(CacheType type, const FilePath& path,
- int max_bytes, bool force, MessageLoop* thread,
- disk_cache::Backend** backend,
- CompletionCallback* callback) {
- if (current_test_ == NULL) {
- EXPECT_TRUE(current_test_);
- return ERR_FAILED;
- }
- if (!current_test_->block_) {
- *backend = new MockDiskCache();
- return OK;
- }
-
- current_test_->backend_ = backend;
- current_test_->callback_ = callback;
- return ERR_IO_PENDING;
- }
-
- private:
- static HttpCacheTest* current_test_;
- disk_cache::Backend** backend_;
- CompletionCallback* callback_;
- bool block_;
-};
-
-// Static.
-HttpCacheTest* HttpCacheTest::current_test_ = NULL;
-
-// Tests that we queue requests when initializing the backend.
-TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) {
- MockHttpCache cache(NULL);
- cache.http_cache()->create_backend_fn_ = MockCreateBackend;
- cache.http_cache()->set_type(MEMORY_CACHE);
- BlockCacheCreation(true);
-
- MockHttpRequest request0(kSimpleGET_Transaction);
- MockHttpRequest request1(kTypicalGET_Transaction);
- MockHttpRequest request2(kETagGET_Transaction);
-
- std::vector<Context*> context_list;
- const int kNumTransactions = 3;
-
- for (int i = 0; i < kNumTransactions; i++) {
- context_list.push_back(new Context());
- Context* c = context_list[i];
-
- c->result = cache.http_cache()->CreateTransaction(&c->trans);
- EXPECT_EQ(OK, c->result);
- }
-
- context_list[0]->result = context_list[0]->trans->Start(
- &request0, &context_list[0]->callback, BoundNetLog());
- context_list[1]->result = context_list[1]->trans->Start(
- &request1, &context_list[1]->callback, BoundNetLog());
- context_list[2]->result = context_list[2]->trans->Start(
- &request2, &context_list[2]->callback, BoundNetLog());
-
- // Just to make sure that everything is still pending.
- MessageLoop::current()->RunAllPending();
-
- // The first request should be creating the disk cache.
- EXPECT_FALSE(context_list[0]->callback.have_result());
-
- BlockCacheCreation(false);
-
- MessageLoop::current()->RunAllPending();
- EXPECT_EQ(3, cache.network_layer()->transaction_count());
- EXPECT_EQ(3, cache.disk_cache()->create_count());
-
- for (int i = 0; i < kNumTransactions; ++i) {
- EXPECT_TRUE(context_list[i]->callback.have_result());
- delete context_list[i];
- }
-}
-
-// Tests that we can cancel requests that are queued waiting for the backend
-// to be initialized.
-TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) {
- MockHttpCache cache(NULL);
- cache.http_cache()->create_backend_fn_ = MockCreateBackend;
- cache.http_cache()->set_type(MEMORY_CACHE);
- BlockCacheCreation(true);
-
- MockHttpRequest request0(kSimpleGET_Transaction);
- MockHttpRequest request1(kTypicalGET_Transaction);
- MockHttpRequest request2(kETagGET_Transaction);
-
- std::vector<Context*> context_list;
- const int kNumTransactions = 3;
-
- for (int i = 0; i < kNumTransactions; i++) {
- context_list.push_back(new Context());
- Context* c = context_list[i];
-
- c->result = cache.http_cache()->CreateTransaction(&c->trans);
- EXPECT_EQ(OK, c->result);
- }
-
- context_list[0]->result = context_list[0]->trans->Start(
- &request0, &context_list[0]->callback, BoundNetLog());
- context_list[1]->result = context_list[1]->trans->Start(
- &request1, &context_list[1]->callback, BoundNetLog());
- context_list[2]->result = context_list[2]->trans->Start(
- &request2, &context_list[2]->callback, BoundNetLog());
-
- // Just to make sure that everything is still pending.
- MessageLoop::current()->RunAllPending();
-
- // The first request should be creating the disk cache.
- EXPECT_FALSE(context_list[0]->callback.have_result());
-
- // Cancel a request from the pending queue.
- delete context_list[1];
- context_list[1] = NULL;
-
- // Cancel the request that is creating the entry.
- delete context_list[0];
- context_list[0] = NULL;
-
- // Complete the last transaction.
- BlockCacheCreation(false);
-
- context_list[2]->result =
- context_list[2]->callback.GetResult(context_list[2]->result);
- ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
-
- EXPECT_EQ(1, cache.network_layer()->transaction_count());
- EXPECT_EQ(1, cache.disk_cache()->create_count());
-
- delete context_list[2];
-}
-
-} // net namespace.
-
TEST(HttpCache, CreateThenDestroy) {
MockHttpCache cache;
@@ -1102,11 +1001,9 @@ TEST(HttpCache, CreateThenDestroy) {
}
TEST(HttpCache, GetBackend) {
- // This will initialize a cache object with NULL backend.
- MockHttpCache cache(NULL);
+ MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
// This will lazily initialize the backend.
- cache.http_cache()->set_type(net::MEMORY_CACHE);
EXPECT_TRUE(cache.http_cache()->GetBackend());
}
@@ -1155,7 +1052,10 @@ TEST(HttpCache, SimpleGETNoDiskCache) {
TEST(HttpCache, SimpleGETNoDiskCache2) {
// This will initialize a cache object with NULL backend.
- MockHttpCache cache(NULL);
+ MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
+ factory->set_fail(true);
+ factory->FinishCreation(); // We'll complete synchronously.
+ MockHttpCache cache(factory);
// Read from the network, and don't use the cache.
RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
@@ -1632,9 +1532,7 @@ TEST(HttpCache, SimpleGET_RacingReaders) {
// See http://code.google.com/p/chromium/issues/detail?id=25588
TEST(HttpCache, SimpleGET_DoomWithPending) {
// We need simultaneous doomed / not_doomed entries so let's use a real cache.
- disk_cache::Backend* disk_cache =
- disk_cache::CreateInMemoryCacheBackend(1024 * 1024);
- MockHttpCache cache(disk_cache);
+ MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
MockHttpRequest request(kSimpleGET_Transaction);
MockHttpRequest writer_request(kSimpleGET_Transaction);
@@ -1919,7 +1817,8 @@ TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
// Tests that we can delete the HttpCache and deal with queued transactions
// ("waiting for the backend" as opposed to Active or Doomed entries).
TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
- scoped_ptr<MockHttpCache> cache(new MockHttpCache(new MockDiskCacheNoCB()));
+ scoped_ptr<MockHttpCache> cache(new MockHttpCache(
+ new MockBackendNoCbFactory()));
MockHttpRequest request(kSimpleGET_Transaction);
@@ -1952,6 +1851,106 @@ TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
}
}
+// Tests that we queue requests when initializing the backend.
+TEST(HttpCache, SimpleGET_WaitForBackend) {
+ MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
+ MockHttpCache cache(factory);
+
+ MockHttpRequest request0(kSimpleGET_Transaction);
+ MockHttpRequest request1(kTypicalGET_Transaction);
+ MockHttpRequest request2(kETagGET_Transaction);
+
+ std::vector<Context*> context_list;
+ const int kNumTransactions = 3;
+
+ for (int i = 0; i < kNumTransactions; i++) {
+ context_list.push_back(new Context());
+ Context* c = context_list[i];
+
+ c->result = cache.http_cache()->CreateTransaction(&c->trans);
+ EXPECT_EQ(net::OK, c->result);
+ }
+
+ context_list[0]->result = context_list[0]->trans->Start(
+ &request0, &context_list[0]->callback, net::BoundNetLog());
+ context_list[1]->result = context_list[1]->trans->Start(
+ &request1, &context_list[1]->callback, net::BoundNetLog());
+ context_list[2]->result = context_list[2]->trans->Start(
+ &request2, &context_list[2]->callback, net::BoundNetLog());
+
+ // Just to make sure that everything is still pending.
+ MessageLoop::current()->RunAllPending();
+
+ // The first request should be creating the disk cache.
+ EXPECT_FALSE(context_list[0]->callback.have_result());
+
+ factory->FinishCreation();
+
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(3, cache.network_layer()->transaction_count());
+ EXPECT_EQ(3, cache.disk_cache()->create_count());
+
+ for (int i = 0; i < kNumTransactions; ++i) {
+ EXPECT_TRUE(context_list[i]->callback.have_result());
+ delete context_list[i];
+ }
+}
+
+// Tests that we can cancel requests that are queued waiting for the backend
+// to be initialized.
+TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
+ MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
+ MockHttpCache cache(factory);
+
+ MockHttpRequest request0(kSimpleGET_Transaction);
+ MockHttpRequest request1(kTypicalGET_Transaction);
+ MockHttpRequest request2(kETagGET_Transaction);
+
+ std::vector<Context*> context_list;
+ const int kNumTransactions = 3;
+
+ for (int i = 0; i < kNumTransactions; i++) {
+ context_list.push_back(new Context());
+ Context* c = context_list[i];
+
+ c->result = cache.http_cache()->CreateTransaction(&c->trans);
+ EXPECT_EQ(net::OK, c->result);
+ }
+
+ context_list[0]->result = context_list[0]->trans->Start(
+ &request0, &context_list[0]->callback, net::BoundNetLog());
+ context_list[1]->result = context_list[1]->trans->Start(
+ &request1, &context_list[1]->callback, net::BoundNetLog());
+ context_list[2]->result = context_list[2]->trans->Start(
+ &request2, &context_list[2]->callback, net::BoundNetLog());
+
+ // Just to make sure that everything is still pending.
+ MessageLoop::current()->RunAllPending();
+
+ // The first request should be creating the disk cache.
+ EXPECT_FALSE(context_list[0]->callback.have_result());
+
+ // Cancel a request from the pending queue.
+ delete context_list[1];
+ context_list[1] = NULL;
+
+ // Cancel the request that is creating the entry.
+ delete context_list[0];
+ context_list[0] = NULL;
+
+ // Complete the last transaction.
+ factory->FinishCreation();
+
+ context_list[2]->result =
+ context_list[2]->callback.GetResult(context_list[2]->result);
+ ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
+
+ EXPECT_EQ(1, cache.network_layer()->transaction_count());
+ EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ delete context_list[2];
+}
+
TEST(HttpCache, TypicalGET_ConditionalRequest) {
MockHttpCache cache;
@@ -3546,9 +3545,7 @@ TEST(HttpCache, RangeGET_InvalidResponse3) {
// Tests that we handle large range values properly.
TEST(HttpCache, RangeGET_LargeValues) {
// We need a real sparse cache for this test.
- disk_cache::Backend* disk_cache =
- disk_cache::CreateInMemoryCacheBackend(1024 * 1024);
- MockHttpCache cache(disk_cache);
+ MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
cache.http_cache()->set_enable_range_support(true);
std::string headers;
@@ -3580,7 +3577,11 @@ TEST(HttpCache, RangeGET_LargeValues) {
// Tests that we don't crash with a range request if the disk cache was not
// initialized properly.
TEST(HttpCache, RangeGET_NoDiskCache) {
- MockHttpCache cache(NULL);
+ MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
+ factory->set_fail(true);
+ factory->FinishCreation(); // We'll complete synchronously.
+ MockHttpCache cache(factory);
+
cache.http_cache()->set_enable_range_support(true);
AddMockTransaction(&kRangeGET_TransactionOK);