summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc22
-rw-r--r--chrome/browser/net/connection_tester.cc2
-rw-r--r--chrome_frame/test/test_server_test.cc2
-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
-rw-r--r--net/proxy/proxy_script_fetcher_unittest.cc2
-rw-r--r--net/tools/fetch/fetch_client.cc3
-rw-r--r--net/url_request/url_request_unittest.h2
-rw-r--r--webkit/tools/test_shell/test_shell_request_context.cc19
10 files changed, 298 insertions, 324 deletions
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index 5c77063..c15bfd3 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -247,13 +247,16 @@ ChromeURLRequestContext* FactoryForOriginal::Create() {
command_line,
MessageLoop::current() /*io_loop*/));
+ net::HttpCache::DefaultBackend* backend =
+ new net::HttpCache::DefaultBackend(net::DISK_CACHE, disk_cache_path_,
+ cache_size_, NULL);
net::HttpCache* cache =
new net::HttpCache(io_thread()->globals()->network_change_notifier.get(),
context->host_resolver(),
context->proxy_service(),
context->ssl_config_service(),
context->http_auth_handler_factory(),
- disk_cache_path_, NULL, cache_size_);
+ backend);
if (command_line.HasSwitch(switches::kDisableByteRangeSupport))
cache->set_enable_range_support(false);
@@ -367,13 +370,16 @@ ChromeURLRequestContext* FactoryForOffTheRecord::Create() {
context->set_http_auth_handler_factory(
original_context->http_auth_handler_factory());
+ net::HttpCache::BackendFactory* backend =
+ net::HttpCache::DefaultBackend::InMemory(0);
+
net::HttpCache* cache =
new net::HttpCache(io_thread()->globals()->network_change_notifier.get(),
context->host_resolver(),
context->proxy_service(),
context->ssl_config_service(),
context->http_auth_handler_factory(),
- 0);
+ backend);
context->set_cookie_store(new net::CookieMonster(NULL,
cookie_monster_delegate_));
context->set_cookie_policy(
@@ -440,6 +446,10 @@ ChromeURLRequestContext* FactoryForMedia::Create() {
// Create a media cache with default size.
// TODO(hclam): make the maximum size of media cache configurable.
+ net::HttpCache::DefaultBackend* backend =
+ new net::HttpCache::DefaultBackend(net::MEDIA_CACHE, disk_cache_path_,
+ cache_size_, NULL);
+
net::HttpCache* main_cache =
main_context->http_transaction_factory()->GetCache();
net::HttpCache* cache;
@@ -448,11 +458,10 @@ ChromeURLRequestContext* FactoryForMedia::Create() {
// HttpTransactionFactory (network_layer()) of HttpCache is implemented
// by HttpNetworkLayer so we can reuse HttpNetworkSession within it. This
// assumption will be invalid if the original HttpCache is constructed with
- // HttpCache(HttpTransactionFactory*, disk_cache::Backend*) constructor.
+ // HttpCache(HttpTransactionFactory*, BackendFactory*) constructor.
net::HttpNetworkLayer* main_network_layer =
static_cast<net::HttpNetworkLayer*>(main_cache->network_layer());
- cache = new net::HttpCache(main_network_layer->GetSession(),
- disk_cache_path_, NULL, cache_size_);
+ cache = new net::HttpCache(main_network_layer->GetSession(), backend);
// TODO(eroman): Since this is poaching the session from the main
// context, it should hold a reference to that context preventing the
// session from getting deleted.
@@ -465,14 +474,13 @@ ChromeURLRequestContext* FactoryForMedia::Create() {
main_context->proxy_service(),
main_context->ssl_config_service(),
main_context->http_auth_handler_factory(),
- disk_cache_path_, NULL, cache_size_);
+ backend);
}
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableByteRangeSupport))
cache->set_enable_range_support(false);
- cache->set_type(net::MEDIA_CACHE);
context->set_http_transaction_factory(cache);
// Use the same appcache service as the profile's main context.
diff --git a/chrome/browser/net/connection_tester.cc b/chrome/browser/net/connection_tester.cc
index c441f1d..430874a 100644
--- a/chrome/browser/net/connection_tester.cc
+++ b/chrome/browser/net/connection_tester.cc
@@ -59,7 +59,7 @@ class ExperimentURLRequestContext : public URLRequestContext {
proxy_service_,
ssl_config_service_,
http_auth_handler_factory_),
- disk_cache::CreateInMemoryCacheBackend(0));
+ net::HttpCache::DefaultBackend::InMemory(0));
// In-memory cookie store.
cookie_store_ = new net::CookieMonster(NULL, NULL);
diff --git a/chrome_frame/test/test_server_test.cc b/chrome_frame/test/test_server_test.cc
index 0523336..9376e0d 100644
--- a/chrome_frame/test/test_server_test.cc
+++ b/chrome_frame/test/test_server_test.cc
@@ -71,7 +71,7 @@ class URLRequestTestContext : public URLRequestContext {
proxy_service_,
ssl_config_service_,
http_auth_handler_factory_),
- disk_cache::CreateInMemoryCacheBackend(0));
+ net::HttpCache::DefaultBackend::InMemory(0));
// In-memory cookie store.
cookie_store_ = new net::CookieMonster(NULL, NULL);
}
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);
diff --git a/net/proxy/proxy_script_fetcher_unittest.cc b/net/proxy/proxy_script_fetcher_unittest.cc
index 7c38470..3a1f707 100644
--- a/net/proxy/proxy_script_fetcher_unittest.cc
+++ b/net/proxy/proxy_script_fetcher_unittest.cc
@@ -41,7 +41,7 @@ class RequestContext : public URLRequestContext {
net::HttpNetworkLayer::CreateFactory(
NULL, host_resolver_, proxy_service_, ssl_config_service_,
NULL),
- disk_cache::CreateInMemoryCacheBackend(0));
+ net::HttpCache::DefaultBackend::InMemory(0));
}
private:
diff --git a/net/tools/fetch/fetch_client.cc b/net/tools/fetch/fetch_client.cc
index c34c6b6..5da7756 100644
--- a/net/tools/fetch/fetch_client.cc
+++ b/net/tools/fetch/fetch_client.cc
@@ -145,7 +145,8 @@ int main(int argc, char**argv) {
if (use_cache) {
factory = new net::HttpCache(NULL, host_resolver, proxy_service,
ssl_config_service,
- http_auth_handler_factory.get(), 0);
+ http_auth_handler_factory.get(),
+ net::HttpCache::DefaultBackend::InMemory(0));
} else {
factory = new net::HttpNetworkLayer(
net::ClientSocketFactory::GetDefaultFactory(), NULL, host_resolver,
diff --git a/net/url_request/url_request_unittest.h b/net/url_request/url_request_unittest.h
index 4861046..6f41e93 100644
--- a/net/url_request/url_request_unittest.h
+++ b/net/url_request/url_request_unittest.h
@@ -166,7 +166,7 @@ class TestURLRequestContext : public URLRequestContext {
proxy_service_,
ssl_config_service_,
http_auth_handler_factory_),
- disk_cache::CreateInMemoryCacheBackend(0));
+ net::HttpCache::DefaultBackend::InMemory(0));
// In-memory cookie store.
cookie_store_ = new net::CookieMonster(NULL, NULL);
accept_language_ = "en-us,fr";
diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc
index 64563e7..25cf877 100644
--- a/webkit/tools/test_shell/test_shell_request_context.cc
+++ b/webkit/tools/test_shell/test_shell_request_context.cc
@@ -78,16 +78,15 @@ void TestShellRequestContext::Init(
base::EnsureNSPRInit();
#endif
- net::HttpCache *cache;
- if (cache_path.empty()) {
- cache = new net::HttpCache(NULL, host_resolver_, proxy_service_,
- ssl_config_service_, http_auth_handler_factory_,
- 0);
- } else {
- cache = new net::HttpCache(NULL, host_resolver_, proxy_service_,
- ssl_config_service_, http_auth_handler_factory_,
- cache_path, NULL, 0);
- }
+ net::HttpCache::DefaultBackend* backend = new net::HttpCache::DefaultBackend(
+ cache_path.empty() ? net::MEMORY_CACHE : net::DISK_CACHE,
+ cache_path, 0, NULL);
+
+ net::HttpCache* cache =
+ new net::HttpCache(NULL, host_resolver_, proxy_service_,
+ ssl_config_service_, http_auth_handler_factory_,
+ backend);
+
cache->set_mode(cache_mode);
http_transaction_factory_ = cache;