Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1855)

Unified Diff: chrome/browser/net/resolve_proxy_msg_helper_unittest.cc

Issue 160619: Remove dependency on SingleThreadedProxyResolver from resolve_proxy_msg_helper_unittest (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Address willchan's comments + sync Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | net/net.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/net/resolve_proxy_msg_helper_unittest.cc
===================================================================
--- chrome/browser/net/resolve_proxy_msg_helper_unittest.cc (revision 22580)
+++ chrome/browser/net/resolve_proxy_msg_helper_unittest.cc (working copy)
@@ -6,13 +6,12 @@
#include "base/waitable_event.h"
#include "net/base/net_errors.h"
+#include "net/proxy/mock_proxy_resolver.h"
#include "net/proxy/proxy_config_service.h"
-#include "net/proxy/proxy_resolver.h"
-#include "net/proxy/single_threaded_proxy_resolver.h"
#include "testing/gtest/include/gtest/gtest.h"
// This ProxyConfigService always returns "http://pac" as the PAC url to use.
-class MockProxyConfigService: public net::ProxyConfigService {
+class MockProxyConfigService : public net::ProxyConfigService {
public:
virtual int GetProxyConfig(net::ProxyConfig* results) {
results->pac_url = GURL("http://pac");
@@ -20,233 +19,46 @@
}
};
-// This PAC resolver always returns the hostname of the query URL as the
-// proxy to use. The Block() method will make GetProxyForURL() hang until
-// Unblock() is called.
-class SyncMockProxyResolver : public net::ProxyResolver {
+class MyDelegate : public ResolveProxyMsgHelper::Delegate {
public:
- SyncMockProxyResolver() : ProxyResolver(false /*expects_pac_bytes*/),
- event_(false, false),
- is_blocked_(false) {
- }
+ struct PendingResult {
+ PendingResult(IPC::Message* msg,
+ int error_code,
+ const std::string& proxy_list)
+ : msg(msg), error_code(error_code), proxy_list(proxy_list) {
+ }
- virtual int GetProxyForURL(const GURL& query_url,
- net::ProxyInfo* results,
- net::CompletionCallback* callback,
- RequestHandle* request) {
- if (is_blocked_)
- event_.Wait();
- results->UseNamedProxy(query_url.host());
- return net::OK;
- }
+ IPC::Message* msg;
+ int error_code;
+ std::string proxy_list;
+ };
- virtual void CancelRequest(RequestHandle request) {
- NOTREACHED();
- }
-
- virtual int SetPacScript(const GURL& /*pac_url*/,
- const std::string& /*bytes*/,
- net::CompletionCallback* /*callback*/) {
- return net::OK;
- }
-
- void Block() {
- is_blocked_ = true;
- event_.Reset();
- }
-
- void Unblock() {
- is_blocked_ = false;
- event_.Signal();
- }
-
- private:
- base::WaitableEvent event_;
- bool is_blocked_;
-};
-
-class MockProxyResolver : public net::SingleThreadedProxyResolver {
- public:
- MockProxyResolver()
- : net::SingleThreadedProxyResolver(new SyncMockProxyResolver) {
- x = reinterpret_cast<SyncMockProxyResolver*>(resolver());
- }
-
- // TODO(eroman): cleanup.
- SyncMockProxyResolver* x;
-};
-
-// This struct holds the values that were passed to
-// Delegate::OnResolveProxyCompleted(). The caller should use WaitUntilDone()
-// to block until the result has been populated.
-struct ResultFuture {
- public:
- ResultFuture()
- : reply_msg(NULL),
- error_code(0),
- started_(false, false),
- completed_(false, false) {
- }
-
- // Wait until the request has completed. In other words we have invoked:
- // ResolveProxyMsgHelper::Delegate::OnResolveProxyCompleted.
- void WaitUntilDone() {
- completed_.Wait();
- }
-
- // Wait until the request has been sent to ResolveProxyMsgHelper.
- void WaitUntilStarted() {
- started_.Wait();
- }
-
- bool TimedWaitUntilDone(const base::TimeDelta& max_time) {
- return completed_.TimedWait(max_time);
- }
-
- // These fields are only valid after returning from WaitUntilDone().
- IPC::Message* reply_msg;
- int error_code;
- std::string proxy_list;
-
- private:
- friend class AsyncRequestRunner;
- base::WaitableEvent started_;
- base::WaitableEvent completed_;
-};
-
-// This class lives on the io thread. It starts async requests using the
-// class under test (ResolveProxyMsgHelper), and signals the result future on
-// completion.
-class AsyncRequestRunner : public ResolveProxyMsgHelper::Delegate {
- public:
- AsyncRequestRunner(net::ProxyService* proxy_service) {
- resolve_proxy_msg_helper_.reset(
- new ResolveProxyMsgHelper(this, proxy_service));
- }
-
- void Start(ResultFuture* future, const GURL& url, IPC::Message* reply_msg) {
- futures_.push_back(future);
- resolve_proxy_msg_helper_->Start(url, reply_msg);
-
- // Notify of request start.
- future->started_.Signal();
- }
-
+ // ResolveProxyMsgHelper::Delegate implementation:
virtual void OnResolveProxyCompleted(IPC::Message* reply_msg,
int error_code,
const std::string& proxy_list) {
- // Update the result future for this request (top of queue), and signal it.
- ResultFuture* future = futures_.front();
- futures_.pop_front();
-
- future->reply_msg = reply_msg;
- future->error_code = error_code;
- future->proxy_list = proxy_list;
-
- // Notify of request completion.
- future->completed_.Signal();
+ DCHECK(!pending_result_.get());
+ pending_result_.reset(new PendingResult(reply_msg, error_code, proxy_list));
}
- private:
- std::deque<ResultFuture*> futures_;
- scoped_ptr<ResolveProxyMsgHelper> resolve_proxy_msg_helper_;
-};
+ const PendingResult* pending_result() const { return pending_result_.get(); }
-// Helper class to start async requests on an io thread, and return a
-// result future. The caller then uses ResultFuture::WaitUntilDone() to
-// get at the results. It "bridges" the originating thread with the helper
-// io thread.
-class RunnerBridge {
- public:
- RunnerBridge() : io_thread_("io_thread"), done_(false, false) {
- // Start an io thread where we will run the async requests.
- base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_IO;
- io_thread_.StartWithOptions(options);
-
- // Construct the state that lives on io thread.
- io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- this, &RunnerBridge::DoConstruct));
- done_.Wait();
+ void clear_pending_result() {
+ pending_result_.reset();
}
- // Start an async request on the io thread.
- ResultFuture* Start(const GURL& url, IPC::Message* reply_msg) {
- ResultFuture* future = new ResultFuture();
-
- io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- async_runner_, &AsyncRequestRunner::Start, future, url, reply_msg));
-
- return future;
- }
-
- void DestroyAsyncRunner() {
- io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- this, &RunnerBridge::DoDestroyAsyncRunner));
- done_.Wait();
- }
-
- ~RunnerBridge() {
- io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- this, &RunnerBridge::DoDestroy));
- done_.Wait();
- }
-
- MockProxyResolver* proxy_resolver() {
- return proxy_resolver_;
- }
-
- // Called from io thread.
- void DoConstruct() {
- proxy_resolver_ = new MockProxyResolver();
- proxy_service_ = new net::ProxyService(new MockProxyConfigService(),
- proxy_resolver_);
- async_runner_ = new AsyncRequestRunner(proxy_service_);
- done_.Signal();
- }
-
- // Called from io thread.
- void DoDestroy() {
- delete async_runner_;
- delete proxy_service_;
- done_.Signal();
- }
-
- // Called from io thread.
- void DoDestroyAsyncRunner() {
- delete async_runner_;
- async_runner_ = NULL;
- done_.Signal();
- }
-
private:
- base::Thread io_thread_;
- base::WaitableEvent done_;
-
- net::ProxyService* proxy_service_;
- MockProxyResolver* proxy_resolver_; // Owned by proxy_service_.
-
- AsyncRequestRunner* async_runner_;
+ scoped_ptr<PendingResult> pending_result_;
};
-// Avoid the need to have an AddRef / Release
-template<>
-void RunnableMethodTraits<RunnerBridge>::RetainCallee(RunnerBridge*) {}
-template<>
-void RunnableMethodTraits<RunnerBridge>::ReleaseCallee(RunnerBridge*) {}
-
-template<>
-void RunnableMethodTraits<AsyncRequestRunner>::RetainCallee(
- AsyncRequestRunner*) {}
-template<>
-void RunnableMethodTraits<AsyncRequestRunner>::ReleaseCallee(
- AsyncRequestRunner*) {}
-
-
// Issue three sequential requests -- each should succeed.
TEST(ResolveProxyMsgHelperTest, Sequential) {
- RunnerBridge runner;
+ net::MockAsyncProxyResolver* resolver = new net::MockAsyncProxyResolver;
+ net::ProxyService service(new MockProxyConfigService, resolver);
+ MyDelegate delegate;
+ ResolveProxyMsgHelper helper(&delegate, &service);
+
GURL url1("http://www.google1.com/");
GURL url2("http://www.google2.com/");
GURL url3("http://www.google3.com/");
@@ -258,34 +70,57 @@
// Execute each request sequentially (so there are never 2 requests
// outstanding at the same time).
- scoped_ptr<ResultFuture> result1(runner.Start(url1, msg1.get()));
- result1->WaitUntilDone();
+ helper.Start(url1, msg1.get());
- scoped_ptr<ResultFuture> result2(runner.Start(url2, msg2.get()));
- result2->WaitUntilDone();
+ // Finish ProxyService's initialization.
+ resolver->pending_set_pac_script_request()->CompleteNow(net::OK);
- scoped_ptr<ResultFuture> result3(runner.Start(url3, msg3.get()));
- result3->WaitUntilDone();
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url1, resolver->pending_requests()[0]->url());
+ resolver->pending_requests()[0]->results()->UseNamedProxy("result1:80");
+ resolver->pending_requests()[0]->CompleteNow(net::OK);
- // Check that each request gave the expected result.
+ // Check result.
+ EXPECT_EQ(msg1.get(), delegate.pending_result()->msg);
+ EXPECT_EQ(net::OK, delegate.pending_result()->error_code);
+ EXPECT_EQ("PROXY result1:80", delegate.pending_result()->proxy_list);
+ delegate.clear_pending_result();
- EXPECT_EQ(msg1.get(), result1->reply_msg);
- EXPECT_EQ(net::OK, result1->error_code);
- EXPECT_EQ("PROXY www.google1.com:80", result1->proxy_list);
+ helper.Start(url2, msg2.get());
- EXPECT_EQ(msg2.get(), result2->reply_msg);
- EXPECT_EQ(net::OK, result2->error_code);
- EXPECT_EQ("PROXY www.google2.com:80", result2->proxy_list);
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url2, resolver->pending_requests()[0]->url());
+ resolver->pending_requests()[0]->results()->UseNamedProxy("result2:80");
+ resolver->pending_requests()[0]->CompleteNow(net::OK);
- EXPECT_EQ(msg3.get(), result3->reply_msg);
- EXPECT_EQ(net::OK, result3->error_code);
- EXPECT_EQ("PROXY www.google3.com:80", result3->proxy_list);
+ // Check result.
+ EXPECT_EQ(msg2.get(), delegate.pending_result()->msg);
+ EXPECT_EQ(net::OK, delegate.pending_result()->error_code);
+ EXPECT_EQ("PROXY result2:80", delegate.pending_result()->proxy_list);
+ delegate.clear_pending_result();
+
+ helper.Start(url3, msg3.get());
+
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url3, resolver->pending_requests()[0]->url());
+ resolver->pending_requests()[0]->results()->UseNamedProxy("result3:80");
+ resolver->pending_requests()[0]->CompleteNow(net::OK);
+
+ // Check result.
+ EXPECT_EQ(msg3.get(), delegate.pending_result()->msg);
+ EXPECT_EQ(net::OK, delegate.pending_result()->error_code);
+ EXPECT_EQ("PROXY result3:80", delegate.pending_result()->proxy_list);
+ delegate.clear_pending_result();
}
// Issue a request while one is already in progress -- should be queued.
TEST(ResolveProxyMsgHelperTest, QueueRequests) {
- RunnerBridge runner;
+ net::MockAsyncProxyResolver* resolver = new net::MockAsyncProxyResolver;
+ net::ProxyService service(new MockProxyConfigService, resolver);
+ MyDelegate delegate;
+ ResolveProxyMsgHelper helper(&delegate, &service);
+
GURL url1("http://www.google1.com/");
GURL url2("http://www.google2.com/");
GURL url3("http://www.google3.com/");
@@ -294,45 +129,65 @@
scoped_ptr<IPC::Message> msg2(new IPC::Message());
scoped_ptr<IPC::Message> msg3(new IPC::Message());
- // Make the proxy resolver hang on the next request.
- runner.proxy_resolver()->x->Block();
+ // Start three requests. Since the proxy resolver is async, all the
+ // requests will be pending.
- // Start three requests. Since the proxy resolver is hung, the second two
- // will be pending.
+ helper.Start(url1, msg1.get());
- scoped_ptr<ResultFuture> result1(runner.Start(url1, msg1.get()));
- scoped_ptr<ResultFuture> result2(runner.Start(url2, msg2.get()));
- scoped_ptr<ResultFuture> result3(runner.Start(url3, msg3.get()));
+ // Finish ProxyService's initialization.
+ resolver->pending_set_pac_script_request()->CompleteNow(net::OK);
- // Wait for the final request to have been scheduled. Otherwise we may rush
- // to calling Unblock() without actually having blocked anything.
- result3->WaitUntilStarted();
+ helper.Start(url2, msg2.get());
+ helper.Start(url3, msg3.get());
- // Unblock the proxy service so requests 1-3 can complete.
- runner.proxy_resolver()->x->Unblock();
+ // ResolveProxyHelper only keeps 1 request outstanding in ProxyService
+ // at a time.
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url1, resolver->pending_requests()[0]->url());
- // Wait for all the requests to finish (they run in FIFO order).
- result3->WaitUntilDone();
+ resolver->pending_requests()[0]->results()->UseNamedProxy("result1:80");
+ resolver->pending_requests()[0]->CompleteNow(net::OK);
- // Check that each call invoked the callback with the right parameters.
+ // Check result.
+ EXPECT_EQ(msg1.get(), delegate.pending_result()->msg);
+ EXPECT_EQ(net::OK, delegate.pending_result()->error_code);
+ EXPECT_EQ("PROXY result1:80", delegate.pending_result()->proxy_list);
+ delegate.clear_pending_result();
- EXPECT_EQ(msg1.get(), result1->reply_msg);
- EXPECT_EQ(net::OK, result1->error_code);
- EXPECT_EQ("PROXY www.google1.com:80", result1->proxy_list);
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url2, resolver->pending_requests()[0]->url());
- EXPECT_EQ(msg2.get(), result2->reply_msg);
- EXPECT_EQ(net::OK, result2->error_code);
- EXPECT_EQ("PROXY www.google2.com:80", result2->proxy_list);
+ resolver->pending_requests()[0]->results()->UseNamedProxy("result2:80");
+ resolver->pending_requests()[0]->CompleteNow(net::OK);
- EXPECT_EQ(msg3.get(), result3->reply_msg);
- EXPECT_EQ(net::OK, result3->error_code);
- EXPECT_EQ("PROXY www.google3.com:80", result3->proxy_list);
+ // Check result.
+ EXPECT_EQ(msg2.get(), delegate.pending_result()->msg);
+ EXPECT_EQ(net::OK, delegate.pending_result()->error_code);
+ EXPECT_EQ("PROXY result2:80", delegate.pending_result()->proxy_list);
+ delegate.clear_pending_result();
+
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url3, resolver->pending_requests()[0]->url());
+
+ resolver->pending_requests()[0]->results()->UseNamedProxy("result3:80");
+ resolver->pending_requests()[0]->CompleteNow(net::OK);
+
+ // Check result.
+ EXPECT_EQ(msg3.get(), delegate.pending_result()->msg);
+ EXPECT_EQ(net::OK, delegate.pending_result()->error_code);
+ EXPECT_EQ("PROXY result3:80", delegate.pending_result()->proxy_list);
+ delegate.clear_pending_result();
}
// Delete the helper while a request is in progress, and others are pending.
TEST(ResolveProxyMsgHelperTest, CancelPendingRequests) {
- RunnerBridge runner;
+ net::MockAsyncProxyResolver* resolver = new net::MockAsyncProxyResolver;
+ net::ProxyService service(new MockProxyConfigService, resolver);
+ MyDelegate delegate;
+ scoped_ptr<ResolveProxyMsgHelper> helper(
+ new ResolveProxyMsgHelper(&delegate, &service));
+
GURL url1("http://www.google1.com/");
GURL url2("http://www.google2.com/");
GURL url3("http://www.google3.com/");
@@ -343,35 +198,32 @@
IPC::Message* msg2 = new IPC::Message();
IPC::Message* msg3 = new IPC::Message();
- // Make the next request block.
- runner.proxy_resolver()->x->Block();
+ // Start three requests. Since the proxy resolver is async, all the
+ // requests will be pending.
- // Start three requests; since the first one blocked, the other two should
- // be pending.
+ helper->Start(url1, msg1);
- scoped_ptr<ResultFuture> result1(runner.Start(url1, msg1));
- scoped_ptr<ResultFuture> result2(runner.Start(url2, msg2));
- scoped_ptr<ResultFuture> result3(runner.Start(url3, msg3));
+ // Finish ProxyService's initialization.
+ resolver->pending_set_pac_script_request()->CompleteNow(net::OK);
- result3->WaitUntilStarted();
+ helper->Start(url2, msg2);
+ helper->Start(url3, msg3);
+ // ResolveProxyHelper only keeps 1 request outstanding in ProxyService
+ // at a time.
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(url1, resolver->pending_requests()[0]->url());
+
// Delete the underlying ResolveProxyMsgHelper -- this should cancel all
// the requests which are outstanding.
- runner.DestroyAsyncRunner();
+ helper.reset();
- // Unblocking the proxy resolver means the three requests can complete --
- // however they should not try to notify the delegate since we have already
- // deleted the helper.
- runner.proxy_resolver()->x->Unblock();
+ // The pending requests sent to the proxy resolver should have been cancelled.
- // Check that none of the requests were sent to the delegate.
- EXPECT_FALSE(
- result1->TimedWaitUntilDone(base::TimeDelta::FromMilliseconds(2)));
- EXPECT_FALSE(
- result2->TimedWaitUntilDone(base::TimeDelta::FromMilliseconds(2)));
- EXPECT_FALSE(
- result3->TimedWaitUntilDone(base::TimeDelta::FromMilliseconds(2)));
+ EXPECT_EQ(0u, resolver->pending_requests().size());
+ EXPECT_EQ(NULL, delegate.pending_result());
+
// It should also be the case that msg1, msg2, msg3 were deleted by the
- // cancellation. (Else will show up as a leak in Purify).
+ // cancellation. (Else will show up as a leak in Purify/Valgrind).
}
« no previous file with comments | « no previous file | net/net.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698